* 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 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel