From d4abb267d2216281586801abac96cdc5759c83ae Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 16 Jan 2021 18:12:50 +0200 Subject: feat: add "obnam show-generation" subcommand --- src/bin/obnam.rs | 7 ++++++- src/cmd/mod.rs | 3 +++ src/cmd/show_gen.rs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/cmd/show_gen.rs diff --git a/src/bin/obnam.rs b/src/bin/obnam.rs index e5703ed..1e09168 100644 --- a/src/bin/obnam.rs +++ b/src/bin/obnam.rs @@ -2,7 +2,7 @@ use log::{debug, error, info, LevelFilter}; use log4rs::append::file::FileAppender; use log4rs::config::{Appender, Config, Logger, Root}; use obnam::client::ClientConfig; -use obnam::cmd::{backup, get_chunk, list, list_files, restore}; +use obnam::cmd::{backup, get_chunk, list, list_files, restore, show_generation}; use std::path::{Path, PathBuf}; use structopt::StructOpt; @@ -21,6 +21,7 @@ fn main() -> anyhow::Result<()> { let result = match opt.cmd { Command::Backup => backup(&config, BUFFER_SIZE), Command::List => list(&config), + Command::ShowGeneration { gen_id } => show_generation(&config, &gen_id), Command::ListFiles { gen_id } => list_files(&config, &gen_id), Command::Restore { gen_id, to } => restore(&config, &gen_id, &to), Command::GetChunk { chunk_id } => get_chunk(&config, &chunk_id), @@ -61,6 +62,10 @@ enum Command { #[structopt(parse(from_os_str))] to: PathBuf, }, + ShowGeneration { + #[structopt(default_value = "latest")] + gen_id: String, + }, GetChunk { #[structopt()] chunk_id: String, diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index 0a22a8a..8f08668 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -12,3 +12,6 @@ pub use restore::restore; pub mod get_chunk; pub use get_chunk::get_chunk; + +pub mod show_gen; +pub use show_gen::show_generation; diff --git a/src/cmd/show_gen.rs b/src/cmd/show_gen.rs new file mode 100644 index 0000000..d355389 --- /dev/null +++ b/src/cmd/show_gen.rs @@ -0,0 +1,46 @@ +use crate::client::BackupClient; +use crate::client::ClientConfig; +use crate::error::ObnamError; +use crate::fsentry::FilesystemKind; +use indicatif::HumanBytes; +use tempfile::NamedTempFile; + +pub fn show_generation(config: &ClientConfig, gen_ref: &str) -> anyhow::Result<()> { + // Create a named temporary file. We don't meed the open file + // handle, so we discard that. + let dbname = { + let temp = NamedTempFile::new()?; + let (_, dbname) = temp.keep()?; + dbname + }; + + let client = BackupClient::new(&config.server_url)?; + + let genlist = client.list_generations()?; + let gen_id: String = match genlist.resolve(gen_ref) { + None => return Err(ObnamError::UnknownGeneration(gen_ref.to_string()).into()), + Some(id) => id, + }; + + let gen = client.fetch_generation(&gen_id, &dbname)?; + let files = gen.files()?; + + let total_bytes = files.iter().fold(0, |acc, file| { + let e = file.entry(); + if e.kind() == FilesystemKind::Regular { + acc + file.entry().len() + } else { + acc + } + }); + + println!("generation-id: {}", gen_id); + println!("file-count: {}", gen.file_count()?); + println!("file-bytes: {}", HumanBytes(total_bytes)); + println!("file-bytes-raw: {}", total_bytes); + + // Delete the temporary file. + std::fs::remove_file(&dbname)?; + + Ok(()) +} -- cgit v1.2.1