]> git.proxmox.com Git - pve-guest-common.git/blobdiff - PVE/AbstractConfig.pm
add create_and_lock_config
[pve-guest-common.git] / PVE / AbstractConfig.pm
index 17985d73348d1714670cedaa05623420a4b22b98..11180df80df1c3bde2a515f6f9784e7256da8910 100644 (file)
@@ -8,6 +8,9 @@ use PVE::INotify;
 use PVE::Cluster;
 use PVE::Storage;
 
+use PVE::ReplicationConfig;
+use PVE::Replication;
+
 my $nodename = PVE::INotify::nodename();
 
 # Printable string, currently either "VM" or "CT"
@@ -79,6 +82,19 @@ sub lock_config_full {
     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
@@ -192,6 +208,15 @@ sub has_feature {
     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
@@ -314,7 +339,6 @@ sub __snapshot_copy_config {
        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};
@@ -330,10 +354,9 @@ sub __snapshot_apply_config {
        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};
     }
@@ -470,9 +493,13 @@ sub snapshot_delete {
 
     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
 
@@ -585,6 +612,17 @@ sub snapshot_rollback {
        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 {