Skip to content

Commit ec38edd

Browse files
[slayerfs]: Improve overall demo functionality (#226)
* [slayerfs]: Improve overall demo functionality Signed-off-by: Luxian <[email protected]> * fix buck2 migrate Signed-off-by: Luxian <[email protected]> * fix fmt and typo Signed-off-by: Luxian <[email protected]> --------- Signed-off-by: Luxian <[email protected]>
1 parent 425bc13 commit ec38edd

File tree

428 files changed

+813
-466
lines changed
  • project
  • third-party/rust/crates
    • ahash/0.7.8
    • aho-corasick/1.1.3
    • allocator-api2/0.2.21
    • anstyle-parse/0.2.7
    • anstyle-query/1.1.4
    • anstyle-wincon/3.0.10
    • anyhow/1.0.100
    • async-channel
    • async-executor/1.13.3
    • async-global-executor/2.4.1
    • async-io
    • async-lock
    • async-notify/0.3.0
    • async-process/1.8.1
    • async-signal/0.2.13
    • async-std/1.13.2
    • async-stream-impl/0.3.6
    • async-stream/0.3.6
    • async-task/4.7.1
    • async-trait/0.1.89
    • atomic-waker/1.1.2
    • aws-config/1.8.8
    • aws-credential-types/1.2.8
    • aws-lc-rs/1.14.1
    • aws-lc-sys/0.32.2
    • aws-runtime/1.5.12
    • aws-sdk-s3/1.108.0
    • aws-sdk-ssooidc/1.88.0
    • aws-sdk-sso/1.86.0
    • aws-sdk-sts/1.88.0
    • aws-sigv4/1.3.5
    • aws-smithy-async/1.2.6
    • aws-smithy-checksums/0.63.9
    • aws-smithy-eventstream/0.60.12
    • aws-smithy-http-client/1.1.3
    • aws-smithy-http/0.62.4
    • aws-smithy-json/0.61.6
    • aws-smithy-observability/0.1.4
    • aws-smithy-query/0.60.8
    • aws-smithy-runtime-api/1.9.1
    • aws-smithy-runtime/1.9.3
    • aws-smithy-types/1.3.3
    • aws-smithy-xml/0.60.11
    • aws-types/1.3.9
    • axum-core/0.5.5
    • axum-extra/0.10.3
    • base64-simd/0.8.0
    • bigdecimal/0.4.8
    • bindgen/0.72.1
    • block-buffer/0.10.4
    • borsh-derive/1.5.7
    • borsh/1.5.7
    • bytecheck/0.6.12
    • byteorder-lite/0.1.0
    • bytes-utils/0.1.4
    • cfg-if/1.0.3
    • clang-sys/1.8.1
    • cni-plugin/0.2.1
    • comfy-table/7.2.1
    • concurrent-queue/2.5.0
    • const-oid/0.9.6
    • context/3.0.0
    • core-foundation-sys/0.8.7
    • core-foundation
    • crc-catalog/2.4.0
    • crc-fast/1.3.0
    • crc32fast/1.5.0
    • critical-section/1.2.0
    • crossbeam-channel/0.5.15
    • crossbeam-deque/0.8.6
    • crossbeam-epoch/0.9.18
    • crossbeam-queue/0.3.12
    • crossbeam-utils/0.8.21
    • crypto-bigint
    • crypto-common/0.1.6
    • data-encoding/2.9.0
    • derive_more-impl/2.0.1
    • dirs-sys/0.5.0
    • doc-comment/0.3.3
    • dockerfile-parser/0.9.0
    • document-features/0.2.11
    • dotenv/0.15.0
    • dyn-clone/1.0.20
    • elliptic-curve/0.12.3
    • endian-type/0.1.2
    • enum-as-inner/0.6.1
    • erased-serde/0.4.8
    • etcd-client
    • event-listener-strategy/0.5.4
    • event-listener
    • find-msvc-tools/0.1.4
    • foreign-types-shared/0.1.1
    • foreign-types/0.3.2
    • futures-channel/0.3.31
    • futures-core/0.3.31
    • futures-executor/0.3.31
    • futures-intrusive/0.5.0
    • futures-io/0.3.31
    • futures-lite
    • futures-macro/0.3.31
    • futures-sink/0.3.31
    • futures-task/0.3.31
    • futures-util/0.3.31
    • generic-array/0.14.7
    • getrandom/0.3.3
    • gloo-timers/0.3.0
    • headers-core/0.3.0
    • hermit-abi
    • hickory-proto/0.25.2
    • hickory-resolver/0.25.2
    • hickory-server/0.25.2
    • http-auth/0.1.10
    • http-body-util/0.1.3
    • http-body
    • httparse/1.10.1
    • hyper-rustls
    • hyper-timeout/0.5.2
    • hyper-tls/0.6.0
    • hyper-util/0.1.17
    • iana-time-zone-haiku/0.1.2
    • iana-time-zone/0.1.64
    • icu_normalizer_data/2.0.0
    • icu_properties_data/2.0.1
    • indexmap/1.9.3
    • io-lifetimes/1.0.11
    • io-uring/0.7.10
    • ipc-channel/0.20.2
    • ipconfig/0.3.2
    • iri-string/0.7.8
    • is-terminal/0.4.16
    • iterator-ext/0.2.1
    • jiff-static/0.2.15
    • jni-sys/0.3.0
    • js-sys/0.3.81
    • kv-log-macro/1.0.7
    • libc/0.2.177
    • libm/0.2.15
    • liboci-cli/0.5.5
    • libseccomp-sys/0.2.1
    • libseccomp/0.3.0
    • libsqlite3-sys/0.30.1
    • libz-rs-sys/0.5.1
    • linux-raw-sys
    • lru-slab/0.1.2
    • md-5/0.10.6
    • memoffset/0.9.1
    • minimal-lexical/0.2.1
    • mockall_derive/0.13.1
    • moka/0.12.11
    • native-tls/0.2.14
    • nc/0.9.6
    • nix
    • ntapi/0.4.1
    • nu-ansi-term/0.50.3
    • num-bigint-dig/0.8.4
    • num-bigint/0.4.6
    • num-conv/0.1.0
    • num-integer/0.1.46
    • num-iter/0.1.45
    • num-traits/0.2.19
    • object/0.37.3
    • oci-client/0.15.0
    • oci-spec/0.8.3
    • olpc-cjson/0.1.4
    • openssl-macros/0.1.1
    • openssl-probe/0.1.6
    • openssl-sys/0.9.109
    • openssl/0.10.73
    • option-ext/0.2.0
    • ordered-float/4.6.0
    • parking_lot_core/0.9.12
    • paste/1.0.15
    • pem-rfc7468/0.7.0
    • percent-encoding/2.3.2
    • pin-project-internal/1.1.10
    • pin-project-lite/0.2.16
    • pin-project/1.1.10
    • pin-utils/0.1.0
    • pkg-config/0.3.32
    • polling/2.8.0
    • portable-atomic-util/0.2.4
    • portable-atomic/1.11.1
    • ppv-lite86/0.2.21
    • predicates-core/1.0.9
    • predicates-tree/1.0.12
    • prefix-trie/0.7.0
    • prettyplease/0.2.37
    • proc-macro-crate/3.4.0
    • proc-macro-error-attr2/2.0.0
    • proc-macro-error2/2.0.1
    • proc-macro2-diagnostics/0.10.1
    • proc-macro2/1.0.101
    • procfs-core/0.17.0
    • procfs/0.17.0
    • prost-build
    • prost-derive
    • prost-types
    • protobuf-codegen/3.2.0
    • protobuf-parse/3.2.0
    • protobuf-support/3.2.0
    • protobuf/3.2.0
    • pulldown-cmark-to-cmark/21.0.0
    • pulldown-cmark/0.13.0
    • quinn-proto/0.11.13
    • quinn-udp/0.5.14
    • quinn/0.11.9
    • quote/1.0.41
    • r-efi/5.3.0
    • radium/0.7.0
    • rayon-core/1.13.0
    • redox_syscall/0.5.18
    • ref-cast-impl/1.0.25
    • ref-cast/1.0.25
    • regex-automata/0.4.12
    • regex-lite/0.1.8
    • regex-syntax/0.8.7
    • rend/0.4.2
    • resolv-conf/0.7.5
    • ring/0.17.14
    • rkyv/0.7.45
    • rust-criu/0.4.0
    • rust_decimal/1.38.0
    • rustc-demangle/0.1.26
    • rustc-hash/2.1.1
    • rustix
    • rustls-native-certs
    • rustls-pemfile/1.0.4
    • rustls-pki-types/1.12.0
    • rustls-platform-verifier-android/0.1.1
    • rustls-platform-verifier/0.6.1
    • rustls-webpki
    • rustls
    • rustversion/1.0.22
    • safe-path/0.1.0
    • same-file/1.0.6
    • sea-bae/0.2.1
    • sea-orm-macros/1.1.17
    • sea-orm/1.1.17
    • sea-query-binder/0.7.0
    • sea-query/0.32.7
    • security-framework-sys/2.15.0
    • security-framework
    • semver-parser/0.10.3
    • serde_core/1.0.228
    • serde_json/1.0.145
    • serde/1.0.228
    • sharded-slab/0.1.7
    • signal-hook-registry/1.4.6
    • simd-adler32/0.3.7
    • snafu-derive/0.6.10
    • sqlx-core/0.8.6
    • sqlx-macros-core/0.8.6
    • sqlx-macros/0.8.6
    • sqlx-mysql/0.8.6
    • sqlx-postgres/0.8.6
    • sqlx-sqlite/0.8.6
    • syn/1.0.109
    • system-configuration-sys/0.6.0
    • system-configuration/0.6.1
    • thiserror-impl
    • thiserror
    • time-core/0.1.6
    • time-macros/0.2.24
    • tokio-macros/2.5.0
    • tokio-native-tls/0.3.1
    • tokio-rustls
    • tokio-stream/0.1.17
    • tokio-util/0.7.16
    • tonic-build
    • tonic-prost-build/0.14.2
    • tonic-prost/0.14.2
    • tower-http/0.6.6
    • tower-layer/0.3.3
    • tower-service/0.3.3
    • tracing-attributes/0.1.30
    • tracing-core/0.1.34
    • tracing-journald/0.3.1
    • tracing-log/0.2.0
    • tracing-serde/0.2.0
    • tracing-subscriber/0.3.20
    • trait-make/0.1.0
    • try-lock/0.2.5
    • typeid/1.0.3
    • typenum/1.19.0
    • typetag-impl/0.2.21
    • typetag/0.2.21
    • ucd-trie/0.1.7
    • unicode-bidi/0.3.18
    • unicode-ident/1.0.19
    • unicode-normalization/0.1.24
    • unicode-properties/0.1.3
    • unicode-segmentation/1.12.0
    • unicode-width/0.2.2
    • unicode-xid/0.2.6
    • unit-prefix/0.5.1
    • unsafe-libyaml/0.2.11
    • uuid-macro-internal/1.18.1
    • valuable/0.1.1
    • value-bag/1.11.1
    • vm-memory/0.16.2
    • vmm-sys-util/0.12.1
    • waker-fn/1.2.0
    • wasm-bindgen-backend/0.2.104
    • wasm-bindgen-futures/0.4.54
    • wasm-bindgen-macro-support/0.2.104
    • wasm-bindgen-macro/0.2.104
    • wasm-bindgen-shared/0.2.104
    • wasm-bindgen/0.2.104
    • wasm-streams/0.4.2
    • web-sys/0.3.81
    • web-time/1.1.0
    • webpki-root-certs/1.0.3
    • webpki-roots
    • winapi-i686-pc-windows-gnu/0.4.0
    • winapi-util/0.1.11
    • winapi-x86_64-pc-windows-gnu/0.4.0
    • winapi/0.3.9
    • windows-collections/0.2.0
    • windows-core
    • windows-future/0.2.1
    • windows-implement/0.60.2
    • windows-interface/0.59.3
    • windows-numerics/0.2.0
    • windows-registry/0.5.3
    • windows-result
    • windows-strings
    • windows-sys
    • windows-targets
    • windows-threading/0.1.0
    • windows_aarch64_gnullvm
    • windows_aarch64_msvc
    • windows_i686_gnullvm
    • windows_i686_gnu
    • windows_i686_msvc
    • windows_x86_64_gnullvm
    • windows_x86_64_gnu
    • windows_x86_64_msvc
    • wit-bindgen/0.46.0
    • yoke-derive/0.8.0
    • zerocopy-derive/0.8.27
    • zerocopy/0.8.27
    • zerofrom-derive/0.1.6
    • zerovec-derive/0.11.1
    • zlib-rs/0.5.1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

428 files changed

+813
-466
lines changed

project/Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

project/libfuse-fs/BUCK

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ filegroup(
1212
cargo.rust_library(
1313
name = "libfuse_fs",
1414
srcs = [":libfuse-fs-vendor"],
15-
crate = "libfuse-fs",
15+
crate = "libfuse_fs",
1616
crate_root = "vendor/src/lib.rs",
1717
edition = "2024",
1818
env = {

project/slayerfs/.env

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# AWS S3 Configuration
2+
AWS_ACCESS_KEY_ID=rustfsadmin
3+
AWS_SECRET_ACCESS_KEY=rustfsadmin
4+
AWS_REGION=us-east-1
5+
AWS_DEFAULT_REGION=us-east-1
6+
AWS_ALLOW_HTTP=true
7+
AWS_EC2_METADATA_DISABLED=true
8+
9+
# S3 Endpoint Configuration
10+
S3_ENDPOINT=http://127.0.0.1:9000
11+
S3_BUCKET=slayerfs
12+
S3_FORCE_PATH_STYLE=true
13+
14+
# Note: Before running the demo, make sure to:
15+
# 1. Start MinIO server: docker run -p 9000:9000 -p 9001:9001 minio/minio server /data --console-address ":9001"
16+
# 2. Create bucket using MinIO client or web console at http://localhost:9001
17+
# 3. Or use AWS CLI: aws --endpoint-url http://localhost:9000 s3 mb s3://slayerfs

project/slayerfs/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
slayerfs-meta/

project/slayerfs/BUCK

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@ cargo.rust_binary(
4141
"//third-party/rust/crates/chrono/0.4.42:chrono",
4242
"//third-party/rust/crates/clap/4.5.48:clap",
4343
"//third-party/rust/crates/dirs/6.0.0:dirs",
44+
"//third-party/rust/crates/dotenv/0.15.0:dotenv",
4445
"//third-party/rust/crates/env_logger/0.10.2:env_logger",
4546
"//third-party/rust/crates/etcd-client/0.17.0:etcd-client",
4647
"//third-party/rust/crates/futures-util/0.3.31:futures-util",
4748
"//third-party/rust/crates/futures/0.3.31:futures",
4849
"//third-party/rust/crates/hex/0.4.3:hex",
50+
"//third-party/rust/crates/http/1.3.1:http",
4951
"//third-party/rust/crates/libc/0.2.177:libc",
5052
"//third-party/rust/crates/log/0.4.28:log",
5153
"//third-party/rust/crates/md5/0.7.0:md5",
@@ -95,11 +97,13 @@ cargo.rust_library(
9597
"//third-party/rust/crates/chrono/0.4.42:chrono",
9698
"//third-party/rust/crates/clap/4.5.48:clap",
9799
"//third-party/rust/crates/dirs/6.0.0:dirs",
100+
"//third-party/rust/crates/dotenv/0.15.0:dotenv",
98101
"//third-party/rust/crates/env_logger/0.10.2:env_logger",
99102
"//third-party/rust/crates/etcd-client/0.17.0:etcd-client",
100103
"//third-party/rust/crates/futures-util/0.3.31:futures-util",
101104
"//third-party/rust/crates/futures/0.3.31:futures",
102105
"//third-party/rust/crates/hex/0.4.3:hex",
106+
"//third-party/rust/crates/http/1.3.1:http",
103107
"//third-party/rust/crates/libc/0.2.177:libc",
104108
"//third-party/rust/crates/log/0.4.28:log",
105109
"//third-party/rust/crates/md5/0.7.0:md5",

project/slayerfs/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ aws-config = { version = "1" }
1313
aws-sdk-s3 = { version = "1", features = ["behavior-version-latest"] }
1414
base64 = "0.21"
1515
md5 = "0.7"
16+
http = "1"
1617
futures = "0.3"
1718
rfuse3 = { version = "0.0.3", features = ["tokio-runtime","unprivileged"]}
1819
futures-util = "0.3.31"
@@ -37,6 +38,7 @@ bitflags = "1.3"
3738
auto_impl = "1.3.0"
3839
tracing = "0.1.41"
3940
tracing-subscriber = "0.3.20"
41+
dotenv = "0.15"
4042

4143
[dev-dependencies]
4244
tempfile = "3"

project/slayerfs/dep

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fuse3
2+
protobuf-compiler
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
use clap::Parser;
2+
use dotenv;
3+
use slayerfs::cadapter::client::ObjectClient;
4+
use slayerfs::cadapter::s3::{S3Backend, S3Config};
5+
use slayerfs::chuck::chunk::ChunkLayout;
6+
use slayerfs::chuck::store::ObjectBlockStore;
7+
use slayerfs::fuse::mount::mount_vfs_unprivileged;
8+
use slayerfs::vfs::fs::VFS;
9+
use std::path::PathBuf;
10+
use tokio::signal;
11+
12+
#[derive(Parser)]
13+
#[command(author, version, about, long_about = None)]
14+
struct Args {
15+
/// Configuration file path (e.g. slayerfs-sqlite.yml, slayerfs-etcd.yml)
16+
#[arg(short, long, default_value = "./slayerfs-sqlite.yml")]
17+
config: PathBuf,
18+
19+
/// Mount point path
20+
#[arg(short, long, default_value = "/tmp/mount")]
21+
mount: PathBuf,
22+
23+
/// Directory used to persist metadata artifacts (SQLite database, config, etc.)
24+
#[arg(long, default_value = "./slayerfs-meta")]
25+
meta_dir: PathBuf,
26+
27+
/// Target S3 bucket name (can be overridden by S3_BUCKET env var)
28+
#[arg(long)]
29+
bucket: Option<String>,
30+
31+
/// S3-compatible endpoint URL (can be overridden by S3_ENDPOINT env var)
32+
#[arg(long)]
33+
endpoint: Option<String>,
34+
35+
/// Optional AWS region (can be overridden by AWS_REGION env var)
36+
#[arg(long)]
37+
region: Option<String>,
38+
}
39+
40+
/// Process config file and adjust SQLite path to absolute path
41+
fn process_config_for_backend(
42+
config_content: &str,
43+
meta_dir: &std::path::Path,
44+
) -> Result<String, Box<dyn std::error::Error>> {
45+
let config: serde_yaml::Value = serde_yaml::from_str(config_content)?;
46+
47+
if let Some(database) = config.get("database") {
48+
if let Some(db_type) = database.get("type").and_then(|t| t.as_str()) {
49+
match db_type {
50+
"sqlite" => {
51+
let db_path = meta_dir.join("metadata.db");
52+
let sqlite_url = format!("sqlite://{}?mode=rwc", db_path.display());
53+
54+
let processed_config = format!(
55+
r#"database:
56+
type: sqlite
57+
url: "{}"
58+
"#,
59+
sqlite_url
60+
);
61+
62+
println!("SQLite database path: {}", db_path.display());
63+
Ok(processed_config)
64+
}
65+
"postgres" | "etcd" => {
66+
println!("Using configured database backend: {}", db_type);
67+
Ok(config_content.to_string())
68+
}
69+
_ => Err(format!("Unsupported database type: {}", db_type).into()),
70+
}
71+
} else {
72+
Err("Missing database.type field in config file".into())
73+
}
74+
} else {
75+
Err("Missing database configuration in config file".into())
76+
}
77+
}
78+
79+
#[tokio::main]
80+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
81+
// 加载 .env 文件
82+
dotenv::dotenv().ok();
83+
84+
let format = tracing_subscriber::fmt::format().with_ansi(false);
85+
tracing_subscriber::fmt().event_format(format).init();
86+
87+
#[cfg(not(target_os = "linux"))]
88+
{
89+
eprintln!("This demo only works on Linux (requires FUSE support).");
90+
eprintln!("If you're on Windows, please run under WSL/WSL2 or Linux host.");
91+
std::process::exit(2);
92+
}
93+
94+
#[cfg(target_os = "linux")]
95+
{
96+
let args = Args::parse();
97+
98+
// 从环境变量获取配置,命令行参数优先
99+
let bucket = args
100+
.bucket
101+
.or_else(|| std::env::var("S3_BUCKET").ok())
102+
.ok_or("S3 bucket must be specified via --bucket or S3_BUCKET env var")?;
103+
104+
let endpoint = args
105+
.endpoint
106+
.or_else(|| std::env::var("S3_ENDPOINT").ok())
107+
.unwrap_or_else(|| "http://127.0.0.1:9000".to_string());
108+
109+
let region = args.region.or_else(|| std::env::var("AWS_REGION").ok());
110+
111+
println!("=== SlayerFS Persistence + S3 Demo ===");
112+
println!("Environment variables loaded from .env file");
113+
println!("Config file: {}", args.config.display());
114+
println!("Metadata dir: {}", args.meta_dir.display());
115+
println!("Mount point: {}", args.mount.display());
116+
println!("S3 bucket: {}", bucket);
117+
println!("S3 endpoint: {}", endpoint);
118+
if let Some(ref region) = region {
119+
println!("S3 region: {}", region);
120+
}
121+
println!();
122+
let config_file = args.config;
123+
let mount_point = args.mount;
124+
let meta_dir = args.meta_dir;
125+
126+
println!("=== SlayerFS Persistence + S3 Demo ===");
127+
println!("Environment variables loaded from .env file");
128+
println!("Config file: {}", config_file.display());
129+
println!("Metadata dir: {}", meta_dir.display());
130+
println!("Mount point: {}", mount_point.display());
131+
println!("S3 bucket: {}", bucket);
132+
println!("S3 endpoint: {}", endpoint);
133+
if let Some(ref region) = region {
134+
println!("S3 region: {}", region);
135+
}
136+
println!();
137+
138+
if !config_file.exists() {
139+
eprintln!(
140+
"Error: Config file {} does not exist",
141+
config_file.display()
142+
);
143+
std::process::exit(1);
144+
}
145+
146+
std::fs::create_dir_all(&mount_point).map_err(|e| {
147+
format!(
148+
"Cannot create mount point directory {}: {}",
149+
mount_point.display(),
150+
e
151+
)
152+
})?;
153+
std::fs::create_dir_all(&meta_dir).map_err(|e| {
154+
format!(
155+
"Cannot create metadata directory {}: {}",
156+
meta_dir.display(),
157+
e
158+
)
159+
})?;
160+
#[cfg(unix)]
161+
{
162+
use std::os::unix::fs::PermissionsExt;
163+
let permissions = std::fs::Permissions::from_mode(0o755);
164+
std::fs::set_permissions(&mount_point, permissions)?;
165+
}
166+
167+
if std::fs::metadata(&mount_point)
168+
.map(|m| !m.is_dir())
169+
.unwrap_or(false)
170+
{
171+
return Err(format!("Mount point {} is not a directory", mount_point.display()).into());
172+
}
173+
174+
if let Ok(entries) = std::fs::read_dir(&mount_point) {
175+
let count = entries.count();
176+
if count > 0 {
177+
eprintln!(
178+
"Warning: Mount point {} is not empty, may already be mounted",
179+
mount_point.display()
180+
);
181+
eprintln!("Please unmount first or use an empty directory");
182+
eprintln!("Try: fusermount -u {}", mount_point.display());
183+
return Err("Mount point not empty".into());
184+
}
185+
}
186+
187+
let config_content = std::fs::read_to_string(&config_file)
188+
.map_err(|e| format!("Cannot read config file: {}", e))?;
189+
190+
let meta_work_dir = meta_dir.join(".slayerfs");
191+
std::fs::create_dir_all(&meta_work_dir)?;
192+
193+
let target_config_path = meta_work_dir.join("slayerfs.yml");
194+
let processed_config = process_config_for_backend(&config_content, &meta_work_dir)?;
195+
std::fs::write(&target_config_path, processed_config)?;
196+
197+
// AWS 环境变量已从 .env 文件加载
198+
199+
let config = slayerfs::meta::config::Config::from_file(&target_config_path)
200+
.map_err(|e| format!("Failed to load config file: {}", e))?;
201+
let meta = slayerfs::meta::factory::MetaStoreFactory::create_from_config(config)
202+
.await
203+
.map_err(|e| format!("Failed to initialize metadata storage: {}", e))?;
204+
205+
let mut s3_config = S3Config {
206+
bucket: bucket.clone(),
207+
region: region.clone().or_else(|| Some("us-east-1".to_string())),
208+
part_size: 16 * 1024 * 1024,
209+
max_concurrency: 8,
210+
..Default::default()
211+
};
212+
s3_config.endpoint = Some(endpoint.clone());
213+
s3_config.force_path_style = true;
214+
215+
let s3_backend = S3Backend::with_config(s3_config)
216+
.await
217+
.map_err(|e| format!("Failed to create S3 backend: {}", e))?;
218+
let object_client = ObjectClient::new(s3_backend);
219+
let block_store = ObjectBlockStore::new(object_client);
220+
221+
let layout = ChunkLayout::default();
222+
let fs = VFS::new(layout, block_store, meta)
223+
.await
224+
.map_err(|e| format!("Failed to create VFS: {}", e))?;
225+
226+
println!("Mounting filesystem...");
227+
228+
let handle = mount_vfs_unprivileged(fs, &mount_point)
229+
.await
230+
.map_err(|e| format!("Failed to mount filesystem: {}", e))?;
231+
232+
println!(
233+
"SlayerFS with S3 backend successfully mounted at: {}",
234+
mount_point.display()
235+
);
236+
println!("Press Ctrl+C to exit and unmount filesystem...");
237+
238+
signal::ctrl_c().await?;
239+
println!("\nUnmounting filesystem...");
240+
241+
handle.unmount().await?;
242+
println!("Filesystem unmounted");
243+
Ok(())
244+
}
245+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
database:
2+
type: sqlite
3+
url: "sqlite://metadata.db?mode=rwc"

project/slayerfs/src/cadapter/s3.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ pub struct S3Config {
2828
pub retry_base_delay: u64,
2929
/// Enable MD5 checksums for uploads (default: true)
3030
pub enable_md5: bool,
31+
/// Custom endpoint URL (e.g. for MinIO or localstack)
32+
pub endpoint: Option<String>,
33+
/// Force path-style access (required for some S3-compatible services)
34+
pub force_path_style: bool,
3135
}
3236

3337
impl Default for S3Config {
@@ -40,6 +44,8 @@ impl Default for S3Config {
4044
max_retries: 3,
4145
retry_base_delay: 100,
4246
enable_md5: true,
47+
endpoint: None,
48+
force_path_style: false,
4349
}
4450
}
4551
}
@@ -79,7 +85,18 @@ impl S3Backend {
7985
}
8086

8187
let aws_config = aws_config_loader.load().await;
82-
let client = Client::new(&aws_config);
88+
89+
let mut s3_config_builder = aws_sdk_s3::config::Builder::from(&aws_config);
90+
91+
if let Some(endpoint) = &config.endpoint {
92+
s3_config_builder = s3_config_builder.endpoint_url(endpoint);
93+
}
94+
95+
if config.force_path_style {
96+
s3_config_builder = s3_config_builder.force_path_style(true);
97+
}
98+
99+
let client = Client::from_conf(s3_config_builder.build());
83100

84101
Ok(Self { client, config })
85102
}

0 commit comments

Comments
 (0)