summaryrefslogtreecommitdiff
path: root/src/bin/obnam.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/obnam.rs')
-rw-r--r--src/bin/obnam.rs170
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),
}