From: Fiona Ebner <f.ebner@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
Filip Schauer <f.schauer@proxmox.com>
Subject: Re: [pve-devel] [PATCH storage v6 5/7] support moving VMA backups to PBS
Date: Thu, 13 Feb 2025 18:20:56 +0100 [thread overview]
Message-ID: <a6d503c5-486f-4c2c-813b-39866a054d13@proxmox.com> (raw)
In-Reply-To: <20250120112842.36450-6-f.schauer@proxmox.com>
Am 20.01.25 um 12:28 schrieb Filip Schauer:
> Extend the move API to support moving VMA backups to a Proxmox Backup
> Server.
>
> Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
> ---
> debian/control | 1 +
> src/PVE/API2/Storage/Content.pm | 53 +++++++++++++++------------
> src/PVE/Storage/PBSPlugin.pm | 65 +++++++++++++++++++++++++++++++++
> 3 files changed, 96 insertions(+), 23 deletions(-)
>
> diff --git a/debian/control b/debian/control
> index 4e1a046..0883777 100644
> --- a/debian/control
> +++ b/debian/control
> @@ -46,6 +46,7 @@ Depends: bzip2,
> nfs-common,
> proxmox-backup-client (>= 2.1.10~),
> proxmox-backup-file-restore,
> + proxmox-vma-to-pbs (>= 0.0.2),
> pve-cluster (>= 5.0-32),
> smartmontools,
> smbclient,
> diff --git a/src/PVE/API2/Storage/Content.pm b/src/PVE/API2/Storage/Content.pm
> index 9ee3c51..c0e2a4e 100644
> --- a/src/PVE/API2/Storage/Content.pm
> +++ b/src/PVE/API2/Storage/Content.pm
> @@ -10,6 +10,7 @@ use File::Copy qw(copy move);
> use PVE::SafeSyslog;
> use PVE::Cluster;
> use PVE::Storage;
> +use PVE::Storage::PBSPlugin;
> use PVE::INotify;
> use PVE::Exception qw(raise_param_exc);
> use PVE::RPCEnvironment;
> @@ -557,12 +558,12 @@ __PACKAGE__->register_method ({
> my $user = $rpcenv->get_user();
>
> PVE::Storage::check_volume_access($rpcenv, $user, $cfg, undef, $src_volid);
> + my $src_cfg = PVE::Storage::storage_config($cfg, $src_storeid);
>
> if ($delete) {
> $rpcenv->check($user, "/storage/$src_storeid", ["Datastore.Allocate"]);
>
> if ($vtype eq 'backup') {
> - my $src_cfg = PVE::Storage::storage_config($cfg, $src_storeid);
> my $src_plugin = PVE::Storage::Plugin->lookup($src_cfg->{type});
> my $protected = $src_plugin->get_volume_attribute($src_cfg, $src_storeid, $volname, 'protected');
> die "cannot delete protected backup\n" if $protected;
> @@ -577,30 +578,36 @@ __PACKAGE__->register_method ({
>
> my $worker = sub {
> PVE::Storage::storage_check_enabled($cfg, $dst_storeid, $dst_node);
> - my $sshinfo;
>
> - if ($src_node eq $dst_node) {
> - $sshinfo = {
> - ip => "localhost",
> - name => $dst_node,
> - };
> + my $dst_cfg = PVE::Storage::storage_config($cfg, $dst_storeid);
> + if ($vtype eq 'backup' && $dst_cfg->{type} eq 'pbs') {
Maybe check that the source plugin is path-based here to rule out some
other third-party backup storages early.
> + PVE::Storage::PBSPlugin::vma_to_pbs($src_cfg, $src_volid, $dst_cfg, $dst_storeid);
> } else {
> - $sshinfo = PVE::SSHInfo::get_ssh_info($dst_node);
> - }
> -
> - my $opts = { 'target_volname' => $volname };
> - PVE::Storage::storage_migrate($cfg, $src_volid, $sshinfo, $dst_storeid, $opts);
> -
> - if ($delete) {
> - my $src_path = PVE::Storage::abs_filesystem_path($cfg, $src_volid);
> - PVE::Storage::archive_remove($src_path, 1);
> - }
> -
> - if ($src_node eq $dst_node) {
> - print "Moved volume '$src_volid' to '$dst_storeid'\n";
> - } else {
> - print "Moved volume '$src_volid' on node '$src_node'"
> - ." to '$dst_storeid' on node '$dst_node'\n";
> + my $sshinfo;
> +
> + if ($src_node eq $dst_node) {
> + $sshinfo = {
> + ip => "localhost",
> + name => $dst_node,
> + };
> + } else {
> + $sshinfo = PVE::SSHInfo::get_ssh_info($dst_node);
> + }
> +
> + my $opts = { 'target_volname' => $volname };
> + PVE::Storage::storage_migrate($cfg, $src_volid, $sshinfo, $dst_storeid, $opts);
> +
> + if ($delete) {
> + my $src_path = PVE::Storage::abs_filesystem_path($cfg, $src_volid);
> + PVE::Storage::archive_remove($src_path, 1);
> + }
> +
> + if ($src_node eq $dst_node) {
> + print "Moved volume '$src_volid' to '$dst_storeid'\n";
> + } else {
> + print "Moved volume '$src_volid' on node '$src_node'"
> + ." to '$dst_storeid' on node '$dst_node'\n";
> + }
> }
> };
>
> diff --git a/src/PVE/Storage/PBSPlugin.pm b/src/PVE/Storage/PBSPlugin.pm
> index 0808bcc..4f8a05d 100644
> --- a/src/PVE/Storage/PBSPlugin.pm
> +++ b/src/PVE/Storage/PBSPlugin.pm
> @@ -6,6 +6,7 @@ use strict;
> use warnings;
>
> use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC);
> +use File::Basename;
> use IO::File;
> use JSON;
> use MIME::Base64 qw(decode_base64);
> @@ -971,4 +972,68 @@ sub volume_has_feature {
> return undef;
> }
>
> +sub vma_to_pbs {
> + my ($source_scfg, $source_volid, $target_scfg, $target_storeid) = @_;
> +
> + my $source_plugin = PVE::Storage::Plugin->lookup($source_scfg->{type});
I know I'm being nitpicky, but I'd kinda prefer not having to access the
source plugin here. The required parameters could be passed in.
> + my $target_plugin = PVE::Storage::Plugin->lookup($target_scfg->{type});
> + my ($source_storeid, $source_volname) = PVE::Storage::parse_volume_id($source_volid, 0);
> + my $source_path = $source_plugin->path($source_scfg, $source_volname, $source_storeid);
> + my $info = PVE::Storage::archive_info($source_path);
> + die "moving non-VMA backups to a Proxmox Backup Server is not supported\n"
> + if $info->{format} ne 'vma';
> +
> + my $repo = PVE::PBSClient::get_repository($target_scfg);
> + my $vmid = ($source_plugin->parse_volname($source_volname))[2];
> + my $fingerprint = $target_scfg->{fingerprint};
> + my $password = PVE::Storage::PBSPlugin::pbs_password_file_name($target_scfg, $target_storeid);
> + my $namespace = $target_scfg->{namespace};
> + my $keyfile = PVE::Storage::PBSPlugin::pbs_encryption_key_file_name(
> + $target_scfg, $target_storeid);
> + my $master_keyfile = PVE::Storage::PBSPlugin::pbs_master_pubkey_file_name(
> + $target_scfg, $target_storeid);
> +
> + my $comp = $info->{compression};
> + my $backup_time = $info->{ctime};
> + my $source_dirname = dirname($source_path);
> + my $log_file_path = "$source_dirname/$info->{logfilename}";
> + my $notes_file_path = "$source_dirname/$info->{notesfilename}";
> +
> + my $vma_to_pbs_cmd = [
> + "vma-to-pbs",
> + "--repository", $repo,
> + "--vmid", $vmid,
> + "--fingerprint", $fingerprint,
> + "--password-file", $password,
> + "--backup-time", $backup_time,
> + "--compress",
> + ];
> +
> + push @$vma_to_pbs_cmd, "--ns", $namespace if $namespace;
> + push @$vma_to_pbs_cmd, "--log-file", $log_file_path if -e $log_file_path;
> + push @$vma_to_pbs_cmd, "--notes-file", $notes_file_path if -e $notes_file_path;
> + push @$vma_to_pbs_cmd, "--encrypt", "--keyfile", $keyfile if -e $keyfile;
> + push @$vma_to_pbs_cmd, "--master-keyfile", $master_keyfile if -e $master_keyfile;
> +
> + if ($comp) {
> + PVE::Storage::decompress_archive_into_pipe($source_path, $vma_to_pbs_cmd);
> + } else {
> + push @$vma_to_pbs_cmd, $source_path;
> + run_command($vma_to_pbs_cmd);
> + }
> +
> + my $protected = $source_plugin->get_volume_attribute(
> + $source_scfg, $source_storeid, $source_volname, 'protected');
> +
> + if ($protected) {
> + my $target_volid = PVE::Storage::PBSPlugin::print_volid(
> + $target_storeid, 'vm', $vmid, $backup_time);
> + my (undef, $target_volname) = PVE::Storage::parse_volume_id($target_volid, 0);
> + $target_plugin->update_volume_attribute(
> + $target_scfg, $target_storeid, $target_volname, 'protected', 1);
> + }
> +
> + return;
> +}
> +
> 1;
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2025-02-13 17:21 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-20 11:28 [pve-devel] [PATCH storage v6 0/7] support moving volumes between storages Filip Schauer
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 1/7] plugin: allow volume import of iso, snippets, vztmpl and import Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-02-14 9:50 ` Fiona Ebner
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 2/7] api: content: implement moving a volume between storages Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 3/7] api: content: support moving backups between path based storages Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 4/7] storage: introduce decompress_archive_into_pipe helper Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 5/7] support moving VMA backups to PBS Filip Schauer
2025-02-13 17:20 ` Fiona Ebner [this message]
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 6/7] pvesm: add a move-volume command Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-01-20 11:28 ` [pve-devel] [PATCH storage v6 7/7] storage migrate: avoid ssh when moving a volume locally Filip Schauer
2025-02-13 17:21 ` Fiona Ebner
2025-02-13 17:23 ` [pve-devel] [PATCH storage v6 0/7] support moving volumes between storages Fiona Ebner
2025-03-11 14:25 ` Filip Schauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a6d503c5-486f-4c2c-813b-39866a054d13@proxmox.com \
--to=f.ebner@proxmox.com \
--cc=f.schauer@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal