rework cloudinit_record_changed logic

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-11-17 14:35:27 +01:00
parent c229961ad3
commit a540985120

View File

@ -4913,44 +4913,61 @@ sub vmconfig_hotplug_pending {
my $ci = ($conf->{cloudinit} //= {});
my $recorded = $ci->{$opt};
my %added = map { $_ => 1 } PVE::Tools::split_list(delete($ci->{added}) // '');
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};
if (defined($new)) {
if (defined($old)) {
# an existing value is being modified
if (defined($recorded)) {
# the value was already not in sync
if ($new eq $recorded) {
# a value is being reverted to the cloud-init state:
delete $ci->{$opt};
delete $added{$opt};
} else {
# the value was changed multiple times, do nothing
}
} elsif ($added{$opt}) {
# the value had been marked as added and is being changed, do nothing
} else {
# the value is new, record it:
$ci->{$opt} = $old;
}
} else {
# $old was newer than $recorded, do nothing
# a new value is being added
if (defined($recorded)) {
# it was already not in sync
if ($new eq $recorded) {
# a value is being reverted to the cloud-init state:
delete $ci->{$opt};
delete $added{$opt};
} else {
# the value had temporarily been removed, do nothing
}
} elsif ($added{$opt}) {
# the value had been marked as added already, do nothing
} else {
# the value is new, add it
$added{$opt} = 1;
}
}
} elsif (!defined($old)) {
# a non-existent value is being removed? ignore...
} 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;
# a value is being deleted
if (defined($recorded)) {
# a value was already recorded, just keep it
} elsif ($added{$opt}) {
# the value was marked as added, remove it
delete $added{$opt};
} else {
# the key was added, no old value exists
$record_added->();
# a previously unrecorded value is being removed, record the old value:
$ci->{$opt} = $old;
}
}
my $added = join(',', sort keys %added);
$ci->{added} = $added if length($added);
};
my $changes = 0;