From b18cc8d58bfba0d243da67a2ef9b1bc0ea119bec Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Sun, 25 Jun 2023 07:09:05 +0200 Subject: [PATCH] prune: Add example using rustic_core --- crates/rustic_core/examples/prune.rs | 21 +++++++++ crates/rustic_core/src/commands/prune.rs | 54 ++++++++++++++++++------ 2 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 crates/rustic_core/examples/prune.rs diff --git a/crates/rustic_core/examples/prune.rs b/crates/rustic_core/examples/prune.rs new file mode 100644 index 000000000..7100e2725 --- /dev/null +++ b/crates/rustic_core/examples/prune.rs @@ -0,0 +1,21 @@ +//! `prune` example +use rustic_core::{PruneOpts, Repository, RepositoryOptions}; +use simplelog::{Config, LevelFilter, SimpleLogger}; + +fn main() { + // Display info logs + let _ = SimpleLogger::init(LevelFilter::Info, Config::default()); + + // Open repository + let mut repo_opts = RepositoryOptions::default(); + repo_opts.repository = Some("/tmp/repo".to_string()); + repo_opts.password = Some("test".to_string()); + let repo = Repository::new(&repo_opts).unwrap().open().unwrap(); + + let prune_opts = PruneOpts::default(); + let prune_plan = repo.prune_plan(&prune_opts).unwrap(); + println!("{:?}", prune_plan.stats); + println!("to repack: {:?}", prune_plan.repack_packs()); + // to run the plan uncomment this line: + // prune_plan.do_prune(&repo, &prune_opts).unwrap(); +} diff --git a/crates/rustic_core/src/commands/prune.rs b/crates/rustic_core/src/commands/prune.rs index dd4e0c18b..6de1729e9 100644 --- a/crates/rustic_core/src/commands/prune.rs +++ b/crates/rustic_core/src/commands/prune.rs @@ -34,56 +34,86 @@ pub(super) mod constants { #[allow(clippy::struct_excessive_bools)] #[cfg_attr(feature = "clap", derive(clap::Parser))] #[derive(Debug, Clone)] -#[group(id = "prune_opts")] +#[cfg_attr(feature = "clap", group(id = "prune_opts"))] pub struct PruneOpts { /// Define maximum data to repack in % of reposize or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited' - #[clap(long, value_name = "LIMIT", default_value = "unlimited")] + #[cfg_attr( + feature = "clap", + clap(long, value_name = "LIMIT", default_value = "unlimited") + )] pub max_repack: LimitOption, /// Tolerate limit of unused data in % of reposize after pruning or as size (e.g. '5b', '2 kB', '3M', '4TiB') or 'unlimited' - #[clap(long, value_name = "LIMIT", default_value = "5%")] + #[cfg_attr( + feature = "clap", + clap(long, value_name = "LIMIT", default_value = "5%") + )] pub max_unused: LimitOption, /// Minimum duration (e.g. 90d) to keep packs before repacking or removing. More recently created /// packs won't be repacked or marked for deletion within this prune run. - #[clap(long, value_name = "DURATION", default_value = "0d")] + #[cfg_attr( + feature = "clap", + clap(long, value_name = "DURATION", default_value = "0d") + )] pub keep_pack: humantime::Duration, /// Minimum duration (e.g. 10m) to keep packs marked for deletion. More recently marked packs won't be /// deleted within this prune run. - #[clap(long, value_name = "DURATION", default_value = "23h")] + #[cfg_attr( + feature = "clap", + clap(long, value_name = "DURATION", default_value = "23h") + )] pub keep_delete: humantime::Duration, /// Delete files immediately instead of marking them. This also removes all files already marked for deletion. /// WARNING: Only use if you are sure the repository is not accessed by parallel processes! - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub instant_delete: bool, /// Simply copy blobs when repacking instead of decrypting; possibly compressing; encrypting - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub fast_repack: bool, /// Repack packs containing uncompressed blobs. This cannot be used with --fast-repack. /// Implies --max-unused=0. - #[clap(long, conflicts_with = "fast_repack")] + #[cfg_attr(feature = "clap", clap(long, conflicts_with = "fast_repack"))] pub repack_uncompressed: bool, /// Repack all packs. Implies --max-unused=0. - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub repack_all: bool, /// Only repack packs which are cacheable [default: true for a hot/cold repository, else false] - #[clap(long, value_name = "TRUE/FALSE")] + #[cfg_attr(feature = "clap", clap(long, value_name = "TRUE/FALSE"))] pub repack_cacheable_only: Option, /// Do not repack packs which only needs to be resized - #[clap(long)] + #[cfg_attr(feature = "clap", clap(long))] pub no_resize: bool, - #[clap(skip)] + #[cfg_attr(feature = "clap", clap(skip))] pub ignore_snaps: Vec, } +impl Default for PruneOpts { + fn default() -> Self { + Self { + max_repack: LimitOption::Unlimited, + max_unused: LimitOption::Percentage(5), + keep_pack: std::time::Duration::from_secs(0).into(), + keep_delete: std::time::Duration::from_secs(82800).into(), // = 23h + instant_delete: false, + fast_repack: false, + repack_uncompressed: false, + repack_all: false, + repack_cacheable_only: None, + no_resize: false, + ignore_snaps: Vec::new(), + } + } +} + impl PruneOpts { pub fn get_plan(&self, repo: &OpenRepository

) -> RusticResult { let pb = &repo.pb;