[pve-devel] [RFC storage 6/6] pbs: integrate support for protected

Fabian Ebner f.ebner at proxmox.com
Fri Sep 17 15:02:26 CEST 2021


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 <f.ebner at proxmox.com>
---

Needs new external dependency for strptime (libposix-strptime-perl),
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.

It depends on Dominik's patches for PBS to work:
https://lists.proxmox.com/pipermail/pbs-devel/2021-September/003926.html

 PVE/Storage/PBSPlugin.pm | 59 ++++++++++++++++++++++++++++++++++------
 1 file changed, 51 insertions(+), 8 deletions(-)

diff --git a/PVE/Storage/PBSPlugin.pm b/PVE/Storage/PBSPlugin.pm
index d8e1ac8..082d138 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,
@@ -658,6 +689,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})) {
@@ -785,12 +817,19 @@ sub deactivate_volume {
 sub get_volume_attribute {
     my ($class, $scfg, $storeid, $volname, $attribute) = @_;
 
-    if ($attribute eq 'notes') {
-	my (undef, $name,  undef, undef, undef, undef, $format) = $class->parse_volname($volname);
+    if ($attribute eq 'notes' || $attribute eq 'protected') {
+	my $param = $class->api_param_from_volname($volname);
 
-	my $data = run_client_cmd($scfg, $storeid, "snapshot", [ "notes", "show", $name ]);
+	my $password = pbs_get_password($scfg, $storeid);
+	my $conn = pbs_api_connect($scfg, $password);
+	my $datastore = $scfg->{datastore};
 
-	return $data->{notes} // '';
+	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;
@@ -799,11 +838,15 @@ sub get_volume_attribute {
 sub update_volume_attribute {
     my ($class, $scfg, $storeid, $volname, $attribute, $value) = @_;
 
-    if ($attribute eq 'notes') {
-	my (undef, $name,  undef, undef, undef, undef, $format) = $class->parse_volname($volname);
+    if ($attribute eq 'notes' || $attribute eq 'protected') {
+	my $param = $class->api_param_from_volname($volname);
+	$param->{$attribute} = $value;
 
-	run_client_cmd($scfg, $storeid, "snapshot", [ "notes", "update", $name, $value ], 1);
+	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;
     }
 
-- 
2.30.2





More information about the pve-devel mailing list