//! Manage and execute Obnam. use lazy_static::lazy_static; use serde::Serialize; use std::path::{Path, PathBuf}; use tempfile::{tempdir, TempDir}; const SERVER_PORT: u16 = 8888; lazy_static! { static ref TLS_KEY: Vec = std::fs::read(concat!(env!("CARGO_MANIFEST_DIR"), "/tls.key")).unwrap(); static ref TLS_CERT: Vec = std::fs::read(concat!(env!("CARGO_MANIFEST_DIR"), "/tls.pem")).unwrap(); } /// An Obnam system. /// /// Manage an Obnam server and run the Obnam client. pub struct Obnam { configs: TempDir, root: TempDir, chunks: TempDir, } /// Possible errors from managing an Obnam system. #[derive(Debug, thiserror::Error)] pub enum ObnamError { /// Error creating a temporary directory. #[error(transparent)] TempDir(#[from] std::io::Error), } impl Obnam { pub fn new() -> Result { let o = Self { configs: tempdir()?, root: tempdir()?, chunks: tempdir()?, }; o.configure()?; Ok(o) } pub fn root(&self) -> &Path { self.root.path() } fn chunks(&self) -> &Path { self.chunks.path() } fn configs(&self) -> &Path { self.configs.path() } fn server_config(&self) -> PathBuf { self.configs().join("server.yaml") } fn tls_key(&self) -> PathBuf { self.configs().join("tls.key") } fn tls_cert(&self) -> PathBuf { self.configs().join("tls.pem") } fn client_config(&self) -> PathBuf { self.configs().join("client.yaml") } fn configure(&self) -> Result<(), ObnamError> { let key = self.tls_key(); let cert = self.tls_cert(); std::fs::write(&key, TLS_KEY.to_vec())?; std::fs::write(&cert, TLS_KEY.to_vec())?; ServerConfig::new(SERVER_PORT, self.chunks(), &key, &cert).write(&self.server_config())?; ClientConfig::new(SERVER_PORT, self.root()).write(&self.client_config())?; Ok(()) } pub fn start_server(&mut self) -> Result<(), ObnamError> { Ok(()) } pub fn stop_server(&mut self) -> Result<(), ObnamError> { Ok(()) } pub fn backup(&mut self) -> Result<(), ObnamError> { Ok(()) } pub fn restore(&mut self) -> Result<(), ObnamError> { Ok(()) } } #[derive(Debug, Serialize)] struct ServerConfig { address: String, chunks: PathBuf, tls_key: PathBuf, tls_cert: PathBuf, } impl ServerConfig { fn new(port: u16, chunks: &Path, tls_key: &Path, tls_cert: &Path) -> Self { Self { address: format!("localhost:{}", port), chunks: chunks.to_path_buf(), tls_key: tls_key.to_path_buf(), tls_cert: tls_cert.to_path_buf(), } } fn write(&self, filename: &Path) -> Result<(), ObnamError> { std::fs::write(filename, serde_yaml::to_string(self).unwrap())?; Ok(()) } } #[derive(Debug, Serialize)] struct ClientConfig { server_url: String, verify_tls_cert: bool, roots: Vec, log: Option, } impl ClientConfig { fn new(port: u16, root: &Path) -> Self { Self { server_url: format!("https://localhost:{}", port), verify_tls_cert: false, roots: vec![root.to_path_buf()], log: None, } } fn write(&self, filename: &Path) -> Result<(), ObnamError> { std::fs::write(filename, serde_yaml::to_string(self).unwrap())?; Ok(()) } }