all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: Hannes Laimer <h.laimer@proxmox.com>, pbs-devel@lists.proxmox.com
Subject: Re: [PATCH proxmox-backup v6 5/8] api: add PUT endpoint for move_namespace
Date: Wed, 08 Apr 2026 09:35:36 +0200	[thread overview]
Message-ID: <1775633527.1rtwr8uwd3.astroid@yuna.none> (raw)
In-Reply-To: <20260331123409.198353-6-h.laimer@proxmox.com>

On March 31, 2026 2:34 pm, Hannes Laimer wrote:
> Add a PUT handler on /admin/datastore/{store}/namespace to move a
> namespace (including all child namespaces and groups) to a new
> location within the same datastore. The handler performs fast
> pre-checks synchronously and spawns a worker task for the actual move.
> 
> Requires DATASTORE_MODIFY on the parent of both the source and target
> namespaces, matching the permissions used by create_namespace() and
> delete_namespace().
> 
> Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
> ---
>  src/api2/admin/namespace.rs | 78 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 76 insertions(+), 2 deletions(-)
> 
> diff --git a/src/api2/admin/namespace.rs b/src/api2/admin/namespace.rs
> index 30e24d8d..5b64fb0d 100644
> --- a/src/api2/admin/namespace.rs
> +++ b/src/api2/admin/namespace.rs
> @@ -1,12 +1,16 @@
>  use anyhow::{bail, Error};
>  
>  use pbs_config::CachedUserInfo;
> -use proxmox_router::{http_bail, ApiMethod, Permission, Router, RpcEnvironment};
> +use proxmox_rest_server::WorkerTask;
> +use proxmox_router::{
> +    http_bail, ApiMethod, Permission, Router, RpcEnvironment, RpcEnvironmentType,
> +};
>  use proxmox_schema::*;
> +use serde_json::{json, Value};
>  
>  use pbs_api_types::{
>      Authid, BackupGroupDeleteStats, BackupNamespace, NamespaceListItem, Operation,
> -    DATASTORE_SCHEMA, NS_MAX_DEPTH_SCHEMA, PROXMOX_SAFE_ID_FORMAT,
> +    DATASTORE_SCHEMA, NS_MAX_DEPTH_SCHEMA, PROXMOX_SAFE_ID_FORMAT, UPID_SCHEMA,
>  };
>  
>  use pbs_datastore::DataStore;
> @@ -189,7 +193,77 @@ pub fn delete_namespace(
>      Ok(stats)
>  }
>  
> +#[api(
> +    input: {
> +        properties: {
> +            store: { schema: DATASTORE_SCHEMA },
> +            ns: {
> +                type: BackupNamespace,
> +            },
> +            "new-ns": {
> +                type: BackupNamespace,

same applies here, this is the target namespace

> +            },
> +        },
> +    },
> +    returns: {
> +        schema: UPID_SCHEMA,
> +    },
> +    access: {
> +        permission: &Permission::Anybody,
> +        description: "Requires DATASTORE_MODIFY on the parent of 'ns' and on the parent of 'new-ns'.",

this matches what is required to delete and create namespaces, so seems
fine.

> +    },
> +)]
> +/// Move a backup namespace (including all child namespaces and groups) to a new location.
> +pub fn move_namespace(
> +    store: String,
> +    ns: BackupNamespace,
> +    new_ns: BackupNamespace,
> +    rpcenv: &mut dyn RpcEnvironment,
> +) -> Result<Value, Error> {
> +    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
> +
> +    check_ns_modification_privs(&store, &ns, &auth_id)?;
> +    check_ns_modification_privs(&store, &new_ns, &auth_id)?;
> +
> +    let datastore = DataStore::lookup_datastore(&store, Operation::Write)?;
> +
> +    // Best-effort pre-checks for a fast synchronous error before spawning a worker.
> +    if ns.is_root() {
> +        bail!("cannot move root namespace");
> +    }
> +    if ns == new_ns {
> +        bail!("source and target namespace must be different");
> +    }
> +    if !datastore.namespace_exists(&ns) {
> +        bail!("source namespace '{ns}' does not exist");
> +    }
> +    if datastore.namespace_exists(&new_ns) {
> +        bail!("target namespace '{new_ns}' already exists");
> +    }
> +    let target_parent = new_ns.parent();
> +    if !datastore.namespace_exists(&target_parent) {
> +        bail!("target parent namespace '{target_parent}' does not exist");
> +    }
> +    if ns.contains(&new_ns).is_some() {
> +        bail!("cannot move namespace '{ns}' into its own subtree (target: '{new_ns}')");
> +    }
> +
> +    let worker_id = format!("{store}:{ns}");

same question here - would it make sense to include both source and
target for better filtering?

> +    let to_stdout = rpcenv.env_type() == RpcEnvironmentType::CLI;
> +
> +    let upid_str = WorkerTask::new_thread(
> +        "move-namespace",
> +        Some(worker_id),
> +        auth_id.to_string(),
> +        to_stdout,
> +        move |_worker| datastore.move_namespace(&ns, &new_ns),
> +    )?;
> +
> +    Ok(json!(upid_str))
> +}
> +
>  pub const ROUTER: Router = Router::new()
>      .get(&API_METHOD_LIST_NAMESPACES)
>      .post(&API_METHOD_CREATE_NAMESPACE)
> +    .put(&API_METHOD_MOVE_NAMESPACE)
>      .delete(&API_METHOD_DELETE_NAMESPACE);
> -- 
> 2.47.3
> 
> 
> 
> 
> 
> 




  reply	other threads:[~2026-04-08  7:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-31 12:34 [PATCH proxmox-backup v6 0/8] fixes #6195: add support for moving groups and namespaces Hannes Laimer
2026-03-31 12:34 ` [PATCH proxmox-backup v6 1/8] ui: show empty groups Hannes Laimer
2026-03-31 12:34 ` [PATCH proxmox-backup v6 2/8] datastore: add move_group Hannes Laimer
2026-04-07 13:18   ` Fabian Grünbichler
2026-03-31 12:34 ` [PATCH proxmox-backup v6 3/8] datastore: add move_namespace Hannes Laimer
2026-04-07 13:18   ` Fabian Grünbichler
2026-03-31 12:34 ` [PATCH proxmox-backup v6 4/8] api: add PUT endpoint for move_group Hannes Laimer
2026-04-08  7:35   ` Fabian Grünbichler
2026-03-31 12:34 ` [PATCH proxmox-backup v6 5/8] api: add PUT endpoint for move_namespace Hannes Laimer
2026-04-08  7:35   ` Fabian Grünbichler [this message]
2026-03-31 12:34 ` [PATCH proxmox-backup v6 6/8] ui: add move group action Hannes Laimer
2026-03-31 12:34 ` [PATCH proxmox-backup v6 7/8] ui: add move namespace action Hannes Laimer
2026-04-02  9:28   ` Arthur Bied-Charreton
2026-03-31 12:34 ` [PATCH proxmox-backup v6 8/8] cli: add move-namespace and move-group commands Hannes Laimer
2026-04-02  9:22   ` Arthur Bied-Charreton
2026-04-02  9:34 ` [PATCH proxmox-backup v6 0/8] fixes #6195: add support for moving groups and namespaces Arthur Bied-Charreton

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=1775633527.1rtwr8uwd3.astroid@yuna.none \
    --to=f.gruenbichler@proxmox.com \
    --cc=h.laimer@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal