74 lines
2.1 KiB
Rust
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)
|
|
}
|
|
}
|