diff --git a/src/fs/mod.rs b/src/fs/mod.rs index 0c75580..9a505aa 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -17,7 +17,7 @@ use polyfuse::{ }; use std::io::SeekFrom; use std::sync::Arc; -use std::{io, os::unix::prelude::*, path::PathBuf, time::Duration}; +use std::{io, path::PathBuf, time::Duration}; use tokio::fs::File; use tokio::sync::Mutex; use tokio::{ @@ -120,11 +120,11 @@ where } if let Some(target) = link.data { - req.reply(target); + req.reply(target)?; return Ok(()); } - return Ok(req.reply_error(libc::ENOLINK)?); + Ok(req.reply_error(libc::ENOLINK)?) } async fn read(&self, req: &Request, op: op::Read<'_>) -> Result<()> { @@ -310,7 +310,7 @@ where out.ttl_attr(TTL); out.ttl_entry(TTL); - return Ok(req.reply(out)?); + Ok(req.reply(out)?) } } @@ -358,8 +358,6 @@ trait AttributeFiller { impl AttributeFiller for Inode { fn fill(&self, attr: &mut FileAttr) { - use std::time::Duration; - attr.mode(self.mode.mode()); attr.ino(self.ino); diff --git a/src/main.rs b/src/main.rs index b5eef90..6fa7bfe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,15 +16,6 @@ mod fs; #[derive(Parser, Debug)] #[clap(name ="rfs", author, version = env!("GIT_VERSION"), about, long_about = None)] struct Options { - /// storage-url is a url to the backend where the data is stored - /// this is a backup url to fall back to for backward compatability. - /// In newered flists, this information is already included int he flist - #[clap( - short, - long = "storage-url", - default_value_t = String::from("redis://hub.grid.tf:9900") - )] - storage_url: String, /// path to metadata file (flist) #[clap(short, long)] meta: String, @@ -142,25 +133,17 @@ async fn app(opts: Options) -> Result<()> { .await .context("failed to initialize metadata database")?; - //let store = store::Router::new(); - let store = store::zdb::make(&opts.storage_url).await?; + let mut router = store::Router::new(); - let cache = cache::Cache::new(opts.cache, store); - - //TODO: print tags - - // match mgr.tags().await { - // Ok(tags) => { - // debug!("flist has {} tags", tags.len()); - // for (k, v) in tags.iter() { - // debug!("[tag][{}]: {}", k, v); - // } - // } - // Err(err) => { - // error!("failed to extract flist tags: {}", err); - // } - // } + for route in meta.routes().await.context("failed to get store routes")? { + let store = store::make(&route.url) + .await + .with_context(|| format!("failed to initialize store '{}'", route.url))?; + router.add(route.start, route.end, store); + } + let cache = cache::Cache::new(opts.cache, router); let filesystem = fs::Filesystem::new(meta, cache); + filesystem.mount(opts.target).await } diff --git a/src/store/mod.rs b/src/store/mod.rs index ad5ce8e..2dbae50 100644 --- a/src/store/mod.rs +++ b/src/store/mod.rs @@ -9,7 +9,7 @@ pub use bs::BlockStore; use futures::Future; lazy_static::lazy_static! { - pub static ref STORES: HashMap = register_stores(); + static ref STORES: HashMap = register_stores(); } /// register_stores is used to register the stores built in types @@ -22,6 +22,16 @@ fn register_stores() -> HashMap { m } +pub async fn make>(u: U) -> Result> { + let parsed = url::Url::parse(u.as_ref())?; + let factory = match STORES.get(parsed.scheme()) { + None => return Err(Error::UnknownStore(parsed.scheme().into())), + Some(factory) => factory, + }; + + factory(u.as_ref()).await +} + #[derive(thiserror::Error, Debug)] pub enum Error { #[error("key not found")] @@ -50,6 +60,8 @@ pub enum Error { #[error("url parse error: {0}")] Url(#[from] url::ParseError), + #[error("unknown store type '{0}'")] + UnknownStore(String), #[error("invalid schema '{0}' expected '{1}'")] InvalidScheme(String, String), #[error("other: {0}")]