From 650ab331c01d623aa7d1da0406dee95c1a1a9d7e Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Thu, 13 Apr 2017 13:32:59 +0200 Subject: [PATCH] List backups by folder (re #5) --- src/cli/mod.rs | 50 ++++++++++++++++++++--------------- src/mount.rs | 2 +- src/repository/backup.rs | 10 ++++--- src/repository/backup_file.rs | 2 +- src/repository/info.rs | 2 +- src/repository/integrity.rs | 2 +- src/repository/mod.rs | 2 +- 7 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 99ba0e7..4315cdb 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -110,7 +110,7 @@ fn find_reference_backup(repo: &Repository, path: &str) -> Result hostname, Err(_) => return Ok(None) }; - let backup_map = match repo.get_backups() { + let backup_map = match repo.get_all_backups() { Ok(backup_map) => backup_map, Err(RepositoryError::BackupFile(BackupFileError::PartialBackupsList(backup_map, _failed))) => { warn!("Some backups could not be read, ignoring them"); @@ -444,30 +444,36 @@ pub fn run() -> Result<(), ErrorCode> { }, Arguments::List{repo_path, backup_name, inode} => { let mut repo = try!(open_repository(&repo_path)); - if let Some(backup_name) = backup_name { - let backup = try!(get_backup(&repo, &backup_name)); - let inode = checked!(repo.get_backup_inode(&backup, inode.as_ref().map(|v| v as &str).unwrap_or("/")), "load subpath inode", ErrorCode::LoadInode); - println!("{}", format_inode_one_line(&inode)); - if let Some(children) = inode.children { - for chunks in children.values() { - let inode = checked!(repo.get_inode(chunks), "load child inode", ErrorCode::LoadInode); - println!("- {}", format_inode_one_line(&inode)); + let backup_map = if let Some(backup_name) = backup_name { + if repo.layout.backups_path().join(&backup_name).is_dir() { + repo.get_backups(&backup_name) + } else { + let backup = try!(get_backup(&repo, &backup_name)); + let inode = checked!(repo.get_backup_inode(&backup, inode.as_ref().map(|v| v as &str).unwrap_or("/")), "load subpath inode", ErrorCode::LoadInode); + println!("{}", format_inode_one_line(&inode)); + if let Some(children) = inode.children { + for chunks in children.values() { + let inode = checked!(repo.get_inode(chunks), "load child inode", ErrorCode::LoadInode); + println!("- {}", format_inode_one_line(&inode)); + } } + return Ok(()) } } else { - let backup_map = match repo.get_backups() { - Ok(backup_map) => backup_map, - Err(RepositoryError::BackupFile(BackupFileError::PartialBackupsList(backup_map, _failed))) => { - warn!("Some backups could not be read, ignoring them"); - backup_map - }, - Err(err) => { - error!("Failed to load backup files: {}", err); - return Err(ErrorCode::LoadBackup) - } - }; - print_backups(&backup_map); - } + repo.get_all_backups() + }; + let backup_map = match backup_map { + Ok(backup_map) => backup_map, + Err(RepositoryError::BackupFile(BackupFileError::PartialBackupsList(backup_map, _failed))) => { + warn!("Some backups could not be read, ignoring them"); + backup_map + }, + Err(err) => { + error!("Failed to load backup files: {}", err); + return Err(ErrorCode::LoadBackup) + } + }; + print_backups(&backup_map); }, Arguments::Info{repo_path, backup_name, inode} => { let mut repo = try!(open_repository(&repo_path)); diff --git a/src/mount.rs b/src/mount.rs index de47ea7..7204bd6 100644 --- a/src/mount.rs +++ b/src/mount.rs @@ -155,7 +155,7 @@ impl<'a> FuseFilesystem<'a> { pub fn from_repository(repository: &'a mut Repository) -> Result { let mut backups = vec![]; - for (name, backup) in try!(repository.get_backups()) { + for (name, backup) in try!(repository.get_all_backups()) { let inode = try!(repository.get_inode(&backup.root)); backups.push((name, backup, inode)); } diff --git a/src/repository/backup.rs b/src/repository/backup.rs index ea9386f..eb43632 100644 --- a/src/repository/backup.rs +++ b/src/repository/backup.rs @@ -38,10 +38,14 @@ pub enum DiffType { impl Repository { - pub fn get_backups(&self) -> Result, RepositoryError> { + pub fn get_all_backups(&self) -> Result, RepositoryError> { Ok(try!(Backup::get_all_from(&self.crypto.lock().unwrap(), self.layout.backups_path()))) } + pub fn get_backups>(&self, path: P) -> Result, RepositoryError> { + Ok(try!(Backup::get_all_from(&self.crypto.lock().unwrap(), self.layout.backups_path().join(path)))) + } + #[inline] pub fn has_backup(&self, name: &str) -> bool { self.layout.backup_path(name).exists() @@ -75,7 +79,7 @@ impl Repository { pub fn prune_backups(&mut self, prefix: &str, daily: usize, weekly: usize, monthly: usize, yearly: usize, force: bool) -> Result<(), RepositoryError> { try!(self.write_mode()); let mut backups = Vec::new(); - let backup_map = match self.get_backups() { + let backup_map = match self.get_all_backups() { Ok(backup_map) => backup_map, Err(RepositoryError::BackupFile(BackupFileError::PartialBackupsList(backup_map, _failed))) => { warn!("Some backups could not be read, ignoring them"); @@ -341,7 +345,7 @@ impl Repository { pub fn find_versions>(&mut self, path: P) -> Result, RepositoryError> { let path = path.as_ref(); let mut versions = HashMap::new(); - for (name, backup) in try!(self.get_backups()) { + for (name, backup) in try!(self.get_all_backups()) { match self.get_backup_inode(&backup, path) { Ok(inode) => { versions.insert((inode.file_type, inode.timestamp, inode.size), (name, inode)); diff --git a/src/repository/backup_file.rs b/src/repository/backup_file.rs index 4758ace..d789f42 100644 --- a/src/repository/backup_file.rs +++ b/src/repository/backup_file.rs @@ -171,7 +171,7 @@ impl Backup { if relpath.extension() != Some("backup".as_ref()) { continue } - let name = relpath.file_stem().unwrap().to_string_lossy().to_string(); + let name = relpath.with_file_name(relpath.file_stem().unwrap()).to_string_lossy().to_string(); if let Ok(backup) = Backup::read_from(crypto, &path) { backups.insert(name, backup); } else { diff --git a/src/repository/info.rs b/src/repository/info.rs index 439550f..8001456 100644 --- a/src/repository/info.rs +++ b/src/repository/info.rs @@ -74,7 +74,7 @@ impl Repository { used_raw_size: 0 }); } - let backups = try!(self.get_backups()); + let backups = try!(self.get_all_backups()); let mut todo = VecDeque::new(); for (_name, backup) in backups { todo.push_back(backup.root); diff --git a/src/repository/integrity.rs b/src/repository/integrity.rs index 5cf1aa2..079be58 100644 --- a/src/repository/integrity.rs +++ b/src/repository/integrity.rs @@ -262,7 +262,7 @@ impl Repository { }; info!("Checking backups..."); let mut checked = Bitmap::new(self.index.capacity()); - let backup_map = match self.get_backups() { + let backup_map = match self.get_all_backups() { Ok(backup_map) => backup_map, Err(RepositoryError::BackupFile(BackupFileError::PartialBackupsList(backup_map, _failed))) => { warn!("Some backups could not be read, ignoring them"); diff --git a/src/repository/mod.rs b/src/repository/mod.rs index cf9a2f7..263cad2 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -163,7 +163,7 @@ impl Repository { try!(repo.crypto.lock().unwrap().register_keyfile(file)); } repo = try!(Repository::open(path)); - let mut backups: Vec<(String, Backup)> = try!(repo.get_backups()).into_iter().collect(); + let mut backups: Vec<(String, Backup)> = try!(repo.get_all_backups()).into_iter().collect(); backups.sort_by_key(|&(_, ref b)| b.date); if let Some((name, backup)) = backups.pop() { info!("Taking configuration from the last backup '{}'", name);