mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-30 10:08:58 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e5cef513f | |||
| 2d4f77fd3b | |||
| 920705417c | |||
| b097c94c59 | |||
| 3991a1d73c |
@@ -10,10 +10,16 @@ never weaken a check to get green.
|
||||
|
||||
## `check_layer_dependencies.sh` — layer DAG in `rustfs/src`
|
||||
|
||||
Enforces `interface (admin, storage/ecfs, storage/s3_api) → app → infra`; no
|
||||
upward imports. Known legacy violations live in
|
||||
Enforces `composition (server, startup/init) → interface (admin,
|
||||
storage/ecfs, storage/s3_api) → app → infra`; no upward imports. Server source
|
||||
files are composition roots, while imports of their exported HTTP contracts
|
||||
are classified as interface dependencies. Known legacy violations live in
|
||||
`scripts/layer-dependency-baseline.txt`.
|
||||
|
||||
Dedicated `*_test.rs` and `tests/` modules are outside this production guard.
|
||||
Inline `#[cfg(test)]` imports remain checked under their source file's layer;
|
||||
move architecture-crossing test scaffolding into a dedicated test module.
|
||||
|
||||
- **New violation**: restructure your change so the dependency points
|
||||
downward (move the shared type/function to the lower layer).
|
||||
- **You legitimately removed a baseline entry**: run
|
||||
|
||||
Generated
+123
-123
@@ -642,9 +642,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.42"
|
||||
version = "0.4.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac"
|
||||
checksum = "3976abdc8fe7d1133d43d304afd42abdf5bc3e1319d263d223bde07b5efc4be8"
|
||||
dependencies = [
|
||||
"compression-codecs",
|
||||
"compression-core",
|
||||
@@ -870,7 +870,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"hex",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"sha1 0.10.7",
|
||||
"time",
|
||||
"tokio",
|
||||
@@ -934,7 +934,7 @@ dependencies = [
|
||||
"bytes-utils",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 0.4.6",
|
||||
"http-body 1.1.0",
|
||||
"percent-encoding",
|
||||
@@ -970,7 +970,7 @@ dependencies = [
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"lru 0.16.4",
|
||||
"percent-encoding",
|
||||
@@ -1001,7 +1001,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -1027,7 +1027,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -1054,7 +1054,7 @@ dependencies = [
|
||||
"aws-types",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -1076,7 +1076,7 @@ dependencies = [
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"p256 0.13.2",
|
||||
"percent-encoding",
|
||||
"sha2 0.11.0",
|
||||
@@ -1108,7 +1108,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"crc-fast",
|
||||
"hex",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"md-5 0.11.0",
|
||||
@@ -1142,7 +1142,7 @@ dependencies = [
|
||||
"bytes-utils",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"percent-encoding",
|
||||
@@ -1161,7 +1161,7 @@ dependencies = [
|
||||
"aws-smithy-runtime-api",
|
||||
"aws-smithy-types",
|
||||
"h2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-util",
|
||||
@@ -1224,7 +1224,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 0.4.6",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
@@ -1245,7 +1245,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"bytes",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -1271,7 +1271,7 @@ checksum = "7d56e0a4e53127a632224e43633b0fe045fa9e1e3cfc68b9830f1115e103f910"
|
||||
dependencies = [
|
||||
"aws-smithy-runtime-api",
|
||||
"aws-smithy-types",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1285,7 +1285,7 @@ dependencies = [
|
||||
"bytes-utils",
|
||||
"futures-core",
|
||||
"http 0.2.12",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 0.4.6",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
@@ -1337,7 +1337,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"form_urlencoded",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -1368,7 +1368,7 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
@@ -3229,7 +3229,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"headers",
|
||||
"htmlescape",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"libc",
|
||||
@@ -3654,7 +3654,7 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
|
||||
|
||||
[[package]]
|
||||
name = "e2e_test"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"astral-tokio-tar",
|
||||
@@ -3672,7 +3672,7 @@ dependencies = [
|
||||
"flate2",
|
||||
"futures",
|
||||
"hex",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
@@ -4384,7 +4384,7 @@ dependencies = [
|
||||
"google-cloud-gax",
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"jsonwebtoken 10.4.0",
|
||||
"reqwest",
|
||||
"rustc_version",
|
||||
@@ -4409,7 +4409,7 @@ dependencies = [
|
||||
"futures",
|
||||
"google-cloud-rpc",
|
||||
"google-cloud-wkt",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"pin-project",
|
||||
"rand 0.10.2",
|
||||
"serde",
|
||||
@@ -4431,7 +4431,7 @@ dependencies = [
|
||||
"google-cloud-rpc",
|
||||
"google-cloud-wkt",
|
||||
"h2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -4544,7 +4544,7 @@ dependencies = [
|
||||
"google-cloud-type",
|
||||
"google-cloud-wkt",
|
||||
"hex",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"md5",
|
||||
"percent-encoding",
|
||||
@@ -4624,7 +4624,7 @@ dependencies = [
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"indexmap 2.14.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -4727,7 +4727,7 @@ dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1 0.10.7",
|
||||
@@ -4739,7 +4739,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4961,9 +4961,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.4.2"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
|
||||
checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"itoa",
|
||||
@@ -4987,7 +4987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4998,7 +4998,7 @@ checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"pin-project-lite",
|
||||
]
|
||||
@@ -5044,7 +5044,7 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"h2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
@@ -5061,7 +5061,7 @@ version = "0.27.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
|
||||
dependencies = [
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"log",
|
||||
@@ -5095,7 +5095,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"hyper",
|
||||
"ipnet",
|
||||
@@ -6704,10 +6704,10 @@ version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"base64 0.21.7",
|
||||
"chrono",
|
||||
"getrandom 0.2.17",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"rand 0.8.7",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -6815,7 +6815,7 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"humantime",
|
||||
"itertools 0.14.0",
|
||||
"parking_lot",
|
||||
@@ -6871,7 +6871,7 @@ dependencies = [
|
||||
"dyn-clone",
|
||||
"ed25519-dalek 2.2.0",
|
||||
"hmac 0.12.1",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"oauth2",
|
||||
@@ -6932,7 +6932,7 @@ checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"opentelemetry",
|
||||
"reqwest",
|
||||
]
|
||||
@@ -6944,7 +6944,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"opentelemetry",
|
||||
"opentelemetry-http",
|
||||
"opentelemetry-proto",
|
||||
@@ -7820,7 +7820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"itertools 0.14.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
@@ -7840,7 +7840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"itertools 0.14.0",
|
||||
"itertools 0.10.5",
|
||||
"log",
|
||||
"multimap",
|
||||
"petgraph 0.8.3",
|
||||
@@ -7861,7 +7861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
@@ -7874,7 +7874,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.14.0",
|
||||
"itertools 0.10.5",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
@@ -8329,9 +8329,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "1.4.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0b9503711b03773e43b31668c7b5bd279ee7cd9b7d18cff7c23a42cc1d08e5a"
|
||||
checksum = "3257df217f7eab0044627a268c9cc6cdb60c0c421c88f83ac41c4e31520b6b84"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"arcstr",
|
||||
@@ -8481,7 +8481,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -8627,7 +8627,7 @@ dependencies = [
|
||||
"async-tungstenite",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"rustls-native-certs",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
@@ -8657,7 +8657,7 @@ dependencies = [
|
||||
"flume",
|
||||
"futures-io",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"log",
|
||||
"mqttbytes-core-next",
|
||||
"rumqttc-core-next",
|
||||
@@ -8845,7 +8845,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"anyhow",
|
||||
@@ -8874,7 +8874,7 @@ dependencies = [
|
||||
"hex-simd",
|
||||
"hmac 0.13.0",
|
||||
"hotpath",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -8981,7 +8981,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-audit"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"chrono",
|
||||
@@ -9003,12 +9003,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-checksums"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"bytes",
|
||||
"crc-fast",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"md-5 0.11.0",
|
||||
"pretty_assertions",
|
||||
"sha1 0.11.0",
|
||||
@@ -9018,7 +9018,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-common"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"metrics",
|
||||
@@ -9033,7 +9033,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-concurrency"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"insta",
|
||||
"rustfs-io-core",
|
||||
@@ -9045,7 +9045,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-config"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"const-str",
|
||||
"serde",
|
||||
@@ -9054,7 +9054,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-credentials"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"hmac 0.13.0",
|
||||
@@ -9067,7 +9067,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-crypto"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"argon2",
|
||||
@@ -9087,7 +9087,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-data-usage"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"rmp-serde",
|
||||
@@ -9097,7 +9097,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-ecstore"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"arc-swap",
|
||||
@@ -9129,7 +9129,7 @@ dependencies = [
|
||||
"hex-simd",
|
||||
"hmac 0.13.0",
|
||||
"hotpath",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -9235,7 +9235,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-extension-schema"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -9244,7 +9244,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-filemeta"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"byteorder",
|
||||
@@ -9270,12 +9270,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-heal"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.23.0",
|
||||
"futures",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"metrics",
|
||||
"rustfs-common",
|
||||
"rustfs-concurrency",
|
||||
@@ -9300,13 +9300,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-iam"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"async-trait",
|
||||
"base64-simd",
|
||||
"futures",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"jsonwebtoken 11.0.0",
|
||||
"moka",
|
||||
"openidconnect",
|
||||
@@ -9337,7 +9337,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-io-core"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memmap2",
|
||||
@@ -9349,7 +9349,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-io-metrics"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"metrics",
|
||||
@@ -9412,11 +9412,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-keystone"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -9438,7 +9438,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-kms"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"arc-swap",
|
||||
@@ -9472,7 +9472,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-lifecycle"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"metrics",
|
||||
@@ -9494,7 +9494,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-lock"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"crossbeam-queue",
|
||||
@@ -9516,7 +9516,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-log-analyzer"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"flate2",
|
||||
@@ -9534,7 +9534,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-madmin"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"humantime",
|
||||
@@ -9548,7 +9548,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-notify"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"async-trait",
|
||||
@@ -9582,7 +9582,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-object-capacity"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"futures",
|
||||
@@ -9600,7 +9600,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-object-data-cache"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"criterion",
|
||||
@@ -9616,7 +9616,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-obs"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
@@ -9668,7 +9668,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-policy"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64-simd",
|
||||
@@ -9697,7 +9697,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-protocols"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"astral-tokio-tar",
|
||||
"async-compression",
|
||||
@@ -9710,7 +9710,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
@@ -9759,7 +9759,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-protos"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
"prost 0.14.4",
|
||||
@@ -9782,7 +9782,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-replication"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
@@ -9799,7 +9799,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-rio"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"arc-swap",
|
||||
@@ -9811,7 +9811,7 @@ dependencies = [
|
||||
"futures",
|
||||
"hex-simd",
|
||||
"hotpath",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body-util",
|
||||
"md-5 0.11.0",
|
||||
"pin-project-lite",
|
||||
@@ -9837,7 +9837,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-rio-v2"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"bytes",
|
||||
@@ -9859,14 +9859,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-s3-ops"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"rustfs-s3-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-s3-types"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -9874,7 +9874,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-s3select-api"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -9882,7 +9882,7 @@ dependencies = [
|
||||
"datafusion",
|
||||
"futures",
|
||||
"futures-core",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"metrics",
|
||||
"parking_lot",
|
||||
"rustfs-common",
|
||||
@@ -9903,7 +9903,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-s3select-query"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
@@ -9919,7 +9919,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-scanner"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -9927,7 +9927,7 @@ dependencies = [
|
||||
"futures",
|
||||
"hex-simd",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"metrics",
|
||||
"rand 0.10.2",
|
||||
"rmp-serde",
|
||||
@@ -9957,18 +9957,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-security-governance"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"thiserror 2.0.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-signer"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"bytes",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"hyper",
|
||||
"rustfs-utils",
|
||||
"s3s",
|
||||
@@ -9981,7 +9981,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-storage-api"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"insta",
|
||||
@@ -9995,7 +9995,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-targets"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"async-nats",
|
||||
@@ -10048,7 +10048,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-test-utils"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"rustfs-data-usage",
|
||||
"rustfs-ecstore",
|
||||
@@ -10063,7 +10063,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-tls-runtime"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"metrics",
|
||||
@@ -10083,11 +10083,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-trusted-proxies"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"ipnetwork",
|
||||
"metrics",
|
||||
"moka",
|
||||
@@ -10119,7 +10119,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-utils"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"blake2",
|
||||
@@ -10133,7 +10133,7 @@ dependencies = [
|
||||
"hex-simd",
|
||||
"highway",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"hyper",
|
||||
"local-ip-address",
|
||||
"lz4",
|
||||
@@ -10160,7 +10160,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfs-zip"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
dependencies = [
|
||||
"astral-tokio-tar",
|
||||
"async-compression",
|
||||
@@ -10190,7 +10190,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"reqwest",
|
||||
"rustify_derive",
|
||||
"serde",
|
||||
@@ -10230,9 +10230,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.42"
|
||||
version = "0.23.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
|
||||
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
@@ -10370,7 +10370,7 @@ dependencies = [
|
||||
"futures",
|
||||
"hex-simd",
|
||||
"hmac 0.13.0",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"httparse",
|
||||
@@ -11498,7 +11498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.4.3",
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
@@ -11734,13 +11734,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.7.1"
|
||||
version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
|
||||
checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11844,7 +11844,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"httparse",
|
||||
"rand 0.8.7",
|
||||
"rustls-pki-types",
|
||||
@@ -11896,7 +11896,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"flate2",
|
||||
"h2",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
@@ -11983,7 +11983,7 @@ dependencies = [
|
||||
"bitflags 2.13.1",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"pin-project-lite",
|
||||
"tower",
|
||||
@@ -12003,7 +12003,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"http-body 1.1.0",
|
||||
"http-body-util",
|
||||
"percent-encoding",
|
||||
@@ -12176,7 +12176,7 @@ checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.9.5",
|
||||
@@ -12363,7 +12363,7 @@ checksum = "30ffcc0e81025065dda612ec1e26a3d81bb16ef3062354873d17a35965d68522"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"derive_builder",
|
||||
"http 1.4.2",
|
||||
"http 1.5.0",
|
||||
"reqwest",
|
||||
"rustify",
|
||||
"rustify_derive",
|
||||
|
||||
+51
-51
@@ -69,7 +69,7 @@ edition = "2024"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/rustfs/rustfs"
|
||||
rust-version = "1.97.1"
|
||||
version = "1.0.0-beta.11"
|
||||
version = "1.0.0-beta.12"
|
||||
homepage = "https://rustfs.com"
|
||||
description = "RustFS is a high-performance distributed object storage software built using Rust, one of the most popular languages worldwide. "
|
||||
keywords = ["RustFS", "Minio", "object-storage", "filesystem", "s3"]
|
||||
@@ -86,58 +86,58 @@ redundant_clone = "warn"
|
||||
|
||||
[workspace.dependencies]
|
||||
# RustFS Internal Crates
|
||||
rustfs = { path = "./rustfs", version = "1.0.0-beta.11" }
|
||||
rustfs-heal = { path = "crates/heal", version = "1.0.0-beta.11" }
|
||||
rustfs-audit = { path = "crates/audit", version = "1.0.0-beta.11" }
|
||||
rustfs-checksums = { path = "crates/checksums", version = "1.0.0-beta.11" }
|
||||
rustfs-common = { path = "crates/common", version = "1.0.0-beta.11" }
|
||||
rustfs-data-usage = { path = "crates/data-usage", version = "1.0.0-beta.11" }
|
||||
rustfs-config = { path = "./crates/config", version = "1.0.0-beta.11" }
|
||||
rustfs-concurrency = { path = "./crates/concurrency", version = "1.0.0-beta.11" }
|
||||
rustfs-credentials = { path = "crates/credentials", version = "1.0.0-beta.11" }
|
||||
rustfs-crypto = { path = "crates/crypto", version = "1.0.0-beta.11" }
|
||||
rustfs-ecstore = { path = "crates/ecstore", version = "1.0.0-beta.11" }
|
||||
rustfs-filemeta = { path = "crates/filemeta", version = "1.0.0-beta.11" }
|
||||
rustfs-iam = { path = "crates/iam", version = "1.0.0-beta.11" }
|
||||
rustfs-keystone = { path = "crates/keystone", version = "1.0.0-beta.11" }
|
||||
rustfs-lifecycle = { path = "crates/lifecycle", version = "1.0.0-beta.11" }
|
||||
rustfs-kms = { path = "crates/kms", version = "1.0.0-beta.11" }
|
||||
rustfs-lock = { path = "crates/lock", version = "1.0.0-beta.11" }
|
||||
rustfs-madmin = { path = "crates/madmin", version = "1.0.0-beta.11" }
|
||||
rustfs-notify = { path = "crates/notify", version = "1.0.0-beta.11" }
|
||||
rustfs-io-metrics = { path = "crates/io-metrics", version = "1.0.0-beta.11" }
|
||||
rustfs-io-core = { path = "crates/io-core", version = "1.0.0-beta.11" }
|
||||
rustfs-object-capacity = { path = "crates/object-capacity", version = "1.0.0-beta.11" }
|
||||
rustfs-object-data-cache = { path = "crates/object-data-cache", version = "1.0.0-beta.11" }
|
||||
rustfs-log-analyzer = { path = "crates/log-analyzer", version = "1.0.0-beta.11" }
|
||||
rustfs-obs = { path = "crates/obs", version = "1.0.0-beta.11" }
|
||||
rustfs-policy = { path = "crates/policy", version = "1.0.0-beta.11" }
|
||||
rustfs-protos = { path = "crates/protos", version = "1.0.0-beta.11" }
|
||||
rustfs-protocols = { path = "crates/protocols", version = "1.0.0-beta.11" }
|
||||
rustfs-replication = { path = "crates/replication", version = "1.0.0-beta.11" }
|
||||
rustfs-rio = { path = "crates/rio", version = "1.0.0-beta.11" }
|
||||
rustfs-rio-v2 = { path = "crates/rio-v2", version = "1.0.0-beta.11" }
|
||||
rustfs-s3-types = { path = "crates/s3-types", version = "1.0.0-beta.11" }
|
||||
rustfs-s3-ops = { path = "crates/s3-ops", version = "1.0.0-beta.11" }
|
||||
rustfs-s3select-api = { path = "crates/s3select-api", version = "1.0.0-beta.11" }
|
||||
rustfs-s3select-query = { path = "crates/s3select-query", version = "1.0.0-beta.11" }
|
||||
rustfs-scanner = { path = "crates/scanner", version = "1.0.0-beta.11" }
|
||||
rustfs-security-governance = { path = "crates/security-governance", version = "1.0.0-beta.11" }
|
||||
rustfs-extension-schema = { path = "crates/extension-schema", version = "1.0.0-beta.11" }
|
||||
rustfs-signer = { path = "crates/signer", version = "1.0.0-beta.11" }
|
||||
rustfs-storage-api = { path = "crates/storage-api", version = "1.0.0-beta.11" }
|
||||
rustfs-trusted-proxies = { path = "crates/trusted-proxies", version = "1.0.0-beta.11" }
|
||||
rustfs-targets = { path = "crates/targets", version = "1.0.0-beta.11" }
|
||||
rustfs-test-utils = { path = "crates/test-utils", version = "1.0.0-beta.11" }
|
||||
rustfs-tls-runtime = { path = "crates/tls-runtime", version = "1.0.0-beta.11" }
|
||||
rustfs-utils = { path = "crates/utils", version = "1.0.0-beta.11" }
|
||||
rustfs-zip = { path = "./crates/zip", version = "1.0.0-beta.11" }
|
||||
rustfs = { path = "./rustfs", version = "1.0.0-beta.12" }
|
||||
rustfs-heal = { path = "crates/heal", version = "1.0.0-beta.12" }
|
||||
rustfs-audit = { path = "crates/audit", version = "1.0.0-beta.12" }
|
||||
rustfs-checksums = { path = "crates/checksums", version = "1.0.0-beta.12" }
|
||||
rustfs-common = { path = "crates/common", version = "1.0.0-beta.12" }
|
||||
rustfs-data-usage = { path = "crates/data-usage", version = "1.0.0-beta.12" }
|
||||
rustfs-config = { path = "./crates/config", version = "1.0.0-beta.12" }
|
||||
rustfs-concurrency = { path = "./crates/concurrency", version = "1.0.0-beta.12" }
|
||||
rustfs-credentials = { path = "crates/credentials", version = "1.0.0-beta.12" }
|
||||
rustfs-crypto = { path = "crates/crypto", version = "1.0.0-beta.12" }
|
||||
rustfs-ecstore = { path = "crates/ecstore", version = "1.0.0-beta.12" }
|
||||
rustfs-filemeta = { path = "crates/filemeta", version = "1.0.0-beta.12" }
|
||||
rustfs-iam = { path = "crates/iam", version = "1.0.0-beta.12" }
|
||||
rustfs-keystone = { path = "crates/keystone", version = "1.0.0-beta.12" }
|
||||
rustfs-lifecycle = { path = "crates/lifecycle", version = "1.0.0-beta.12" }
|
||||
rustfs-kms = { path = "crates/kms", version = "1.0.0-beta.12" }
|
||||
rustfs-lock = { path = "crates/lock", version = "1.0.0-beta.12" }
|
||||
rustfs-madmin = { path = "crates/madmin", version = "1.0.0-beta.12" }
|
||||
rustfs-notify = { path = "crates/notify", version = "1.0.0-beta.12" }
|
||||
rustfs-io-metrics = { path = "crates/io-metrics", version = "1.0.0-beta.12" }
|
||||
rustfs-io-core = { path = "crates/io-core", version = "1.0.0-beta.12" }
|
||||
rustfs-object-capacity = { path = "crates/object-capacity", version = "1.0.0-beta.12" }
|
||||
rustfs-object-data-cache = { path = "crates/object-data-cache", version = "1.0.0-beta.12" }
|
||||
rustfs-log-analyzer = { path = "crates/log-analyzer", version = "1.0.0-beta.12" }
|
||||
rustfs-obs = { path = "crates/obs", version = "1.0.0-beta.12" }
|
||||
rustfs-policy = { path = "crates/policy", version = "1.0.0-beta.12" }
|
||||
rustfs-protos = { path = "crates/protos", version = "1.0.0-beta.12" }
|
||||
rustfs-protocols = { path = "crates/protocols", version = "1.0.0-beta.12" }
|
||||
rustfs-replication = { path = "crates/replication", version = "1.0.0-beta.12" }
|
||||
rustfs-rio = { path = "crates/rio", version = "1.0.0-beta.12" }
|
||||
rustfs-rio-v2 = { path = "crates/rio-v2", version = "1.0.0-beta.12" }
|
||||
rustfs-s3-types = { path = "crates/s3-types", version = "1.0.0-beta.12" }
|
||||
rustfs-s3-ops = { path = "crates/s3-ops", version = "1.0.0-beta.12" }
|
||||
rustfs-s3select-api = { path = "crates/s3select-api", version = "1.0.0-beta.12" }
|
||||
rustfs-s3select-query = { path = "crates/s3select-query", version = "1.0.0-beta.12" }
|
||||
rustfs-scanner = { path = "crates/scanner", version = "1.0.0-beta.12" }
|
||||
rustfs-security-governance = { path = "crates/security-governance", version = "1.0.0-beta.12" }
|
||||
rustfs-extension-schema = { path = "crates/extension-schema", version = "1.0.0-beta.12" }
|
||||
rustfs-signer = { path = "crates/signer", version = "1.0.0-beta.12" }
|
||||
rustfs-storage-api = { path = "crates/storage-api", version = "1.0.0-beta.12" }
|
||||
rustfs-trusted-proxies = { path = "crates/trusted-proxies", version = "1.0.0-beta.12" }
|
||||
rustfs-targets = { path = "crates/targets", version = "1.0.0-beta.12" }
|
||||
rustfs-test-utils = { path = "crates/test-utils", version = "1.0.0-beta.12" }
|
||||
rustfs-tls-runtime = { path = "crates/tls-runtime", version = "1.0.0-beta.12" }
|
||||
rustfs-utils = { path = "crates/utils", version = "1.0.0-beta.12" }
|
||||
rustfs-zip = { path = "./crates/zip", version = "1.0.0-beta.12" }
|
||||
|
||||
# Async Runtime and Networking
|
||||
async-channel = "2.5.0"
|
||||
async_zip = { default-features = false, version = "0.0.18" }
|
||||
mysql_async = { default-features = false, version = "0.37" }
|
||||
async-compression = { version = "0.4.42" }
|
||||
async-compression = { version = "0.4.43" }
|
||||
async-recursion = "1.1.1"
|
||||
async-trait = "0.1.91"
|
||||
async-nats = { version = "0.50.0", default-features = false }
|
||||
@@ -152,7 +152,7 @@ lapin = { default-features = false, version = "4.10.0" }
|
||||
hyper = { version = "1.11.0" }
|
||||
hyper-rustls = { default-features = false, version = "0.27.9" }
|
||||
hyper-util = { version = "0.1.20" }
|
||||
http = "1.4.2"
|
||||
http = "1.5.0"
|
||||
http-body = "1.1.0"
|
||||
http-body-util = "0.1.4"
|
||||
minlz = "1.2.3"
|
||||
@@ -200,7 +200,7 @@ jsonwebtoken = { version = "11.0.0" }
|
||||
openidconnect = { default-features = false, version = "4.0" }
|
||||
pbkdf2 = "0.13.0"
|
||||
rsa = { version = "=0.10.0-rc.18" }
|
||||
rustls = { default-features = false, version = "0.23.42" }
|
||||
rustls = { default-features = false, version = "0.23.43" }
|
||||
rustls-native-certs = "0.8"
|
||||
rustls-pki-types = "1.15.1"
|
||||
sha1 = "0.11.0"
|
||||
@@ -283,7 +283,7 @@ reed-solomon-erasure = { package = "rustfs-erasure-codec", version = "8.0.2" }
|
||||
reed-solomon-simd = "3.1.0"
|
||||
regex = { version = "1.13.1" }
|
||||
rumqttc = { package = "rumqttc-next", version = "0.33.3" }
|
||||
redis = { version = "1.4.1" }
|
||||
redis = { version = "1.5.0" }
|
||||
rustix = { version = "1.1.4" }
|
||||
rust-embed = { version = "8.12.0" }
|
||||
rustc-hash = { version = "2.1.3" }
|
||||
|
||||
@@ -116,7 +116,7 @@ chown -R 10001:10001 data logs
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest
|
||||
|
||||
# Using specific version
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0-beta.11
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0-beta.12
|
||||
```
|
||||
|
||||
If you use [podman](https://github.com/containers/podman) instead of docker, you can install the RustFS with the below command
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ chown -R 10001:10001 data logs
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:latest
|
||||
|
||||
# 使用指定版本运行
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0-beta.11
|
||||
docker run -d -p 9000:9000 -p 9001:9001 -v $(pwd)/data:/data -v $(pwd)/logs:/logs rustfs/rustfs:1.0.0-beta.12
|
||||
```
|
||||
|
||||
如果您通过绑定挂载启用 TLS 证书目录,也请用同样方式准备该目录:
|
||||
|
||||
@@ -184,8 +184,8 @@ pub mod bucket {
|
||||
get_global_replication_stats, init_background_replication, read_durable_mrf_backlog, replication_state_to_filemeta,
|
||||
replication_status_to_filemeta, replication_statuses_map, replication_target_arns, resync_start_conflict_id,
|
||||
should_remove_replication_target, should_schedule_delete_replication, should_use_existing_delete_replication_info,
|
||||
should_use_existing_delete_replication_source, unsupported_replication_config_field,
|
||||
validate_replication_config_target_arns, version_purge_status_to_filemeta,
|
||||
should_use_existing_delete_replication_source, validate_replication_config_target_arns,
|
||||
version_purge_status_to_filemeta,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ mod runtime_boundary;
|
||||
pub use datatypes::ResyncStatusType;
|
||||
pub use replication_config_boundary::{
|
||||
ObjectOpts, ReplicationConfigurationExt, ReplicationTargetValidationError, replication_target_arns,
|
||||
should_remove_replication_target, unsupported_replication_config_field, validate_replication_config_target_arns,
|
||||
should_remove_replication_target, validate_replication_config_target_arns,
|
||||
};
|
||||
#[cfg(test)]
|
||||
pub(crate) use replication_filemeta_boundary::ReplicateTargetDecision;
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
|
||||
pub use rustfs_replication::{
|
||||
ObjectOpts, ReplicationConfigurationExt, ReplicationTargetValidationError, replication_target_arns,
|
||||
should_remove_replication_target, unsupported_replication_config_field, validate_replication_config_target_arns,
|
||||
should_remove_replication_target, validate_replication_config_target_arns,
|
||||
};
|
||||
|
||||
@@ -14,11 +14,8 @@
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use super::replication_error_boundary::Result;
|
||||
use super::replication_filemeta_boundary::{ReplicateDecision, ReplicationStatusType, ReplicationType};
|
||||
use super::replication_object_config::{
|
||||
check_replicate_delete, check_replicate_delete_strict, get_must_replicate_options, must_replicate,
|
||||
};
|
||||
use super::replication_object_config::{check_replicate_delete, get_must_replicate_options, must_replicate};
|
||||
use super::replication_object_decision_boundary::MustReplicateOptions;
|
||||
use super::replication_pool::{schedule_replication, schedule_replication_delete};
|
||||
use super::replication_queue_boundary::DeletedObjectReplicationInfo;
|
||||
@@ -53,16 +50,6 @@ impl ReplicationObjectBridge {
|
||||
check_replicate_delete(bucket, object, source, opts, get_error).await
|
||||
}
|
||||
|
||||
pub async fn check_delete_strict(
|
||||
bucket: &str,
|
||||
object: &ObjectToDelete,
|
||||
source: &ObjectInfo,
|
||||
opts: &ObjectOptions,
|
||||
get_error: Option<String>,
|
||||
) -> Result<ReplicateDecision> {
|
||||
check_replicate_delete_strict(bucket, object, source, opts, get_error).await
|
||||
}
|
||||
|
||||
pub async fn schedule_object<S: ReplicationStorage>(
|
||||
object: ObjectInfo,
|
||||
storage: Arc<S>,
|
||||
|
||||
@@ -169,8 +169,9 @@ pub(crate) async fn check_replicate_delete(
|
||||
del_opts: &ObjectOptions,
|
||||
gerr: Option<String>,
|
||||
) -> ReplicateDecision {
|
||||
match check_replicate_delete_strict(bucket, dobj, oi, del_opts, gerr).await {
|
||||
Ok(decision) => decision,
|
||||
let rcfg = match get_replication_config(bucket).await {
|
||||
Ok(Some(config)) => config,
|
||||
Ok(None) => return ReplicateDecision::default(),
|
||||
Err(err) => {
|
||||
error!(
|
||||
event = EVENT_RESYNC_CONFIG_LOOKUP_SKIPPED,
|
||||
@@ -181,30 +182,16 @@ pub(crate) async fn check_replicate_delete(
|
||||
error = %err,
|
||||
"Failed to look up replication config for delete replication"
|
||||
);
|
||||
ReplicateDecision::default()
|
||||
return ReplicateDecision::default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn check_replicate_delete_strict(
|
||||
bucket: &str,
|
||||
dobj: &ObjectToDelete,
|
||||
oi: &ObjectInfo,
|
||||
del_opts: &ObjectOptions,
|
||||
gerr: Option<String>,
|
||||
) -> Result<ReplicateDecision> {
|
||||
let rcfg = match get_replication_config(bucket).await {
|
||||
Ok(Some(config)) => config,
|
||||
Ok(None) => return Ok(ReplicateDecision::default()),
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
if del_opts.replication_request {
|
||||
return Ok(ReplicateDecision::default());
|
||||
return ReplicateDecision::default();
|
||||
}
|
||||
|
||||
if !del_opts.versioned && !del_opts.version_suspended {
|
||||
return Ok(ReplicateDecision::default());
|
||||
if !del_opts.versioned {
|
||||
return ReplicateDecision::default();
|
||||
}
|
||||
|
||||
let replication_delete = object_to_delete_for_replication(dobj);
|
||||
@@ -222,7 +209,7 @@ pub(crate) async fn check_replicate_delete_strict(
|
||||
let mut dsc = ReplicateDecision::new();
|
||||
|
||||
if tgt_arns.is_empty() {
|
||||
return Ok(dsc);
|
||||
return dsc;
|
||||
}
|
||||
|
||||
for tgt_arn in tgt_arns {
|
||||
@@ -252,7 +239,7 @@ pub(crate) async fn check_replicate_delete_strict(
|
||||
dsc.set(tgt_dsc);
|
||||
}
|
||||
|
||||
Ok(dsc)
|
||||
dsc
|
||||
}
|
||||
|
||||
pub(crate) async fn must_replicate(bucket: &str, object: &str, mopts: MustReplicateOptions) -> ReplicateDecision {
|
||||
|
||||
@@ -1151,6 +1151,60 @@ pub async fn replicate_delete<S: ReplicationStorage>(dobj: DeletedObjectReplicat
|
||||
dobj.delete_object.version_id
|
||||
};
|
||||
|
||||
let _rcfg = match get_replication_config(&bucket).await {
|
||||
Ok(Some(config)) => config,
|
||||
Ok(None) => {
|
||||
debug!(
|
||||
event = EVENT_REPLICATION_DELETE_SKIPPED,
|
||||
component = LOG_COMPONENT_ECSTORE,
|
||||
subsystem = LOG_SUBSYSTEM_REPLICATION_RESYNC,
|
||||
bucket = %bucket,
|
||||
reason = "replication_config_missing",
|
||||
"Skipping replication delete because replication config is missing"
|
||||
);
|
||||
send_local_event(EventArgs {
|
||||
event_name: EventName::ObjectReplicationNotTracked.to_string(),
|
||||
bucket_name: bucket.clone(),
|
||||
object: ObjectInfo {
|
||||
bucket: bucket.clone(),
|
||||
name: dobj.delete_object.object_name.clone(),
|
||||
version_id,
|
||||
delete_marker: dobj.delete_object.delete_marker,
|
||||
..Default::default()
|
||||
},
|
||||
user_agent: "Internal: [Replication]".to_string(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
Err(err) => {
|
||||
debug!(
|
||||
event = EVENT_REPLICATION_DELETE_SKIPPED,
|
||||
component = LOG_COMPONENT_ECSTORE,
|
||||
subsystem = LOG_SUBSYSTEM_REPLICATION_RESYNC,
|
||||
bucket = %bucket,
|
||||
error = %err,
|
||||
reason = "replication_config_lookup_failed",
|
||||
"Skipping replication delete because replication config lookup failed"
|
||||
);
|
||||
send_local_event(EventArgs {
|
||||
event_name: EventName::ObjectReplicationNotTracked.to_string(),
|
||||
bucket_name: bucket.clone(),
|
||||
object: ObjectInfo {
|
||||
bucket: bucket.clone(),
|
||||
name: dobj.delete_object.object_name.clone(),
|
||||
version_id,
|
||||
delete_marker: dobj.delete_object.delete_marker,
|
||||
..Default::default()
|
||||
},
|
||||
user_agent: "Internal: [Replication]".to_string(),
|
||||
..Default::default()
|
||||
});
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if dobj.delete_object.delete_marker
|
||||
&& let Some(delete_marker_version_id) = dobj.delete_object.delete_marker_version_id
|
||||
{
|
||||
|
||||
@@ -5849,23 +5849,27 @@ mod tests {
|
||||
crate::disk::DataDirDeleteStatus::Deleted
|
||||
);
|
||||
release_slow_candidate.notify_one();
|
||||
for _ in 0..10 {
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
assert_eq!(
|
||||
disk2
|
||||
.delete_data_dir(
|
||||
bucket,
|
||||
data_dir,
|
||||
DeleteOptions {
|
||||
recursive: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("a token acquired after the deadline must be released"),
|
||||
crate::disk::DataDirDeleteStatus::Deleted
|
||||
);
|
||||
timeout(Duration::from_secs(1), async {
|
||||
loop {
|
||||
match disk2
|
||||
.delete_data_dir(
|
||||
bucket,
|
||||
data_dir,
|
||||
DeleteOptions {
|
||||
recursive: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("a token acquired after the deadline must be released")
|
||||
{
|
||||
crate::disk::DataDirDeleteStatus::Deleted => return,
|
||||
crate::disk::DataDirDeleteStatus::Deferred => tokio::time::sleep(Duration::from_millis(1)).await,
|
||||
}
|
||||
}
|
||||
})
|
||||
.await
|
||||
.expect("late snapshot lease cleanup must finish within the bounded wait");
|
||||
}
|
||||
|
||||
#[tokio::test(start_paused = true)]
|
||||
|
||||
@@ -310,12 +310,13 @@ impl ECStore {
|
||||
meta.set_created(opts.created_at);
|
||||
|
||||
if opts.lock_enabled {
|
||||
meta.object_lock_config_xml = crate::bucket::utils::serialize::<ObjectLockConfiguration>(&enableObjcetLockConfig)?;
|
||||
meta.versioning_config_xml = crate::bucket::utils::serialize::<VersioningConfiguration>(&enableVersioningConfig)?;
|
||||
meta.object_lock_config_xml =
|
||||
crate::bucket::utils::serialize::<ObjectLockConfiguration>(&ENABLED_OBJECT_LOCK_CONFIG)?;
|
||||
meta.versioning_config_xml = crate::bucket::utils::serialize::<VersioningConfiguration>(&ENABLED_VERSIONING_CONFIG)?;
|
||||
}
|
||||
|
||||
if opts.versioning_enabled {
|
||||
meta.versioning_config_xml = crate::bucket::utils::serialize::<VersioningConfiguration>(&enableVersioningConfig)?;
|
||||
meta.versioning_config_xml = crate::bucket::utils::serialize::<VersioningConfiguration>(&ENABLED_VERSIONING_CONFIG)?;
|
||||
}
|
||||
|
||||
await_bucket_namespace_operation(
|
||||
|
||||
@@ -428,11 +428,11 @@ impl ECStore {
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref enableObjcetLockConfig: ObjectLockConfiguration = ObjectLockConfiguration {
|
||||
static ref ENABLED_OBJECT_LOCK_CONFIG: ObjectLockConfiguration = ObjectLockConfiguration {
|
||||
object_lock_enabled: Some(ObjectLockEnabled::from_static(ObjectLockEnabled::ENABLED)),
|
||||
..Default::default()
|
||||
};
|
||||
static ref enableVersioningConfig: VersioningConfiguration = VersioningConfiguration {
|
||||
static ref ENABLED_VERSIONING_CONFIG: VersioningConfiguration = VersioningConfiguration {
|
||||
status: Some(BucketVersioningStatus::from_static(BucketVersioningStatus::ENABLED)),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -556,7 +556,7 @@ where
|
||||
Ok(now)
|
||||
}
|
||||
|
||||
pub async fn list_polices(&self, bucket_name: &str) -> Result<HashMap<String, Policy>> {
|
||||
pub async fn list_policies(&self, bucket_name: &str) -> Result<HashMap<String, Policy>> {
|
||||
let mut m = HashMap::new();
|
||||
|
||||
self.api.load_policy_docs(&mut m).await?;
|
||||
@@ -588,6 +588,15 @@ where
|
||||
Ok(filtered)
|
||||
}
|
||||
|
||||
/// Backward-compatible misspelling retained until the next breaking release.
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "use list_policies instead; this alias will be removed in the next breaking release"
|
||||
)]
|
||||
pub async fn list_polices(&self, bucket_name: &str) -> Result<HashMap<String, Policy>> {
|
||||
self.list_policies(bucket_name).await
|
||||
}
|
||||
|
||||
pub async fn merge_policies(&self, name: &str) -> (String, Policy) {
|
||||
let mut policies = Vec::new();
|
||||
let mut to_merge = Vec::new();
|
||||
@@ -2184,7 +2193,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_default_policyes() -> HashMap<String, PolicyDoc> {
|
||||
pub fn get_default_policies() -> HashMap<String, PolicyDoc> {
|
||||
let default_policies = &DEFAULT_POLICIES;
|
||||
default_policies
|
||||
.iter()
|
||||
@@ -2201,6 +2210,15 @@ pub fn get_default_policyes() -> HashMap<String, PolicyDoc> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Backward-compatible misspelling retained until the next breaking release.
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "use get_default_policies instead; this alias will be removed in the next breaking release"
|
||||
)]
|
||||
pub fn get_default_policyes() -> HashMap<String, PolicyDoc> {
|
||||
get_default_policies()
|
||||
}
|
||||
|
||||
fn set_default_canned_policies(policies: &mut HashMap<String, PolicyDoc>) {
|
||||
let default_policies = &DEFAULT_POLICIES;
|
||||
for (k, v) in default_policies.iter() {
|
||||
@@ -2900,7 +2918,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_get_default_policies() {
|
||||
let policies = get_default_policyes();
|
||||
let policies = get_default_policies();
|
||||
|
||||
// Should contain some default policies
|
||||
assert!(!policies.is_empty());
|
||||
@@ -2913,6 +2931,12 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn deprecated_get_default_policyes_matches_current_api() {
|
||||
assert_eq!(get_default_policyes().len(), get_default_policies().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_token_signing_key() {
|
||||
// This function returns the global action credential's secret key
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::{
|
||||
cache::{Cache, CacheEntity},
|
||||
error::{is_err_no_such_policy, is_err_no_such_user},
|
||||
keyring,
|
||||
manager::{extract_jwt_claims, extract_jwt_claims_allow_missing_exp, get_default_policyes},
|
||||
manager::{extract_jwt_claims, extract_jwt_claims_allow_missing_exp, get_default_policies},
|
||||
root_credentials,
|
||||
};
|
||||
use futures::future::join_all;
|
||||
@@ -1127,7 +1127,7 @@ impl Store for ObjectStore {
|
||||
let cache_snapshot = cache.snapshot();
|
||||
let listed_config_items = self.list_all_iamconfig_items().await?;
|
||||
|
||||
let mut policy_docs_cache = CacheEntity::new(get_default_policyes());
|
||||
let mut policy_docs_cache = CacheEntity::new(get_default_policies());
|
||||
|
||||
if let Some(policies_list) = listed_config_items.get(POLICIES_LIST_KEY) {
|
||||
// Load in fixed-size chunks so each policy is fetched exactly once.
|
||||
|
||||
+20
-5
@@ -18,7 +18,7 @@ use crate::error::is_err_no_such_temp_account;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::federation::OIDC_VIRTUAL_PARENT_CLAIM;
|
||||
use crate::manager::extract_jwt_claims;
|
||||
use crate::manager::get_default_policyes;
|
||||
use crate::manager::get_default_policies;
|
||||
use crate::manager::{IamCache, IamSyncMetricsSnapshot};
|
||||
use crate::store::GroupInfo;
|
||||
use crate::store::MappedPolicy;
|
||||
@@ -249,7 +249,7 @@ impl<T: Store> IamSys<T> {
|
||||
}
|
||||
|
||||
pub async fn delete_policy(&self, name: &str, notify: bool) -> Result<()> {
|
||||
for k in get_default_policyes().keys() {
|
||||
for k in get_default_policies().keys() {
|
||||
if k == name {
|
||||
return Err(Error::other("system policy can not be deleted"));
|
||||
}
|
||||
@@ -291,8 +291,17 @@ impl<T: Store> IamSys<T> {
|
||||
self.store.api.load_mapped_policies(user_type, is_group, m).await
|
||||
}
|
||||
|
||||
pub async fn list_policies(&self, bucket_name: &str) -> Result<HashMap<String, Policy>> {
|
||||
self.store.list_policies(bucket_name).await
|
||||
}
|
||||
|
||||
/// Backward-compatible misspelling retained until the next breaking release.
|
||||
#[deprecated(
|
||||
since = "1.0.0",
|
||||
note = "use list_policies instead; this alias will be removed in the next breaking release"
|
||||
)]
|
||||
pub async fn list_polices(&self, bucket_name: &str) -> Result<HashMap<String, Policy>> {
|
||||
self.store.list_polices(bucket_name).await
|
||||
self.list_policies(bucket_name).await
|
||||
}
|
||||
|
||||
pub async fn list_policy_docs(&self, bucket_name: &str) -> Result<HashMap<String, PolicyDoc>> {
|
||||
@@ -1683,11 +1692,17 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::cache::{Cache, CacheEntity};
|
||||
use crate::error::Error;
|
||||
use crate::manager::get_default_policyes;
|
||||
use crate::manager::get_default_policies;
|
||||
use crate::store::{GroupInfo, MappedPolicy, Store, UserType};
|
||||
use rustfs_credentials::{Credentials, init_global_action_credentials};
|
||||
use rustfs_policy::auth::{UserIdentity, get_new_credentials_with_metadata};
|
||||
use rustfs_policy::policy::Args;
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn deprecated_list_polices_api_is_available() {
|
||||
let _ = IamSys::<StsTestMockStore>::list_polices;
|
||||
}
|
||||
use rustfs_policy::policy::action::{Action, AdminAction, S3Action};
|
||||
use rustfs_policy::policy::policy_uses_existing_object_tag_conditions;
|
||||
use serde_json::Value;
|
||||
@@ -1925,7 +1940,7 @@ mod tests {
|
||||
}
|
||||
|
||||
async fn load_all(&self, cache: &Cache) -> Result<()> {
|
||||
let mut policy_docs = get_default_policyes();
|
||||
let mut policy_docs = get_default_policies();
|
||||
let custom_claim_policy =
|
||||
Policy::parse_config(CUSTOM_STS_CLAIM_POLICY_JSON.as_bytes()).expect("custom STS claim policy should parse");
|
||||
policy_docs.insert(CUSTOM_STS_CLAIM_POLICY.to_string(), PolicyDoc::new(custom_claim_policy));
|
||||
|
||||
@@ -51,28 +51,6 @@ pub enum ReplicationTargetValidationError {
|
||||
StaleTarget,
|
||||
}
|
||||
|
||||
pub fn unsupported_replication_config_field(config: &ReplicationConfiguration) -> Option<&'static str> {
|
||||
for rule in &config.rules {
|
||||
if rule
|
||||
.source_selection_criteria
|
||||
.as_ref()
|
||||
.is_some_and(|criteria| criteria.sse_kms_encrypted_objects.is_some())
|
||||
{
|
||||
return Some("SourceSelectionCriteria.SseKmsEncryptedObjects");
|
||||
}
|
||||
if rule.destination.encryption_configuration.is_some() {
|
||||
return Some("Destination.EncryptionConfiguration");
|
||||
}
|
||||
if rule.destination.metrics.is_some() {
|
||||
return Some("Destination.Metrics");
|
||||
}
|
||||
if rule.destination.replication_time.is_some() {
|
||||
return Some("Destination.ReplicationTime");
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn active_replication_rule_destination_arns(config: &ReplicationConfiguration) -> HashSet<String> {
|
||||
let mut arns = HashSet::new();
|
||||
|
||||
@@ -239,6 +217,11 @@ impl ReplicationConfigurationExt for ReplicationConfiguration {
|
||||
}
|
||||
|
||||
if obj.version_id.is_some() {
|
||||
if obj.delete_marker {
|
||||
return rule.delete_marker_replication.clone().is_some_and(|d| {
|
||||
d.status == Some(DeleteMarkerReplicationStatus::from_static(DeleteMarkerReplicationStatus::ENABLED))
|
||||
});
|
||||
}
|
||||
return rule
|
||||
.delete_replication
|
||||
.clone()
|
||||
@@ -322,11 +305,7 @@ impl ReplicationConfigurationExt for ReplicationConfiguration {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use s3s::dto::{
|
||||
DeleteMarkerReplication, DeleteReplication, Destination, EncryptionConfiguration, ExistingObjectReplication, Metrics,
|
||||
MetricsStatus, ReplicationRule, ReplicationTime, ReplicationTimeStatus, ReplicationTimeValue, SourceSelectionCriteria,
|
||||
SseKmsEncryptedObjects, SseKmsEncryptedObjectsStatus,
|
||||
};
|
||||
use s3s::dto::{DeleteMarkerReplication, Destination, ExistingObjectReplication, ReplicationRule};
|
||||
|
||||
fn replication_rule(id: &str, arn: &str) -> ReplicationRule {
|
||||
ReplicationRule {
|
||||
@@ -626,99 +605,4 @@ mod tests {
|
||||
"highest-priority rule disables delete-marker replication, so the delete marker must not replicate"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_purge_uses_delete_replication_for_object_and_marker_versions() {
|
||||
let arn = "arn:rustfs:replication:us-east-1:target:bucket";
|
||||
let mut rule = replication_rule("delete", arn);
|
||||
rule.delete_marker_replication = Some(DeleteMarkerReplication {
|
||||
status: Some(DeleteMarkerReplicationStatus::from_static(DeleteMarkerReplicationStatus::DISABLED)),
|
||||
});
|
||||
rule.delete_replication = Some(DeleteReplication {
|
||||
status: DeleteReplicationStatus::from_static(DeleteReplicationStatus::ENABLED),
|
||||
});
|
||||
let mut config = ReplicationConfiguration {
|
||||
role: String::new(),
|
||||
rules: vec![rule],
|
||||
};
|
||||
let version_id = Some(Uuid::new_v4());
|
||||
|
||||
for delete_marker in [false, true] {
|
||||
assert!(config.replicate(&ObjectOpts {
|
||||
name: "object".to_string(),
|
||||
version_id,
|
||||
delete_marker,
|
||||
op_type: ReplicationType::Delete,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
assert!(!config.replicate(&ObjectOpts {
|
||||
name: "object".to_string(),
|
||||
delete_marker: true,
|
||||
op_type: ReplicationType::Delete,
|
||||
..Default::default()
|
||||
}));
|
||||
|
||||
let rule = &mut config.rules[0];
|
||||
rule.delete_marker_replication = Some(DeleteMarkerReplication {
|
||||
status: Some(DeleteMarkerReplicationStatus::from_static(DeleteMarkerReplicationStatus::ENABLED)),
|
||||
});
|
||||
rule.delete_replication = Some(DeleteReplication {
|
||||
status: DeleteReplicationStatus::from_static(DeleteReplicationStatus::DISABLED),
|
||||
});
|
||||
|
||||
for delete_marker in [false, true] {
|
||||
assert!(!config.replicate(&ObjectOpts {
|
||||
name: "object".to_string(),
|
||||
version_id,
|
||||
delete_marker,
|
||||
op_type: ReplicationType::Delete,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
assert!(config.replicate(&ObjectOpts {
|
||||
name: "object".to_string(),
|
||||
delete_marker: true,
|
||||
op_type: ReplicationType::Delete,
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsupported_replication_fields_are_reported_before_persistence() {
|
||||
let arn = "arn:rustfs:replication:us-east-1:target:bucket";
|
||||
let mut config = ReplicationConfiguration {
|
||||
role: String::new(),
|
||||
rules: vec![replication_rule("unsupported", arn)],
|
||||
};
|
||||
|
||||
config.rules[0].source_selection_criteria = Some(SourceSelectionCriteria {
|
||||
replica_modifications: None,
|
||||
sse_kms_encrypted_objects: Some(SseKmsEncryptedObjects {
|
||||
status: SseKmsEncryptedObjectsStatus::from_static(SseKmsEncryptedObjectsStatus::ENABLED),
|
||||
}),
|
||||
});
|
||||
assert_eq!(
|
||||
unsupported_replication_config_field(&config),
|
||||
Some("SourceSelectionCriteria.SseKmsEncryptedObjects")
|
||||
);
|
||||
|
||||
config.rules[0].source_selection_criteria = None;
|
||||
config.rules[0].destination.encryption_configuration = Some(EncryptionConfiguration::default());
|
||||
assert_eq!(unsupported_replication_config_field(&config), Some("Destination.EncryptionConfiguration"));
|
||||
|
||||
config.rules[0].destination.encryption_configuration = None;
|
||||
config.rules[0].destination.metrics = Some(Metrics {
|
||||
event_threshold: None,
|
||||
status: MetricsStatus::from_static(MetricsStatus::ENABLED),
|
||||
});
|
||||
assert_eq!(unsupported_replication_config_field(&config), Some("Destination.Metrics"));
|
||||
|
||||
config.rules[0].destination.metrics = None;
|
||||
config.rules[0].destination.replication_time = Some(ReplicationTime {
|
||||
status: ReplicationTimeStatus::from_static(ReplicationTimeStatus::ENABLED),
|
||||
time: ReplicationTimeValue { minutes: Some(15) },
|
||||
});
|
||||
assert_eq!(unsupported_replication_config_field(&config), Some("Destination.ReplicationTime"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@ pub mod tagging;
|
||||
|
||||
pub use config::{
|
||||
ObjectOpts, ReplicationConfigurationExt, ReplicationTargetValidationError, active_replication_rule_destination_arns,
|
||||
replication_target_arns, should_remove_replication_target, unsupported_replication_config_field,
|
||||
validate_replication_config_target_arns,
|
||||
replication_target_arns, should_remove_replication_target, validate_replication_config_target_arns,
|
||||
};
|
||||
pub use delete::{
|
||||
DeletedObjectReplicationInfo, is_retryable_delete_replication_head_error, is_version_delete_replication,
|
||||
|
||||
@@ -322,9 +322,9 @@ mod tests {
|
||||
use crate::storage_api::ObjectToDelete;
|
||||
use crate::{ReplicationStatusType, ReplicationType, VersionPurgeStatusType, target_reset_header};
|
||||
use s3s::dto::{
|
||||
DeleteMarkerReplication, DeleteMarkerReplicationStatus, DeleteReplication, DeleteReplicationStatus, Destination,
|
||||
ExistingObjectReplication, ExistingObjectReplicationStatus, ReplicaModifications, ReplicaModificationsStatus,
|
||||
ReplicationConfiguration, ReplicationRule, ReplicationRuleStatus, SourceSelectionCriteria,
|
||||
DeleteMarkerReplication, DeleteMarkerReplicationStatus, Destination, ExistingObjectReplication,
|
||||
ExistingObjectReplicationStatus, ReplicaModifications, ReplicaModificationsStatus, ReplicationConfiguration,
|
||||
ReplicationRule, ReplicationRuleStatus, SourceSelectionCriteria,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use time::{Duration, OffsetDateTime};
|
||||
@@ -433,9 +433,7 @@ mod tests {
|
||||
delete_marker_replication: Some(DeleteMarkerReplication {
|
||||
status: Some(DeleteMarkerReplicationStatus::from_static(DeleteMarkerReplicationStatus::ENABLED)),
|
||||
}),
|
||||
delete_replication: Some(DeleteReplication {
|
||||
status: DeleteReplicationStatus::from_static(DeleteReplicationStatus::ENABLED),
|
||||
}),
|
||||
delete_replication: None,
|
||||
destination: Destination {
|
||||
bucket: arn.to_string(),
|
||||
..Default::default()
|
||||
@@ -515,7 +513,7 @@ mod tests {
|
||||
};
|
||||
|
||||
let state = delete_replication_state_from_config(&config, &source)
|
||||
.expect("delete-marker version purge should honor delete replication rules");
|
||||
.expect("delete-marker version purge should honor delete-marker replication rules");
|
||||
let pending = format!("{arn}=PENDING;");
|
||||
|
||||
assert_eq!(state.version_purge_status_internal.as_deref(), Some(pending.as_str()));
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{
|
||||
default = rustPlatform.buildRustPackage {
|
||||
pname = "rustfs";
|
||||
version = "1.0.0-beta.11";
|
||||
version = "1.0.0-beta.12";
|
||||
|
||||
src = ./.;
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ apiVersion: v2
|
||||
name: rustfs
|
||||
description: RustFS helm chart to deploy RustFS on kubernetes cluster.
|
||||
type: application
|
||||
version: "0.11.0"
|
||||
appVersion: "1.0.0-beta.11"
|
||||
version: "0.12.0"
|
||||
appVersion: "1.0.0-beta.12"
|
||||
home: https://rustfs.com
|
||||
icon: https://media.sys.truenas.net/apps/rustfs/icons/icon.svg
|
||||
maintainers:
|
||||
|
||||
+5
-2
@@ -1,9 +1,9 @@
|
||||
%global _enable_debug_packages 0
|
||||
%global _empty_manifest_terminate_build 0
|
||||
%global prerelease beta.11
|
||||
%global prerelease beta.12
|
||||
Name: rustfs
|
||||
Version: 1.0.0
|
||||
Release: beta.11
|
||||
Release: beta.12
|
||||
Summary: High-performance distributed object storage for MinIO alternative
|
||||
|
||||
License: Apache-2.0
|
||||
@@ -58,6 +58,9 @@ install %_builddir/%{name}-%{version}-%{prerelease}/target/%_arch/%_arch-unknown
|
||||
%_bindir/rustfs
|
||||
|
||||
%changelog
|
||||
* Thu Jul 30 2026 overtrue <anzhengchao@gmail.com>
|
||||
- Update RPM package to RustFS 1.0.0-beta.12
|
||||
|
||||
* Thu Jul 23 2026 overtrue <anzhengchao@gmail.com>
|
||||
- Update RPM package to RustFS 1.0.0-beta.11
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ impl Operation for ListCannedPolicies {
|
||||
return Err(s3_error!(InternalError, "iam is not initialized"));
|
||||
};
|
||||
|
||||
let policies = iam_store.list_polices(&query.bucket).await.map_err(|e| {
|
||||
let policies = iam_store.list_policies(&query.bucket).await.map_err(|e| {
|
||||
warn!(
|
||||
component = LOG_COMPONENT_ADMIN,
|
||||
subsystem = LOG_SUBSYSTEM_POLICY,
|
||||
|
||||
@@ -179,20 +179,6 @@ impl RemoteTargetRequest {
|
||||
return Err(s3_error!(InvalidRequest, "credentials.secretKey is required"));
|
||||
}
|
||||
|
||||
for (unsupported, configured) in [
|
||||
("disableProxy", self.disable_proxy),
|
||||
("healthCheckDuration", self.health_check_duration != 0),
|
||||
("edge", self.edge),
|
||||
("edgeSyncBeforeExpiry", self.edge_sync_before_expiry),
|
||||
] {
|
||||
if configured {
|
||||
return Err(s3_error!(
|
||||
InvalidRequest,
|
||||
"remote target field {unsupported} is not supported by this RustFS version"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(BucketTarget {
|
||||
source_bucket: self.source_bucket,
|
||||
endpoint: self.endpoint,
|
||||
@@ -1218,27 +1204,6 @@ mod tests {
|
||||
assert!(err.to_string().contains("credentials.secretKey is required"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_target_request_rejects_unimplemented_fields() {
|
||||
for (field, value) in [
|
||||
("disableProxy", serde_json::json!(true)),
|
||||
("healthCheckDuration", serde_json::json!(5)),
|
||||
("edge", serde_json::json!(true)),
|
||||
("edgeSyncBeforeExpiry", serde_json::json!(true)),
|
||||
] {
|
||||
let mut request = valid_remote_target_request();
|
||||
request[field] = value;
|
||||
let request: RemoteTargetRequest =
|
||||
serde_json::from_value(request).expect("unsupported field should still deserialize");
|
||||
let err = request
|
||||
.into_bucket_target()
|
||||
.expect_err("unimplemented remote target fields must not be persisted");
|
||||
|
||||
assert!(err.to_string().contains(field));
|
||||
assert!(err.to_string().contains("not supported by this RustFS version"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_target_request_converts_to_bucket_target() {
|
||||
let target = serde_json::from_value::<RemoteTargetRequest>(valid_remote_target_request())
|
||||
|
||||
@@ -724,7 +724,7 @@ impl Operation for ExportIam {
|
||||
match file {
|
||||
ALL_POLICIES_FILE => {
|
||||
let policies: HashMap<String, rustfs_policy::policy::Policy> = iam_store
|
||||
.list_polices("")
|
||||
.list_policies("")
|
||||
.await
|
||||
.map_err(|e| S3Error::with_message(S3ErrorCode::InternalError, e.to_string()))?;
|
||||
let json_str = serde_json::to_vec(&policies)
|
||||
|
||||
@@ -35,7 +35,7 @@ use super::storage_api::bucket_usecase::bucket::{
|
||||
policy_sys::PolicySys,
|
||||
replication::{
|
||||
ReplicationTargetValidationError, replication_target_arns, should_remove_replication_target,
|
||||
unsupported_replication_config_field, validate_replication_config_target_arns,
|
||||
validate_replication_config_target_arns,
|
||||
},
|
||||
target::{BucketTargetType, BucketTargets},
|
||||
utils::serialize,
|
||||
@@ -556,16 +556,6 @@ fn validate_replication_config_targets(targets: &BucketTargets, config: &Replica
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_replication_config_capabilities(config: &ReplicationConfiguration) -> S3Result<()> {
|
||||
if let Some(field) = unsupported_replication_config_field(config) {
|
||||
return Err(S3Error::with_message(
|
||||
S3ErrorCode::InvalidRequest,
|
||||
format!("replication field {field} is not supported by this RustFS version"),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn validate_bucket_replication_update(bucket: &str, config: &ReplicationConfiguration) -> S3Result<()> {
|
||||
if !BucketVersioningSys::enabled(bucket).await {
|
||||
return Err(s3_error!(
|
||||
@@ -574,8 +564,6 @@ async fn validate_bucket_replication_update(bucket: &str, config: &ReplicationCo
|
||||
));
|
||||
}
|
||||
|
||||
validate_replication_config_capabilities(config)?;
|
||||
|
||||
let targets = metadata_sys::get_bucket_targets_config(bucket)
|
||||
.await
|
||||
.map_err(|err| match err {
|
||||
@@ -3087,25 +3075,6 @@ mod tests {
|
||||
validate_replication_config_targets(&targets, &config).expect("disabled rules should not require live targets");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_replication_config_capabilities_names_unsupported_field() {
|
||||
let mut rule = replication_rule_for_target("arn:rustfs:replication:us-east-1:target:bucket");
|
||||
rule.destination.encryption_configuration = Some(s3s::dto::EncryptionConfiguration::default());
|
||||
let config = ReplicationConfiguration {
|
||||
role: String::new(),
|
||||
rules: vec![rule],
|
||||
};
|
||||
|
||||
let err = validate_replication_config_capabilities(&config)
|
||||
.expect_err("destination encryption must be rejected until the execution path supports it");
|
||||
|
||||
assert_eq!(err.code(), &S3ErrorCode::InvalidRequest);
|
||||
assert!(
|
||||
err.to_string()
|
||||
.contains("Destination.EncryptionConfiguration is not supported")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_replication_targets_from_config_targets_only_removes_referenced_replication_targets() {
|
||||
let removed_arn = "arn:rustfs:replication:us-east-1:removed:bucket";
|
||||
|
||||
@@ -44,8 +44,8 @@ use super::storage_api::object_usecase::bucket::{
|
||||
REPLICATE_INCOMING_DELETE, ReplicationStatusType, VersionPurgeStatusType, check_replicate_delete,
|
||||
delete_replication_state_from_config, delete_replication_version_id, deleted_object_has_pending_replication_delete,
|
||||
must_replicate_object, schedule_object_replication, schedule_replication_delete, set_deleted_object_replication_state,
|
||||
set_object_to_delete_version_purge_status, should_use_existing_delete_replication_info,
|
||||
should_use_existing_delete_replication_source,
|
||||
set_object_to_delete_version_purge_status, should_schedule_delete_replication,
|
||||
should_use_existing_delete_replication_info, should_use_existing_delete_replication_source,
|
||||
},
|
||||
tagging::decode_tags,
|
||||
validate_restore_request,
|
||||
@@ -6704,7 +6704,7 @@ impl DefaultObjectUsecase {
|
||||
// the same early, advisory rejection as before.
|
||||
let store_ref = &store;
|
||||
let bucket_ref = bucket.as_str();
|
||||
let admitted_deletes: Vec<Result<AdmittedDelete, ApiError>> =
|
||||
let admitted_deletes: Vec<AdmittedDelete> =
|
||||
futures::stream::iter(prepared_deletes.into_iter().map(|prepared| async move {
|
||||
let PreparedDelete {
|
||||
idx,
|
||||
@@ -6729,7 +6729,7 @@ impl DefaultObjectUsecase {
|
||||
&& let Some(block_reason) = check_object_lock_for_deletion(bucket_ref, &goi, bypass_governance).await
|
||||
{
|
||||
let blocked_key = object.object_name.clone();
|
||||
return Ok(AdmittedDelete {
|
||||
return AdmittedDelete {
|
||||
idx,
|
||||
object,
|
||||
size: 0,
|
||||
@@ -6740,11 +6740,15 @@ impl DefaultObjectUsecase {
|
||||
message: Some(block_reason.error_message()),
|
||||
version_id,
|
||||
}),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
let size = goi.size;
|
||||
|
||||
if is_dir_object(&object.object_name) && object.version_id.is_none() {
|
||||
object.version_id = Some(Uuid::nil());
|
||||
}
|
||||
|
||||
if replicate_deletes {
|
||||
let dsc = check_replicate_delete(
|
||||
bucket_ref,
|
||||
@@ -6757,8 +6761,7 @@ impl DefaultObjectUsecase {
|
||||
&opts,
|
||||
gerr.clone(),
|
||||
)
|
||||
.await
|
||||
.map_err(ApiError::from)?;
|
||||
.await;
|
||||
if dsc.replicate_any() {
|
||||
if object.version_id.is_some() {
|
||||
set_object_to_delete_version_purge_status(&mut object, VersionPurgeStatusType::Pending);
|
||||
@@ -6770,23 +6773,18 @@ impl DefaultObjectUsecase {
|
||||
}
|
||||
}
|
||||
|
||||
if is_dir_object(&object.object_name) && object.version_id.is_none() {
|
||||
object.version_id = Some(Uuid::nil());
|
||||
}
|
||||
|
||||
let existing = (!skip_stat && gerr.is_none()).then_some(goi);
|
||||
Ok(AdmittedDelete {
|
||||
AdmittedDelete {
|
||||
idx,
|
||||
object,
|
||||
size,
|
||||
existing,
|
||||
blocked: None,
|
||||
})
|
||||
}
|
||||
}))
|
||||
.buffered(DELETE_OBJECTS_PRE_STAT_CONCURRENCY)
|
||||
.collect()
|
||||
.await;
|
||||
let admitted_deletes: Vec<AdmittedDelete> = admitted_deletes.into_iter().collect::<Result<_, ApiError>>()?;
|
||||
|
||||
// Phase 3 (serial): apply outcomes in the original request order so
|
||||
// per-key success/failure reporting is unchanged.
|
||||
@@ -7104,28 +7102,6 @@ impl DefaultObjectUsecase {
|
||||
}
|
||||
};
|
||||
|
||||
let delete_replication_state = if !replica && !force_delete && (opts.versioned || opts.version_suspended) {
|
||||
let fallback_source;
|
||||
let source = if let Some(source) = existing_object_info.as_ref() {
|
||||
source
|
||||
} else {
|
||||
fallback_source = ObjectInfo {
|
||||
name: key.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
&fallback_source
|
||||
};
|
||||
match metadata_sys::get_replication_config(&bucket).await {
|
||||
Ok((config, _)) => {
|
||||
delete_replication_state_from_config(&config, source, version_id_clone.as_ref().and(source.version_id), false)
|
||||
}
|
||||
Err(StorageError::ConfigNotFound) => None,
|
||||
Err(err) => return Err(ApiError::from(err).into()),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let cache_adapter = self.object_data_cache();
|
||||
// A force (delete_prefix) delete removes every object under `key` as a
|
||||
// prefix, so invalidating only the exact key would strand every cached
|
||||
@@ -7221,7 +7197,7 @@ impl DefaultObjectUsecase {
|
||||
let schedule_delete_replication = if opts.replication_request && replica {
|
||||
should_schedule_replica_delete_replication(&bucket, replication_state_source, delete_replication_version_id).await
|
||||
} else {
|
||||
delete_replication_state.is_some()
|
||||
should_schedule_delete_replication(&opts, deleted_object_source, deleted_delete_marker_version)
|
||||
};
|
||||
|
||||
if schedule_delete_replication {
|
||||
@@ -7243,12 +7219,8 @@ impl DefaultObjectUsecase {
|
||||
replication_state: None,
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(state) = delete_replication_state.as_ref() {
|
||||
set_deleted_object_replication_state(&mut deleted_object, state);
|
||||
} else {
|
||||
set_deleted_object_replication_state(&mut deleted_object, &replication_state_source.replication_state());
|
||||
enrich_delete_replication_state_if_needed(&bucket, &mut deleted_object, replication_state_source).await;
|
||||
}
|
||||
set_deleted_object_replication_state(&mut deleted_object, &replication_state_source.replication_state());
|
||||
enrich_delete_replication_state_if_needed(&bucket, &mut deleted_object, replication_state_source).await;
|
||||
schedule_replication_delete(deleted_object, bucket.clone(), REPLICATE_INCOMING_DELETE.to_string()).await;
|
||||
}
|
||||
|
||||
@@ -8386,10 +8358,9 @@ mod tests {
|
||||
use super::*;
|
||||
use http::{Extensions, HeaderMap, HeaderName, HeaderValue, Method, Uri};
|
||||
use s3s::dto::{
|
||||
Delete, DeleteMarkerReplication, DeleteMarkerReplicationStatus, DeleteReplication, DeleteReplicationStatus, Destination,
|
||||
ExistingObjectReplication, ExistingObjectReplicationStatus, ObjectIdentifier, ReplicaModifications,
|
||||
ReplicaModificationsStatus, ReplicationConfiguration, ReplicationRule, ReplicationRuleStatus, RestoreRequest,
|
||||
SourceSelectionCriteria,
|
||||
Delete, DeleteMarkerReplication, DeleteMarkerReplicationStatus, Destination, ExistingObjectReplication,
|
||||
ExistingObjectReplicationStatus, ObjectIdentifier, ReplicaModifications, ReplicaModificationsStatus,
|
||||
ReplicationConfiguration, ReplicationRule, ReplicationRuleStatus, RestoreRequest, SourceSelectionCriteria,
|
||||
};
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
@@ -13397,6 +13368,63 @@ mod tests {
|
||||
assert!(!can_skip_delete_objects_pre_stat(false, false, &delete_marker_creating_opts(), false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_schedule_delete_replication_skips_replica_requests() {
|
||||
let opts = ObjectOptions {
|
||||
replication_request: true,
|
||||
version_id: Some(Uuid::new_v4().to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
let replication_source = ObjectInfo {
|
||||
delete_marker: true,
|
||||
replication_status: ReplicationStatusType::Completed,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert!(
|
||||
!should_schedule_delete_replication(&opts, &replication_source, true),
|
||||
"replica delete requests on target sites must not enqueue a second replication delete task"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_schedule_delete_replication_keeps_delete_marker_version_purge_from_source() {
|
||||
let opts = ObjectOptions {
|
||||
replication_request: false,
|
||||
version_id: Some(Uuid::new_v4().to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
let replication_source = ObjectInfo {
|
||||
delete_marker: true,
|
||||
replication_status: ReplicationStatusType::Completed,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert!(
|
||||
should_schedule_delete_replication(&opts, &replication_source, true),
|
||||
"source-side delete-marker version purge still needs replication scheduling"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_schedule_delete_replication_keeps_object_version_purge_from_completed_source() {
|
||||
let opts = ObjectOptions {
|
||||
replication_request: false,
|
||||
version_id: Some(Uuid::new_v4().to_string()),
|
||||
..Default::default()
|
||||
};
|
||||
let replication_source = ObjectInfo {
|
||||
delete_marker: false,
|
||||
replication_status: ReplicationStatusType::Completed,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert!(
|
||||
should_schedule_delete_replication(&opts, &replication_source, false),
|
||||
"source-side object version purge must still enqueue delete replication after the original PUT completed"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "requires isolated global object layer state"]
|
||||
async fn execute_get_object_attributes_returns_internal_error_when_store_uninitialized() {
|
||||
@@ -13661,9 +13689,7 @@ mod tests {
|
||||
delete_marker_replication: Some(DeleteMarkerReplication {
|
||||
status: Some(DeleteMarkerReplicationStatus::from_static(DeleteMarkerReplicationStatus::ENABLED)),
|
||||
}),
|
||||
delete_replication: Some(DeleteReplication {
|
||||
status: DeleteReplicationStatus::from_static(DeleteReplicationStatus::ENABLED),
|
||||
}),
|
||||
delete_replication: None,
|
||||
destination: Destination {
|
||||
bucket: arn.clone(),
|
||||
..Default::default()
|
||||
|
||||
@@ -649,8 +649,8 @@ pub(crate) mod bucket {
|
||||
oi: &crate::storage::storage_api::StorageObjectInfo,
|
||||
del_opts: &crate::storage::storage_api::StorageObjectOptions,
|
||||
gerr: Option<String>,
|
||||
) -> Result<ReplicateDecision, crate::storage::storage_api::StorageError> {
|
||||
ReplicationObjectBridge::check_delete_strict(bucket, dobj, oi, del_opts, gerr).await
|
||||
) -> ReplicateDecision {
|
||||
ReplicationObjectBridge::check_delete(bucket, dobj, oi, del_opts, gerr).await
|
||||
}
|
||||
|
||||
pub(crate) fn delete_replication_version_id(
|
||||
@@ -751,6 +751,21 @@ pub(crate) mod bucket {
|
||||
replication_contracts::should_remove_replication_target(target_arn, is_replication_service, target_arns)
|
||||
}
|
||||
|
||||
pub(crate) fn should_schedule_delete_replication(
|
||||
opts: &crate::storage::storage_api::StorageObjectOptions,
|
||||
replication_source: &crate::storage::storage_api::StorageObjectInfo,
|
||||
deleted_delete_marker_version: bool,
|
||||
) -> bool {
|
||||
replication_contracts::should_schedule_delete_replication(replication_contracts::ReplicationDeleteScheduleInput {
|
||||
replication_request: opts.replication_request,
|
||||
version_id_requested: opts.version_id.is_some(),
|
||||
source_delete_marker: replication_source.delete_marker,
|
||||
source_replication_status: &replication_source.replication_status,
|
||||
source_version_purge_status: &replication_source.version_purge_status,
|
||||
deleted_delete_marker_version,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn should_use_existing_delete_replication_info(
|
||||
opts: &crate::storage::storage_api::StorageObjectOptions,
|
||||
) -> bool {
|
||||
@@ -775,10 +790,6 @@ pub(crate) mod bucket {
|
||||
) -> Result<(), ReplicationTargetValidationError> {
|
||||
replication_contracts::validate_replication_config_target_arns(configured_arns, config)
|
||||
}
|
||||
|
||||
pub(crate) fn unsupported_replication_config_field(config: &s3s::dto::ReplicationConfiguration) -> Option<&'static str> {
|
||||
replication_contracts::unsupported_replication_config_field(config)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod tagging {
|
||||
|
||||
@@ -13,7 +13,14 @@ fi
|
||||
classify_source_layer() {
|
||||
local file="$1"
|
||||
|
||||
if [[ "$file" == rustfs/src/app/* ]]; then
|
||||
if [[ "$file" == rustfs/src/server/* ]] ||
|
||||
[[ "$file" == rustfs/src/startup_*.rs ]] ||
|
||||
[[ "$file" == rustfs/src/init.rs ]] ||
|
||||
[[ "$file" == rustfs/src/main.rs ]] ||
|
||||
[[ "$file" == rustfs/src/lib.rs ]] ||
|
||||
[[ "$file" == rustfs/src/embedded.rs ]]; then
|
||||
printf 'composition'
|
||||
elif [[ "$file" == rustfs/src/app/* ]]; then
|
||||
printf 'app'
|
||||
elif [[ "$file" == rustfs/src/admin/* ]] || [[ "$file" == rustfs/src/storage/ecfs.rs ]] || [[ "$file" == rustfs/src/storage/s3_api/* ]]; then
|
||||
printf 'interface'
|
||||
@@ -30,6 +37,14 @@ classify_target_layer() {
|
||||
local storage_path
|
||||
|
||||
case "$root" in
|
||||
init | main | lib | embedded | startup_*)
|
||||
printf 'composition'
|
||||
;;
|
||||
server)
|
||||
# Server files are composition roots when they import lower layers, but
|
||||
# their exported HTTP contracts belong to the interface boundary.
|
||||
printf 'interface'
|
||||
;;
|
||||
app)
|
||||
printf 'app'
|
||||
;;
|
||||
@@ -53,6 +68,9 @@ classify_target_layer() {
|
||||
|
||||
layer_rank() {
|
||||
case "$1" in
|
||||
composition)
|
||||
printf '4'
|
||||
;;
|
||||
interface)
|
||||
printf '3'
|
||||
;;
|
||||
@@ -68,6 +86,50 @@ layer_rank() {
|
||||
esac
|
||||
}
|
||||
|
||||
is_reverse_dependency() {
|
||||
local source_rank target_rank
|
||||
|
||||
source_rank="$(layer_rank "$1")"
|
||||
target_rank="$(layer_rank "$2")"
|
||||
(( source_rank < target_rank ))
|
||||
}
|
||||
|
||||
assert_dependency_direction() {
|
||||
local expected="$1"
|
||||
local source="$2"
|
||||
local target="$3"
|
||||
local actual='allowed'
|
||||
|
||||
if is_reverse_dependency "$source" "$target"; then
|
||||
actual='reverse'
|
||||
fi
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
printf 'Layer dependency guard self-test failed: %s -> %s (expected %s, got %s)\n' \
|
||||
"$source" "$target" "$expected" "$actual" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_layer_model_self_tests() {
|
||||
local server_source app_source storage_source server_target admin_target app_target storage_target
|
||||
|
||||
server_source="$(classify_source_layer rustfs/src/server/http.rs)"
|
||||
app_source="$(classify_source_layer rustfs/src/app/bucket_usecase.rs)"
|
||||
storage_source="$(classify_source_layer rustfs/src/storage/rpc/node_service.rs)"
|
||||
server_target="$(classify_target_layer server::http)"
|
||||
admin_target="$(classify_target_layer admin::router)"
|
||||
app_target="$(classify_target_layer app::bucket_usecase)"
|
||||
storage_target="$(classify_target_layer storage::rpc)"
|
||||
|
||||
assert_dependency_direction 'allowed' "$server_source" "$admin_target"
|
||||
assert_dependency_direction 'allowed' "$server_source" "$app_target"
|
||||
assert_dependency_direction 'allowed' "$server_source" "$storage_target"
|
||||
assert_dependency_direction 'reverse' "$app_source" "$server_target"
|
||||
assert_dependency_direction 'reverse' "$storage_source" "$server_target"
|
||||
assert_dependency_direction 'reverse' "$app_source" "$admin_target"
|
||||
assert_dependency_direction 'reverse' "$storage_source" "$admin_target"
|
||||
}
|
||||
|
||||
normalize_import_group_item() {
|
||||
local prefix="$1"
|
||||
local item="$2"
|
||||
@@ -182,6 +244,11 @@ normalize_import_path() {
|
||||
|
||||
emit_crate_use_statements() {
|
||||
(cd "$ROOT_DIR" && rg --files -g '*.rs' rustfs/src | while IFS= read -r file; do
|
||||
# The guard is file-scoped: dedicated test modules are excluded, while
|
||||
# inline #[cfg(test)] imports remain subject to the source file's layer.
|
||||
if [[ "$file" == *_test.rs ]] || [[ "$file" == */tests/* ]]; then
|
||||
continue
|
||||
fi
|
||||
perl -0777 -ne '
|
||||
while (/\buse\s+crate::.*?;/sg) {
|
||||
my $statement = $&;
|
||||
@@ -194,6 +261,26 @@ emit_crate_use_statements() {
|
||||
done)
|
||||
}
|
||||
|
||||
write_baseline_file() {
|
||||
local entries="$1"
|
||||
|
||||
cat >"$BASELINE_FILE" <<'EOF'
|
||||
# Layer dependency baseline for the rustfs binary crate.
|
||||
#
|
||||
# The guard models production imports as:
|
||||
# composition -> interface -> app -> infra
|
||||
#
|
||||
# Canonical dependency entry:
|
||||
# dep|source_file|source_layer->target_layer|crate::imported_symbol
|
||||
#
|
||||
# Canonical conceptual cycle entry:
|
||||
# cycle|left_layer<->right_layer
|
||||
EOF
|
||||
cat "$entries" >>"$BASELINE_FILE"
|
||||
}
|
||||
|
||||
run_layer_model_self_tests
|
||||
|
||||
normalize_baseline_file() {
|
||||
local input="$1"
|
||||
local output="$2"
|
||||
@@ -265,10 +352,7 @@ while IFS= read -r line; do
|
||||
printf '%s->%s\n' "$source_layer" "$target_layer" >>"$EDGES_RAW"
|
||||
fi
|
||||
|
||||
source_rank="$(layer_rank "$source_layer")"
|
||||
target_rank="$(layer_rank "$target_layer")"
|
||||
|
||||
if (( source_rank < target_rank )); then
|
||||
if is_reverse_dependency "$source_layer" "$target_layer"; then
|
||||
printf 'dep|%s|%s->%s|crate::%s\n' "$file" "$source_layer" "$target_layer" "$import_path" >>"$VIOLATIONS_RAW"
|
||||
fi
|
||||
done < <(normalize_import_path "$text")
|
||||
@@ -292,7 +376,7 @@ done <"${TMP_DIR}/edges_sorted.txt" | sort -u >"${TMP_DIR}/cycles_sorted.txt"
|
||||
cat "${TMP_DIR}/violations_sorted.txt" "${TMP_DIR}/cycles_sorted.txt" | sort -u >"$CURRENT_BASELINE"
|
||||
|
||||
if [[ "$MODE" == "update" ]]; then
|
||||
cp "$CURRENT_BASELINE" "$BASELINE_FILE"
|
||||
write_baseline_file "$CURRENT_BASELINE"
|
||||
echo "Updated baseline: $BASELINE_FILE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
# Layer dependency baseline for the rustfs binary crate.
|
||||
#
|
||||
# These are intra-crate module references within rustfs/ that cross the
|
||||
# conceptual layer boundaries (app, infra/server, interface/admin).
|
||||
# Since they live inside one Cargo crate, Rust doesn't enforce separation.
|
||||
# The list is maintained for architectural awareness during code review.
|
||||
# The guard models production imports as:
|
||||
# composition -> interface -> app -> infra
|
||||
#
|
||||
# Format for dependency entries:
|
||||
# status|source_file|direction|imported_symbol|reason
|
||||
# Canonical dependency entry:
|
||||
# dep|source_file|source_layer->target_layer|crate::imported_symbol
|
||||
#
|
||||
# Format for conceptual cycles:
|
||||
# status|cycle|direction_pair|reason
|
||||
#
|
||||
# Status:
|
||||
# accepted - reviewed and intentionally allowed
|
||||
# todo - should be resolved in a future refactor
|
||||
|
||||
# Canonical conceptual cycle entry:
|
||||
# cycle|left_layer<->right_layer
|
||||
cycle|app<->infra
|
||||
cycle|app<->interface
|
||||
cycle|composition<->infra
|
||||
cycle|composition<->interface
|
||||
cycle|infra<->interface
|
||||
dep|rustfs/src/admin/handlers/scanner.rs|interface->composition|crate::startup_background::ENV_SCANNER_ENABLED
|
||||
dep|rustfs/src/admin/handlers/scanner.rs|interface->composition|crate::startup_background::scanner_enabled_from_env
|
||||
dep|rustfs/src/app/admin_usecase.rs|app->interface|crate::server::DependencyReadiness
|
||||
dep|rustfs/src/app/admin_usecase.rs|app->interface|crate::server::collect_dependency_readiness_report
|
||||
dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_bucket_meta_hook
|
||||
dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_delete_bucket_hook
|
||||
dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::admin::handlers::site_replication::site_replication_make_bucket_hook
|
||||
dep|rustfs/src/init.rs|infra->interface|crate::admin
|
||||
dep|rustfs/src/app/bucket_usecase.rs|app->interface|crate::server::RemoteAddr
|
||||
dep|rustfs/src/app/object_usecase.rs|app->interface|crate::server::convert_ecstore_object_info
|
||||
dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::DependencyReadiness
|
||||
dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::DependencyReadinessReport
|
||||
dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::ReadinessDegradedReason
|
||||
dep|rustfs/src/cluster_snapshot.rs|infra->interface|crate::server::snapshot_dependency_readiness_report
|
||||
dep|rustfs/src/runtime_sources.rs|infra->app|crate::app::context
|
||||
dep|rustfs/src/server/http.rs|infra->interface|crate::admin
|
||||
dep|rustfs/src/server/layer.rs|infra->interface|crate::admin::console::is_console_path
|
||||
dep|rustfs/src/storage/access.rs|infra->interface|crate::server::RemoteAddr
|
||||
dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::server::cors
|
||||
dep|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery
|
||||
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::FS
|
||||
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::validate_object_lock_configuration_input
|
||||
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_initiator
|
||||
dep|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_owner
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::convert_ecstore_object_info
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::is_audit_module_enabled
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::is_notify_module_enabled
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::refresh_audit_module_enabled
|
||||
dep|rustfs/src/storage/helper.rs|infra->interface|crate::server::refresh_notify_module_enabled
|
||||
dep|rustfs/src/storage/rpc/http_service.rs|infra->interface|crate::server::RPC_PREFIX
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_dynamic_config_runtime_state
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state
|
||||
dep|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::server::MODULE_SWITCHES_SIGNAL_SUBSYSTEM
|
||||
dep|rustfs/src/storage/rpc/node_service/heal.rs|infra->composition|crate::startup_background::heal_enabled_from_env
|
||||
dep|rustfs/src/storage/rpc/node_service/heal.rs|infra->composition|crate::startup_background::scanner_enabled_from_env
|
||||
|
||||
Reference in New Issue
Block a user