From f3e8bc4627727ccb87daf32dfc3c77cc68270c76 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 27 Jun 2022 10:29:19 +0200 Subject: [PATCH] cache: Add Option --cache-dir and use restic/rustic cache dir --- src/backend/cache.rs | 36 +++++++++++++++++++++++------------- src/commands/mod.rs | 15 ++++++++++++--- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/backend/cache.rs b/src/backend/cache.rs index 7d66352..5e84ab9 100644 --- a/src/backend/cache.rs +++ b/src/backend/cache.rs @@ -18,15 +18,8 @@ pub struct CachedBackend { } impl CachedBackend { - pub fn new(be: BE, id: Id, create: bool) -> Self { - Self { - be, - cache: Cache::new(id, create).unwrap(), - } - } - - pub fn cache(&self) -> &Option { - &self.cache + pub fn new(be: BE, cache: Option) -> Self { + Self { be, cache } } } @@ -136,13 +129,26 @@ pub struct Cache { } impl Cache { - pub fn new(id: Id, create: bool) -> Result> { - let mut path = cache_dir().ok_or_else(|| anyhow!("no cache dir"))?; - path.push("restic"); + pub fn new(id: Id, path: Option, create: bool) -> Result> { + let mut path = path.unwrap_or(cache_dir().ok_or_else(|| anyhow!("no cache dir"))?); + + // first try if a restic cache dir exists and if yes, use it + let mut path_restic = path.clone(); + path_restic.push("restic"); + if path_restic.exists() && cachedir::is_tagged(&path_restic)? { + path_restic.push(id.to_hex()); + if path_restic.exists() { + return Ok(Some(Self { path: path_restic })); + } + } + + // else use rustic cache dir + path.push("rustic"); + if create { fs::create_dir_all(&path)?; cachedir::ensure_tag(&path)?; - } else if !cachedir::is_tagged(&path)? { + } else if !path.exists() || !cachedir::is_tagged(&path)? { return Ok(None); } @@ -154,6 +160,10 @@ impl Cache { Ok(Some(Self { path })) } + pub fn location(&self) -> &str { + self.path.to_str().unwrap() + } + fn dir(&self, tpe: FileType, id: &Id) -> PathBuf { let hex_id = id.to_hex(); self.path.join(tpe.name()).join(&hex_id[0..2]) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 718e7fd..256b648 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -4,7 +4,7 @@ use anyhow::{bail, Result}; use clap::{Parser, Subcommand}; use crate::backend::{ - CachedBackend, ChooseBackend, DecryptBackend, DecryptReadBackend, FileType, ReadBackend, + Cache, CachedBackend, ChooseBackend, DecryptBackend, DecryptReadBackend, FileType, ReadBackend, }; use crate::repo::ConfigFile; @@ -49,6 +49,11 @@ struct Opts { #[clap(long)] no_cache: bool, + /// Use this thir as cache dir. If not given, rustic searches for restic cache dirs + /// and rustic cache dirs + #[clap(long, parse(from_os_str), conflicts_with = "no-cache")] + cache_dir: Option, + #[clap(subcommand)] command: Command, } @@ -121,8 +126,12 @@ pub async fn execute() -> Result<()> { let key = get_key(&be, args.password_file).await?; let dbe = DecryptBackend::new(&be, key.clone()); let config: ConfigFile = dbe.get_file(&config_ids[0]).await?; - let be_cached = CachedBackend::new(be.clone(), config.id, !args.no_cache); - let cache = be_cached.cache().clone(); + let cache = Cache::new(config.id, args.cache_dir, !args.no_cache)?; + match &cache { + None => v1!("using no cache"), + Some(cache) => v1!("using cache at {}", cache.location()), + } + let be_cached = CachedBackend::new(be.clone(), cache.clone()); let dbe = DecryptBackend::new(&be_cached, key.clone()); (cmd, key, dbe, cache, be, config) }