The MTU part of the patch looks good and works fine here. It would be great if you could send that as a separate patch when you send a v2 of the patch series.

Any reason why snippets [0] are not enough for custom userdata?


Also we don't want any further cloudinit options in the global config scope. Instead we use cicustom for new cloudinit options. There you should be able to extend the user part to support custom userdata as a urlencoded base64 string instead of only as a volume id (snippet). This can be done by registering a new format (PVE::JSONSchema::register_format) for it with a validator function that accepts both a pve-volume-id as well as the userdata string and then using this format in cicustom_fmt.


[0] https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_cloud_init (10.8.3 Custom Cloud-Init Configuration)

On 7/2/20 6:08 PM, Marius Schellenberger wrote:
Extended the PVE API to configure cloud-init userdata and network
interface MTU.

Signed-off-by: Marius Schellenberger <prox...@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') {


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to