From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9FB9870C2B for ; Thu, 30 Sep 2021 13:42:55 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2E7C11EE6E for ; Thu, 30 Sep 2021 13:42:25 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 838FF1ED46 for ; Thu, 30 Sep 2021 13:42:20 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 5CE1144958 for ; Thu, 30 Sep 2021 13:42:20 +0200 (CEST) From: Fabian Ebner To: pve-devel@lists.proxmox.com Date: Thu, 30 Sep 2021 13:42:10 +0200 Message-Id: <20210930114215.240095-8-f.ebner@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210930114215.240095-1-f.ebner@proxmox.com> References: <20210930114215.240095-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.298 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% 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 URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [pbsplugin.pm, proxmox.com] Subject: [pve-devel] [PATCH v2 storage 7/7] pbs: integrate support for protected 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: , X-List-Received-Date: Thu, 30 Sep 2021 11:42:55 -0000 free_image doesn't need to check for protection, because that will happen on the server. Getting/updating notes has also been refactored to re-use the code for the PBS api calls. Signed-off-by: Fabian Ebner --- Changes from v1: * Rebase, because of newly introduced fall-back to {get, update}_volume_notes. * Set mark 'protected' rather than 'keep' if backup is protected in prune_backups(). Needs new external dependency for strptime, because it's not in perl's POSIX module. An alternative would be to use perlmod and export the proxmox crate's function for parsing the timestring. Also depends on Dominik's patches for PBS: https://lists.proxmox.com/pipermail/pbs-devel/2021-September/004099.html PVE/Storage/PBSPlugin.pm | 66 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/PVE/Storage/PBSPlugin.pm b/PVE/Storage/PBSPlugin.pm index 76699e6..06ebfa7 100644 --- a/PVE/Storage/PBSPlugin.pm +++ b/PVE/Storage/PBSPlugin.pm @@ -9,7 +9,8 @@ use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC); use IO::File; use JSON; use MIME::Base64 qw(decode_base64); -use POSIX qw(strftime ENOENT); +use POSIX qw(mktime strftime ENOENT); +use POSIX::strptime; use PVE::APIClient::LWP; use PVE::JSONSchema qw(get_standard_option); @@ -218,6 +219,36 @@ sub print_volid { return "${storeid}:${volname}"; } +# essentially the inverse of print_volid +sub api_param_from_volname { + my ($class, $volname) = @_; + + my $name = ($class->parse_volname($volname))[1]; + + my ($btype, $bid, $timestr) = split('/', $name); + + my @tm = (POSIX::strptime($timestr, "%FT%TZ")); + # expect sec, min, hour, mday, mon, year + die "error parsing time from '$volname'" if grep { !defined($_) } @tm[0..5]; + + my $btime; + { + local $ENV{TZ} = 'UTC'; # $timestr is UTC + + # Fill in isdst to avoid undef warning. No daylight saving time for UTC. + $tm[8] //= 0; + + my $since_epoch = mktime(@tm) or die "error converting time from '$volname'\n"; + $btime = int($since_epoch); + } + + return { + 'backup-type' => $btype, + 'backup-id' => $bid, + 'backup-time' => $btime, + }; +} + my $USE_CRYPT_PARAMS = { backup => 1, restore => 1, @@ -403,9 +434,12 @@ sub prune_backups { my $vmid = $backup->{'backup-id'}; my $volid = print_volid($storeid, $type, $vmid, $ctime); + my $mark = $backup->{keep} ? 'keep' : 'remove'; + $mark = 'protected' if $backup->{protected}; + push @{$prune_list}, { ctime => $ctime, - mark => $backup->{keep} ? 'keep' : 'remove', + mark => $mark, type => $type eq 'vm' ? 'qemu' : 'lxc', vmid => $vmid, volid => $volid, @@ -658,6 +692,7 @@ sub list_volumes { $info->{verification} = $item->{verification} if defined($item->{verification}); $info->{notes} = $item->{comment} if defined($item->{comment}); + $info->{protected} = 1 if $item->{protected}; if (defined($item->{fingerprint})) { $info->{encrypted} = $item->{fingerprint}; } elsif (snapshot_files_encrypted($item->{files})) { @@ -813,6 +848,21 @@ sub get_volume_attribute { return $class->get_volume_notes($scfg, $storeid, $volname); } + if ($attribute eq 'protected') { + my $param = $class->api_param_from_volname($volname); + + my $password = pbs_get_password($scfg, $storeid); + my $conn = pbs_api_connect($scfg, $password); + my $datastore = $scfg->{datastore}; + + my $res = eval { $conn->get("/api2/json/admin/datastore/$datastore/$attribute", $param); }; + if (my $err = $@) { + return if $err->{code} == 404; # not supported + die $err; + } + return $res; + } + return; } @@ -823,6 +873,18 @@ sub update_volume_attribute { return $class->update_volume_notes($scfg, $storeid, $volname, $value); } + if ($attribute eq 'protected') { + my $param = $class->api_param_from_volname($volname); + $param->{$attribute} = $value; + + my $password = pbs_get_password($scfg, $storeid); + my $conn = pbs_api_connect($scfg, $password); + my $datastore = $scfg->{datastore}; + + $conn->put("/api2/json/admin/datastore/$datastore/$attribute", $param); + return; + } + die "attribute '$attribute' is not supported for storage type '$scfg->{type}'\n"; } -- 2.30.2