summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2021-04-10 09:02:27 +0300
committerLars Wirzenius <liw@liw.fi>2021-04-10 10:29:27 +0300
commite13ef6a773755e8eed4d0fb1e55f3bd80a6c5cfd (patch)
tree0ef79cad97789850efc5fcfe8073dd120b8473d7
parentf3ed6ba027dbb410161970c4a706192885d92a3d (diff)
downloadobnam2-e13ef6a773755e8eed4d0fb1e55f3bd80a6c5cfd.tar.gz
refactor: move ClientConfig into its own module
-rw-r--r--src/backup_run.rs3
-rw-r--r--src/bin/obnam.rs2
-rw-r--r--src/client.rs122
-rw-r--r--src/cmd/backup.rs3
-rw-r--r--src/cmd/get_chunk.rs2
-rw-r--r--src/cmd/init.rs2
-rw-r--r--src/cmd/list.rs3
-rw-r--r--src/cmd/list_files.rs2
-rw-r--r--src/cmd/restore.rs2
-rw-r--r--src/cmd/show_config.rs2
-rw-r--r--src/cmd/show_gen.rs2
-rw-r--r--src/config.rs122
-rw-r--r--src/error.rs3
-rw-r--r--src/lib.rs1
14 files changed, 140 insertions, 131 deletions
diff --git a/src/backup_run.rs b/src/backup_run.rs
index e9d094d..e966855 100644
--- a/src/backup_run.rs
+++ b/src/backup_run.rs
@@ -1,7 +1,8 @@
use crate::backup_progress::BackupProgress;
use crate::backup_reason::Reason;
use crate::chunkid::ChunkId;
-use crate::client::{BackupClient, ClientConfig, ClientError};
+use crate::client::{BackupClient, ClientError};
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsentry::FilesystemEntry;
use crate::fsiter::{FsIterError, FsIterResult};
diff --git a/src/bin/obnam.rs b/src/bin/obnam.rs
index bb0cbdb..10048a3 100644
--- a/src/bin/obnam.rs
+++ b/src/bin/obnam.rs
@@ -2,10 +2,10 @@ 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, init, list, list_files, restore, show_config, show_generation,
};
+use obnam::config::ClientConfig;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
diff --git a/src/client.rs b/src/client.rs
index 37bfe91..1b33372 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -4,136 +4,18 @@ use crate::chunk::{GenerationChunk, GenerationChunkError};
use crate::chunker::{Chunker, ChunkerError};
use crate::chunkid::ChunkId;
use crate::chunkmeta::ChunkMeta;
+use crate::config::ClientConfig;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use crate::generation::{FinishedGeneration, LocalGeneration, LocalGenerationError};
use crate::genlist::GenerationList;
-use crate::passwords::{passwords_filename, PasswordError, Passwords};
-use bytesize::MIB;
use chrono::{DateTime, Local};
use log::{debug, error, info, trace};
use reqwest::blocking::Client;
-use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-
-const DEFAULT_CHUNK_SIZE: usize = MIB as usize;
-const DEVNULL: &str = "/dev/null";
-
-#[derive(Debug, Deserialize, Clone)]
-#[serde(deny_unknown_fields)]
-struct TentativeClientConfig {
- server_url: String,
- verify_tls_cert: Option<bool>,
- chunk_size: Option<usize>,
- roots: Vec<PathBuf>,
- log: Option<PathBuf>,
- encrypt: 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 server_url: String,
- pub verify_tls_cert: bool,
- pub chunk_size: usize,
- pub roots: Vec<PathBuf>,
- pub log: PathBuf,
- pub encrypt: 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(transparent)]
- IoError(#[from] std::io::Error),
-
- #[error(transparent)]
- SerdeYamlError(#[from] serde_yaml::Error),
-}
-
-pub type ClientConfigResult<T> = Result<T, ClientConfigError>;
-
-impl ClientConfigWithoutPasswords {
- pub fn read_config(filename: &Path) -> ClientConfigResult<Self> {
- trace!("read_config: filename={:?}", filename);
- let config = std::fs::read_to_string(filename)?;
- let tentative: TentativeClientConfig = serde_yaml::from_str(&config)?;
-
- let encrypt = tentative.encrypt.or(Some(false)).unwrap();
-
- let config = Self {
- server_url: tentative.server_url,
- roots: tentative.roots,
- verify_tls_cert: tentative.verify_tls_cert.or(Some(false)).unwrap(),
- chunk_size: tentative.chunk_size.or(Some(DEFAULT_CHUNK_SIZE)).unwrap(),
- log: tentative
- .log
- .or_else(|| Some(PathBuf::from(DEVNULL)))
- .unwrap(),
- encrypt,
- };
-
- config.check()?;
- Ok(config)
- }
-
- fn check(&self) -> Result<(), ClientConfigError> {
- if self.server_url.is_empty() {
- return Err(ClientConfigError::ServerUrlIsEmpty);
- }
- if !self.server_url.starts_with("https://") {
- return Err(ClientConfigError::NotHttps(self.server_url.to_string()));
- }
- if self.roots.is_empty() {
- return Err(ClientConfigError::NoBackupRoot);
- }
- Ok(())
- }
-}
+use std::path::Path;
#[derive(Debug, thiserror::Error)]
pub enum ClientError {
diff --git a/src/cmd/backup.rs b/src/cmd/backup.rs
index bd36a3a..1091241 100644
--- a/src/cmd/backup.rs
+++ b/src/cmd/backup.rs
@@ -1,7 +1,8 @@
use crate::backup_progress::BackupProgress;
use crate::backup_run::{BackupError, IncrementalBackup, InitialBackup};
use crate::chunkid::ChunkId;
-use crate::client::{BackupClient, ClientConfig};
+use crate::client::BackupClient;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsiter::FsIterator;
use crate::generation::NascentGeneration;
diff --git a/src/cmd/get_chunk.rs b/src/cmd/get_chunk.rs
index 385c4d5..c9d640e 100644
--- a/src/cmd/get_chunk.rs
+++ b/src/cmd/get_chunk.rs
@@ -1,6 +1,6 @@
use crate::chunkid::ChunkId;
use crate::client::BackupClient;
-use crate::client::ClientConfig;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use std::io::{stdout, Write};
diff --git a/src/cmd/init.rs b/src/cmd/init.rs
index f0ddb69..fb8a6af 100644
--- a/src/cmd/init.rs
+++ b/src/cmd/init.rs
@@ -1,4 +1,4 @@
-use crate::client::ClientConfigWithoutPasswords;
+use crate::config::ClientConfigWithoutPasswords;
use crate::error::ObnamError;
use crate::passwords::{passwords_filename, Passwords};
use std::path::Path;
diff --git a/src/cmd/list.rs b/src/cmd/list.rs
index a3f059b..f48512b 100644
--- a/src/cmd/list.rs
+++ b/src/cmd/list.rs
@@ -1,4 +1,5 @@
-use crate::client::{BackupClient, ClientConfig};
+use crate::client::BackupClient;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
pub fn list(config: &ClientConfig) -> Result<(), ObnamError> {
diff --git a/src/cmd/list_files.rs b/src/cmd/list_files.rs
index 71b0d68..d490e85 100644
--- a/src/cmd/list_files.rs
+++ b/src/cmd/list_files.rs
@@ -1,6 +1,6 @@
use crate::backup_reason::Reason;
use crate::client::BackupClient;
-use crate::client::ClientConfig;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use tempfile::NamedTempFile;
diff --git a/src/cmd/restore.rs b/src/cmd/restore.rs
index 183f207..c2cbb7f 100644
--- a/src/cmd/restore.rs
+++ b/src/cmd/restore.rs
@@ -1,6 +1,6 @@
use crate::backup_reason::Reason;
-use crate::client::ClientConfig;
use crate::client::{BackupClient, ClientError};
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsentry::{FilesystemEntry, FilesystemKind};
use crate::generation::{LocalGeneration, LocalGenerationError};
diff --git a/src/cmd/show_config.rs b/src/cmd/show_config.rs
index 8acd1c8..88ee9ec 100644
--- a/src/cmd/show_config.rs
+++ b/src/cmd/show_config.rs
@@ -1,4 +1,4 @@
-use crate::client::ClientConfig;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
pub fn show_config(config: &ClientConfig) -> Result<(), ObnamError> {
diff --git a/src/cmd/show_gen.rs b/src/cmd/show_gen.rs
index 143aed6..5b786cf 100644
--- a/src/cmd/show_gen.rs
+++ b/src/cmd/show_gen.rs
@@ -1,5 +1,5 @@
use crate::client::BackupClient;
-use crate::client::ClientConfig;
+use crate::config::ClientConfig;
use crate::error::ObnamError;
use crate::fsentry::FilesystemKind;
use indicatif::HumanBytes;
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..41ddcd6
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,122 @@
+use crate::passwords::{passwords_filename, PasswordError, Passwords};
+
+use bytesize::MIB;
+use log::{error, trace};
+use serde::{Deserialize, Serialize};
+use std::path::{Path, PathBuf};
+
+const DEFAULT_CHUNK_SIZE: usize = MIB as usize;
+const DEVNULL: &str = "/dev/null";
+
+#[derive(Debug, Deserialize, Clone)]
+#[serde(deny_unknown_fields)]
+struct TentativeClientConfig {
+ server_url: String,
+ verify_tls_cert: Option<bool>,
+ chunk_size: Option<usize>,
+ roots: Vec<PathBuf>,
+ log: Option<PathBuf>,
+ encrypt: 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 server_url: String,
+ pub verify_tls_cert: bool,
+ pub chunk_size: usize,
+ pub roots: Vec<PathBuf>,
+ pub log: PathBuf,
+ pub encrypt: 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(transparent)]
+ IoError(#[from] std::io::Error),
+
+ #[error(transparent)]
+ SerdeYamlError(#[from] serde_yaml::Error),
+}
+
+pub type ClientConfigResult<T> = Result<T, ClientConfigError>;
+
+impl ClientConfigWithoutPasswords {
+ pub fn read_config(filename: &Path) -> ClientConfigResult<Self> {
+ trace!("read_config: filename={:?}", filename);
+ let config = std::fs::read_to_string(filename)?;
+ let tentative: TentativeClientConfig = serde_yaml::from_str(&config)?;
+
+ let encrypt = tentative.encrypt.or(Some(false)).unwrap();
+
+ let config = Self {
+ server_url: tentative.server_url,
+ roots: tentative.roots,
+ verify_tls_cert: tentative.verify_tls_cert.or(Some(false)).unwrap(),
+ chunk_size: tentative.chunk_size.or(Some(DEFAULT_CHUNK_SIZE)).unwrap(),
+ log: tentative
+ .log
+ .or_else(|| Some(PathBuf::from(DEVNULL)))
+ .unwrap(),
+ encrypt,
+ };
+
+ config.check()?;
+ Ok(config)
+ }
+
+ fn check(&self) -> Result<(), ClientConfigError> {
+ if self.server_url.is_empty() {
+ return Err(ClientConfigError::ServerUrlIsEmpty);
+ }
+ if !self.server_url.starts_with("https://") {
+ return Err(ClientConfigError::NotHttps(self.server_url.to_string()));
+ }
+ if self.roots.is_empty() {
+ return Err(ClientConfigError::NoBackupRoot);
+ }
+ Ok(())
+ }
+}
diff --git a/src/error.rs b/src/error.rs
index 454bba6..8241d5d 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,6 +1,7 @@
use crate::backup_run::BackupError;
-use crate::client::{ClientConfigError, ClientError};
+use crate::client::ClientError;
use crate::cmd::restore::RestoreError;
+use crate::config::ClientConfigError;
use crate::generation::{LocalGenerationError, NascentError};
use crate::genlist::GenerationListError;
use crate::passwords::PasswordError;
diff --git a/src/lib.rs b/src/lib.rs
index fb4c7fe..82dab15 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,6 +9,7 @@ pub mod chunkid;
pub mod chunkmeta;
pub mod client;
pub mod cmd;
+pub mod config;
pub mod error;
pub mod fsentry;
pub mod fsiter;