mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
add filter for SnapshotFile::latest, add hostname
This commit is contained in:
parent
6ce09c8634
commit
b72f798ba5
@ -35,6 +35,7 @@ boomphf = {version = "0.5", optional = true}
|
||||
walkdir = "2"
|
||||
ignore = "0.4"
|
||||
# commands
|
||||
gethostname = "0.2"
|
||||
bytesize = "1"
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
rpassword = "5"
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsString;
|
||||
use std::io::BufRead;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
@ -145,7 +146,7 @@ impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn finalize_snapshot(&mut self, backup_path: PathBuf) -> Result<()> {
|
||||
pub fn finalize_snapshot(&mut self, backup_path: PathBuf, hostname: OsString) -> Result<()> {
|
||||
self.finish_trees(&PathBuf::from("/"))?;
|
||||
|
||||
let chunk = self.tree.serialize()?;
|
||||
@ -165,7 +166,7 @@ impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
|
||||
.to_str()
|
||||
.ok_or(anyhow!("non-unicode path {:?}", backup_path))?
|
||||
.to_string()],
|
||||
"host".to_string(),
|
||||
hostname.to_str().unwrap().to_string(),
|
||||
"user".to_string(),
|
||||
0,
|
||||
0,
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
use gethostname::gethostname;
|
||||
use std::fs::{read_link, File};
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use chrono::{TimeZone, Utc};
|
||||
use clap::Parser;
|
||||
use ignore::{DirEntry, WalkBuilder};
|
||||
@ -34,17 +35,29 @@ pub(super) fn execute(opts: Opts, be: &impl DecryptFullBackend) -> Result<()> {
|
||||
let poly = u64::from_str_radix(config.chunker_polynomial(), 16)?;
|
||||
let backup_path = PathBuf::from(&opts.source);
|
||||
let backup_path = backup_path.absolutize()?;
|
||||
let backup_path_str = backup_path
|
||||
.to_str()
|
||||
.ok_or(anyhow!("non-unicode path {:?}", backup_path))?
|
||||
.to_string();
|
||||
|
||||
println! {"reading index..."}
|
||||
let index = IndexBackend::new(be)?;
|
||||
let parent_tree = match opts.parent {
|
||||
None => None,
|
||||
Some(parent) => {
|
||||
let snap = SnapshotFile::from_str(be, &parent)?;
|
||||
let parent = match opts.parent {
|
||||
None => SnapshotFile::latest(be, |snap| snap.paths.contains(&backup_path_str)).ok(),
|
||||
Some(parent) => SnapshotFile::from_id(be, &parent).ok(),
|
||||
};
|
||||
let parent_tree = match parent {
|
||||
Some(snap) => {
|
||||
println!("using parent {}", snap.id);
|
||||
Some(snap.tree)
|
||||
}
|
||||
None => {
|
||||
println!("using no parent");
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
println! {"reading index..."}
|
||||
let index = IndexBackend::new(be)?;
|
||||
|
||||
let parent = Parent::new(&index, parent_tree.as_ref());
|
||||
let mut archiver = Archiver::new(be.clone(), index, poly, parent)?;
|
||||
|
||||
@ -62,7 +75,7 @@ pub(super) fn execute(opts: Opts, be: &impl DecryptFullBackend) -> Result<()> {
|
||||
let (path, node, r) = res?;
|
||||
archiver.add_entry(&path, node, r)?;
|
||||
}
|
||||
archiver.finalize_snapshot(backup_path.to_path_buf())?;
|
||||
archiver.finalize_snapshot(backup_path.to_path_buf(), gethostname())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ pub(super) struct Opts {
|
||||
}
|
||||
|
||||
pub(super) fn execute(be: &impl DecryptReadBackend, opts: Opts) -> Result<()> {
|
||||
let snap = SnapshotFile::from_str(be, &opts.id)?;
|
||||
let snap = SnapshotFile::from_str(be, &opts.id, |_| true)?;
|
||||
let index = IndexBackend::new(be)?;
|
||||
|
||||
let tree_iter = tree_iterator(&index, vec![snap.tree])?.filter_map(Result::ok);
|
||||
|
||||
@ -34,7 +34,7 @@ pub(super) struct Opts {
|
||||
|
||||
pub(super) fn execute(be: &impl DecryptReadBackend, opts: Opts) -> Result<()> {
|
||||
println!("getting snapshot...");
|
||||
let snap = SnapshotFile::from_str(be, &opts.id)?;
|
||||
let snap = SnapshotFile::from_str(be, &opts.id, |_| true)?;
|
||||
|
||||
let dest = LocalBackend::new(&opts.dest);
|
||||
|
||||
|
||||
@ -62,22 +62,30 @@ impl SnapshotFile {
|
||||
Ok(snap)
|
||||
}
|
||||
|
||||
pub fn from_str<B: ReadBackend>(be: &B, string: &str) -> Result<Self> {
|
||||
pub fn from_str<B: ReadBackend>(
|
||||
be: &B,
|
||||
string: &str,
|
||||
predicate: impl FnMut(&Self) -> bool,
|
||||
) -> Result<Self> {
|
||||
match string {
|
||||
"latest" => Self::latest(be),
|
||||
"latest" => Self::latest(be, predicate),
|
||||
_ => Self::from_id(be, string),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the latest SnapshotFile from the backend
|
||||
pub fn latest<B: ReadBackend>(be: &B) -> Result<Self> {
|
||||
pub fn latest<B: ReadBackend>(be: &B, predicate: impl FnMut(&Self) -> bool) -> Result<Self> {
|
||||
let mut latest: Option<Self> = None;
|
||||
let mut pred = predicate;
|
||||
for snap in be
|
||||
.list(FileType::Snapshot)?
|
||||
.iter()
|
||||
.map(|id| SnapshotFile::from_backend(be, &id))
|
||||
{
|
||||
let snap = snap?;
|
||||
if !pred(&snap) {
|
||||
continue;
|
||||
}
|
||||
match &latest {
|
||||
Some(l) if l.time > snap.time => {}
|
||||
_ => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user