From 893b784fced0ce16c1c4808f0565bdf5342d080f Mon Sep 17 00:00:00 2001 From: Lee Smet Date: Tue, 22 Dec 2020 10:43:40 +0100 Subject: [PATCH] Close #11: Add cmd to verify file existence Signed-off-by: Lee Smet --- src/etcd.rs | 17 +++++++++-------- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- src/test_etcd.rs | 2 +- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/etcd.rs b/src/etcd.rs index 55eeda5..e3980be 100644 --- a/src/etcd.rs +++ b/src/etcd.rs @@ -64,15 +64,16 @@ impl Etcd { } /// loads the metadata for a given path and prefix - pub async fn load_meta(&self, path: &PathBuf) -> Result { + pub async fn load_meta(&self, path: &PathBuf) -> Result, String> { let key = self.build_key(path)?; - Ok(toml::from_slice( - &self - .read_value(&key) - .await? - .ok_or("no meta found for path".to_string())?, - ) - .map_err(|e| e.to_string())?) + Ok(if let Some(value) = self.read_value(&key).await? { + Some( + toml::from_slice(&value) + .map_err(|e| format!("could not decode metadata: {}", e))?, + ) + } else { + None + }) } // helper functions to read and write a value diff --git a/src/main.rs b/src/main.rs index 051a111..253cbd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,6 +78,17 @@ enum Cmd { #[structopt(name = "file", long, short, parse(from_os_str))] file: std::path::PathBuf, }, + /// Check if a file exists in the backend + /// + /// Checks if a valid metadata entry is available for the path. If it is, the hex of the file + /// checksum is printed, as well as the resolved path + Check { + /// Path of the file to check. + /// + /// The original path which was used to store the file. + #[structopt(name = "file", long, short, parse(from_os_str))] + file: std::path::PathBuf, + }, } fn main() -> Result<(), String> { @@ -148,7 +159,11 @@ fn main() -> Result<(), String> { cluster.save_meta(&file, &metadata).compat().await?; } Cmd::Retrieve { ref file } => { - let metadata = cluster.load_meta(file).compat().await?; + let metadata = cluster + .load_meta(file) + .compat() + .await? + .ok_or("no metadata found for file")?; let decoded = recover_data(&metadata).await?; let encryptor = AESGCM::new(metadata.encryption().key().clone()); @@ -169,12 +184,36 @@ fn main() -> Result<(), String> { out.write_all(&original).map_err(|e| e.to_string())?; } Cmd::Rebuild { ref file } => { - let metadata = cluster.load_meta(file).compat().await?; + let metadata = cluster + .load_meta(file) + .compat() + .await? + .ok_or("no metadata found for file")?; let decoded = recover_data(&metadata).await?; let metadata = store_data(decoded, metadata.checksum().clone(), &cfg).await?; cluster.save_meta(&file, &metadata).compat().await?; } + Cmd::Check { ref file } => { + match cluster.load_meta(file).compat().await? { + Some(metadata) => { + let file = canonicalize_path(&file)?; + // strip the virtual_root, if one is set + let actual_path = if let Some(ref virtual_root) = cfg.virtual_root() { + file.strip_prefix(virtual_root) + .map_err(|e| format!("could not strip path prefix: {}", e))? + } else { + file.as_path() + }; + println!( + "{}\t{}", + hex::encode(metadata.checksum()), + actual_path.to_string_lossy() + ); + } + None => std::process::exit(1), + }; + } }; Ok(()) diff --git a/src/test_etcd.rs b/src/test_etcd.rs index 04204d9..329c36a 100644 --- a/src/test_etcd.rs +++ b/src/test_etcd.rs @@ -59,7 +59,7 @@ fn main() { let rec = cluster.load_meta(&path).compat().await.unwrap(); log::info!("comparing data"); - assert_eq!(&rec, &data); + assert_eq!(&rec.unwrap(), &data); log::info!("compared data"); }); }