//! 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 { client_config: PathBuf, server_config: PathBuf, tls_key: PathBuf, tls_cert: PathBuf, 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 configs = tempdir()?; let path = configs.path(); let root = tempdir()?; let o = Self { client_config: path.join("client.yaml"), server_config: path.join("server.yaml"), tls_key: path.join("tls.key"), tls_cert: path.join("tls.pem"), root, chunks: tempdir()?, }; o.configure()?; Ok(o) } pub fn root(&self) -> &Path { self.root.path() } fn chunks(&self) -> &Path { self.chunks.path() } fn server_config(&self) -> &Path { &self.server_config } fn tls_key(&self) -> &Path { &self.tls_key } fn tls_cert(&self) -> &Path { &self.tls_cert } fn client_config(&self) -> &Path { &self.client_config } fn configure(&self) -> Result<(), ObnamError> { std::fs::write(self.tls_key(), TLS_KEY.to_vec())?; std::fs::write(self.tls_cert(), TLS_KEY.to_vec())?; ServerConfig::new(SERVER_PORT, self.chunks(), self.tls_key(), self.tls_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(()) } }