]> git.proxmox.com Git - pve-manager.git/commitdiff
PVE::API2::ReplicationConfig - implement delete
authorDietmar Maurer <dietmar@proxmox.com>
Mon, 29 May 2017 06:37:38 +0000 (08:37 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 31 May 2017 06:23:47 +0000 (08:23 +0200)
We just set the remove_job property in the configuration. Actual removal
is done asynchronous inside replicate().

PVE/API2/ReplicationConfig.pm
PVE/CLI/pvesr.pm
PVE/Replication.pm

index 6f4de385f4dab0b0e1f16595393f0b95926c7e5c..0095bf378b2f0e0059e4d4be4da83246b24f32dd 100644 (file)
@@ -4,7 +4,7 @@ use warnings;
 use strict;
 
 use PVE::Tools qw(extract_param);
-use PVE::Exception qw(raise_perm_exc);
+use PVE::Exception qw(raise_perm_exc raise_param_exc);
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::RPCEnvironment;
 use PVE::ReplicationConfig;
@@ -112,7 +112,6 @@ __PACKAGE__->register_method ({
        my $code = sub {
            my $cfg = PVE::ReplicationConfig->new();
 
-           #die "replication job for guest '$param->{guest}' to target '$param->{target}' already exists\n"
            die "replication job '$id' already exists\n"
                if $cfg->{ids}->{$id};
 
@@ -171,7 +170,7 @@ __PACKAGE__->register_method ({
     protected => 1,
     path => '{id}',
     method => 'DELETE',
-    description => "Delete replication job",
+    description => "Mark replication job for removal.",
     permissions => {
        check => ['perm', '/storage', ['Datastore.Allocate']],
     },
@@ -191,21 +190,21 @@ __PACKAGE__->register_method ({
     code => sub {
        my ($param) = @_;
 
-       my $id = extract_param($param, 'id');
-
        my $code = sub {
            my $cfg = PVE::ReplicationConfig->new();
 
-           my $data = $cfg->{ids}->{$id};
-           die "no such job '$id'\n" if !$data;
+           my $id = $param->{id};
 
-           if (!$param->{keep}) {
-               # fixme: cleanup data at target
+           my $jobcfg = $cfg->{ids}->{$id};
+           die "no such job '$id'\n" if !$jobcfg;
 
+           if (!$param->{keep} && $jobcfg->{type} eq 'local') {
+               # remove local snapshots and remote volumes
+               $jobcfg->{remove_job} = 'full';
+           } else {
+               # only remove local snapshots
+               $jobcfg->{remove_job} = 'local';
            }
-           # fixme: cleanup snapshots
-
-           delete $cfg->{ids}->{$id};
 
            $cfg->write();
        };
@@ -214,4 +213,5 @@ __PACKAGE__->register_method ({
 
        return undef;
     }});
+
 1;
index 97ec2b525a2b673235d6e8ae53fad9bc61669d3d..93f1a2dbcb668b22cdf95b0b1c3906f5556995a0 100644 (file)
@@ -37,6 +37,12 @@ __PACKAGE__->register_method ({
            vmid => get_standard_option('pve-vmid', { completion => \&PVE::Cluster::complete_vmid }),
            'extra-args' => get_standard_option('extra-args', {
                description => "The list of volume IDs to consider." }),
+           force => {
+               description => "Allow to remove all existion volumes (empty volume list).",
+               type => 'boolean',
+               optional => 1,
+               default => 0,
+           },
            last_sync => {
                description => "Time (UNIX epoch) of last successful sync. If not specified, all replication snapshots get removed.",
                type => 'integer',
@@ -65,7 +71,8 @@ __PACKAGE__->register_method ({
 
        my $volids = [];
 
-       die "no volumes specified\n" if !scalar(@{$param->{'extra-args'}});
+       die "no volumes specified\n"
+           if !$param->{force} && !scalar(@{$param->{'extra-args'}});
 
        foreach my $volid (@{$param->{'extra-args'}}) {
 
index 711b08ffd7a7838aa1230ceefb5219cd42bdd68c..01111787a056d0ed521670d2fa7ccc676ecbff13 100644 (file)
@@ -103,15 +103,22 @@ sub job_status {
        $jobcfg->{vmtype} = $vms->{ids}->{$vmid}->{type};
 
        my $next_sync = 0;
-       if (my $fail_count = $state->{fail_count}) {
-           if ($fail_count < 3) {
-               $next_sync = $state->{last_try} + 5*60*$fail_count;
+
+       if ($jobcfg->{remove_job}) {
+           $next_sync = 1; # lowest possible value
+           # todo: consider fail_count? How many retries?
+       } else  {
+           if (my $fail_count = $state->{fail_count}) {
+               if ($fail_count < 3) {
+                   $next_sync = $state->{last_try} + 5*60*$fail_count;
+               }
+           } else {
+               my $schedule =  $jobcfg->{schedule} || '*/15';
+               my $calspec = PVE::CalendarEvent::parse_calendar_event($schedule);
+               $next_sync = PVE::CalendarEvent::compute_next_event($calspec, $state->{last_try}) // 0;
            }
-       } else {
-           my $schedule =  $jobcfg->{schedule} || '*/15';
-           my $calspec = PVE::CalendarEvent::parse_calendar_event($schedule);
-           $next_sync = PVE::CalendarEvent::compute_next_event($calspec, $state->{last_try}) // 0;
        }
+
        $jobcfg->{next_sync} = $next_sync;
 
        $jobs->{$jobid} = $jobcfg;
@@ -168,11 +175,14 @@ sub replication_snapshot_name {
 }
 
 sub remote_prepare_local_job {
-    my ($ssh_info, $jobid, $vmid, $volumes, $last_sync) = @_;
+    my ($ssh_info, $jobid, $vmid, $volumes, $last_sync, $force) = @_;
 
     my $ssh_cmd = PVE::Cluster::ssh_info_to_command($ssh_info);
-    my $cmd = [@$ssh_cmd, '--', 'pvesr', 'prepare-local-job', $jobid,
-              $vmid, @$volumes, '--last_sync', $last_sync];
+    my $cmd = [@$ssh_cmd, '--', 'pvesr', 'prepare-local-job', $jobid, $vmid];
+    push @$cmd, @$volumes if scalar(@$volumes);
+
+    push @$cmd, '--last_sync', $last_sync;
+    push @$cmd, '--force' if $force;
 
     my $remote_snapshots;
 
@@ -231,6 +241,18 @@ sub replicate_volume {
                                  $base_snapshot, $sync_snapname);
 }
 
+sub delete_job {
+    my ($jobid) = @_;
+
+    my $code = sub {
+       my $cfg = PVE::ReplicationConfig->new();
+       delete $cfg->{ids}->{$jobid};
+       $cfg->write();
+    };
+
+    PVE::ReplicationConfig::lock($code);
+}
+
 sub replicate {
     my ($jobcfg, $last_sync, $start_time, $logfunc) = @_;
 
@@ -284,9 +306,27 @@ sub replicate {
     $logfunc->($start_time, "$jobid: guest => $vmid, type => $vmtype, running => $running");
     $logfunc->($start_time, "$jobid: volumes => " . join(',', @$sorted_volids));
 
+    if (my $remove_job = $jobcfg->{remove_job}) {
+
+       $logfunc->($start_time, "$jobid: start job removal - mode '${remove_job}'");
+
+       if ($remove_job eq 'full') {
+           # remove all remote volumes
+           remote_prepare_local_job($ssh_info, $jobid, $vmid, [], 0, 1);
+
+       }
+       # remove all local replication snapshots (lastsync => 0)
+       prepare($storecfg, $sorted_volids, $jobid, 0, $start_time, $logfunc);
+
+       delete_job($jobid); # update config
+       $logfunc->($start_time, "$jobid: job removed");
+
+       return;
+    }
+
     # prepare remote side
     my $remote_snapshots = remote_prepare_local_job(
-       $ssh_info, $jobid, $vmid, $volumes, $last_sync);
+       $ssh_info, $jobid, $vmid, $sorted_volids, $last_sync);
 
     # test if we have a replication_ snapshot from last sync
     # and remove all other/stale replication snapshots