[pve-devel] [PATCH qemu-server] api: cloud-init support for mtu and userdata

Marius Schellenberger proxmox at giftfish.de
Thu Jul 2 18:08:37 CEST 2020


Extended the PVE API to configure cloud-init userdata and network
interface MTU.

Signed-off-by: Marius Schellenberger <proxmox at giftfish.de>
---
 PVE/API2/Qemu.pm            |  1 +
 PVE/QemuServer.pm           | 18 +++++++++++++++++-
 PVE/QemuServer/Cloudinit.pm | 31 +++++++++++++++++++++++++++++--
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index b33359d..02507de 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -324,6 +324,7 @@ my $cloudinitoptions = {
     cipassword => 1,
     citype => 1,
     ciuser => 1,
+    ciuserdata => 1,
     nameserver => 1,
     searchdomain => 1,
     sshkeys => 1,
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 6872e06..ef4342d 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -727,6 +727,12 @@ my $confdesc_cloudinit = {
 	description => 'cloud-init: Specify custom files to replace the automatically generated ones at start.',
 	format => 'pve-qm-cicustom',
     },
+    ciuserdata => {
+        optional => 1,
+        type => 'string',
+        format => 'urlencoded',
+        description => 'cloud-init: Specify custom user-data as urlencoded base64 string to replace the automatically generated one at start. When set, the following options have no effect: `ciuser`, `cipassword`, `sshkeys`',
+    },
     searchdomain => {
 	optional => 1,
 	type => 'string',
@@ -932,6 +938,12 @@ my $ipconfig_fmt = {
 	optional => 1,
 	requires => 'ip6',
     },
+    mtu => {
+	type => 'string',
+	format_description => 'MTU',
+	description => 'MTU value for interface.',
+	optional => 1,
+    },
 };
 PVE::JSONSchema::register_format('pve-qm-ipconfig', $ipconfig_fmt);
 my $ipconfigdesc = {
@@ -1701,7 +1713,7 @@ sub parse_net {
     return $res;
 }
 
-# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip
+# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip,mtu=mtu
 sub parse_ipconfig {
     my ($data) = @_;
 
@@ -1711,6 +1723,10 @@ sub parse_ipconfig {
 	return undef;
     }
 
+    if ($res->{mtu} && !$res->{ip} && !$res->{ip6}) {
+	warn 'mtu specified without specifying an IP or IPv6 address';
+	return undef;
+    }
     if ($res->{gw} && !$res->{ip}) {
 	warn 'gateway specified without specifying an IP address';
 	return undef;
diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm
index 439de99..a47e0ce 100644
--- a/PVE/QemuServer/Cloudinit.pm
+++ b/PVE/QemuServer/Cloudinit.pm
@@ -6,6 +6,7 @@ use warnings;
 use File::Path;
 use Digest::SHA;
 use URI::Escape;
+use MIME::Base64 qw(decode_base64);
 
 use PVE::Tools qw(run_command file_set_contents);
 use PVE::Storage;
@@ -111,6 +112,11 @@ sub get_dns_conf {
 sub cloudinit_userdata {
     my ($conf, $vmid) = @_;
 
+    my $userdata = $conf->{ciuserdata};
+    if (defined($userdata) && $userdata ne "") {
+        return decode_base64(uri_unescape($userdata));
+    }
+
     my ($hostname, $fqdn) = get_hostname_fqdn($conf, $vmid);
 
     my $content = "#cloud-config\n";
@@ -176,7 +182,9 @@ sub configdrive2_network {
 	(my $id = $iface) =~ s/^net//;
 	next if !$conf->{"ipconfig$id"};
 	my $net = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
+	next if !defined($net);
 	$id = "eth$id";
+	my $mtu = $net->{mtu};
 
 	$content .="auto $id\n";
 	if ($net->{ip}) {
@@ -189,6 +197,9 @@ sub configdrive2_network {
 		$content .= "        netmask $mask\n";
 		$content .= "        gateway $net->{gw}\n" if $net->{gw};
 	    }
+	    if (defined($mtu) && $mtu ne "") {
+		$content .= "        mtu $mtu\n";
+	    }
 	}
 	if ($net->{ip6}) {
 	    if ($net->{ip6} =~ /^(auto|dhcp)$/) {
@@ -200,6 +211,9 @@ sub configdrive2_network {
 		$content .= "        netmask $mask\n";
 		$content .= "        gateway $net->{gw6}\n" if $net->{gw6};
 	    }
+	    if (defined($mtu) && $mtu ne "") {
+		$content .= "        mtu $mtu\n";
+	    }
 	}
     }
 
@@ -261,6 +275,7 @@ sub nocloud_network_v2 {
 
 	my $net = PVE::QemuServer::parse_net($conf->{$iface});
 	my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
+	next if !defined($ipconfig);
 
 	my $mac = $net->{macaddr}
 	    or die "network interface '$iface' has no mac address\n";
@@ -295,6 +310,10 @@ sub nocloud_network_v2 {
 	if (defined(my $gw = $ipconfig->{gw6})) {
 	    $content .= "${i}gateway6: '$gw'\n";
 	}
+	my $mtu = $ipconfig->{mtu};
+	if (defined($mtu) && $mtu ne "") {
+	    $content .= "${i}mtu: $mtu\n";
+	}
 
 	next if $dns_done;
 	$dns_done = 1;
@@ -332,14 +351,22 @@ sub nocloud_network {
 
 	my $net = PVE::QemuServer::parse_net($conf->{$iface});
 	my $ipconfig = PVE::QemuServer::parse_ipconfig($conf->{"ipconfig$id"});
+	next if !defined($ipconfig);
 
 	my $mac = lc($net->{macaddr})
 	    or die "network interface '$iface' has no mac address\n";
 
+	my $mtu = $ipconfig->{mtu};
+
 	$content .= "${i}- type: physical\n"
 	          . "${i}  name: eth$id\n"
-	          . "${i}  mac_address: '$mac'\n"
-	          . "${i}  subnets:\n";
+	          . "${i}  mac_address: '$mac'\n";
+
+	if (defined($mtu) && $mtu ne "") {
+	    $content .= "${i}  mtu: $mtu\n";
+	}
+
+	$content .= "${i}  subnets:\n";
 	$i .= '  ';
 	if (defined(my $ip = $ipconfig->{ip})) {
 	    if ($ip eq 'dhcp') {
-- 
2.27.0




More information about the pve-devel mailing list