From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id F058F8DD6 for ; Wed, 16 Nov 2022 18:14:11 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C45CC232A4 for ; Wed, 16 Nov 2022 18:14:11 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Wed, 16 Nov 2022 18:14:09 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 6C3D044D80; Wed, 16 Nov 2022 18:14:09 +0100 (CET) From: Wolfgang Bumiller To: pve-devel@lists.proxmox.com Date: Wed, 16 Nov 2022 18:14:06 +0100 Message-Id: <20221116171408.216775-5-w.bumiller@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221116171408.216775-1-w.bumiller@proxmox.com> References: <20221116171408.216775-1-w.bumiller@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: =?UTF-8?Q?0=0A=09?=AWL 0.232 Adjusted score from AWL reputation of From: =?UTF-8?Q?address=0A=09?=BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict =?UTF-8?Q?Alignment=0A=09?=SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF =?UTF-8?Q?Record=0A=09?=SPF_PASS -0.001 SPF: sender matches SPF =?UTF-8?Q?record=0A=09?=URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [qemuserver.pm] Subject: [pve-devel] [PATCH qemu-server 4/6] record cloud-init changes in the cloudinit section X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Nov 2022 17:14:12 -0000 introducing an 'added' value in the cloudinit section for values which have not been present when the cloudinit image has been generated Signed-off-by: Wolfgang Bumiller --- PVE/QemuServer.pm | 67 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index d8bcfff..6053d6c 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -2290,6 +2290,15 @@ sub cloudinit_config_properties { return dclone($confdesc_cloudinit); } +sub cloudinit_pending_properties { + my $p = { + map { $_ => 1 } keys $confdesc_cloudinit->%*, + name => 1, + }; + $p->{"net$_"} = 1 for 0..($MAX_NETS-1); + return $p; +} + sub check_type { my ($key, $value) = @_; @@ -4892,11 +4901,61 @@ sub vmconfig_hotplug_pending { $errors->{$opt} = "hotplug problem - $msg"; }; + my $cloudinit_pending_properties = PVE::QemuServer::cloudinit_pending_properties(); + + my $cloudinit_record_changed = sub { + my ($conf, $opt, $old, $new) = @_; + return if !$cloudinit_pending_properties->{$opt}; + + my $ci = ($conf->{cloudinit} //= {}); + + my $recorded = $ci->{$opt}; + + my $remove_added = sub { + my @added = grep { $_ ne $opt } PVE::Tools::split_list(delete($ci->{added}) // ''); + my $added = join(',', @added); + $ci->{added} = $added if length($added); + }; + + my $record_added = sub { + my %added = map { $_ => 1 } PVE::Tools::split_list(delete($ci->{added}) // ''); + $added{$opt} = 1; + $ci->{added} = join(',', keys %added); + }; + + if (defined($recorded)) { + # cloud-init already had a version of this key + if (!defined($new)) { + # the option existed temporarily and was now removed: + $remove_added->(); + } elsif ($new eq $recorded) { + # it was reverted to the state in cloud-init + delete $ci->{$opt}; + } else { + # $old was newer than $recorded, do nothing + } + } else { + # the key was not present the last time we generated the cloud-init image: + if (!defined($new)) { + # it is being deleted, which means we're back to the cloud-init sate: + delete $ci->{$opt}; + $remove_added->(); + } elsif (defined($old)) { + # the key was modified + $ci->{$opt} = $old; + } else { + # the key was added, no old value exists + $record_added->(); + } + } + }; + my $changes = 0; foreach my $opt (keys %{$conf->{pending}}) { # add/change if ($fast_plug_option->{$opt}) { - $conf->{$opt} = $conf->{pending}->{$opt}; - delete $conf->{pending}->{$opt}; + my $new = delete $conf->{pending}->{$opt}; + $cloudinit_record_changed->($conf, $opt, $conf->{$opt}, $new); + $conf->{$opt} = $new; $changes = 1; } } @@ -4914,6 +4973,7 @@ sub vmconfig_hotplug_pending { my $cgroup = PVE::QemuServer::CGroup->new($vmid); my $pending_delete_hash = PVE::QemuConfig->parse_pending_delete($conf->{pending}->{delete}); + foreach my $opt (sort keys %$pending_delete_hash) { next if $selection && !$selection->{$opt}; my $force = $pending_delete_hash->{$opt}->{force}; @@ -4967,7 +5027,8 @@ sub vmconfig_hotplug_pending { if (my $err = $@) { &$add_error($opt, $err) if $err ne "skip\n"; } else { - delete $conf->{$opt}; + my $old = delete $conf->{$opt}; + $cloudinit_record_changed->($conf, $opt, $old, undef); PVE::QemuConfig->remove_from_pending_delete($conf, $opt); } } -- 2.30.2