]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/PBSClient.pm
pbs client: forget snapshot: suppress output
[pve-common.git] / src / PVE / PBSClient.pm
index bfeae3b154364ca57216f692722dc0b59e63f82f..4b5b485255e7a0836f19017606b456d0decf11ca 100644 (file)
@@ -77,7 +77,7 @@ sub delete_password {
 
     my $pwfile = password_file_name($self);
 
-    unlink $pwfile or die "deleting password file failed - $!\n";
+    unlink $pwfile or $! == ENOENT or die "deleting password file failed - $!\n";
 };
 
 sub get_password {
@@ -130,18 +130,22 @@ my sub open_encryption_key {
 }
 
 my $USE_CRYPT_PARAMS = {
-    backup => 1,
-    restore => 1,
-    'upload-log' => 1,
-    list => 1,
-    extract => 1,
+    'proxmox-backup-client' => {
+       backup => 1,
+       restore => 1,
+       'upload-log' => 1,
+    },
+    'proxmox-file-restore' => {
+       list => 1,
+       extract => 1,
+    },
 };
 
 my sub do_raw_client_cmd {
     my ($self, $client_cmd, $param, %opts) = @_;
 
     my $client_bin = (delete $opts{binary}) || 'proxmox-backup-client';
-    my $use_crypto = $USE_CRYPT_PARAMS->{$client_cmd};
+    my $use_crypto = $USE_CRYPT_PARAMS->{$client_bin}->{$client_cmd} // 0;
 
     my $client_exe = "/usr/bin/$client_bin";
     die "executable not found '$client_exe'! $client_bin not installed?\n" if ! -x $client_exe;
@@ -174,6 +178,9 @@ my sub do_raw_client_cmd {
     push @$cmd, @$param if defined($param);
 
     push @$cmd, "--repository", $repo;
+    if (defined(my $ns = delete($opts{namespace}))) {
+       push @$cmd, '--ns', $ns;
+    }
 
     local $ENV{PBS_PASSWORD} = $self->get_password();
 
@@ -190,13 +197,13 @@ my sub do_raw_client_cmd {
     run_command($cmd, %opts);
 }
 
-my sub run_raw_client_cmd {
+my sub run_raw_client_cmd : prototype($$$%) {
     my ($self, $client_cmd, $param, %opts) = @_;
     return do_raw_client_cmd($self, $client_cmd, $param, %opts);
 }
 
-my sub run_client_cmd {
-    my ($self, $client_cmd, $param, $no_output, $binary) = @_;
+my sub run_client_cmd : prototype($$;$$$$) {
+    my ($self, $client_cmd, $param, $no_output, $binary, $namespace) = @_;
 
     my $json_str = '';
     my $outfunc = sub { $json_str .= "$_[0]\n" };
@@ -215,6 +222,7 @@ my sub run_client_cmd {
        outfunc => $outfunc,
        errmsg => "$binary failed",
        binary => $binary,
+       namespace => $namespace,
     );
 
     return undef if $no_output;
@@ -234,20 +242,35 @@ sub autogen_encryption_key {
     return file_get_contents($encfile);
 };
 
+# Snapshot or group parameters can be either just a string and will then refer to the root
+# namespace, or a tuple of `[namespace, snapshot]`.
+my sub split_namespaced_parameter : prototype($) {
+    my ($snapshot) = @_;
+    return (undef, $snapshot) if !ref($snapshot);
+
+    (my $namespace, $snapshot) = @$snapshot;
+    return ($namespace, $snapshot);
+}
+
 # lists all snapshots, optionally limited to a specific group
 sub get_snapshots {
     my ($self, $group) = @_;
 
+    my $namespace;
+    if (defined($group)) {
+       ($namespace, $group) = split_namespaced_parameter($group);
+    }
+
     my $param = [];
     push @$param, $group if defined($group);
 
-    return run_client_cmd($self, "snapshots", $param);
+    return run_client_cmd($self, "snapshots", $param, undef, undef, $namespace);
 };
 
 # create a new PXAR backup of a FS directory tree - doesn't cross FS boundary
 # by default.
 sub backup_fs_tree {
-    my ($self, $root, $id, $pxarname, $cmd_opts) = @_;
+    my ($self, $root, $id, $pxarname, $cmd_opts, $namespace) = @_;
 
     die "backup-id not provided\n" if !defined($id);
     die "backup root dir not provided\n" if !defined($root);
@@ -261,6 +284,8 @@ sub backup_fs_tree {
 
     $cmd_opts //= {};
 
+    $cmd_opts->{namespace} = $namespace if defined($namespace);
+
     return run_raw_client_cmd($self, 'backup', $param, %$cmd_opts);
 };
 
@@ -271,6 +296,8 @@ sub restore_pxar {
     die "archive name not provided\n" if !defined($pxarname);
     die "restore-target not provided\n" if !defined($target);
 
+    (my $namespace, $snapshot) = split_namespaced_parameter($snapshot);
+
     my $param = [
        "$snapshot",
        "$pxarname.pxar",
@@ -279,6 +306,8 @@ sub restore_pxar {
     ];
     $cmd_opts //= {};
 
+    $cmd_opts->{namespace} = $namespace;
+
     return run_raw_client_cmd($self, 'restore', $param, %$cmd_opts);
 };
 
@@ -287,7 +316,9 @@ sub forget_snapshot {
 
     die "snapshot not provided\n" if !defined($snapshot);
 
-    return run_raw_client_cmd($self, 'forget', ["$snapshot"]);
+    (my $namespace, $snapshot) = split_namespaced_parameter($snapshot);
+
+    return run_client_cmd($self, 'forget', ["$snapshot"], 1, undef, $namespace)
 };
 
 sub prune_group {
@@ -295,6 +326,8 @@ sub prune_group {
 
     die "group not provided\n" if !defined($group);
 
+    (my $namespace, $group) = split_namespaced_parameter($group);
+
     # do nothing if no keep options specified for remote
     return [] if scalar(keys %$prune_opts) == 0;
 
@@ -311,7 +344,7 @@ sub prune_group {
     }
     push @$param, "$group";
 
-    return run_client_cmd($self, 'prune', $param);
+    return run_client_cmd($self, 'prune', $param, undef, undef, $namespace);
 };
 
 sub status {
@@ -339,12 +372,16 @@ sub status {
 
 sub file_restore_list {
     my ($self, $snapshot, $filepath, $base64) = @_;
+
+    (my $namespace, $snapshot) = split_namespaced_parameter($snapshot);
+
     return run_client_cmd(
        $self,
        "list",
        [ $snapshot, $filepath, "--base64", $base64 ? 1 : 0 ],
        0,
        "proxmox-file-restore",
+       $namespace,
     );
 }
 
@@ -372,6 +409,8 @@ sub file_restore_extract_prepare {
 sub file_restore_extract {
     my ($self, $output_file, $snapshot, $filepath, $base64) = @_;
 
+    (my $namespace, $snapshot) = split_namespaced_parameter($snapshot);
+
     my $ret = eval {
        local $SIG{ALRM} = sub { die "got timeout\n" };
        alarm(30);
@@ -387,6 +426,7 @@ sub file_restore_extract {
             "extract",
            [ $snapshot, $filepath, "-", "--base64", $base64 ? 1 : 0 ],
            binary => "proxmox-file-restore",
+           namespace => $namespace,
            errfunc => $errfunc,
            output => ">&$fn",
        );