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 5BF706C7F3 for ; Thu, 23 Sep 2021 13:38:16 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 39CF624D5D for ; Thu, 23 Sep 2021 13:37:46 +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 DFE0F24C21 for ; Thu, 23 Sep 2021 13:37:40 +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 B437044A83 for ; Thu, 23 Sep 2021 13:37:40 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Thu, 23 Sep 2021 13:37:29 +0200 Message-Id: <20210923113739.4151043-4-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210923113739.4151043-1-d.csapak@proxmox.com> References: <20210923113739.4151043-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.360 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 v2 03/13] add protected info of snapshots to api and task logs 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: Thu, 23 Sep 2021 11:38:16 -0000 adds the info that a snapshot is protected to: * snapshot list * manual pruning (also dry-run) * prune jobs Signed-off-by: Dominik Csapak --- pbs-api-types/src/datastore.rs | 2 ++ pbs-datastore/src/prune.rs | 40 +++++++++++++++++++++++++++------- src/api2/admin/datastore.rs | 15 ++++++++----- src/server/prune_job.rs | 6 ++--- tests/prune.rs | 4 ++-- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/pbs-api-types/src/datastore.rs b/pbs-api-types/src/datastore.rs index 75f82ea4..31b4d483 100644 --- a/pbs-api-types/src/datastore.rs +++ b/pbs-api-types/src/datastore.rs @@ -393,6 +393,8 @@ pub struct SnapshotListItem { /// The owner of the snapshots group #[serde(skip_serializing_if = "Option::is_none")] pub owner: Option, + /// Protection from prunes + pub protected: bool, } #[api( diff --git a/pbs-datastore/src/prune.rs b/pbs-datastore/src/prune.rs index 1eb4208f..7614999c 100644 --- a/pbs-datastore/src/prune.rs +++ b/pbs-datastore/src/prune.rs @@ -7,7 +7,30 @@ use pbs_api_types::PruneOptions; use super::BackupInfo; -enum PruneMark { Protected, Keep, KeepPartial, Remove } +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum PruneMark { Protected, Keep, KeepPartial, Remove } + +impl PruneMark { + pub fn keep(&self) -> bool { + *self != PruneMark::Remove + } + + pub fn protected(&self) -> bool { + *self == PruneMark::Protected + } +} + +impl std::fmt::Display for PruneMark { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let txt = match self { + PruneMark::Protected => "protected", + PruneMark::Keep => "keep", + PruneMark::KeepPartial => "keep-partial", + PruneMark::Remove => "remove", + }; + write!(f, "{}", txt) + } +} fn mark_selections Result> ( mark: &mut HashMap, @@ -125,7 +148,7 @@ pub fn cli_options_string(options: &PruneOptions) -> String { pub fn compute_prune_info( mut list: Vec, options: &PruneOptions, -) -> Result, Error> { +) -> Result, Error> { let mut mark = HashMap::new(); @@ -173,15 +196,16 @@ pub fn compute_prune_info( })?; } - let prune_info: Vec<(BackupInfo, bool)> = list.into_iter() + let prune_info: Vec<(BackupInfo, PruneMark)> = list.into_iter() .map(|info| { let backup_id = info.backup_dir.relative_path(); - let keep = match mark.get(&backup_id) { - Some(PruneMark::Keep) => true, - Some(PruneMark::KeepPartial) => true, - _ => false, + let mark = if info.protected { + PruneMark::Protected + } else { + *mark.get(&backup_id).unwrap_or(&PruneMark::Remove) }; - (info, keep) + + (info, mark) }) .collect(); diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs index 0b14dfbf..7390a62f 100644 --- a/src/api2/admin/datastore.rs +++ b/src/api2/admin/datastore.rs @@ -439,6 +439,7 @@ pub fn list_snapshots ( let backup_type = group.backup_type().to_string(); let backup_id = group.backup_id().to_string(); let backup_time = info.backup_dir.backup_time(); + let protected = info.backup_dir.is_protected(base_path.clone()); match get_all_snapshot_files(&datastore, &info) { Ok((manifest, files)) => { @@ -477,6 +478,7 @@ pub fn list_snapshots ( files, size, owner, + protected, } }, Err(err) => { @@ -501,6 +503,7 @@ pub fn list_snapshots ( files, size: None, owner, + protected, } }, } @@ -844,8 +847,8 @@ pub fn prune( let keep_all = !pbs_datastore::prune::keeps_something(&prune_options); if dry_run { - for (info, mut keep) in prune_info { - if keep_all { keep = true; } + for (info, mark) in prune_info { + let keep = keep_all || mark.keep(); let backup_time = info.backup_dir.backup_time(); let group = info.backup_dir.group(); @@ -855,6 +858,7 @@ pub fn prune( "backup-id": group.backup_id(), "backup-time": backup_time, "keep": keep, + "protected": mark.protected(), })); } return Ok(json!(prune_result)); @@ -872,8 +876,8 @@ pub fn prune( store, backup_type, backup_id)); } - for (info, mut keep) in prune_info { - if keep_all { keep = true; } + 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(); @@ -885,7 +889,7 @@ pub fn prune( group.backup_type(), group.backup_id(), timestamp, - if keep { "keep" } else { "remove" }, + mark, ); worker.log(msg); @@ -895,6 +899,7 @@ pub fn prune( "backup-id": group.backup_id(), "backup-time": backup_time, "keep": keep, + "protected": mark.protected(), })); if !(dry_run || keep) { diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs index f298a74c..42c806a1 100644 --- a/src/server/prune_job.rs +++ b/src/server/prune_job.rs @@ -65,12 +65,12 @@ pub fn prune_datastore( group.backup_id() ); - for (info, mut keep) in prune_info { - if keep_all { keep = true; } + for (info, mark) in prune_info { + let keep = keep_all || mark.keep(); task_log!( worker, "{} {}/{}/{}", - if keep { "keep" } else { "remove" }, + mark, group.backup_type(), group.backup_id(), info.backup_dir.backup_time_string() diff --git a/tests/prune.rs b/tests/prune.rs index a733ff82..14ecc887 100644 --- a/tests/prune.rs +++ b/tests/prune.rs @@ -18,8 +18,8 @@ fn get_prune_list( prune_info .iter() - .filter_map(|(info, keep)| { - if *keep != return_kept { + .filter_map(|(info, mark)| { + if mark.keep() != return_kept { None } else { Some(info.backup_dir.relative_path()) -- 2.30.2