sub parse_pending_delete {
my ($class, $data) = @_;
- $data ||= '';
+
+ return {} if !$data;
+
$data =~ s/[,;]/ /g;
$data =~ s/^\s+//;
- return { map { /^(!?)(.*)$/ && ($2, { 'force' => $1 eq '!' ? 1 : 0 } ) } ($data =~ /\S+/g) };
+
+ my $pending_deletions = {};
+ for my $entry (split(/\s+/, $data)) {
+ my ($force, $key) = $entry =~ /^(!?)(.*)$/;
+
+ $pending_deletions->{$key} = {
+ force => $force ? 1 : 0,
+ };
+ }
+
+ return $pending_deletions;
}
sub print_pending_delete {
my ($class, $delete_hash) = @_;
- join ",", map { ( $delete_hash->{$_}->{force} ? '!' : '' ) . $_ } keys %$delete_hash;
+
+ my $render_key = sub {
+ my $key = shift;
+ $key = "!$key" if $delete_hash->{$key}->{force};
+ return $key;
+ };
+
+ join (',', map { $render_key->($_) } sort keys %$delete_hash);
}
sub add_to_pending_delete {
my ($class, $conf, $key, $force) = @_;
- delete $conf->{pending}->{$key};
- my $pending_delete_hash = $class->parse_pending_delete($conf->{pending}->{delete});
- $pending_delete_hash->{$key}->{force} = $force;
- $conf->{pending}->{delete} = $class->print_pending_delete($pending_delete_hash);
+ $conf->{pending} //= {};
+ my $pending = $conf->{pending};
+ my $pending_delete_hash = $class->parse_pending_delete($pending->{delete});
+
+ $pending_delete_hash->{$key} = { force => $force };
+
+ $pending->{delete} = $class->print_pending_delete($pending_delete_hash);
+
+ return $conf;
}
sub remove_from_pending_delete {
return $changes;
}
+sub load_snapshot_config {
+ my ($class, $vmid, $snapname) = @_;
+
+ my $conf = $class->load_config($vmid);
+
+ my $snapshot = $conf->{snapshots}->{$snapname};
+ die "snapshot '$snapname' does not exist\n" if !defined($snapshot);
+
+ $snapshot->{digest} = $conf->{digest};
+
+ return $snapshot;
+
+}
+
+sub load_current_config {
+ my ($class, $vmid, $current) = @_;
+
+ my $conf = $class->load_config($vmid);
+
+ # take pending changes in
+ if (!$current) {
+ foreach my $opt (keys %{$conf->{pending}}) {
+ next if $opt eq 'delete';
+ my $value = $conf->{pending}->{$opt};
+ next if ref($value); # just to be sure
+ $conf->{$opt} = $value;
+ }
+ my $pending_delete_hash = $class->parse_pending_delete($conf->{pending}->{delete});
+ foreach my $opt (keys %$pending_delete_hash) {
+ delete $conf->{$opt} if $conf->{$opt};
+ }
+ }
+
+ delete $conf->{snapshots};
+ delete $conf->{pending};
+
+ return $conf;
+}
+
+
# Lock config file using flock, run $code with @param, unlock config file.
# $timeout is the maximum time to aquire the flock
sub lock_config_full {