From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pbs-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 9327E1FF164 for <inbox@lore.proxmox.com>; Fri, 9 May 2025 14:28:06 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C485C3D218; Fri, 9 May 2025 14:28:25 +0200 (CEST) Date: Fri, 09 May 2025 14:27:48 +0200 From: Fabian =?iso-8859-1?q?Gr=FCnbichler?= <f.gruenbichler@proxmox.com> To: Proxmox Backup Server development discussion <pbs-devel@lists.proxmox.com> References: <20250508130555.494782-1-c.ebner@proxmox.com> <20250508130555.494782-4-c.ebner@proxmox.com> In-Reply-To: <20250508130555.494782-4-c.ebner@proxmox.com> MIME-Version: 1.0 User-Agent: astroid/0.16.0 (https://github.com/astroidmail/astroid) Message-Id: <1746790489.fw746s24j7.astroid@yuna.none> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.046 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy 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: Re: [pbs-devel] [RFC v2 proxmox-backup 03/21] datastore: allow filtering of backups by their trash status X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion <pbs-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pbs-devel>, <mailto:pbs-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pbs-devel/> List-Post: <mailto:pbs-devel@lists.proxmox.com> List-Help: <mailto:pbs-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel>, <mailto:pbs-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox Backup Server development discussion <pbs-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" <pbs-devel-bounces@lists.proxmox.com> On May 8, 2025 3:05 pm, Christian Ebner wrote: > Extends the BackupGroup::list_backups method by an enum parameter to > filter backup snapshots based on their trash status. > > This allows to reuse the same logic for listing active, trashed or > all snapshots. > > Signed-off-by: Christian Ebner <c.ebner@proxmox.com> > --- > pbs-datastore/src/backup_info.rs | 33 +++++++++++++++++++++++++++++--- > pbs-datastore/src/datastore.rs | 4 ++-- > src/api2/admin/datastore.rs | 10 +++++----- > src/api2/tape/backup.rs | 4 ++-- > src/backup/verify.rs | 4 ++-- > src/server/prune_job.rs | 3 ++- > src/server/pull.rs | 3 ++- > 7 files changed, 45 insertions(+), 16 deletions(-) > > diff --git a/pbs-datastore/src/backup_info.rs b/pbs-datastore/src/backup_info.rs > index 9ce4cb0f8..a8c864ac8 100644 > --- a/pbs-datastore/src/backup_info.rs > +++ b/pbs-datastore/src/backup_info.rs > @@ -52,6 +52,12 @@ impl fmt::Debug for BackupGroup { > } > } > > +pub enum ListBackupFilter { > + Active, active sounds like there's currently a backup going on.. > + All, > + Trashed, > +} > + > impl BackupGroup { > pub(crate) fn new( > store: Arc<DataStore>, > @@ -99,7 +105,7 @@ impl BackupGroup { > self.full_group_path().exists() > } > > - pub fn list_backups(&self) -> Result<Vec<BackupInfo>, Error> { > + pub fn list_backups(&self, filter: ListBackupFilter) -> Result<Vec<BackupInfo>, Error> { > let mut list = vec![]; > > let path = self.full_group_path(); > @@ -117,6 +123,19 @@ impl BackupGroup { > let files = list_backup_files(l2_fd, backup_time)?; > > let protected = backup_dir.is_protected(); > + match filter { > + ListBackupFilter::All => (), > + ListBackupFilter::Trashed => { > + if !backup_dir.is_trashed() { > + return Ok(()); > + } > + } > + ListBackupFilter::Active => { > + if backup_dir.is_trashed() { > + return Ok(()); > + } > + } > + } > > list.push(BackupInfo { > backup_dir, > @@ -132,7 +151,7 @@ impl BackupGroup { > > /// Finds the latest backup inside a backup group > pub fn last_backup(&self, only_finished: bool) -> Result<Option<BackupInfo>, Error> { > - let backups = self.list_backups()?; > + let backups = self.list_backups(ListBackupFilter::Active)?; > Ok(backups > .into_iter() > .filter(|item| !only_finished || item.is_finished()) > @@ -480,6 +499,11 @@ impl BackupDir { > path.exists() > } > > + pub fn is_trashed(&self) -> bool { > + let path = self.full_path().join(TRASH_MARKER_FILENAME); > + path.exists() > + } > + > pub fn backup_time_to_string(backup_time: i64) -> Result<String, Error> { > // fixme: can this fail? (avoid unwrap) > proxmox_time::epoch_to_rfc3339_utc(backup_time) > @@ -637,7 +661,10 @@ impl BackupDir { > // > // Do not error out, as we have already removed the snapshot, there is nothing a user could > // do to rectify the situation. > - if guard.is_ok() && group.list_backups()?.is_empty() && !*OLD_LOCKING { > + if guard.is_ok() > + && group.list_backups(ListBackupFilter::All)?.is_empty() > + && !*OLD_LOCKING > + { > group.remove_group_dir()?; > } else if let Err(err) = guard { > log::debug!("{err:#}"); > diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs > index e546bc532..867324380 100644 > --- a/pbs-datastore/src/datastore.rs > +++ b/pbs-datastore/src/datastore.rs > @@ -28,7 +28,7 @@ use pbs_api_types::{ > }; > use pbs_config::BackupLockGuard; > > -use crate::backup_info::{BackupDir, BackupGroup, BackupInfo, OLD_LOCKING}; > +use crate::backup_info::{BackupDir, BackupGroup, BackupInfo, ListBackupFilter, OLD_LOCKING}; > use crate::chunk_store::ChunkStore; > use crate::dynamic_index::{DynamicIndexReader, DynamicIndexWriter}; > use crate::fixed_index::{FixedIndexReader, FixedIndexWriter}; > @@ -1158,7 +1158,7 @@ impl DataStore { > _ => bail!("exhausted retries and unexpected counter overrun"), > }; > > - let mut snapshots = match group.list_backups() { > + let mut snapshots = match group.list_backups(ListBackupFilter::All) { > Ok(snapshots) => snapshots, > Err(err) => { > if group.exists() { > diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs > index aafd1bbd7..133a6d658 100644 > --- a/src/api2/admin/datastore.rs > +++ b/src/api2/admin/datastore.rs > @@ -51,7 +51,7 @@ use pbs_api_types::{ > }; > use pbs_client::pxar::{create_tar, create_zip}; > use pbs_config::CachedUserInfo; > -use pbs_datastore::backup_info::BackupInfo; > +use pbs_datastore::backup_info::{BackupInfo, ListBackupFilter}; > use pbs_datastore::cached_chunk_reader::CachedChunkReader; > use pbs_datastore::catalog::{ArchiveEntry, CatalogReader}; > use pbs_datastore::data_blob::DataBlob; > @@ -223,7 +223,7 @@ pub fn list_groups( > return Ok(group_info); > } > > - let snapshots = match group.list_backups() { > + let snapshots = match group.list_backups(ListBackupFilter::Active) { > Ok(snapshots) => snapshots, > Err(_) => return Ok(group_info), > }; > @@ -624,7 +624,7 @@ unsafe fn list_snapshots_blocking( > return Ok(snapshots); > } > > - let group_backups = group.list_backups()?; > + let group_backups = group.list_backups(ListBackupFilter::Active)?; > > snapshots.extend( > group_backups > @@ -657,7 +657,7 @@ async fn get_snapshots_count( > Ok(group) => group, > Err(_) => return Ok(counts), // TODO: add this as error counts? > }; > - let snapshot_count = group.list_backups()?.len() as u64; > + let snapshot_count = group.list_backups(ListBackupFilter::Active)?.len() as u64; > > // only include groups with snapshots, counting/displaying empty groups can confuse > if snapshot_count > 0 { > @@ -1042,7 +1042,7 @@ pub fn prune( > } > let mut prune_result: Vec<PruneResult> = Vec::new(); > > - let list = group.list_backups()?; > + let list = group.list_backups(ListBackupFilter::Active)?; > > let mut prune_info = compute_prune_info(list, &keep_options)?; > > diff --git a/src/api2/tape/backup.rs b/src/api2/tape/backup.rs > index 31293a9a9..923cb7834 100644 > --- a/src/api2/tape/backup.rs > +++ b/src/api2/tape/backup.rs > @@ -17,7 +17,7 @@ use pbs_api_types::{ > }; > > use pbs_config::CachedUserInfo; > -use pbs_datastore::backup_info::{BackupDir, BackupInfo}; > +use pbs_datastore::backup_info::{BackupDir, BackupInfo, ListBackupFilter}; > use pbs_datastore::{DataStore, StoreProgress}; > > use crate::tape::TapeNotificationMode; > @@ -433,7 +433,7 @@ fn backup_worker( > progress.done_snapshots = 0; > progress.group_snapshots = 0; > > - let snapshot_list = group.list_backups()?; > + let snapshot_list = group.list_backups(ListBackupFilter::Active)?; > > // filter out unfinished backups > let mut snapshot_list: Vec<_> = snapshot_list > diff --git a/src/backup/verify.rs b/src/backup/verify.rs > index 3d2cba8ac..1b5e8564b 100644 > --- a/src/backup/verify.rs > +++ b/src/backup/verify.rs > @@ -14,7 +14,7 @@ use pbs_api_types::{ > CryptMode, SnapshotVerifyState, VerifyState, PRIV_DATASTORE_BACKUP, PRIV_DATASTORE_VERIFY, > UPID, > }; > -use pbs_datastore::backup_info::{BackupDir, BackupGroup, BackupInfo}; > +use pbs_datastore::backup_info::{BackupDir, BackupGroup, BackupInfo, ListBackupFilter}; > use pbs_datastore::index::IndexFile; > use pbs_datastore::manifest::{BackupManifest, FileInfo}; > use pbs_datastore::{DataBlob, DataStore, StoreProgress}; > @@ -411,7 +411,7 @@ pub fn verify_backup_group( > filter: Option<&dyn Fn(&BackupManifest) -> bool>, > ) -> Result<Vec<String>, Error> { > let mut errors = Vec::new(); > - let mut list = match group.list_backups() { > + let mut list = match group.list_backups(ListBackupFilter::Active) { > Ok(list) => list, > Err(err) => { > info!( > diff --git a/src/server/prune_job.rs b/src/server/prune_job.rs > index 1c86647a0..596afe086 100644 > --- a/src/server/prune_job.rs > +++ b/src/server/prune_job.rs > @@ -1,6 +1,7 @@ > use std::sync::Arc; > > use anyhow::Error; > +use pbs_datastore::backup_info::ListBackupFilter; > use tracing::{info, warn}; > > use pbs_api_types::{ > @@ -54,7 +55,7 @@ pub fn prune_datastore( > )? { > let group = group?; > let ns = group.backup_ns(); > - let list = group.list_backups()?; > + let list = group.list_backups(ListBackupFilter::Active)?; > > let mut prune_info = compute_prune_info(list, &prune_options.keep)?; > prune_info.reverse(); // delete older snapshots first > diff --git a/src/server/pull.rs b/src/server/pull.rs > index b1724c142..50d7b0806 100644 > --- a/src/server/pull.rs > +++ b/src/server/pull.rs > @@ -7,6 +7,7 @@ use std::sync::{Arc, Mutex}; > use std::time::SystemTime; > > use anyhow::{bail, format_err, Error}; > +use pbs_datastore::backup_info::ListBackupFilter; > use proxmox_human_byte::HumanByte; > use tracing::info; > > @@ -660,7 +661,7 @@ async fn pull_group( > .target > .store > .backup_group(target_ns.clone(), group.clone()); > - let local_list = group.list_backups()?; > + let local_list = group.list_backups(ListBackupFilter::Active)?; > for info in local_list { > let snapshot = info.backup_dir; > if source_snapshots.contains(&snapshot.backup_time()) { > -- > 2.39.5 > > > > _______________________________________________ > pbs-devel mailing list > pbs-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel > > > _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel