[pbs-devel] [RFC v2 proxmox-backup 17/21] api: namespace: add option to list all namespaces, including trashed

Christian Ebner c.ebner at proxmox.com
Thu May 8 15:05:51 CEST 2025


Add an optional parameter so all namespaces can be listed, including
ones which are marked as trash. This allows to display all namespace
in the UI, independent of their current state.

Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
 src/api2/admin/namespace.rs             | 28 +++++++++++++++++--------
 src/bin/proxmox-backup-manager.rs       | 12 ++++++++---
 src/bin/proxmox_backup_manager/prune.rs |  2 +-
 3 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/api2/admin/namespace.rs b/src/api2/admin/namespace.rs
index 6f70497a6..098e69ee8 100644
--- a/src/api2/admin/namespace.rs
+++ b/src/api2/admin/namespace.rs
@@ -75,6 +75,12 @@ pub fn create_namespace(
                 schema: NS_MAX_DEPTH_SCHEMA,
                 optional: true,
             },
+            "include-trashed": {
+                type: bool,
+                optional: true,
+                default: false,
+                description: "List also namespaces marked as trash.",
+            }
         },
     },
     returns: pbs_api_types::ADMIN_DATASTORE_LIST_NAMESPACE_RETURN_TYPE,
@@ -89,6 +95,7 @@ pub fn list_namespaces(
     store: String,
     parent: Option<BackupNamespace>,
     max_depth: Option<usize>,
+    include_trashed: bool,
     rpcenv: &mut dyn RpcEnvironment,
 ) -> Result<Vec<NamespaceListItem>, Error> {
     let parent = parent.unwrap_or_default();
@@ -99,14 +106,17 @@ pub fn list_namespaces(
 
     let datastore = DataStore::lookup_datastore(&store, Some(Operation::Read))?;
 
-    let iter =
-        match datastore.recursive_iter_backup_ns_ok(parent, max_depth, NamespaceListFilter::Active)
-        {
-            Ok(iter) => iter,
-            // parent NS doesn't exists and user has no privs on it, avoid info leakage.
-            Err(_) if parent_access.is_err() => http_bail!(FORBIDDEN, "permission check failed"),
-            Err(err) => return Err(err),
-        };
+    let filter = if include_trashed {
+        NamespaceListFilter::All
+    } else {
+        NamespaceListFilter::Active
+    };
+    let iter = match datastore.recursive_iter_backup_ns_ok(parent, max_depth, filter) {
+        Ok(iter) => iter,
+        // parent NS doesn't exists and user has no privs on it, avoid info leakage.
+        Err(_) if parent_access.is_err() => http_bail!(FORBIDDEN, "permission check failed"),
+        Err(err) => return Err(err),
+    };
 
     let ns_to_item =
         |ns: BackupNamespace| -> NamespaceListItem { NamespaceListItem { ns, comment: None } };
@@ -148,7 +158,7 @@ pub fn list_namespaces(
             "skip-trash": {
                 type: bool,
                 optional: true,
-                default: true,
+                default: false,
                 description: "Remove and namespace immediately, skip moving to trash",
             },
         },
diff --git a/src/bin/proxmox-backup-manager.rs b/src/bin/proxmox-backup-manager.rs
index d4363e717..0c4d70b41 100644
--- a/src/bin/proxmox-backup-manager.rs
+++ b/src/bin/proxmox-backup-manager.rs
@@ -857,8 +857,14 @@ pub fn complete_remote_datastore_namespace(
         Some((None, source_store)) => {
             let mut rpcenv = CliEnvironment::new();
             rpcenv.set_auth_id(Some(String::from("root at pam")));
-            crate::api2::admin::namespace::list_namespaces(source_store, None, None, &mut rpcenv)
-                .ok()
+            crate::api2::admin::namespace::list_namespaces(
+                source_store,
+                None,
+                None,
+                false,
+                &mut rpcenv,
+            )
+            .ok()
         }
         _ => None,
     } {
@@ -893,7 +899,7 @@ pub fn complete_sync_local_datastore_namespace(
 
     if let Some(store) = store {
         if let Ok(data) =
-            crate::api2::admin::namespace::list_namespaces(store, None, None, &mut rpcenv)
+            crate::api2::admin::namespace::list_namespaces(store, None, None, false, &mut rpcenv)
         {
             for item in data {
                 list.push(item.ns.name());
diff --git a/src/bin/proxmox_backup_manager/prune.rs b/src/bin/proxmox_backup_manager/prune.rs
index 923eb6f51..b57c39bd7 100644
--- a/src/bin/proxmox_backup_manager/prune.rs
+++ b/src/bin/proxmox_backup_manager/prune.rs
@@ -164,7 +164,7 @@ fn complete_prune_local_datastore_namespace(
 
     if let Some(store) = store {
         if let Ok(data) =
-            crate::api2::admin::namespace::list_namespaces(store, None, None, &mut rpcenv)
+            crate::api2::admin::namespace::list_namespaces(store, None, None, false, &mut rpcenv)
         {
             for item in data {
                 list.push(item.ns.name());
-- 
2.39.5





More information about the pbs-devel mailing list