[pve-devel] [PATCH qemu-server 2/4] add ipconfigX to vm config

Alexandre Derumier aderumier at odiso.com
Fri Oct 6 16:49:12 CEST 2017


 * Add ipconfigX for all netX configuration options and
   using ip=CIDR, gw=IP, ip6=CIDR, gw6=IP as option names
   like in LXC.
---
 PVE/API2/Qemu.pm  |  2 +-
 PVE/QemuServer.pm | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 89 insertions(+), 2 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index c3f1004..b9fca89 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -293,7 +293,7 @@ my $check_vm_modify_config_perm = sub {
 	    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.PowerMgmt']);
 	} elsif ($diskoptions->{$opt}) {
 	    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Disk']);
-	} elsif ($opt =~ m/^net\d+$/) {
+	} elsif ($opt =~ m/^(net|ipconfig)\d+$/) {
 	    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Network']);
 	} else {
 	    # catches usb\d+, hostpci\d+, args, lock, etc.
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 2455e20..6c41a57 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -22,7 +22,7 @@ use PVE::SafeSyslog;
 use Storable qw(dclone);
 use PVE::Exception qw(raise raise_param_exc);
 use PVE::Storage;
-use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach);
+use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach $IPV6RE $IPV4RE);
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::INotify;
@@ -666,8 +666,60 @@ my $netdesc = {
 
 PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
 
+my $ipconfig_fmt = {
+    ip => {
+	type => 'string',
+	format => 'pve-ipv4-config',
+	format_description => 'IPv4Format/CIDR',
+	description => 'IPv4 address in CIDR format.',
+	optional => 1,
+	default => 'dhcp',
+    },
+    gw => {
+	type => 'string',
+	format => 'ipv4',
+	format_description => 'GatewayIPv4',
+	description => 'Default gateway for IPv4 traffic.',
+	optional => 1,
+	requires => 'ip',
+    },
+    ip6 => {
+	type => 'string',
+	format => 'pve-ipv6-config',
+	format_description => 'IPv6Format/CIDR',
+	description => 'IPv6 address in CIDR format.',
+	optional => 1,
+	default => 'dhcp',
+    },
+    gw6 => {
+	type => 'string',
+	format => 'ipv6',
+	format_description => 'GatewayIPv6',
+	description => 'Default gateway for IPv6 traffic.',
+	optional => 1,
+	requires => 'ip6',
+    },
+};
+PVE::JSONSchema::register_format('pve-qm-ipconfig', $ipconfig_fmt);
+my $ipconfigdesc = {
+    optional => 1,
+    type => 'string', format => 'pve-qm-ipconfig',
+    description => <<'EODESCR',
+Specify IP addresses and gateways for the corresponding interface.
+
+IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified.
+
+The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided.
+For IPv6 the special string 'auto' can be used to use stateless autoconfiguration.
+
+If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4.
+EODESCR
+};
+PVE::JSONSchema::register_standard_option("pve-qm-ipconfig", $netdesc);
+
 for (my $i = 0; $i < $MAX_NETS; $i++)  {
     $confdesc->{"net$i"} = $netdesc;
+    $confdesc->{"ipconfig$i"} = $ipconfigdesc;
 }
 
 PVE::JSONSchema::register_format('pve-volume-id-or-qm-path', \&verify_volume_id_or_qm_path);
@@ -1839,6 +1891,41 @@ sub parse_net {
     return $res;
 }
 
+# ipconfigX ip=cidr,gw=ip,ip6=cidr,gw6=ip
+sub parse_ipconfig {
+    my ($data) = @_;
+
+    my $res = eval { PVE::JSONSchema::parse_property_string($ipconfig_fmt, $data) };
+    if ($@) {
+	warn $@;
+	return undef;
+    }
+
+    if ($res->{gw} && !$res->{ip}) {
+	warn 'gateway specified without specifying an IP address';
+	return undef;
+    }
+    if ($res->{gw6} && !$res->{ip6}) {
+	warn 'IPv6 gateway specified without specifying an IPv6 address';
+	return undef;
+    }
+    if ($res->{gw} && $res->{ip} eq 'dhcp') {
+	warn 'gateway specified together with DHCP';
+	return undef;
+    }
+    if ($res->{gw6} && $res->{ip6} !~ /^$IPV6RE/) {
+	# gw6 + auto/dhcp
+	warn "IPv6 gateway specified together with $res->{ip6} address";
+	return undef;
+    }
+
+    if (!$res->{ip} && !$res->{ip6}) {
+	return { ip => 'dhcp', ip6 => 'dhcp' };
+    }
+
+    return $res;
+}
+
 sub print_net {
     my $net = shift;
 
-- 
2.11.0



More information about the pve-devel mailing list