From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 3636C76895 for ; Fri, 16 Jul 2021 10:54:05 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 7B090E2A7 for ; Fri, 16 Jul 2021 10:53:34 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 33588E1B6 for ; Fri, 16 Jul 2021 10:53:30 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0D2E6420A7 for ; Fri, 16 Jul 2021 10:53:30 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Fri, 16 Jul 2021 10:53:26 +0200 Message-Id: <20210716085328.3731574-10-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210716085328.3731574-1-d.csapak@proxmox.com> References: <20210716085328.3731574-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.575 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 09/11] api: admin/datastore: add new 'prune-datastore' api call X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Jul 2021 08:54:05 -0000 to prune the whole datastore at once, with the given parameters. We need a new api call since this can take a while and we need to start a worker for this. The exisiting api call returns a list of removed/kept snapshots and is synchronous. Signed-off-by: Dominik Csapak --- src/api2/admin/datastore.rs | 63 ++++++++++++++++++++++++++++++++++++- src/server/prune_job.rs | 9 ++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 79ab97e7..60941501 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -820,7 +820,7 @@ pub fn verify( permission: &Permission::Privilege(&["datastore", "{store}"], PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_PRUNE, true), }, )] -/// Prune the datastore +/// Prune a group on the datastore pub fn prune( backup_id: String, backup_type: String, @@ -922,6 +922,62 @@ pub fn prune( Ok(json!(prune_result)) } +#[api( + input: { + properties: { + "dry-run": { + optional: true, + type: bool, + default: false, + description: "Just show what prune would do, but do not delete anything.", + }, + "prune-options": { + type: PruneOptions, + flatten: true, + }, + store: { + schema: DATASTORE_SCHEMA, + }, + }, + }, + returns: { + schema: UPID_SCHEMA, + }, + access: { + permission: &Permission::Privilege(&["datastore", "{store}"], PRIV_DATASTORE_MODIFY | PRIV_DATASTORE_PRUNE, true), + }, +)] +/// Prune the datastore +pub fn prune_datastore( + dry_run: bool, + prune_options: PruneOptions, + store: String, + _param: Value, + rpcenv: &mut dyn RpcEnvironment, +) -> Result { + + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; + + let datastore = DataStore::lookup_datastore(&store)?; + + let upid_str = WorkerTask::new_thread( + "prune", + Some(store.clone()), + auth_id.clone(), + false, + move |worker| crate::server::prune_datastore( + worker.clone(), + auth_id, + prune_options, + &store, + datastore, + dry_run + ), + )?; + + Ok(upid_str) +} + #[api( input: { properties: { @@ -1844,6 +1900,11 @@ const DATASTORE_INFO_SUBDIRS: SubdirMap = &[ &Router::new() .post(&API_METHOD_PRUNE) ), + ( + "prune-datastore", + &Router::new() + .post(&API_METHOD_PRUNE_DATASTORE) + ), ( "pxar-file-download", &Router::new() diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs index bbf53ade..255e21ce 100644 --- a/src/server/prune_job.rs +++ b/src/server/prune_job.rs @@ -19,9 +19,14 @@ pub fn prune_datastore( prune_options: PruneOptions, store: &str, datastore: Arc, + dry_run: bool, ) -> Result<(), Error> { task_log!(worker, "Starting datastore prune on store \"{}\"", store); + if dry_run { + task_log!(worker, "(dry test run)"); + } + let keep_all = !prune_options.keeps_something(); if keep_all { @@ -69,7 +74,7 @@ pub fn prune_datastore( group.backup_id(), info.backup_dir.backup_time_string() ); - if !keep { + if !keep && !dry_run { if let Err(err) = datastore.remove_backup_dir(&info.backup_dir, false) { task_warn!( worker, @@ -108,7 +113,7 @@ pub fn do_prune_job( task_log!(worker, "task triggered by schedule '{}'", event_str); } - let result = prune_datastore(worker.clone(), auth_id, prune_options, &store, datastore); + let result = prune_datastore(worker.clone(), auth_id, prune_options, &store, datastore, false); let status = worker.create_state(&result); -- 2.30.2