public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Thomas Lamprecht <t.lamprecht@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH v2 3/5] client: migrate commands to flattened repository args
Date: Mon, 30 Mar 2026 20:20:39 +0200	[thread overview]
Message-ID: <20260330182352.2346420-4-t.lamprecht@proxmox.com> (raw)
In-Reply-To: <20260330182352.2346420-1-t.lamprecht@proxmox.com>

Replace the individual repository and ns property definitions in all
client command API schema macros with the flattened repository args
struct. This makes --server, --port, --datastore, --auth-id, and --ns
available on every command that previously only accepted --repository.

For some commands the --ns namespace option doesn't make really sense,
like e.g. login, but that is really not different from the
pre-existing datastore component that one could pass through the
repository URL.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---

changes v1 -> v2:
- split out from the single v1 commit; purely mechanical migration
- fixed duplicate ns property in restore command's #[api] block

 proxmox-backup-client/src/benchmark.rs |  8 +--
 proxmox-backup-client/src/catalog.rs   | 26 +++-----
 proxmox-backup-client/src/group.rs     | 14 ++--
 proxmox-backup-client/src/main.rs      | 88 +++++++++++---------------
 proxmox-backup-client/src/mount.rs     | 17 +++--
 proxmox-backup-client/src/namespace.rs | 33 +++-------
 proxmox-backup-client/src/snapshot.rs  | 84 ++++++++----------------
 proxmox-backup-client/src/task.rs      | 20 +++---
 proxmox-file-restore/src/main.rs       | 37 +++++------
 src/bin/proxmox_backup_debug/diff.rs   | 20 +++---
 10 files changed, 139 insertions(+), 208 deletions(-)

diff --git a/proxmox-backup-client/src/benchmark.rs b/proxmox-backup-client/src/benchmark.rs
index ad8c60ed9..c113e2ca2 100644
--- a/proxmox-backup-client/src/benchmark.rs
+++ b/proxmox-backup-client/src/benchmark.rs
@@ -22,7 +22,7 @@ use pbs_key_config::{load_and_decrypt_key, KeyDerivationConfig};
 use pbs_tools::crypt_config::CryptConfig;
 
 use crate::{
-    connect, extract_repository_from_value, record_repository, KEYFILE_SCHEMA, REPO_URL_SCHEMA,
+    connect, extract_repository_from_value, record_repository, BackupRepositoryArgs, KEYFILE_SCHEMA,
 };
 
 #[api()]
@@ -105,9 +105,9 @@ static BENCHMARK_RESULT_2020_TOP: BenchmarkResult = BenchmarkResult {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             keyfile: {
                 schema: KEYFILE_SCHEMA,
diff --git a/proxmox-backup-client/src/catalog.rs b/proxmox-backup-client/src/catalog.rs
index b1b22ff24..1426019f7 100644
--- a/proxmox-backup-client/src/catalog.rs
+++ b/proxmox-backup-client/src/catalog.rs
@@ -7,7 +7,7 @@ use serde_json::Value;
 use proxmox_router::cli::*;
 use proxmox_schema::api;
 
-use pbs_api_types::{BackupArchiveName, BackupNamespace, CATALOG_NAME};
+use pbs_api_types::{BackupArchiveName, CATALOG_NAME};
 use pbs_client::pxar::tools::get_remote_pxar_reader;
 use pbs_client::tools::key_source::get_encryption_key_password;
 use pbs_client::{BackupReader, RemoteChunkReader};
@@ -20,20 +20,16 @@ use crate::{
     complete_backup_snapshot, complete_group_or_snapshot, complete_namespace,
     complete_pxar_archive_name, complete_repository, connect, crypto_parameters, decrypt_key,
     dir_or_last_from_group, extract_repository_from_value, format_key_source, optional_ns_param,
-    record_repository, BackupDir, BufferedDynamicReader, CatalogReader, DynamicIndexReader,
-    IndexFile, Shell, KEYFD_SCHEMA, REPO_URL_SCHEMA,
+    record_repository, BackupDir, BackupRepositoryArgs, BufferedDynamicReader, CatalogReader,
+    DynamicIndexReader, IndexFile, Shell, KEYFD_SCHEMA,
 };
 
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -159,10 +155,6 @@ async fn dump_catalog(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            ns: {
-                type: BackupNamespace,
-                optional: true,
-            },
             "snapshot": {
                 type: String,
                 description: "Group/Snapshot path.",
@@ -170,9 +162,9 @@ async fn dump_catalog(param: Value) -> Result<Value, Error> {
             "archive-name": {
                 type: BackupArchiveName,
             },
-            "repository": {
-                optional: true,
-                schema: REPO_URL_SCHEMA,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "keyfile": {
                 optional: true,
diff --git a/proxmox-backup-client/src/group.rs b/proxmox-backup-client/src/group.rs
index 2c12db2ee..ec2ea6138 100644
--- a/proxmox-backup-client/src/group.rs
+++ b/proxmox-backup-client/src/group.rs
@@ -6,9 +6,9 @@ use proxmox_schema::api;
 
 use crate::{
     complete_backup_group, complete_namespace, complete_repository, merge_group_into,
-    REPO_URL_SCHEMA,
+    BackupRepositoryArgs,
 };
-use pbs_api_types::{BackupGroup, BackupNamespace};
+use pbs_api_types::BackupGroup;
 use pbs_client::tools::{connect, remove_repository_from_value};
 
 pub fn group_mgmt_cli() -> CliCommandMap {
@@ -29,13 +29,9 @@ pub fn group_mgmt_cli() -> CliCommandMap {
                 type: String,
                 description: "Backup group",
             },
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
         }
     }
diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs
index 2ada87bdd..cdcf99f8c 100644
--- a/proxmox-backup-client/src/main.rs
+++ b/proxmox-backup-client/src/main.rs
@@ -27,8 +27,8 @@ use pbs_api_types::{
     ArchiveType, Authid, BackupArchiveName, BackupDir, BackupGroup, BackupNamespace, BackupPart,
     BackupType, ClientRateLimitConfig, CryptMode, Fingerprint, GroupListItem, PathPattern,
     PruneJobOptions, PruneListItem, RateLimitConfig, SnapshotListItem, StorageStatus,
-    BACKUP_ID_SCHEMA, BACKUP_NAMESPACE_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_TYPE_SCHEMA,
-    CATALOG_NAME, ENCRYPTED_KEY_BLOB_NAME, MANIFEST_BLOB_NAME,
+    BACKUP_ID_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_TYPE_SCHEMA, CATALOG_NAME,
+    ENCRYPTED_KEY_BLOB_NAME, MANIFEST_BLOB_NAME,
 };
 use pbs_client::catalog_shell::Shell;
 use pbs_client::pxar::{ErrorHandler as PxarErrorHandler, MetadataArchiveReader, PxarPrevRef};
@@ -41,13 +41,13 @@ use pbs_client::tools::{
         crypto_parameters, format_key_source, get_encryption_key_password, KEYFD_SCHEMA,
         KEYFILE_SCHEMA, MASTER_PUBKEY_FD_SCHEMA, MASTER_PUBKEY_FILE_SCHEMA,
     },
-    raise_nofile_limit, CHUNK_SIZE_SCHEMA, REPO_URL_SCHEMA,
+    raise_nofile_limit, CHUNK_SIZE_SCHEMA,
 };
 use pbs_client::{
     delete_ticket_info, parse_backup_specification, view_task_result, BackupDetectionMode,
-    BackupReader, BackupRepository, BackupSpecificationType, BackupStats, BackupWriter,
-    BackupWriterOptions, ChunkStream, FixedChunkStream, HttpClient, IndexType, InjectionData,
-    PxarBackupStream, RemoteChunkReader, UploadOptions, BACKUP_SOURCE_SCHEMA,
+    BackupReader, BackupRepository, BackupRepositoryArgs, BackupSpecificationType, BackupStats,
+    BackupWriter, BackupWriterOptions, ChunkStream, FixedChunkStream, HttpClient, IndexType,
+    InjectionData, PxarBackupStream, RemoteChunkReader, UploadOptions, BACKUP_SOURCE_SCHEMA,
 };
 use pbs_datastore::catalog::{BackupCatalogWriter, CatalogReader, CatalogWriter};
 use pbs_datastore::chunk_store::verify_chunk_size;
@@ -340,13 +340,9 @@ pub fn optional_ns_param(param: &Value) -> Result<BackupNamespace, Error> {
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            "ns": {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "output-format": {
                 schema: OUTPUT_FORMAT,
@@ -433,18 +429,14 @@ fn merge_group_into(to: &mut serde_json::Map<String, Value>, group: BackupGroup)
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             group: {
                 type: String,
                 description: "Backup group.",
             },
-            "ns": {
-                type: BackupNamespace,
-                optional: true,
-            },
             "new-owner": {
                 type: Authid,
             },
@@ -478,9 +470,9 @@ async fn change_backup_owner(group: String, mut param: Value) -> Result<(), Erro
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
         }
    }
@@ -500,9 +492,9 @@ async fn api_login(param: Value) -> Result<Value, Error> {
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
         }
    }
@@ -519,9 +511,9 @@ fn api_logout(param: Value) -> Result<Value, Error> {
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "output-format": {
                 schema: OUTPUT_FORMAT,
@@ -572,9 +564,9 @@ async fn api_version(param: Value) -> Result<(), Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "output-format": {
                 schema: OUTPUT_FORMAT,
@@ -662,9 +654,9 @@ fn spawn_catalog_upload(
                     schema: BACKUP_SOURCE_SCHEMA,
                 }
             },
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "include-dev": {
                 description:
@@ -708,10 +700,6 @@ fn spawn_catalog_upload(
                 optional: true,
                 default: false,
             },
-            "ns": {
-                schema: BACKUP_NAMESPACE_SCHEMA,
-                optional: true,
-            },
             "backup-type": {
                 schema: BACKUP_TYPE_SCHEMA,
                 optional: true,
@@ -1439,13 +1427,9 @@ async fn dump_image<W: Write>(
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -1837,9 +1821,9 @@ async fn restore(
                 default: false,
                 description: "Minimal output - only show removals.",
             },
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
         },
     },
@@ -1929,9 +1913,9 @@ async fn prune(
 #[api(
    input: {
        properties: {
-           repository: {
-               schema: REPO_URL_SCHEMA,
-               optional: true,
+           repo: {
+               type: BackupRepositoryArgs,
+               flatten: true,
            },
            "output-format": {
                schema: OUTPUT_FORMAT,
diff --git a/proxmox-backup-client/src/mount.rs b/proxmox-backup-client/src/mount.rs
index e815c8a9c..91e85dde5 100644
--- a/proxmox-backup-client/src/mount.rs
+++ b/proxmox-backup-client/src/mount.rs
@@ -17,11 +17,12 @@ use proxmox_router::{cli::*, ApiHandler, ApiMethod, RpcEnvironment};
 use proxmox_schema::*;
 use proxmox_sortable_macro::sortable;
 
-use pbs_api_types::{ArchiveType, BackupArchiveName, BackupNamespace};
+use pbs_api_types::{ArchiveType, Authid, BackupArchiveName, BackupNamespace, DATASTORE_SCHEMA};
 use pbs_client::tools::key_source::{
     crypto_parameters, format_key_source, get_encryption_key_password,
 };
 use pbs_client::{BackupReader, RemoteChunkReader};
+use pbs_client::{BACKUP_REPO_PORT_SCHEMA, BACKUP_REPO_SERVER_SCHEMA, REPO_URL_SCHEMA};
 use pbs_datastore::cached_chunk_reader::CachedChunkReader;
 use pbs_datastore::index::IndexFile;
 use pbs_key_config::decrypt_key;
@@ -32,7 +33,7 @@ use crate::helper;
 use crate::{
     complete_group_or_snapshot, complete_img_archive_name, complete_namespace,
     complete_pxar_archive_name, complete_repository, connect, dir_or_last_from_group,
-    extract_repository_from_value, optional_ns_param, record_repository, REPO_URL_SCHEMA,
+    extract_repository_from_value, optional_ns_param, record_repository,
 };
 
 #[sortable]
@@ -41,7 +42,6 @@ const API_METHOD_MOUNT: ApiMethod = ApiMethod::new(
     &ObjectSchema::new(
         "Mount pxar archive.",
         &sorted!([
-            ("ns", true, &BackupNamespace::API_SCHEMA,),
             (
                 "snapshot",
                 false,
@@ -53,7 +53,12 @@ const API_METHOD_MOUNT: ApiMethod = ApiMethod::new(
                 false,
                 &StringSchema::new("Target directory path.").schema()
             ),
+            ("ns", true, &BackupNamespace::API_SCHEMA),
             ("repository", true, &REPO_URL_SCHEMA),
+            ("server", true, &BACKUP_REPO_SERVER_SCHEMA),
+            ("port", true, &BACKUP_REPO_PORT_SCHEMA),
+            ("datastore", true, &DATASTORE_SCHEMA),
+            ("auth-id", true, &Authid::API_SCHEMA),
             (
                 "keyfile",
                 true,
@@ -77,14 +82,18 @@ const API_METHOD_MAP: ApiMethod = ApiMethod::new(
         "Map a drive image from a VM backup to a local loopback device. Use 'unmap' to undo.
 WARNING: Only do this with *trusted* backups!",
         &sorted!([
-            ("ns", true, &BackupNamespace::API_SCHEMA,),
             (
                 "snapshot",
                 false,
                 &StringSchema::new("Group/Snapshot path.").schema()
             ),
             ("archive-name", false, &BackupArchiveName::API_SCHEMA),
+            ("ns", true, &BackupNamespace::API_SCHEMA),
             ("repository", true, &REPO_URL_SCHEMA),
+            ("server", true, &BACKUP_REPO_SERVER_SCHEMA),
+            ("port", true, &BACKUP_REPO_PORT_SCHEMA),
+            ("datastore", true, &DATASTORE_SCHEMA),
+            ("auth-id", true, &Authid::API_SCHEMA),
             (
                 "keyfile",
                 true,
diff --git a/proxmox-backup-client/src/namespace.rs b/proxmox-backup-client/src/namespace.rs
index 2929e394b..e2928dc93 100644
--- a/proxmox-backup-client/src/namespace.rs
+++ b/proxmox-backup-client/src/namespace.rs
@@ -1,8 +1,7 @@
 use anyhow::{bail, Error};
 use serde_json::{json, Value};
 
-use pbs_api_types::BackupNamespace;
-use pbs_client::tools::REPO_URL_SCHEMA;
+use pbs_client::BackupRepositoryArgs;
 
 use proxmox_router::cli::{
     format_and_print_result, get_output_format, CliCommand, CliCommandMap, OUTPUT_FORMAT,
@@ -17,13 +16,9 @@ use crate::{
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "max-depth": {
                 description: "maximum recursion depth",
@@ -84,13 +79,9 @@ async fn list_namespaces(param: Value, max_depth: Option<usize>) -> Result<(), E
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
         }
     },
@@ -124,13 +115,9 @@ async fn create_namespace(param: Value) -> Result<(), Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "delete-groups": {
                 description: "Destroys all groups in the hierarchy.",
diff --git a/proxmox-backup-client/src/snapshot.rs b/proxmox-backup-client/src/snapshot.rs
index 500fd2bb8..05f0ec1c7 100644
--- a/proxmox-backup-client/src/snapshot.rs
+++ b/proxmox-backup-client/src/snapshot.rs
@@ -17,8 +17,8 @@ use pbs_tools::json::required_string_param;
 use crate::{
     api_datastore_list_snapshots, complete_backup_group, complete_backup_snapshot,
     complete_namespace, complete_repository, connect, crypto_parameters,
-    extract_repository_from_value, optional_ns_param, record_repository, BackupDir, KEYFD_SCHEMA,
-    KEYFILE_SCHEMA, REPO_URL_SCHEMA,
+    extract_repository_from_value, optional_ns_param, record_repository, BackupDir,
+    BackupRepositoryArgs, KEYFD_SCHEMA, KEYFILE_SCHEMA,
 };
 
 fn snapshot_args(ns: &BackupNamespace, snapshot: &BackupDir) -> Result<Value, Error> {
@@ -32,13 +32,9 @@ fn snapshot_args(ns: &BackupNamespace, snapshot: &BackupDir) -> Result<Value, Er
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             group: {
                 type: String,
@@ -108,13 +104,9 @@ async fn list_snapshots(param: Value) -> Result<Value, Error> {
 #[api(
    input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -161,13 +153,9 @@ async fn list_snapshot_files(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -200,13 +188,9 @@ async fn forget_snapshots(param: Value) -> Result<(), Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -281,13 +265,9 @@ async fn upload_log(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -338,13 +318,9 @@ async fn show_notes(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -380,13 +356,9 @@ async fn update_notes(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -437,13 +409,9 @@ async fn show_protection(param: Value) -> Result<(), Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
diff --git a/proxmox-backup-client/src/task.rs b/proxmox-backup-client/src/task.rs
index 472db0860..dba50cc85 100644
--- a/proxmox-backup-client/src/task.rs
+++ b/proxmox-backup-client/src/task.rs
@@ -10,14 +10,14 @@ use pbs_tools::json::required_string_param;
 
 use pbs_api_types::UPID;
 
-use crate::{complete_repository, connect, extract_repository_from_value, REPO_URL_SCHEMA};
+use crate::{complete_repository, connect, extract_repository_from_value, BackupRepositoryArgs};
 
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             limit: {
                 description: "The maximal number of tasks to list.",
@@ -87,9 +87,9 @@ async fn task_list(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             upid: {
                 type: UPID,
@@ -112,9 +112,9 @@ async fn task_log(param: Value) -> Result<Value, Error> {
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             upid: {
                 type: UPID,
diff --git a/proxmox-file-restore/src/main.rs b/proxmox-file-restore/src/main.rs
index bf6cf9aed..64de94b42 100644
--- a/proxmox-file-restore/src/main.rs
+++ b/proxmox-file-restore/src/main.rs
@@ -31,9 +31,8 @@ use pbs_client::tools::{
         crypto_parameters_keep_fd, format_key_source, get_encryption_key_password, KEYFD_SCHEMA,
         KEYFILE_SCHEMA,
     },
-    REPO_URL_SCHEMA,
 };
-use pbs_client::{BackupReader, BackupRepository, RemoteChunkReader};
+use pbs_client::{BackupReader, BackupRepository, BackupRepositoryArgs, RemoteChunkReader};
 use pbs_datastore::catalog::{ArchiveEntry, CatalogReader, DirEntryAttribute};
 use pbs_datastore::dynamic_index::BufferedDynamicReader;
 use pbs_datastore::index::IndexFile;
@@ -212,13 +211,9 @@ async fn list_files(
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -272,7 +267,6 @@ async fn list_files(
 )]
 /// List a directory from a backup snapshot.
 async fn list(
-    ns: Option<BackupNamespace>,
     snapshot: String,
     path: String,
     base64: bool,
@@ -280,7 +274,11 @@ async fn list(
     param: Value,
 ) -> Result<(), Error> {
     let repo = extract_repository_from_value(&param)?;
-    let ns = ns.unwrap_or_default();
+    let ns: BackupNamespace = param["ns"]
+        .as_str()
+        .map(|s| s.parse())
+        .transpose()?
+        .unwrap_or_default();
     let snapshot: BackupDir = snapshot.parse()?;
     let path = parse_path(path, base64)?;
 
@@ -361,13 +359,9 @@ async fn list(
 #[api(
     input: {
         properties: {
-            repository: {
-                schema: REPO_URL_SCHEMA,
-                optional: true,
-            },
-            ns: {
-                type: BackupNamespace,
-                optional: true,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             snapshot: {
                 type: String,
@@ -426,7 +420,6 @@ async fn list(
 /// Restore files from a backup snapshot.
 #[allow(clippy::too_many_arguments)]
 async fn extract(
-    ns: Option<BackupNamespace>,
     snapshot: String,
     path: String,
     base64: bool,
@@ -436,7 +429,11 @@ async fn extract(
     param: Value,
 ) -> Result<(), Error> {
     let repo = extract_repository_from_value(&param)?;
-    let namespace = ns.unwrap_or_default();
+    let namespace: BackupNamespace = param["ns"]
+        .as_str()
+        .map(|s| s.parse())
+        .transpose()?
+        .unwrap_or_default();
     let snapshot: BackupDir = snapshot.parse()?;
     let orig_path = path;
     let path = parse_path(orig_path.clone(), base64)?;
diff --git a/src/bin/proxmox_backup_debug/diff.rs b/src/bin/proxmox_backup_debug/diff.rs
index 116216e51..53d0efd10 100644
--- a/src/bin/proxmox_backup_debug/diff.rs
+++ b/src/bin/proxmox_backup_debug/diff.rs
@@ -19,9 +19,8 @@ use pbs_client::tools::key_source::{
 };
 use pbs_client::tools::{
     complete_archive_name, complete_group_or_snapshot, connect, extract_repository_from_value,
-    REPO_URL_SCHEMA,
 };
-use pbs_client::{BackupReader, BackupRepository, RemoteChunkReader};
+use pbs_client::{BackupReader, BackupRepository, BackupRepositoryArgs, RemoteChunkReader};
 use pbs_datastore::dynamic_index::{BufferedDynamicReader, DynamicIndexReader, LocalDynamicReadAt};
 use pbs_datastore::index::IndexFile;
 use pbs_key_config::decrypt_key;
@@ -57,10 +56,6 @@ pub fn diff_commands() -> CommandLineInterface {
 #[api(
     input: {
         properties: {
-            "ns": {
-                type: BackupNamespace,
-                optional: true,
-            },
             "prev-snapshot": {
                 description: "Path for the first snapshot.",
                 type: String,
@@ -72,9 +67,9 @@ pub fn diff_commands() -> CommandLineInterface {
             "archive-name": {
                 type: BackupArchiveName,
             },
-            "repository": {
-                optional: true,
-                schema: REPO_URL_SCHEMA,
+            repo: {
+                type: BackupRepositoryArgs,
+                flatten: true,
             },
             "keyfile": {
                 optional: true,
@@ -108,13 +103,16 @@ async fn diff_archive_cmd(
     archive_name: BackupArchiveName,
     compare_content: bool,
     color: Option<ColorMode>,
-    ns: Option<BackupNamespace>,
     param: Value,
 ) -> Result<(), Error> {
     let repo = extract_repository_from_value(&param)?;
 
     let color = color.unwrap_or_default();
-    let namespace = ns.unwrap_or_else(BackupNamespace::root);
+    let namespace: BackupNamespace = param["ns"]
+        .as_str()
+        .map(|s| s.parse())
+        .transpose()?
+        .unwrap_or_default();
 
     let crypto = crypto_parameters(&param)?;
 
-- 
2.47.3





  parent reply	other threads:[~2026-03-30 18:24 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-30 18:20 [PATCH v2 0/5] client: repository: add individual component parameters Thomas Lamprecht
2026-03-30 18:20 ` [PATCH v2 1/5] client: repository: add tests for BackupRepository parsing Thomas Lamprecht
2026-03-30 18:20 ` [PATCH v2 2/5] client: repository: add individual component parameters Thomas Lamprecht
2026-03-31  8:55   ` Thomas Lamprecht
2026-03-30 18:20 ` Thomas Lamprecht [this message]
2026-03-30 18:20 ` [PATCH v2 4/5] docs: document repository component options and env vars Thomas Lamprecht
2026-03-30 18:20 ` [PATCH v2 5/5] fix #5340: client: repository: add PBS_NAMESPACE environment variable Thomas Lamprecht
2026-04-01 22:56 ` superseded: [PATCH v2 0/5] client: repository: add individual component parameters Thomas Lamprecht

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=20260330182352.2346420-4-t.lamprecht@proxmox.com \
    --to=t.lamprecht@proxmox.com \
    --cc=pbs-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal