use PVE::Cluster;
use PVE::Storage;
+use PVE::ReplicationConfig;
+use PVE::Replication;
+
my $nodename = PVE::INotify::nodename();
# Printable string, currently either "VM" or "CT"
return $res;
}
+sub create_and_lock_config {
+ my ($class, $vmid, $allow_existing) = @_;
+
+ $class->lock_config_full($vmid, 5, sub {
+ PVE::Cluster::check_vmid_unused($vmid, $allow_existing);
+
+ my $conf = eval { $class->load_config($vmid) } || {};
+ $class->check_lock($conf);
+ $conf->{lock} = 'create';
+ $class->write_config($vmid, $conf);
+ });
+}
+
# Lock config file using flock, run $code with @param, unlock config file.
# $timeout is the maximum time to aquire the flock
# $shared eq 1 creates a non-exclusive ("read") flock
die "implement me - abstract method\n";
}
+# get all replicatable volume (hash $res->{$volid} = 1)
+# $cleanup: for cleanup - simply ignores volumes without replicate feature
+# $norerr: never raise exceptions - return undef instead
+sub get_replicatable_volumes {
+ my ($class, $storecfg, $vmid, $conf, $cleanup, $noerr) = @_;
+
+ die "implement me - abstract method\n";
+}
+
# Internal snapshots
# NOTE: Snapshot create/delete involves several non-atomic
next if $k eq 'lock';
next if $k eq 'digest';
next if $k eq 'description';
- next if $k eq 'replicate';
next if $k =~ m/^unused\d+$/;
$dest->{$k} = $source->{$k};
snapshots => $conf->{snapshots},
};
- # keep description, list of unused disks and replicate parameters
+ # keep description and list of unused disks
foreach my $k (keys %$conf) {
- next if !($k =~ m/^unused\d+$/ || $k eq 'description' ||
- $k eq 'replicate');
+ next if !($k =~ m/^unused\d+$/ || $k eq 'description');
$newconf->{$k} = $conf->{$k};
}
my $prepare = 1;
- my $snap;
my $unused = [];
+ my $conf = $class->load_config($vmid);
+ my $snap = $conf->{snapshots}->{$snapname};
+
+ die "snapshot '$snapname' does not exist\n" if !defined($snap);
+
$class->set_lock($vmid, 'snapshot-delete')
if (!$drivehash); # doesn't already have a 'snapshot' lock
return $res;
};
+ my $repl_conf = PVE::ReplicationConfig->new();
+ if ($repl_conf->check_for_existing_jobs($vmid, 1)) {
+ # remove all replication snapshots
+ my $volumes = $class->get_replicatable_volumes($storecfg, $vmid, $conf, 1);
+ my $sorted_volids = [ sort keys %$volumes ];
+
+ # remove all local replication snapshots (jobid => undef)
+ my $logfunc = sub { my $line = shift; chomp $line; print "$line\n"; };
+ PVE::Replication::prepare($storecfg, $sorted_volids, undef, 0, undef, $logfunc);
+ }
+
my $snap = &$get_snapshot_config();
$class->__snapshot_foreach_volume($snap, sub {