diff --git a/imag-store/Cargo.toml b/imag-store/Cargo.toml index 3a3aa737..27cd787d 100644 --- a/imag-store/Cargo.toml +++ b/imag-store/Cargo.toml @@ -12,6 +12,8 @@ toml = "0.1.25" [dependencies.libimagstore] path = "../libimagstore" +default-features = false +features = ["verify"] [dependencies.libimagrt] path = "../libimagrt" diff --git a/imag-store/src/main.rs b/imag-store/src/main.rs index c2996fc1..56c46241 100644 --- a/imag-store/src/main.rs +++ b/imag-store/src/main.rs @@ -33,6 +33,7 @@ mod get; mod retrieve; mod ui; mod update; +mod verify; mod util; use create::create; @@ -41,6 +42,7 @@ use get::get; use retrieve::retrieve; use ui::build_ui; use update::update; +use verify::verify; fn main() { let rt = generate_runtime_setup("imag-store", @@ -63,6 +65,7 @@ fn main() { "get" => get(&rt), "retrieve" => retrieve(&rt), "update" => update(&rt), + "verify" => verify(&rt), _ => { debug!("Unknown command"); // More error handling diff --git a/imag-store/src/ui.rs b/imag-store/src/ui.rs index 220c8433..a317a445 100644 --- a/imag-store/src/ui.rs +++ b/imag-store/src/ui.rs @@ -181,4 +181,9 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("Remove Store Entry with this path. Root (/) is the store itself") .value_name("PATH")) ) + + .subcommand(SubCommand::with_name("verify") + .about("Verify the store") + .version("0.1") + ) } diff --git a/imag-store/src/verify.rs b/imag-store/src/verify.rs new file mode 100644 index 00000000..ca836e3f --- /dev/null +++ b/imag-store/src/verify.rs @@ -0,0 +1,13 @@ +use std::process::exit; + +use libimagrt::runtime::Runtime; + +pub fn verify(rt: &Runtime) { + if rt.store().verify() { + info!("Store seems to be fine"); + } else { + warn!("Store seems to be broken somehow"); + exit(1); + } +} + diff --git a/libimagstore/Cargo.toml b/libimagstore/Cargo.toml index 050472a0..3f253a68 100644 --- a/libimagstore/Cargo.toml +++ b/libimagstore/Cargo.toml @@ -25,3 +25,7 @@ path = "../libimagutil" tempdir = "0.3.4" env_logger = "0.3" +[features] +default = [] +verify = [] + diff --git a/libimagstore/src/store.rs b/libimagstore/src/store.rs index 9ed41d24..be05710e 100644 --- a/libimagstore/src/store.rs +++ b/libimagstore/src/store.rs @@ -321,6 +321,56 @@ impl Store { self.configuration.as_ref() } + /// Verify the store. + /// + /// This function is not intended to be called by normal programs but only by `imag-store`. + #[cfg(feature = "verify")] + pub fn verify(&self) -> bool { + info!("Header | Content length | Path"); + info!("-------+----------------+-----"); + + WalkDir::new(self.location.clone()) + .into_iter() + .map(|res| { + match res { + Ok(dent) => { + if dent.file_type().is_file() { + match self.get(PathBuf::from(dent.path())) { + Ok(Some(fle)) => { + let p = fle.get_location(); + let content_len = fle.get_content().len(); + let header = if fle.get_header().verify().is_ok() { + "ok" + } else { + "broken" + }; + + info!("{: >6} | {: >14} | {:?}", header, content_len, p.deref()); + }, + + Ok(None) => { + info!("{: >6} | {: >14} | {:?}", "?", "couldn't load", dent.path()); + }, + + Err(e) => { + debug!("{:?}", e); + }, + } + } else { + info!("{: >6} | {: >14} | {:?}", "?", "", dent.path()); + } + }, + + Err(e) => { + debug!("{:?}", e); + }, + } + + true + }) + .all(|b| b) + } + /// Creates the Entry at the given location (inside the entry) pub fn create<'a, S: IntoStoreId>(&'a self, id: S) -> Result> { let id = id.into_storeid().storified(self);