Files
zfs_backup_rust/src/todo.rs
T
2026-05-05 17:52:41 +02:00

74 lines
2.1 KiB
Rust

use anyhow::Result;
use crate::zfs::Snapshot;
use crate::zfs::ZPool;
use crate::zfs::Dataset;
pub enum Todo {
Absolute(Dataset, Snapshot),
Incremental(Dataset, Snapshot, Snapshot),
UpToDate(Dataset, Snapshot),
}
impl Todo {
pub fn print(&self) {
match self {
Todo::Absolute(dataset, snapshot) => {
println!(" {dataset}@{snapshot} -> [new]")
}
Todo::Incremental(dataset, last_common_snapshot, recent_snapshot) => {
println!(" {dataset}@{last_common_snapshot} -> ...@{recent_snapshot}")
}
Todo::UpToDate(dataset, snapshot) => {
println!(" {dataset}@{snapshot} is already backed up")
}
}
}
pub fn plan(
local: &ZPool,
remote: &ZPool,
snapshot_tag: String,
snapshot_interval: String,
) -> Result<Vec<Self>> {
let mut result = vec![];
for local_dataset in &local.datasets {
let last_snapshot_with_tag =
local_dataset.find_last_snapshot_with_tag(&snapshot_tag, &snapshot_interval)?;
let remote_dataset = local_dataset.change_pool_name(remote);
if !remote.contains(&remote_dataset) {
result.push(Todo::Absolute(
local_dataset.clone(),
last_snapshot_with_tag,
));
continue;
}
let remote_dataset = remote.get_matching_dataset(local_dataset).unwrap();
let last_common_snapshot = Snapshot::find_last_common_snapshot_with_tag(
local_dataset,
&remote_dataset,
&snapshot_tag,
)
.unwrap();
let todo = if last_common_snapshot == last_snapshot_with_tag {
Todo::UpToDate(local_dataset.clone(), last_common_snapshot)
} else {
Todo::Incremental(
local_dataset.clone(),
last_common_snapshot,
last_snapshot_with_tag,
)
};
result.push(todo);
}
Ok(result)
}
}