From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 766331FF2CA for ; Tue, 23 Jul 2024 11:57:18 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 92F9A3FB6C; Tue, 23 Jul 2024 11:57:24 +0200 (CEST) From: Fiona Ebner To: pve-devel@lists.proxmox.com Date: Tue, 23 Jul 2024 11:56:24 +0200 Message-Id: <20240723095624.53621-24-f.ebner@proxmox.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240723095624.53621-1-f.ebner@proxmox.com> References: <20240723095624.53621-1-f.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.061 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [RFC manager 23/23] backup: implement backup for external providers X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Hooks from the backup provider are called during start/end/abort for both job and backup. And it is necessary to adapt some log messages and special case some things like is already done for PBS, e.g. log file handling. Signed-off-by: Fiona Ebner --- PVE/VZDump.pm | 43 +++++++++++++++++++++++++++++++++++------ test/vzdump_new_test.pl | 3 +++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/PVE/VZDump.pm b/PVE/VZDump.pm index f1a6b220..8e48bd0a 100644 --- a/PVE/VZDump.pm +++ b/PVE/VZDump.pm @@ -707,6 +707,13 @@ sub new { $opts->{pbs} = $info->{pbs}; $opts->{'prune-backups'} //= $info->{'prune-backups'}; } + + my $backup_provider = PVE::Storage::new_backup_provider( + $storage_cfg, + $opts->{storage}, + sub { debugmsg($_[0], $_[1]); }, + ); + $self->{'backup-provider'} = $backup_provider if $backup_provider; } elsif ($opts->{dumpdir}) { $add_error->("dumpdir '$opts->{dumpdir}' does not exist") if ! -d $opts->{dumpdir}; @@ -990,7 +997,7 @@ sub exec_backup_task { } } - if (!$self->{opts}->{pbs}) { + if (!$self->{opts}->{pbs} && !$self->{'backup-provider'}) { $task->{logfile} = "$opts->{dumpdir}/$basename.log"; } @@ -1000,7 +1007,10 @@ sub exec_backup_task { $ext .= ".${comp_ext}"; } - if ($self->{opts}->{pbs}) { + if ($self->{'backup-provider'}) { + die "unable to pipe backup to stdout\n" if $opts->{stdout}; + $task->{target} = $self->{'backup-provider'}->backup_get_target($vmid, $vmtype); + } elsif ($self->{opts}->{pbs}) { die "unable to pipe backup to stdout\n" if $opts->{stdout}; $task->{target} = $pbs_snapshot_name; } else { @@ -1018,7 +1028,7 @@ sub exec_backup_task { my $pid = $$; if ($opts->{tmpdir}) { $task->{tmpdir} = "$opts->{tmpdir}/vzdumptmp${pid}_$vmid/"; - } elsif ($self->{opts}->{pbs}) { + } elsif ($self->{opts}->{pbs} || $self->{'backup-provider'}) { $task->{tmpdir} = "/var/tmp/vzdumptmp${pid}_$vmid"; } else { # dumpdir is posix? then use it as temporary dir @@ -1090,6 +1100,7 @@ sub exec_backup_task { if ($mode eq 'stop') { $plugin->prepare ($task, $vmid, $mode); + $self->{'backup-provider'}->backup_start($vmid, $vmtype) if $self->{'backup-provider'}; $self->run_hook_script ('backup-start', $task, $logfd); if ($running) { @@ -1104,6 +1115,7 @@ sub exec_backup_task { } elsif ($mode eq 'suspend') { $plugin->prepare ($task, $vmid, $mode); + $self->{'backup-provider'}->backup_start($vmid, $vmtype) if $self->{'backup-provider'}; $self->run_hook_script ('backup-start', $task, $logfd); if ($vmtype eq 'lxc') { @@ -1130,6 +1142,7 @@ sub exec_backup_task { } } elsif ($mode eq 'snapshot') { + $self->{'backup-provider'}->backup_start($vmid, $vmtype) if $self->{'backup-provider'}; $self->run_hook_script ('backup-start', $task, $logfd); my $snapshot_count = $task->{snapshot_count} || 0; @@ -1172,11 +1185,13 @@ sub exec_backup_task { return; } - my $archive_txt = $self->{opts}->{pbs} ? 'Proxmox Backup Server' : 'vzdump'; + my $archive_txt = 'vzdump'; + $archive_txt = 'Proxmox Backup Server' if $self->{opts}->{pbs}; + $archive_txt = $self->{'backup-provider'}->provider_name() if $self->{'backup-provider'}; debugmsg('info', "creating $archive_txt archive '$task->{target}'", $logfd); $plugin->archive($task, $vmid, $task->{tmptar}, $comp); - if ($self->{opts}->{pbs}) { + if ($self->{'backup-provider'} || $self->{opts}->{pbs}) { # size is added to task struct in guest vzdump plugins } else { rename ($task->{tmptar}, $task->{target}) || @@ -1190,7 +1205,8 @@ sub exec_backup_task { # Mark as protected before pruning. if (my $storeid = $opts->{storage}) { - my $volname = $opts->{pbs} ? $task->{target} : basename($task->{target}); + my $volname = $opts->{pbs} || $self->{'backup-provider'} ? $task->{target} + : basename($task->{target}); my $volid = "${storeid}:backup/${volname}"; if ($opts->{'notes-template'} && $opts->{'notes-template'} ne '') { @@ -1243,6 +1259,7 @@ sub exec_backup_task { debugmsg ('info', "pruned $pruned backup(s)${log_pruned_extra}", $logfd); } + $self->{'backup-provider'}->backup_end($vmid) if $self->{'backup-provider'}; $self->run_hook_script ('backup-end', $task, $logfd); }; my $err = $@; @@ -1302,6 +1319,11 @@ sub exec_backup_task { debugmsg ('err', "Backup of VM $vmid failed - $err", $logfd, 1); debugmsg ('info', "Failed at " . strftime("%F %H:%M:%S", localtime())); + if ($self->{'backup-provider'}) { + eval { $self->{'backup-provider'}->backup_abort($vmid, $err); }; + debugmsg('warn', "hook 'backup-abort' for external provider failed - $@") if $@; + } + eval { $self->run_hook_script ('backup-abort', $task, $logfd); }; debugmsg('warn', $@) if $@; # message already contains command with phase name @@ -1329,6 +1351,8 @@ sub exec_backup_task { }; debugmsg('warn', "$@") if $@; # $@ contains already error prefix } + } elsif ($self->{'backup-provider'}) { + $self->{'backup-provider'}->backup_handle_log_file($vmid, $task->{tmplog}); } elsif ($task->{logfile}) { system {'cp'} 'cp', $task->{tmplog}, $task->{logfile}; } @@ -1387,6 +1411,7 @@ sub exec_backup { my $errcount = 0; eval { + $self->{'backup-provider'}->job_start($starttime) if $self->{'backup-provider'}; $self->run_hook_script ('job-start', undef, $job_start_fd); foreach my $task (@$tasklist) { @@ -1394,11 +1419,17 @@ sub exec_backup { $errcount += 1 if $task->{state} ne 'ok'; } + $self->{'backup-provider'}->job_end() if $self->{'backup-provider'}; $self->run_hook_script ('job-end', undef, $job_end_fd); }; my $err = $@; if ($err) { + if ($self->{'backup-provider'}) { + eval { $self->{'backup-provider'}->job_abort($err); }; + $err .= "hook 'job-abort' for external provider failed - $@" if $@; + } + eval { $self->run_hook_script ('job-abort', undef, $job_end_fd); }; $err .= $@ if $@; debugmsg ('err', "Backup job failed - $err", undef, 1); diff --git a/test/vzdump_new_test.pl b/test/vzdump_new_test.pl index 8cd73075..01f2a661 100755 --- a/test/vzdump_new_test.pl +++ b/test/vzdump_new_test.pl @@ -51,6 +51,9 @@ $pve_storage_module->mock( activate_storage => sub { return; }, + get_backup_provider => sub { + return; + }, ); my $pve_cluster_module = Test::MockModule->new('PVE::Cluster'); -- 2.39.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel