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 58102D414 for ; Wed, 30 Nov 2022 16:01:58 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 3E29320072 for ; Wed, 30 Nov 2022 16:01:28 +0100 (CET) Received: from lana.proxmox.com (unknown [94.136.29.99]) by firstgate.proxmox.com (Proxmox) with ESMTP for ; Wed, 30 Nov 2022 16:01:26 +0100 (CET) Received: by lana.proxmox.com (Postfix, from userid 10043) id CD62B2C277D; Wed, 30 Nov 2022 16:01:26 +0100 (CET) From: Stefan Hanreich To: pbs-devel@lists.proxmox.com Date: Wed, 30 Nov 2022 16:00:59 +0100 Message-Id: <20221130150102.242374-5-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221130150102.242374-1-s.hanreich@proxmox.com> References: <20221130150102.242374-1-s.hanreich@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.331 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 KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.001 Envelope sender has no MX or A DNS records RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pbs-devel] [PATCH proxmox-backup v2 4/7] use new PruneJob in prune command 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: Wed, 30 Nov 2022 15:01:58 -0000 The prune command has been slightly refactored in order to use the functionality of the newly created PruneJob struct, instead of simply calling compute_prune_info and the pruning the respective groups manually. Signed-off-by: Stefan Hanreich --- src/api2/admin/datastore.rs | 69 ++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 6797844e..90f9cb48 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -1,5 +1,6 @@ //! Datastore Management +use std::cell::RefCell; use std::collections::HashSet; use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; @@ -26,7 +27,7 @@ use proxmox_sys::fs::{ file_read_firstline, file_read_optional_string, replace_file, CreateOptions, }; use proxmox_sys::sortable; -use proxmox_sys::{task_log, task_warn}; +use proxmox_sys::task_log; use pxar::accessor::aio::Accessor; use pxar::EntryKind; @@ -978,18 +979,18 @@ pub fn prune( let worker_id = format!("{}:{}:{}", store, ns, group); let group = datastore.backup_group(ns.clone(), group); - let mut prune_result = Vec::new(); + // RefCell is okay to use here, since we access the Vec sequentially via the callback + let prune_result = RefCell::new(Vec::new()); let list = group.list_backups()?; - let mut prune_info = PruneJob::compute_prune_info(list, &keep_options)?; - - prune_info.reverse(); // delete older snapshots first + let mut prune_job = PruneJob::new(list, &keep_options)?; + prune_job.dry_run(dry_run); let keep_all = !keep_options.keeps_something(); if dry_run { - for (info, mark) in prune_info { + prune_job.run_with_callback(|info, mark, _| { let keep = keep_all || mark.keep(); let mut result = json!({ @@ -999,13 +1000,17 @@ pub fn prune( "keep": keep, "protected": mark.protected(), }); + let prune_ns = info.backup_dir.backup_ns(); + if !prune_ns.is_root() { - result["ns"] = serde_json::to_value(prune_ns)?; + result["ns"] = json!(prune_ns); } - prune_result.push(result); - } - return Ok(json!(prune_result)); + + prune_result.borrow_mut().push(result); + }); + + return Ok(json!(prune_result.into_inner())); } // We use a WorkerTask just to have a task log, but run synchrounously @@ -1029,40 +1034,26 @@ pub fn prune( ); } - for (info, mark) in prune_info { - let keep = keep_all || mark.keep(); - - let backup_time = info.backup_dir.backup_time(); - let timestamp = info.backup_dir.backup_time_string(); - let group: &pbs_api_types::BackupGroup = info.backup_dir.as_ref(); - - let msg = format!("{}/{}/{} {}", group.ty, group.id, timestamp, mark,); - - task_log!(worker, "{}", msg); + prune_job + .logging(worker.clone()) + .run_with_callback(|info, mark, _| { + let keep = keep_all || mark.keep(); - prune_result.push(json!({ - "backup-type": group.ty, - "backup-id": group.id, - "backup-time": backup_time, - "keep": keep, - "protected": mark.protected(), - })); + let backup_time = info.backup_dir.backup_time(); + let group: &pbs_api_types::BackupGroup = info.backup_dir.as_ref(); - if !(dry_run || keep) { - if let Err(err) = info.backup_dir.destroy(false) { - task_warn!( - worker, - "failed to remove dir {:?}: {}", - info.backup_dir.relative_path(), - err, - ); - } - } - } + prune_result.borrow_mut().push(json!({ + "backup-type": group.ty, + "backup-id": group.id, + "backup-time": backup_time, + "keep": keep, + "protected": mark.protected(), + })); + }); worker.log_result(&Ok(())); - Ok(json!(prune_result)) + Ok(json!(prune_result.into_inner())) } #[api( -- 2.30.2