From 33eb23d57e1785787e2e3e47406109e747a8611b Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Fri, 15 Apr 2022 12:24:56 +0200 Subject: [PATCH] datastore: add snapshot iterator and provide example will be more used in the future, when the upend-datastore master plan comes in effect. also a preparatory work for namespaces Signed-off-by: Thomas Lamprecht --- pbs-datastore/examples/ls-snapshots.rs | 34 +++++++++++++++++++ pbs-datastore/src/datastore.rs | 47 +++++++++++++++++++++++++- pbs-datastore/src/lib.rs | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 pbs-datastore/examples/ls-snapshots.rs diff --git a/pbs-datastore/examples/ls-snapshots.rs b/pbs-datastore/examples/ls-snapshots.rs new file mode 100644 index 00000000..e81c9017 --- /dev/null +++ b/pbs-datastore/examples/ls-snapshots.rs @@ -0,0 +1,34 @@ +use std::path::PathBuf; + +use anyhow::{bail, Error}; + +use pbs_datastore::{ListGroups, ListSnapshots}; + +fn run() -> Result<(), Error> { + let base: PathBuf = match std::env::args().skip(1).next() { + Some(path) => path.into(), + None => bail!("no path passed"), + }; + + for group in ListGroups::new(base.to_owned())? { + let group = group?; + println!("found group {}", group); + + let group_path = base.as_path().join(group.to_string()); + for snapshot in ListSnapshots::new(group, group_path)? { + println!("\t{}", snapshot?); + } + } + + Ok(()) +} + +fn main() { + std::process::exit(match run() { + Ok(_) => 0, + Err(err) => { + eprintln!("error: {}", err); + 1 + } + }); +} diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs index 0bd1fa34..7f935ad8 100644 --- a/pbs-datastore/src/datastore.rs +++ b/pbs-datastore/src/datastore.rs @@ -19,7 +19,7 @@ use proxmox_sys::{task_log, task_warn}; use pbs_api_types::{ Authid, ChunkOrder, DataStoreConfig, DatastoreTuning, GarbageCollectionStatus, HumanByte, - Operation, BACKUP_ID_REGEX, BACKUP_TYPE_REGEX, UPID, + Operation, BACKUP_DATE_REGEX, BACKUP_ID_REGEX, BACKUP_TYPE_REGEX, UPID, }; use pbs_config::{open_backup_lockfile, BackupLockGuard, ConfigVersionCache}; @@ -1065,6 +1065,51 @@ impl DataStore { } } +/// A iterator for all BackupDir's (Snapshots) in a BackupGroup +pub struct ListSnapshots { + group: BackupGroup, + fd: proxmox_sys::fs::ReadDir, +} + +impl ListSnapshots { + pub fn new(group: BackupGroup, group_path: PathBuf) -> Result { + Ok(ListSnapshots { + fd: proxmox_sys::fs::read_subdir(libc::AT_FDCWD, &group_path)?, + group, + }) + } +} + +impl Iterator for ListSnapshots { + type Item = Result; + + fn next(&mut self) -> Option { + loop { + let item = self.fd.next()?; + match item { + Ok(ref entry) => { + if let Ok(name) = entry.file_name().to_str() { + match entry.file_type() { + Some(nix::dir::Type::Directory) => {} // OK + _ => continue, + } + if BACKUP_DATE_REGEX.is_match(name) { + let backup_time = match proxmox_time::parse_rfc3339(&name) { + Ok(time) => time, + Err(err) => return Some(Err(err)), + }; + + return Some(BackupDir::with_group(self.group.clone(), backup_time)); + } + } + continue; // file did not match regex or isn't valid utf-8 + } + Err(err) => return Some(Err(err)), + } + } + } +} + /// A iterator for a (single) level of Backup Groups pub struct ListGroups { type_fd: proxmox_sys::fs::ReadDir, diff --git a/pbs-datastore/src/lib.rs b/pbs-datastore/src/lib.rs index 4cb0e68b..bb6b99a6 100644 --- a/pbs-datastore/src/lib.rs +++ b/pbs-datastore/src/lib.rs @@ -204,7 +204,7 @@ pub use manifest::BackupManifest; pub use store_progress::StoreProgress; mod datastore; -pub use datastore::{check_backup_owner, DataStore, ListGroups}; +pub use datastore::{check_backup_owner, DataStore, ListGroups, ListSnapshots}; mod snapshot_reader; pub use snapshot_reader::SnapshotReader;