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(())
+}

Reply via email to