summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backup_run.rs2
-rw-r--r--src/bin/obnam.rs39
-rw-r--r--src/cmd/backup.rs2
-rw-r--r--src/cmd/init.rs8
-rw-r--r--src/cmd/show_config.rs2
-rw-r--r--src/config.rs92
-rw-r--r--subplot/client.py11
-rw-r--r--subplot/client.yaml5
8 files changed, 63 insertions, 98 deletions
diff --git a/src/backup_run.rs b/src/backup_run.rs
index 23c97f6..16d6700 100644
--- a/src/backup_run.rs
+++ b/src/backup_run.rs
@@ -41,7 +41,6 @@ pub type BackupResult<T> = Result<T, BackupError>;
impl<'a> InitialBackup<'a> {
pub fn new(config: &ClientConfig, client: &'a BackupClient) -> BackupResult<Self> {
let progress = BackupProgress::initial();
- let config = config.config();
Ok(Self {
client,
buffer_size: config.chunk_size,
@@ -81,7 +80,6 @@ impl<'a> InitialBackup<'a> {
impl<'a> IncrementalBackup<'a> {
pub fn new(config: &ClientConfig, client: &'a BackupClient) -> BackupResult<Self> {
- let config = config.config();
let policy = BackupPolicy::default();
Ok(Self {
client,
diff --git a/src/bin/obnam.rs b/src/bin/obnam.rs
index cdb5179..c8da6c2 100644
--- a/src/bin/obnam.rs
+++ b/src/bin/obnam.rs
@@ -3,6 +3,7 @@ use log::{debug, error, info, LevelFilter};
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Logger, Root};
use obnam::cmd::backup::Backup;
+use obnam::cmd::chunk::{DecryptChunk, EncryptChunk};
use obnam::cmd::get_chunk::GetChunk;
use obnam::cmd::init::Init;
use obnam::cmd::list::List;
@@ -20,28 +21,24 @@ const APPLICATION: &str = "obnam";
fn main() -> anyhow::Result<()> {
let opt = Opt::from_args();
- let config = load_config_without_passwords(&opt)?;
- setup_logging(&config.config().log)?;
+ 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::Init(x) => x.run(config.config()),
- _ => {
- let config = load_config_with_passwords(&opt)?;
- match opt.cmd {
- Command::Init(_) => panic!("this can't happen"),
- Command::Backup(x) => x.run(&config),
- Command::List(x) => x.run(&config),
- Command::ShowGeneration(x) => x.run(&config),
- Command::ListFiles(x) => x.run(&config),
- Command::Restore(x) => x.run(&config),
- Command::GetChunk(x) => x.run(&config),
- Command::Config(x) => x.run(&config),
- }
- }
+ Command::Init(x) => x.run(&config),
+ Command::Backup(x) => x.run(&config),
+ Command::List(x) => x.run(&config),
+ Command::ShowGeneration(x) => x.run(&config),
+ Command::ListFiles(x) => x.run(&config),
+ Command::Restore(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),
};
if let Err(ref e) = result {
@@ -66,14 +63,6 @@ fn setup_logging(filename: &Path) -> anyhow::Result<()> {
Ok(())
}
-fn load_config_with_passwords(opt: &Opt) -> Result<ClientConfig, anyhow::Error> {
- Ok(ClientConfig::read_with_passwords(&config_filename(opt))?)
-}
-
-fn load_config_without_passwords(opt: &Opt) -> Result<ClientConfig, anyhow::Error> {
- Ok(ClientConfig::read_without_passwords(&config_filename(opt))?)
-}
-
fn config_filename(opt: &Opt) -> PathBuf {
match opt.config {
None => default_config(),
@@ -109,4 +98,6 @@ enum Command {
ShowGeneration(ShowGeneration),
GetChunk(GetChunk),
Config(ShowConfig),
+ EncryptChunk(EncryptChunk),
+ DecryptChunk(DecryptChunk),
}
diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs
index 0479844..22afd6e 100644
--- a/src/cmd/backup.rs
+++ b/src/cmd/backup.rs
@@ -60,7 +60,6 @@ fn initial_backup(
info!("fresh backup without a previous generation");
let newtemp = NamedTempFile::new()?;
let run = InitialBackup::new(config, &client)?;
- let config = config.config();
let mut all_warnings = vec![];
let count = {
let mut new = NascentGeneration::create(newtemp.path())?;
@@ -87,7 +86,6 @@ fn incremental_backup(
info!("incremental backup based on {}", old_ref);
let newtemp = NamedTempFile::new()?;
let mut run = IncrementalBackup::new(config, &client)?;
- let config = config.config();
let mut all_warnings = vec![];
let count = {
let oldtemp = NamedTempFile::new()?;
diff --git a/src/cmd/init.rs b/src/cmd/init.rs
index cb61fba..08060f7 100644
--- a/src/cmd/init.rs
+++ b/src/cmd/init.rs
@@ -1,4 +1,4 @@
-use crate::config::ClientConfigWithoutPasswords;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::passwords::{passwords_filename, Passwords};
use structopt::StructOpt;
@@ -12,11 +12,7 @@ pub struct Init {
}
impl Init {
- pub fn run(&self, config: &ClientConfigWithoutPasswords) -> Result<(), ObnamError> {
- if !config.encrypt {
- panic!("no encryption specified");
- }
-
+ pub fn run(&self, config: &ClientConfig) -> Result<(), ObnamError> {
let passphrase = match &self.insecure_passphrase {
Some(x) => x.to_string(),
None => rpassword::read_password_from_tty(Some(PROMPT)).unwrap(),
diff --git a/src/cmd/show_config.rs b/src/cmd/show_config.rs
index 424e2ed..05e83c1 100644
--- a/src/cmd/show_config.rs
+++ b/src/cmd/show_config.rs
@@ -7,7 +7,7 @@ pub struct ShowConfig {}
impl ShowConfig {
pub fn run(&self, config: &ClientConfig) -> Result<(), ObnamError> {
- println!("{}", serde_json::to_string_pretty(&config.config())?);
+ println!("{}", serde_json::to_string_pretty(config)?);
Ok(())
}
}
diff --git a/src/config.rs b/src/config.rs
index 33e08a2..0d4e9de 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -16,78 +16,22 @@ struct TentativeClientConfig {
chunk_size: Option<usize>,
roots: Vec<PathBuf>,
log: Option<PathBuf>,
- encrypt: Option<bool>,
exclude_cache_tag_directories: Option<bool>,
}
#[derive(Debug, Serialize, Clone)]
-pub enum ClientConfig {
- Plain(ClientConfigWithoutPasswords),
- WithPasswords(ClientConfigWithoutPasswords, Passwords),
-}
-
-impl ClientConfig {
- pub fn read_without_passwords(filename: &Path) -> Result<Self, ClientConfigError> {
- let config = ClientConfigWithoutPasswords::read_config(filename)?;
- Ok(ClientConfig::Plain(config))
- }
-
- pub fn read_with_passwords(filename: &Path) -> Result<Self, ClientConfigError> {
- let config = ClientConfigWithoutPasswords::read_config(filename)?;
- if config.encrypt {
- let passwords = Passwords::load(&passwords_filename(filename))
- .map_err(ClientConfigError::PasswordsMissing)?;
- Ok(ClientConfig::WithPasswords(config, passwords))
- } else {
- Ok(ClientConfig::Plain(config))
- }
- }
-
- pub fn config(&self) -> &ClientConfigWithoutPasswords {
- match self {
- Self::Plain(config) => &config,
- Self::WithPasswords(config, _) => &config,
- }
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-pub struct ClientConfigWithoutPasswords {
+pub struct ClientConfig {
pub filename: PathBuf,
pub server_url: String,
pub verify_tls_cert: bool,
pub chunk_size: usize,
pub roots: Vec<PathBuf>,
pub log: PathBuf,
- pub encrypt: bool,
pub exclude_cache_tag_directories: bool,
}
-#[derive(Debug, thiserror::Error)]
-pub enum ClientConfigError {
- #[error("server_url is empty")]
- ServerUrlIsEmpty,
-
- #[error("No backup roots in config; at least one is needed")]
- NoBackupRoot,
-
- #[error("server URL doesn't use https: {0}")]
- NotHttps(String),
-
- #[error("No passwords are set: you may need to run 'obnam init': {0}")]
- PasswordsMissing(PasswordError),
-
- #[error("failed to read configuration file {0}: {1}")]
- Read(PathBuf, std::io::Error),
-
- #[error("failed to parse configuration file {0} as YAML: {1}")]
- YamlParse(PathBuf, serde_yaml::Error),
-}
-
-pub type ClientConfigResult<T> = Result<T, ClientConfigError>;
-
-impl ClientConfigWithoutPasswords {
- pub fn read_config(filename: &Path) -> ClientConfigResult<Self> {
+impl ClientConfig {
+ pub fn read(filename: &Path) -> ClientConfigResult<Self> {
trace!("read_config: filename={:?}", filename);
let config = std::fs::read_to_string(filename)
.map_err(|err| ClientConfigError::Read(filename.to_path_buf(), err))?;
@@ -102,12 +46,10 @@ impl ClientConfigWithoutPasswords {
.log
.map(|path| expand_tilde(&path))
.unwrap_or_else(|| PathBuf::from(DEVNULL));
- let encrypt = tentative.encrypt.or(Some(false)).unwrap();
let exclude_cache_tag_directories = tentative.exclude_cache_tag_directories.unwrap_or(true);
let config = Self {
chunk_size: tentative.chunk_size.or(Some(DEFAULT_CHUNK_SIZE)).unwrap(),
- encrypt,
filename: filename.to_path_buf(),
roots,
server_url: tentative.server_url,
@@ -132,8 +74,36 @@ impl ClientConfigWithoutPasswords {
}
Ok(())
}
+
+ pub fn passwords(&self) -> Result<Passwords, ClientConfigError> {
+ Passwords::load(&passwords_filename(&self.filename))
+ .map_err(ClientConfigError::PasswordsMissing)
+ }
}
+#[derive(Debug, thiserror::Error)]
+pub enum ClientConfigError {
+ #[error("server_url is empty")]
+ ServerUrlIsEmpty,
+
+ #[error("No backup roots in config; at least one is needed")]
+ NoBackupRoot,
+
+ #[error("server URL doesn't use https: {0}")]
+ NotHttps(String),
+
+ #[error("No passwords are set: you may need to run 'obnam init': {0}")]
+ PasswordsMissing(PasswordError),
+
+ #[error("failed to read configuration file {0}: {1}")]
+ Read(PathBuf, std::io::Error),
+
+ #[error("failed to parse configuration file {0} as YAML: {1}")]
+ YamlParse(PathBuf, serde_yaml::Error),
+}
+
+pub type ClientConfigResult<T> = Result<T, ClientConfigError>;
+
fn expand_tilde(path: &Path) -> PathBuf {
if path.starts_with("~/") {
if let Some(home) = std::env::var_os("HOME") {
diff --git a/subplot/client.py b/subplot/client.py
index be0a6d6..d0beba5 100644
--- a/subplot/client.py
+++ b/subplot/client.py
@@ -16,7 +16,7 @@ def uninstall_obnam(ctx):
runcmd_run(ctx, ["chmod", "-R", "u+rwX", "."])
-def configure_client(ctx, filename=None):
+def configure_client_without_init(ctx, filename=None):
get_file = globals()["get_file"]
assert ctx.get("server_url") is not None
@@ -35,6 +35,15 @@ def configure_client(ctx, filename=None):
yaml.safe_dump(config, stream=f)
+def configure_client_with_init(ctx, filename=None):
+ runcmd_run = globals()["runcmd_run"]
+ runcmd_exit_code_is_zero = globals()["runcmd_exit_code_is_zero"]
+
+ configure_client_without_init(ctx, filename=filename)
+ runcmd_run(ctx, ["obnam", "init", "--insecure-passphrase=hunter2"])
+ runcmd_exit_code_is_zero(ctx)
+
+
def run_obnam_restore(ctx, genid=None, todir=None):
runcmd_run = globals()["runcmd_run"]
diff --git a/subplot/client.yaml b/subplot/client.yaml
index 6de04c9..d660089 100644
--- a/subplot/client.yaml
+++ b/subplot/client.yaml
@@ -3,7 +3,10 @@
cleanup: uninstall_obnam
- given: "a client config based on {filename}"
- function: configure_client
+ function: configure_client_with_init
+
+- given: "a client config, without passphrase, based on {filename}"
+ function: configure_client_without_init
- when: "I invoke obnam restore <{genid}> {todir}"
function: run_obnam_restore