diff options
Diffstat (limited to 'src/bin/obnam.rs')
-rw-r--r-- | src/bin/obnam.rs | 170 |
1 files changed, 98 insertions, 72 deletions
diff --git a/src/bin/obnam.rs b/src/bin/obnam.rs index e9f30ca..240960b 100644 --- a/src/bin/obnam.rs +++ b/src/bin/obnam.rs @@ -1,100 +1,126 @@ +use clap::Parser; +use directories_next::ProjectDirs; 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, show_generation}; +use log4rs::config::{Appender, Logger, Root}; +use obnam::cmd::backup::Backup; +use obnam::cmd::chunk::{DecryptChunk, EncryptChunk}; +use obnam::cmd::chunkify::Chunkify; +use obnam::cmd::gen_info::GenInfo; +use obnam::cmd::get_chunk::GetChunk; +use obnam::cmd::init::Init; +use obnam::cmd::inspect::Inspect; +use obnam::cmd::list::List; +use obnam::cmd::list_backup_versions::ListSchemaVersions; +use obnam::cmd::list_files::ListFiles; +use obnam::cmd::resolve::Resolve; +use obnam::cmd::restore::Restore; +use obnam::cmd::show_config::ShowConfig; +use obnam::cmd::show_gen::ShowGeneration; +use obnam::config::ClientConfig; +use obnam::performance::{Clock, Performance}; use std::path::{Path, PathBuf}; -use structopt::StructOpt; -const BUFFER_SIZE: usize = 1024 * 1024; +const QUALIFIER: &str = ""; +const ORG: &str = ""; +const APPLICATION: &str = "obnam"; -fn main() -> anyhow::Result<()> { - let opt = Opt::from_args(); - let config_file = match opt.config { - None => default_config(), - Some(ref path) => path.to_path_buf(), - }; - let config = ClientConfig::read_config(&config_file)?; - if let Some(ref log) = config.log { - setup_logging(&log)?; +fn main() { + let mut perf = Performance::default(); + perf.start(Clock::RunTime); + if let Err(err) = main_program(&mut perf) { + error!("{}", err); + eprintln!("ERROR: {}", err); + std::process::exit(1); } + perf.stop(Clock::RunTime); + perf.log(); +} + +fn main_program(perf: &mut Performance) -> anyhow::Result<()> { + let opt = Opt::parse(); + let config = ClientConfig::read(&config_filename(&opt))?; + setup_logging(&config.log)?; info!("client starts"); debug!("{:?}", opt); + debug!("configuration: {:#?}", config); - 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), - }; - - if let Err(ref e) = result { - error!("{}", e); - eprintln!("ERROR: {}", e); - return result; - } + match opt.cmd { + Command::Init(x) => x.run(&config), + Command::ListBackupVersions(x) => x.run(&config), + Command::Backup(x) => x.run(&config, perf), + Command::Inspect(x) => x.run(&config), + Command::Chunkify(x) => x.run(&config), + Command::List(x) => x.run(&config), + Command::ShowGeneration(x) => x.run(&config), + Command::ListFiles(x) => x.run(&config), + Command::Resolve(x) => x.run(&config), + Command::Restore(x) => x.run(&config), + Command::GenInfo(x) => x.run(&config), + Command::GetChunk(x) => x.run(&config), + Command::Config(x) => x.run(&config), + Command::EncryptChunk(x) => x.run(&config), + Command::DecryptChunk(x) => x.run(&config), + }?; info!("client ends successfully"); Ok(()) } +fn setup_logging(filename: &Path) -> anyhow::Result<()> { + let logfile = FileAppender::builder().build(filename)?; + + let config = log4rs::Config::builder() + .appender(Appender::builder().build("obnam", Box::new(logfile))) + .logger(Logger::builder().build("obnam", LevelFilter::Debug)) + .build(Root::builder().appender("obnam").build(LevelFilter::Debug))?; + + log4rs::init_config(config)?; + + Ok(()) +} + +fn config_filename(opt: &Opt) -> PathBuf { + match opt.config { + None => default_config(), + Some(ref filename) => filename.to_path_buf(), + } +} + fn default_config() -> PathBuf { - if let Some(path) = dirs::config_dir() { - path.join("obnam").join("obnam.yaml") - } else if let Some(path) = dirs::home_dir() { - path.join(".config").join("obnam").join("obnam.yaml") + if let Some(dirs) = ProjectDirs::from(QUALIFIER, ORG, APPLICATION) { + dirs.config_dir().join("obnam.yaml") } else { - panic!("can't find config dir or home dir"); + panic!("can't figure out the configuration directory"); } } -#[derive(Debug, StructOpt)] -#[structopt(name = "obnam-backup", about = "Simplistic backup client")] +#[derive(Debug, Parser)] +#[clap(name = "obnam-backup", version, about = "Simplistic backup client")] struct Opt { - #[structopt(long, short, parse(from_os_str))] + #[clap(long, short)] config: Option<PathBuf>, - #[structopt(subcommand)] + #[clap(subcommand)] cmd: Command, } -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] enum Command { - Backup, - List, - ListFiles { - #[structopt(default_value = "latest")] - gen_id: String, - }, - Restore { - #[structopt()] - gen_id: String, - - #[structopt(parse(from_os_str))] - to: PathBuf, - }, - ShowGeneration { - #[structopt(default_value = "latest")] - gen_id: String, - }, - GetChunk { - #[structopt()] - chunk_id: String, - }, -} - -fn setup_logging(filename: &Path) -> anyhow::Result<()> { - let logfile = FileAppender::builder().build(filename)?; - - let config = Config::builder() - .appender(Appender::builder().build("obnam", Box::new(logfile))) - .logger(Logger::builder().build("obnam", LevelFilter::Debug)) - .build(Root::builder().appender("obnam").build(LevelFilter::Debug))?; - - log4rs::init_config(config)?; - - Ok(()) + Init(Init), + Backup(Backup), + Inspect(Inspect), + Chunkify(Chunkify), + List(List), + ListBackupVersions(ListSchemaVersions), + ListFiles(ListFiles), + Restore(Restore), + GenInfo(GenInfo), + ShowGeneration(ShowGeneration), + Resolve(Resolve), + GetChunk(GetChunk), + Config(ShowConfig), + EncryptChunk(EncryptChunk), + DecryptChunk(DecryptChunk), } |