From a30e0f4a8cddafcc3f028378c89d492618a49fb7 Mon Sep 17 00:00:00 2001 From: timeshifter Date: Wed, 6 May 2026 19:14:50 +0200 Subject: [PATCH] add stuff --- config.toml | 2 ++ src/config.rs | 1 + src/lib.rs | 1 + src/main.rs | 12 +++++++++-- src/pathbuf.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/todo.rs | 14 +++++++++++- src/zfs.rs | 4 ++-- 7 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 src/pathbuf.rs diff --git a/config.toml b/config.toml index 505baa1..f72ce0f 100644 --- a/config.toml +++ b/config.toml @@ -3,6 +3,8 @@ snapshot_interval = "monthly" local_pool_name = "tank" +do_not_backup_datasets = ["docker", "cache"] + [backup_pools] backup1 = 'a235c116-764f-4082-97fc-47ca31e11e53' backup2 = '200ced55-894c-4f70-b089-b140e60193fc' diff --git a/src/config.rs b/src/config.rs index 2c5fad3..99f3c66 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,6 +8,7 @@ pub struct Config { pub snapshot_tag: String, pub snapshot_interval: String, pub local_pool_name: String, + pub do_not_backup_datasets: Vec, pub backup_pools: BackupPools, } diff --git a/src/lib.rs b/src/lib.rs index f4dd8a2..46a603e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod cmd; pub mod config; pub mod encryption; +pub mod pathbuf; pub mod todo; pub mod zfs; diff --git a/src/main.rs b/src/main.rs index bc97d41..b534054 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,7 @@ fn main() -> Result<()> { &backup_pool, config.snapshot_tag, config.snapshot_interval, + config.do_not_backup_datasets, )?; if something_was_done { @@ -56,9 +57,16 @@ fn do_backup( backup_pool: &ZPool, snapshot_tag: String, snapshot_interval: String, + datasets: Vec, ) -> Result { - let todos = todo::Todo::plan(local_pool, backup_pool, snapshot_tag, snapshot_interval) - .context("planning todos")?; + let todos = todo::Todo::plan( + local_pool, + backup_pool, + datasets, + snapshot_tag, + snapshot_interval, + ) + .context("planning todos")?; if todos.is_empty() { println!("nothing to do"); diff --git a/src/pathbuf.rs b/src/pathbuf.rs new file mode 100644 index 0000000..6b35196 --- /dev/null +++ b/src/pathbuf.rs @@ -0,0 +1,58 @@ +use crate::zfs::Dataset; + +pub trait Relative { + fn is_child_of(&self, other: &Dataset) -> bool; +} + +impl Relative for Dataset { + fn is_child_of(&self, other: &Dataset) -> bool { + let self_components: Vec<_> = self.0.components().collect(); + let other_components: Vec<_> = other.0.components().collect(); + + if self_components.len() < other_components.len() { + return false; + } + + other + .0 + .iter() + .zip(self.0.iter()) + .map(|(left, right)| left == right) + .reduce(|left, right| left && right) + .unwrap() + } +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use super::*; + + #[test] + fn base() { + let mut pb1 = PathBuf::new(); + pb1.push("/a/b/c"); + let ds1 = Dataset::new(pb1); + + let mut pb2 = PathBuf::new(); + pb2.push("/a/b/c/d"); + let ds2 = Dataset::new(pb2); + + assert!(ds2.is_child_of(&ds1)); + assert!(!ds1.is_child_of(&ds2)); + } + + #[test] + fn not_related() { + let mut pb1 = PathBuf::new(); + pb1.push("/a/z/c"); + let ds1 = Dataset::new(pb1); + + let mut pb2 = PathBuf::new(); + pb2.push("/a/b/c"); + let ds2 = Dataset::new(pb2); + + assert!(!ds2.is_child_of(&ds1)); + } +} diff --git a/src/todo.rs b/src/todo.rs index 1b429a8..5839bc3 100644 --- a/src/todo.rs +++ b/src/todo.rs @@ -1,8 +1,12 @@ +use std::path::PathBuf; + use anyhow::Result; use crate::zfs::Snapshot; use crate::zfs::ZPool; +use crate::pathbuf::Relative; + use crate::zfs::Dataset; pub enum Todo { @@ -29,12 +33,20 @@ impl Todo { pub fn plan( local: &ZPool, remote: &ZPool, + do_not_backup_datasets: Vec, snapshot_tag: String, snapshot_interval: String, ) -> Result> { let mut result = vec![]; - for local_dataset in &local.datasets { + 'outer: for local_dataset in &local.datasets { + for do_not_backup in &do_not_backup_datasets { + let ds = Dataset::new(PathBuf::from(do_not_backup)); + if local_dataset.is_child_of(&ds) { + continue 'outer; + } + } + let last_snapshot_with_tag = local_dataset.find_last_snapshot_with_tag(&snapshot_tag, &snapshot_interval)?; diff --git a/src/zfs.rs b/src/zfs.rs index e6e9e9c..29b2aa2 100644 --- a/src/zfs.rs +++ b/src/zfs.rs @@ -120,10 +120,10 @@ impl ZPool { /// E.g. if the name of the pool is `tank`, with the elements `ROOT` and `default` below it, this /// struct would contain `tank/ROOT/default`. #[derive(Debug, PartialEq, Clone)] -pub struct Dataset(PathBuf); +pub struct Dataset(pub(crate) PathBuf); impl Dataset { - fn new(path: PathBuf) -> Self { + pub fn new(path: PathBuf) -> Self { Self(path) }