all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support
@ 2021-07-11 22:46 Alexandre Derumier
  2021-07-11 22:46 ` [pve-devel] [PATCH v2 qemu-server 1/9] add ipam module Alexandre Derumier
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:46 UTC (permalink / raw)
  To: pve-devel

Hi,

This is an RFC to implement ipam support on qemu-server.

This don't change the cloud-init current working.

As I need to manage pending ip registration configuration, to follow the pending netX interfaces.

I have added ip,ip6,gw,gw6 field to netX interfaces options. (same than LXC).

(as current ipconfigX pending, is pending cloudinit generation)


so the workflow is:

--> update netX=...,ip=.... 
   --> ip is registered as pending
         --> hotplug/coldplug succesful
               ---> pending ip replace current conf oldip
                       ---->the ip set in cloudinit pending ipconfigX
                            ------> cloudinit regeneration
                                 ---> ipconfigX is remove from pending

As documentation said than ipconfigX is for cloudinit config,
I think it could be ok.

Some users could use the sdn features without cloudinit(allow some subnets only, and autogenerate firewall ipfilter).

Also, for ipam, I need bridge && mac from the netX, and ip need to follow pending states of the nic.

Changelog v2:

- rebase on last master / proxmox7
- fix handling errors when multiple nics are hotplugged at same time
- keep ip address in ipam if snapshots reference it
- only update dns when pending ip is apply (need new pve-network patch)
- implement snapshot rollback/delete
- implement vm create/destroy


todo : implement backup restore


Alexandre Derumier (9):
  add ipam module
  add print_ipconfig
  add ip options to netdescr
  ipam : add update/delete support
  ipam : add revert ip support
  ipam : add snapshot rollback support
  ipam : add snaphot delete support
  ipam : add create vm support
  ipam : add destroy vm support

 PVE/API2/Qemu.pm        |  56 +++++++++-
 PVE/QemuConfig.pm       |  32 ++++++
 PVE/QemuServer.pm       | 228 ++++++++++++++++++++++++++++++++++++++++
 PVE/QemuServer/Ipam.pm  | 141 +++++++++++++++++++++++++
 PVE/QemuServer/Makefile |   1 +
 5 files changed, 457 insertions(+), 1 deletion(-)
 create mode 100644 PVE/QemuServer/Ipam.pm

-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 1/9] add ipam module
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
@ 2021-07-11 22:46 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 2/9] add print_ipconfig Alexandre Derumier
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:46 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/QemuServer/Ipam.pm  | 141 ++++++++++++++++++++++++++++++++++++++++
 PVE/QemuServer/Makefile |   1 +
 2 files changed, 142 insertions(+)
 create mode 100644 PVE/QemuServer/Ipam.pm

diff --git a/PVE/QemuServer/Ipam.pm b/PVE/QemuServer/Ipam.pm
new file mode 100644
index 0000000..202474c
--- /dev/null
+++ b/PVE/QemuServer/Ipam.pm
@@ -0,0 +1,141 @@
+package PVE::QemuServer::Ipam;
+
+use strict;
+use warnings;
+
+my $have_sdn;
+eval {
+    require PVE::Network::SDN::Zones;
+    $have_sdn = 1;
+};
+
+sub is_static_ip {
+    my ($ip) = @_;
+
+    return 1 if $ip !~ m/(dhcp|manual|auto)$/;
+}
+
+
+sub ip_has_changed {
+    my ($version, $net, $oldnet) = @_;
+
+    my $ipfield = $version == 4 ? "ip" : "ip6";
+    my $ip = $net->{$ipfield};
+    my $oldip = $oldnet->{$ipfield};
+
+    return 1 if !$oldip && $ip;
+    return 1 if !$ip && $oldip;
+    return 1 if $ip && $oldip && $ip ne $oldip;
+    return 1 if !$oldnet->{bridge} || !$net->{bridge} || $oldnet->{bridge} ne $net->{bridge};
+}
+
+sub add_net_ip {
+    my ($version, $net, $hostname, $description, $skipdns) = @_;
+
+    my $bridge = $net->{bridge};
+    my $mac = $net->{hwaddr};
+    my $ipfield = $version == 4 ? "ip" : "ip6";
+    my $ip = $net->{$ipfield};
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    eval {
+        if (!$ip) {
+	print"add_find_free\n";
+
+            my $next_free_ip = PVE::Network::SDN::Vnets::get_next_free_cidr($bridge, $hostname, $mac, $description, $version, $skipdns);
+            $net->{$ipfield} = $next_free_ip if $next_free_ip;
+        } elsif (is_static_ip($ip)) {
+	print"add_cidr $ip\n";
+	    PVE::Network::SDN::Vnets::add_cidr($bridge, $ip, $hostname, $mac, $description, $skipdns);
+        }
+    };
+    if ($@) {
+        die $@;
+    }
+}
+
+sub update_net_ip {
+    my ($version, $net, $hostname, $oldhostname, $description, $skipdns) = @_;
+
+    my $bridge = $net->{bridge};
+    my $mac = $net->{hwaddr};
+    my $ipfield = $version == 4 ? "ip" : "ip6";
+    my $ip = $net->{$ipfield};
+
+    return if !$ip || !is_static_ip($ip);
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    eval {
+	#update ip attributes if no ip address change
+	print"update_cidr $ip\n";
+	PVE::Network::SDN::Vnets::update_cidr($bridge, $ip, $hostname, $oldhostname, $mac, $description, $skipdns);
+    };
+    if ($@) {
+        die $@;
+    }
+}
+
+
+sub update_net_gateway {
+    my ($version, $net) = @_;
+
+    my $bridge = $net->{bridge};
+    my $netip = $version == 4 ? $net->{ip} : $net->{ip6};
+    my $gwfield = $version == 4 ? "gw" : "gw6";
+
+    return if (!$netip || !is_static_ip($netip));
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    #update gateway
+    my ($ip, $mask) = split(/\//, $netip);
+    my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
+    my $gw = $subnet->{gateway} if $subnet->{gateway};
+    $net->{$gwfield} = $gw if $gw;
+
+}
+
+sub delete_net_ip {
+    my ($version, $net, $hostname, $skipdns) = @_;
+
+    return if !$have_sdn;
+
+    my $bridge = $net->{bridge};
+    my $ip = $version == 4 ? $net->{ip} : $net->{ip6};
+
+    return if !$ip || !is_static_ip($ip);
+
+    my $subnets = PVE::Network::SDN::Vnets::get_subnets($bridge);
+    return if !keys %{$subnets};
+
+    eval {
+	print"del_cidr $ip\n";
+
+        PVE::Network::SDN::Vnets::del_cidr($bridge, $ip, $hostname, $skipdns);
+    };
+    warn $@ if $@;
+}
+
+sub is_ip_referenced {
+    my ($version, $nets, $net, $skipsnap, $checkcurrent) = @_;
+
+    if ($checkcurrent) {
+        foreach my $opt (keys %{$nets->{current}}) {
+            return 1 if !ip_has_changed($version, $net, $nets->{current}->{$opt});
+        }
+    }
+
+    foreach my $snapname (keys %{$nets->{snapshots}}) {
+        next if $skipsnap && $skipsnap eq $snapname;
+        my $snapnets = $nets->{snapshots}->{$snapname};
+        foreach my $opt (keys %{$snapnets}) {
+            return 1 if !ip_has_changed($version, $net, $snapnets->{$opt});
+        }
+    }
+}
+
+1;
\ No newline at end of file
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index e4ed184..0292383 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -11,6 +11,7 @@ SOURCES=PCI.pm		\
 	CPUConfig.pm	\
 	CGroup.pm	\
 	Drive.pm	\
+	Ipam.pm		\
 
 .PHONY: install
 install: ${SOURCES}
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 2/9] add print_ipconfig
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
  2021-07-11 22:46 ` [pve-devel] [PATCH v2 qemu-server 1/9] add ipam module Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 3/9] add ip options to netdescr Alexandre Derumier
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/QemuServer.pm | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index b0fe257..a0e4949 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -1899,6 +1899,12 @@ sub parse_ipconfig {
     return $res;
 }
 
+sub print_ipconfig {
+    my $ipconfig = shift;
+
+    return PVE::JSONSchema::print_property_string($ipconfig, $ipconfig_fmt);
+}
+
 sub print_net {
     my $net = shift;
 
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 3/9] add ip options to netdescr
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
  2021-07-11 22:46 ` [pve-devel] [PATCH v2 qemu-server 1/9] add ipam module Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 2/9] add print_ipconfig Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 4/9] ipam : add update/delete support Alexandre Derumier
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/QemuServer.pm | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index a0e4949..18dd1ed 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -914,6 +914,38 @@ my $net_fmt = {
 	description => "Force MTU, for VirtIO only. Set to '1' to use the bridge MTU",
 	optional => 1,
     },
+    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',
+    },
 };
 
 my $netdesc = {
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 4/9] ipam : add update/delete support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (2 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 3/9] add ip options to netdescr Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 5/9] ipam : add revert ip support Alexandre Derumier
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Qemu.pm  |  12 +++-
 PVE/QemuServer.pm | 157 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index f2557e3..6bf88b7 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1255,6 +1255,7 @@ my $update_vm_api  = sub {
 	    # write updates to pending section
 
 	    my $modified = {}; # record what $option we modify
+	    my $errors = {};
 
 	    my @bootorder;
 	    if (my $boot = $conf->{boot}) {
@@ -1371,6 +1372,16 @@ my $update_vm_api  = sub {
 			die "only root can modify '$opt' config for real devices\n";
 		    }
 		    $conf->{pending}->{$opt} = $param->{$opt};
+		} elsif ($opt =~ m/^net(\d+)/) {
+		    my $net = PVE::QemuServer::parse_net($param->{$opt});
+		    PVE::QemuServer::vmconfig_delete_pendingnet_ip($conf, $vmid, $opt, $net);
+		    eval {
+			PVE::QemuServer::vmconfig_allocate_pending_ip($conf, $vmid, $opt, $net);
+		    };
+		    if($@){
+			$errors->{$opt} = $@;
+		    }
+		    
 		} else {
 		    $conf->{pending}->{$opt} = $param->{$opt};
 
@@ -1409,7 +1420,6 @@ my $update_vm_api  = sub {
 
 	    $conf = PVE::QemuConfig->load_config($vmid); # update/reload
 
-	    my $errors = {};
 	    if ($running) {
 		PVE::QemuServer::vmconfig_hotplug_pending($vmid, $conf, $storecfg, $modified, $errors);
 	    } else {
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 18dd1ed..7d34a74 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -4659,6 +4659,8 @@ sub vmconfig_hotplug_pending {
 	    } elsif ($opt =~ m/^net(\d+)$/) {
 		die "skip\n" if !$hotplug_features->{network};
 		vm_deviceunplug($vmid, $conf, $opt);
+		my $net = PVE::QemuServer::parse_net($conf->{$opt});
+		vmconfig_delete_net_ip($conf, $net);
 	    } elsif (is_valid_drivename($opt)) {
 		die "skip\n" if !$hotplug_features->{disk} || $opt =~ m/(ide|sata)(\d+)/;
 		vm_deviceunplug($vmid, $conf, $opt);
@@ -4745,9 +4747,12 @@ sub vmconfig_hotplug_pending {
 		    mon_cmd($vmid, "balloon", value => $balloon*1024*1024);
 		}
 	    } elsif ($opt =~ m/^net(\d+)$/) {
+		die "skip" if $errors->{$opt};
 		# some changes can be done without hotplug
 		vmconfig_update_net($storecfg, $conf, $hotplug_features->{network},
 				    $vmid, $opt, $value, $arch, $machine_type);
+
+                vmconfig_update_net_ip($conf, $vmid, $opt);
 	    } elsif (is_valid_drivename($opt)) {
 		die "skip\n" if $opt eq 'efidisk0';
 		# some changes can be done without hotplug
@@ -4842,6 +4847,10 @@ sub vmconfig_apply_pending {
 	    } elsif (defined($conf->{$opt}) && is_valid_drivename($opt)) {
 		vmconfig_delete_or_detach_drive($vmid, $storecfg, $conf, $opt, $force);
 	    }
+	    if($opt =~ m/net(\d+)$/) {
+		my $net = PVE::QemuServer::parse_net($conf->{$opt});
+		vmconfig_delete_net_ip($conf, $net);
+	    }
 	};
 	if (my $err = $@) {
 	    $add_apply_error->($opt, $err);
@@ -4859,6 +4868,11 @@ sub vmconfig_apply_pending {
 	    if (defined($conf->{$opt}) && is_valid_drivename($opt)) {
 		vmconfig_register_unused_drive($storecfg, $vmid, $conf, parse_drive($opt, $conf->{$opt}))
 	    }
+
+	    if($opt =~ m/net(\d+)$/) {
+                die "skip" if $errors->{$opt};
+		vmconfig_update_net_ip($conf, $vmid, $opt);
+	    }
 	};
 	if (my $err = $@) {
 	    $add_apply_error->($opt, $err);
@@ -4871,6 +4885,149 @@ sub vmconfig_apply_pending {
     PVE::QemuConfig->write_config($vmid, $conf);
 }
 
+sub vmconfig_update_net_ip {
+    my ($conf, $vmid, $opt) = @_;
+
+    my $ipconfigid = undef;
+    if($opt =~ m/net(\d+)$/) {
+	$ipconfigid = "ipconfig$1";
+    }
+
+    my $nets = PVE::QemuServer::get_nets_ipconfig($conf);
+    my $net = PVE::QemuServer::parse_net($conf->{pending}->{$opt});
+    my $oldnet = PVE::QemuServer::parse_net($conf->{$opt}) if $conf->{$opt};
+    my $hostname = $conf->{name};
+
+    #delete current ip from ipam if different and not referenced in snapshots
+    eval {
+
+	if(PVE::QemuServer::Ipam::ip_has_changed(4, $net, $oldnet) && !PVE::QemuServer::Ipam::is_ip_referenced(4, $nets, $oldnet)) {
+	    PVE::QemuServer::Ipam::delete_net_ip(4, $oldnet, $hostname);
+	} 
+
+	if(PVE::QemuServer::Ipam::ip_has_changed(6, $net, $oldnet) && !PVE::QemuServer::Ipam::is_ip_referenced(6, $nets, $oldnet)) {
+	    PVE::QemuServer::Ipam::delete_net_ip(6, $oldnet, $hostname);
+	} 
+    };
+
+    #update pending ip info (dns,..)
+    PVE::QemuServer::Ipam::update_net_ip(4,$net, $hostname, $hostname, "vm:$vmid net:$opt");
+    PVE::QemuServer::Ipam::update_net_ip(6,$net, $hostname, $hostname, "vm:$vmid net:$opt");
+
+    #set ip info as pending in cloud-init config
+    my $ipconfig = {};
+    $ipconfig->{ip} = $net->{ip} if $net->{ip};
+    $ipconfig->{ip6} = $net->{ip6} if $net->{ip6};
+    $ipconfig->{gw} = $net->{gw} if $net->{gw};
+    $ipconfig->{gw6} = $net->{gw6} if $net->{gw6};
+    my $value = PVE::QemuServer::print_ipconfig($ipconfig);
+    $conf->{pending}->{$ipconfigid} = $value;
+
+}
+
+sub vmconfig_delete_net_ip {
+    my ($conf, $net, $snapname, $checkcurrent) = @_;
+
+    my $hostname = $conf->{name};
+  
+    return if !$net;
+    my $nets = PVE::QemuServer::get_nets_ipconfig($conf);
+
+    eval {
+	if ($net->{ip} && !PVE::QemuServer::Ipam::is_ip_referenced(4, $nets, $net, $snapname, $checkcurrent)) {
+	    PVE::QemuServer::Ipam::delete_net_ip(4, $net, $hostname);
+	}
+	if ($net->{ip6} && !PVE::QemuServer::Ipam::is_ip_referenced(6, $nets, $net, $snapname, $checkcurrent)) {
+	    PVE::QemuServer::Ipam::delete_net_ip(6, $net, $hostname);
+	}
+    };
+}
+
+sub get_nets_ipconfig {
+    my ($conf) = @_;
+
+    my $nets = {};
+
+    foreach my $opt (keys %{$conf}) {
+	next if $opt !~ m/^net(\d+)$/;
+	my $net = PVE::QemuServer::parse_net($conf->{$opt});
+	$nets->{current}->{$opt} = $net;
+    }
+
+    foreach my $snapname (keys %{$conf->{snapshots}}) {
+	my $snapconf = $conf->{snapshots}->{$snapname};
+	foreach my $opt (keys %{$snapconf}) {
+	    next if $opt !~ m/^net(\d+)$/;
+	    my $net = PVE::QemuServer::parse_net($snapconf->{$opt});
+	    $nets->{snapshots}->{$snapname}->{$opt} = $net;
+	}
+    }
+    return $nets;
+}
+
+sub vmconfig_allocate_pending_ip {
+    my ($conf, $vmid, $opt, $pendingnet) = @_;
+
+    my $oldnet = PVE::QemuServer::parse_net($conf->{$opt}) if $conf->{$opt};
+    my $nets = PVE::QemuServer::get_nets_ipconfig($conf);
+    my $hostname = $conf->{pending}->{name} ? $conf->{pending}->{name} : $conf->{name};
+    my $description = "vm:$vmid net:$opt pending:1";
+    my $skipdns = 1;
+
+    my $errors = "";
+    eval {
+	#add new ip to ipam if different than current and no reference in snapshots
+	if (PVE::QemuServer::Ipam::ip_has_changed(4, $pendingnet, $oldnet) && !PVE::QemuServer::Ipam::is_ip_referenced(4, $nets, $pendingnet)) {
+	    PVE::QemuServer::Ipam::add_net_ip(4,$pendingnet, $hostname, $description, $skipdns);
+	}
+	PVE::QemuServer::Ipam::update_net_gateway(4, $pendingnet);
+    };
+
+    if($@) {
+	$errors = $@;
+	delete $pendingnet->{ip};
+	delete $pendingnet->{gw};
+    }
+
+    eval {
+	#add new ip to ipam if different than current and no reference in snapshots
+	if (PVE::QemuServer::Ipam::ip_has_changed(6, $pendingnet, $oldnet) && !PVE::QemuServer::Ipam::is_ip_referenced(6, $nets, $pendingnet)) {
+	    PVE::QemuServer::Ipam::add_net_ip(6,$pendingnet, $hostname, $description, $skipdns);
+	}
+	PVE::QemuServer::Ipam::update_net_gateway(6, $pendingnet);
+    };
+    if($@) {
+	$errors = $@;
+	delete $pendingnet->{ip6};
+	delete $pendingnet->{gw6};
+    }
+    $conf->{pending}->{$opt} = PVE::QemuServer::print_net($pendingnet);
+
+    die $errors if $errors;
+}
+
+sub vmconfig_delete_pendingnet_ip {
+    my ($conf, $vmid, $opt, $net) = @_;
+    my $pendingnet = PVE::QemuServer::parse_net($conf->{pending}->{$opt}) if $conf->{pending}->{$opt};
+
+    return if !$pendingnet;
+
+    my $nets = PVE::QemuServer::get_nets_ipconfig($conf);
+    my $hostname = $conf->{name};
+    my $skipdns = 1;
+    my $skipsnap = undef;
+    my $checkcurrent = 1;
+    my $checkpending = 1;
+
+    #delete old pending ips if different and no ip reference in running config or snapshots
+    if (PVE::QemuServer::Ipam::ip_has_changed(4, $net, $pendingnet) && !PVE::QemuServer::Ipam::is_ip_referenced(4, $nets, $pendingnet, $skipsnap, $checkcurrent)) {
+	PVE::QemuServer::Ipam::delete_net_ip(4, $pendingnet, $hostname, $skipdns);
+    }
+    if (PVE::QemuServer::Ipam::ip_has_changed(6, $net, $pendingnet) && !PVE::QemuServer::Ipam::is_ip_referenced(6, $nets, $pendingnet, $skipsnap, $checkcurrent)) {
+	PVE::QemuServer::Ipam::delete_net_ip(6, $pendingnet, $hostname, $skipdns);
+    }
+}
+
 sub vmconfig_update_net {
     my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $arch, $machine_type) = @_;
 
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 5/9] ipam : add revert ip support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (3 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 4/9] ipam : add update/delete support Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 6/9] ipam : add snapshot rollback support Alexandre Derumier
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Qemu.pm | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 6bf88b7..e2a6a0a 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -1286,6 +1286,10 @@ my $update_vm_api  = sub {
 		    $modified->{$opt} = 0;
 		    next;
 		}
+		if (defined($conf->{pending}->{$opt}) && $opt =~ m/^net(\d+)$/) {
+		    my $net = PVE::QemuServer::parse_net($conf->{pending}->{$opt});
+		    PVE::QemuServer::vmconfig_delete_net_ip($conf, $net);
+		}
 		my $is_pending_val = defined($conf->{pending}->{$opt});
 		delete $conf->{pending}->{$opt};
 
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 6/9] ipam : add snapshot rollback support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (4 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 5/9] ipam : add revert ip support Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 7/9] ipam : add snaphot delete support Alexandre Derumier
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/QemuConfig.pm | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/PVE/QemuConfig.pm b/PVE/QemuConfig.pm
index 7ee8876..6627e2f 100644
--- a/PVE/QemuConfig.pm
+++ b/PVE/QemuConfig.pm
@@ -12,6 +12,7 @@ use PVE::QemuServer::Helpers;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer;
 use PVE::QemuServer::Machine;
+use PVE::QemuServer::Ipam;
 use PVE::Storage;
 use PVE::Tools;
 use PVE::Format qw(render_bytes render_duration);
@@ -397,6 +398,7 @@ sub __snapshot_rollback_hook {
     if ($prepare) {
 	# we save the machine of the current config
 	$data->{oldmachine} = $conf->{machine};
+	$data->{oldconf} = $conf;
     } else {
 	# if we have a 'runningmachine' entry in the snapshot we use that
 	# for the forcemachine parameter, else we use the old logic
@@ -424,6 +426,36 @@ sub __snapshot_rollback_hook {
 	    # re-initializing its random number generator
 	    $conf->{vmgenid} = PVE::QemuServer::generate_uuid();
 	}
+
+	my $oldconf = $data->{oldconf};
+	my $pendingoldconf = $oldconf->{pending};
+
+	#remove ip from current pending net interfaces
+	foreach my $opt (keys %$pendingoldconf) {
+	    next if $opt !~ m/^net(\d+)$/;
+	    my $net = PVE::QemuServer::parse_net($pendingoldconf->{$opt});
+	    PVE::QemuServer::vmconfig_delete_net_ip($conf, $net);
+	}
+
+	#remove ip from net current conf
+	foreach my $opt (keys %$oldconf) {
+	    next if $opt !~ m/^net(\d+)$/;
+	    my $net = PVE::QemuServer::parse_net($oldconf->{$opt});
+	    PVE::QemuServer::vmconfig_delete_net_ip($oldconf, $net);
+	}
+
+	#update ipam description/dns
+	foreach my $opt (keys %$conf) {
+	    next if $opt !~ m/^net(\d+)$/;
+	    my $netid = $1;
+	    my $net = PVE::QemuServer::parse_net($conf->{$opt});
+	    my $hostname = $conf->{name};
+	    my $oldhostname = $oldconf->{name};
+	    PVE::QemuServer::Ipam::update_net_ip(4,$net, $hostname, $oldhostname, "vm:$vmid net:$opt");
+	    PVE::QemuServer::Ipam::update_net_ip(6,$net, $hostname, $oldhostname, "vm:$vmid net:$opt");
+
+	    $conf->{$opt} = PVE::QemuServer::print_net($net);
+	}
     }
 
     return;
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 7/9] ipam : add snaphot delete support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (5 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 6/9] ipam : add snapshot rollback support Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 8/9] ipam : add create vm support Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 9/9] ipam : add destroy " Alexandre Derumier
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

This should be move to abstract config with a new hook

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Qemu.pm | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index e2a6a0a..aaefcec 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -4308,7 +4308,15 @@ __PACKAGE__->register_method({
 
 	my $realcmd = sub {
 	    PVE::Cluster::log_msg('info', $authuser, "delete snapshot VM $vmid: $snapname");
+	    my $conf = PVE::QemuConfig->load_config($vmid);
+	    my $checkcurrent = 1;
+	    foreach my $opt (keys %{$conf->{snapshots}->{$snapname}}) {
+		next if $opt !~ m/^net(\d+)$/;
+                my $net = PVE::QemuServer::parse_net($conf->{snapshots}->{$snapname}->{$opt});
+                PVE::QemuServer::vmconfig_delete_net_ip($conf, $net, $snapname, $checkcurrent);
+	    }
 	    PVE::QemuConfig->snapshot_delete($vmid, $snapname, $param->{force});
+
 	};
 
 	return $rpcenv->fork_worker('qmdelsnapshot', $vmid, $authuser, $realcmd);
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 8/9] ipam : add create vm support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (6 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 7/9] ipam : add snaphot delete support Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 9/9] ipam : add destroy " Alexandre Derumier
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/API2/Qemu.pm | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index aaefcec..66a21ba 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -703,7 +703,31 @@ __PACKAGE__->register_method({
 		my $arch = PVE::QemuServer::get_vm_arch($conf);
 
 		my $vollist = [];
+		my $nets = {};
 		eval {
+		    foreach my $opt (keys %{$conf}) {
+			next if $opt !~ m/^net(\d+)$/;
+			my $hostname = $conf->{name};
+			my $description = "vm:$vmid net:$opt";
+			my $net = PVE::QemuServer::parse_net($conf->{$opt});
+			PVE::QemuServer::Ipam::add_net_ip(4,$net, $hostname, $description);
+			PVE::QemuServer::Ipam::update_net_gateway(4, $net);
+			$nets->{$opt} = PVE::QemuServer::print_net($net);
+			PVE::QemuServer::Ipam::add_net_ip(6,$net, $hostname, $description);
+			PVE::QemuServer::Ipam::update_net_gateway(6, $net);
+			$nets->{$opt} = PVE::QemuServer::print_net($net);
+			$conf->{$opt} = PVE::QemuServer::print_net($net);
+			if($opt =~ m/net(\d+)$/) {
+			    my $ipconfigid = "ipconfig$1";
+			    my $ipconfig = {};
+			    $ipconfig->{ip} = $net->{ip} if $net->{ip};
+			    $ipconfig->{ip6} = $net->{ip6} if $net->{ip6};
+			    $ipconfig->{gw} = $net->{gw} if $net->{gw};
+			    $ipconfig->{gw6} = $net->{gw6} if $net->{gw6};
+			    $conf->{$ipconfigid} = PVE::QemuServer::print_ipconfig($ipconfig);
+			}
+		    }
+
 		    $vollist = &$create_disks($rpcenv, $authuser, $conf, $arch, $storecfg, $vmid, $pool, $param, $storage);
 
 		    if (!$conf->{boot}) {
@@ -738,6 +762,14 @@ __PACKAGE__->register_method({
 			eval { PVE::Storage::vdisk_free($storecfg, $volid); };
 			warn $@ if $@;
 		    }
+                    foreach my $opt (keys %{$nets}) {
+			my $net = PVE::QemuServer::parse_net($nets->{$opt});
+			my $hostname = $conf->{name};
+			eval { PVE::QemuServer::Ipam::delete_net_ip(6, $net, $hostname); };
+			warn $@ if $@;
+			eval { PVE::QemuServer::Ipam::delete_net_ip(4, $net, $hostname); };
+			warn $@ if $@;
+		    }
 		    die "$emsg $err";
 		}
 
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pve-devel] [PATCH v2 qemu-server 9/9] ipam : add destroy vm support
  2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
                   ` (7 preceding siblings ...)
  2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 8/9] ipam : add create vm support Alexandre Derumier
@ 2021-07-11 22:47 ` Alexandre Derumier
  8 siblings, 0 replies; 10+ messages in thread
From: Alexandre Derumier @ 2021-07-11 22:47 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/QemuServer.pm | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 7d34a74..f6f14a6 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -2215,6 +2215,8 @@ sub destroy_vm {
     };
     PVE::QemuConfig->foreach_volume_full($conf, $include_opts, $remove_owned_drive);
 
+    PVE::QemuServer::vmconfig_destroy_nets_ip($conf);
+
     for my $snap (values %{$conf->{snapshots}}) {
 	next if !defined($snap->{vmstate});
 	my $drive = PVE::QemuConfig->parse_volume('vmstate', $snap->{vmstate}, 1);
@@ -4922,7 +4924,6 @@ sub vmconfig_update_net_ip {
     $ipconfig->{gw6} = $net->{gw6} if $net->{gw6};
     my $value = PVE::QemuServer::print_ipconfig($ipconfig);
     $conf->{pending}->{$ipconfigid} = $value;
-
 }
 
 sub vmconfig_delete_net_ip {
@@ -5028,6 +5029,37 @@ sub vmconfig_delete_pendingnet_ip {
     }
 }
 
+sub vmconfig_destroy_nets_ip {
+    my ($conf) = @_;
+
+    foreach my $snapname (keys %{$conf->{snapshots}}) {
+	my $snapconf = $conf->{snapshots}->{$snapname};
+	foreach my $opt (keys %{$snapconf}) {
+	    next if $opt !~ m/^net(\d+)$/;
+	    my $hostname = $snapconf->{name};
+	    my $net = PVE::QemuServer::parse_net($snapconf->{$opt});
+	    eval {
+		PVE::QemuServer::Ipam::delete_net_ip(4, $net, $hostname);
+	    };
+	    eval {
+		PVE::QemuServer::Ipam::delete_net_ip(6, $net, $hostname);
+	    };
+        }
+    }
+
+    foreach my $opt (keys %{$conf}) {
+	next if $opt !~ m/^net(\d+)$/;
+	my $net = PVE::QemuServer::parse_net($conf->{$opt});
+	my $hostname = $conf->{name};
+	eval {
+	    PVE::QemuServer::Ipam::delete_net_ip(4, $net, $hostname);
+	};
+	eval {
+	    PVE::QemuServer::Ipam::delete_net_ip(6, $net, $hostname);
+	};
+    }
+}
+
 sub vmconfig_update_net {
     my ($storecfg, $conf, $hotplug, $vmid, $opt, $value, $arch, $machine_type) = @_;
 
@@ -6121,6 +6153,7 @@ my $restore_cleanup_oldconf = sub {
 	    }
 	}
     }
+
 };
 
 # Helper to parse vzdump backup device hints
-- 
2.30.2




^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-07-11 22:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-11 22:46 [pve-devel] [PATCH v2 qemu-server 0/9] RFC: sdn: add ipam support Alexandre Derumier
2021-07-11 22:46 ` [pve-devel] [PATCH v2 qemu-server 1/9] add ipam module Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 2/9] add print_ipconfig Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 3/9] add ip options to netdescr Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 4/9] ipam : add update/delete support Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 5/9] ipam : add revert ip support Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 6/9] ipam : add snapshot rollback support Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 7/9] ipam : add snaphot delete support Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 8/9] ipam : add create vm support Alexandre Derumier
2021-07-11 22:47 ` [pve-devel] [PATCH v2 qemu-server 9/9] ipam : add destroy " Alexandre Derumier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal