This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 6d3b4a2986 feat(ofs): introduce ofs execute bin (#4033)
6d3b4a2986 is described below
commit 6d3b4a2986ddf4e8d1ab8dbe9e1bec62ec96826c
Author: Jun Ouyang <[email protected]>
AuthorDate: Sun Jan 21 00:54:11 2024 +0800
feat(ofs): introduce ofs execute bin (#4033)
* feat(ofs): introduce ofs execute bin
* feat(ofs): fix code
* feat(ofs): fix code
* feat(ofs): fix code
* feat(ofs): fix code
* feat(ofs): fix code
* feat(ofs): fix code
---
Cargo.lock | 46 ++++++++++++++++++++++------
bin/ofs/Cargo.toml | 13 +++++++-
bin/ofs/src/bin/ofs.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 132 insertions(+), 10 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index c4d7e82eed..0381b429dd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -79,9 +79,9 @@ checksum =
"4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
-version = "0.6.4"
+version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
+checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -1372,9 +1372,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.4.8"
+version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
+checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1382,9 +1382,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.4.8"
+version = "4.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
+checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
dependencies = [
"anstream",
"anstyle",
@@ -1706,7 +1706,7 @@ dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
- "memoffset",
+ "memoffset 0.9.0",
"scopeguard",
]
@@ -2665,11 +2665,12 @@ dependencies = [
"futures-channel",
"futures-util",
"libc",
- "nix",
+ "nix 0.26.4",
"serde",
"slab",
"tokio",
"tracing",
+ "which",
]
[[package]]
@@ -3928,6 +3929,15 @@ dependencies = [
"libc",
]
+[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
[[package]]
name = "memoffset"
version = "0.9.0"
@@ -4379,6 +4389,18 @@ dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
+ "memoffset 0.7.1",
+]
+
+[[package]]
+name = "nix"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
+dependencies = [
+ "bitflags 2.4.1",
+ "cfg-if",
+ "libc",
]
[[package]]
@@ -4572,12 +4594,18 @@ dependencies = [
name = "ofs"
version = "0.0.1"
dependencies = [
+ "anyhow",
"async-trait",
+ "clap",
+ "env_logger",
"fuse3",
"futures-util",
"libc",
"log",
+ "nix 0.27.1",
"opendal",
+ "tokio",
+ "url",
]
[[package]]
@@ -5652,7 +5680,7 @@ dependencies = [
"cfg-if",
"indoc",
"libc",
- "memoffset",
+ "memoffset 0.9.0",
"parking_lot 0.12.1",
"pyo3-build-config",
"pyo3-ffi",
diff --git a/bin/ofs/Cargo.toml b/bin/ofs/Cargo.toml
index 1829f07882..860904d7ce 100644
--- a/bin/ofs/Cargo.toml
+++ b/bin/ofs/Cargo.toml
@@ -31,8 +31,19 @@ rust-version.workspace = true
[dependencies]
async-trait = "0.1.75"
-fuse3 = { "version" = "0.6.1", "features" = ["tokio-runtime"] }
+fuse3 = { "version" = "0.6.1", "features" = ["tokio-runtime", "unprivileged"] }
futures-util = "0.3.30"
libc = "0.2.151"
log = "0.4.20"
+anyhow = "1"
+tokio = { version = "1.34", features = [
+ "fs",
+ "macros",
+ "rt-multi-thread",
+ "io-std",
+] }
+nix = { version = "0.27.1", features = ["user"] }
+env_logger = "0.10"
+clap = { version = "4.4.18", features = ["derive", "env"] }
+url = "2.5.0"
opendal.workspace = true
diff --git a/bin/ofs/src/bin/ofs.rs b/bin/ofs/src/bin/ofs.rs
new file mode 100644
index 0000000000..08399b56ef
--- /dev/null
+++ b/bin/ofs/src/bin/ofs.rs
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::collections::HashMap;
+use std::str::FromStr;
+
+use anyhow::anyhow;
+use anyhow::Context;
+use anyhow::Result;
+use clap::Parser;
+use fuse3::path::Session;
+use fuse3::MountOptions;
+use ofs::Ofs;
+use opendal::Operator;
+use opendal::Scheme;
+use url::Url;
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ env_logger::init();
+ fuse().await
+}
+
+#[derive(Parser, Debug)]
+#[command(version, about)]
+struct Config {
+ /// fuse mount path
+ #[arg(env = "OFS_MOUNT_PATH", index = 1)]
+ mount_path: String,
+
+ /// location of opendal service
+ /// format: <scheme>://?<key>=<value>&<key>=<value>
+ /// example: fs://root=/tmp
+ #[arg(env = "OFS_BACKEND", index = 2)]
+ backend: String,
+}
+
+async fn fuse() -> Result<()> {
+ let cfg = Config::try_parse().context("parse command line arguments")?;
+
+ let location = Url::parse(&cfg.backend)?;
+ if location.has_host() {
+ Err(anyhow!("Host part in a location is not supported."))?;
+ }
+
+ let scheme_str = location.scheme();
+
+ let op_args = location
+ .query_pairs()
+ .into_owned()
+ .collect::<HashMap<String, String>>();
+
+ let scheme = Scheme::from_str(scheme_str).context("unsupported scheme")?;
+ let op = Operator::via_map(scheme, op_args)?;
+
+ let mut mount_option = MountOptions::default();
+ mount_option.uid(nix::unistd::getuid().into());
+ mount_option.gid(nix::unistd::getgid().into());
+
+ let ofs = Ofs { op };
+
+ let mounthandle = Session::new(mount_option)
+ .mount_with_unprivileged(ofs, cfg.mount_path)
+ .await?;
+
+ mounthandle.await?;
+
+ Ok(())
+}