add stuff
This commit is contained in:
@@ -3,6 +3,8 @@ snapshot_interval = "monthly"
|
|||||||
|
|
||||||
local_pool_name = "tank"
|
local_pool_name = "tank"
|
||||||
|
|
||||||
|
do_not_backup_datasets = ["docker", "cache"]
|
||||||
|
|
||||||
[backup_pools]
|
[backup_pools]
|
||||||
backup1 = 'a235c116-764f-4082-97fc-47ca31e11e53'
|
backup1 = 'a235c116-764f-4082-97fc-47ca31e11e53'
|
||||||
backup2 = '200ced55-894c-4f70-b089-b140e60193fc'
|
backup2 = '200ced55-894c-4f70-b089-b140e60193fc'
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ pub struct Config {
|
|||||||
pub snapshot_tag: String,
|
pub snapshot_tag: String,
|
||||||
pub snapshot_interval: String,
|
pub snapshot_interval: String,
|
||||||
pub local_pool_name: String,
|
pub local_pool_name: String,
|
||||||
|
pub do_not_backup_datasets: Vec<String>,
|
||||||
pub backup_pools: BackupPools,
|
pub backup_pools: BackupPools,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
pub mod cmd;
|
pub mod cmd;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod encryption;
|
pub mod encryption;
|
||||||
|
pub mod pathbuf;
|
||||||
pub mod todo;
|
pub mod todo;
|
||||||
pub mod zfs;
|
pub mod zfs;
|
||||||
|
|||||||
+9
-1
@@ -26,6 +26,7 @@ fn main() -> Result<()> {
|
|||||||
&backup_pool,
|
&backup_pool,
|
||||||
config.snapshot_tag,
|
config.snapshot_tag,
|
||||||
config.snapshot_interval,
|
config.snapshot_interval,
|
||||||
|
config.do_not_backup_datasets,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if something_was_done {
|
if something_was_done {
|
||||||
@@ -56,8 +57,15 @@ fn do_backup(
|
|||||||
backup_pool: &ZPool,
|
backup_pool: &ZPool,
|
||||||
snapshot_tag: String,
|
snapshot_tag: String,
|
||||||
snapshot_interval: String,
|
snapshot_interval: String,
|
||||||
|
datasets: Vec<String>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
let todos = todo::Todo::plan(local_pool, backup_pool, snapshot_tag, snapshot_interval)
|
let todos = todo::Todo::plan(
|
||||||
|
local_pool,
|
||||||
|
backup_pool,
|
||||||
|
datasets,
|
||||||
|
snapshot_tag,
|
||||||
|
snapshot_interval,
|
||||||
|
)
|
||||||
.context("planning todos")?;
|
.context("planning todos")?;
|
||||||
|
|
||||||
if todos.is_empty() {
|
if todos.is_empty() {
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-1
@@ -1,8 +1,12 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::zfs::Snapshot;
|
use crate::zfs::Snapshot;
|
||||||
use crate::zfs::ZPool;
|
use crate::zfs::ZPool;
|
||||||
|
|
||||||
|
use crate::pathbuf::Relative;
|
||||||
|
|
||||||
use crate::zfs::Dataset;
|
use crate::zfs::Dataset;
|
||||||
|
|
||||||
pub enum Todo {
|
pub enum Todo {
|
||||||
@@ -29,12 +33,20 @@ impl Todo {
|
|||||||
pub fn plan(
|
pub fn plan(
|
||||||
local: &ZPool,
|
local: &ZPool,
|
||||||
remote: &ZPool,
|
remote: &ZPool,
|
||||||
|
do_not_backup_datasets: Vec<String>,
|
||||||
snapshot_tag: String,
|
snapshot_tag: String,
|
||||||
snapshot_interval: String,
|
snapshot_interval: String,
|
||||||
) -> Result<Vec<Self>> {
|
) -> Result<Vec<Self>> {
|
||||||
let mut result = vec![];
|
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 =
|
let last_snapshot_with_tag =
|
||||||
local_dataset.find_last_snapshot_with_tag(&snapshot_tag, &snapshot_interval)?;
|
local_dataset.find_last_snapshot_with_tag(&snapshot_tag, &snapshot_interval)?;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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
|
/// 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`.
|
/// struct would contain `tank/ROOT/default`.
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Dataset(PathBuf);
|
pub struct Dataset(pub(crate) PathBuf);
|
||||||
|
|
||||||
impl Dataset {
|
impl Dataset {
|
||||||
fn new(path: PathBuf) -> Self {
|
pub fn new(path: PathBuf) -> Self {
|
||||||
Self(path)
|
Self(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user