From ef111a3e407bbf5b8d3435966fe81586294c9935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Sun, 21 Jun 2026 23:33:44 +0800 Subject: [PATCH] refactor: prune outer compat facade aliases (#3700) --- docs/architecture/crate-boundaries.md | 5 ++ docs/architecture/migration-progress.md | 47 ++++++++++++++----- rustfs/src/admin/storage_compat.rs | 4 +- rustfs/src/app/storage_compat.rs | 18 +++---- rustfs/src/storage/storage_compat.rs | 4 +- scripts/check_architecture_migration_rules.sh | 13 +++++ 6 files changed, 67 insertions(+), 24 deletions(-) diff --git a/docs/architecture/crate-boundaries.md b/docs/architecture/crate-boundaries.md index 66420f8d9..514ce2ae3 100644 --- a/docs/architecture/crate-boundaries.md +++ b/docs/architecture/crate-boundaries.md @@ -175,6 +175,11 @@ directly except temporary trait imports needed for method resolution. Remaining storage-owner compatibility symbols must be local constants, type aliases, or wrapper functions so storage-owned global state and helper access stays visible at the boundary. +RustFS app, admin, and storage outer `storage_compat.rs` object and error +facade aliases must stay anchored on storage-api associated object types and +local `StorageError` aliases. They must not reintroduce raw +`rustfs_ecstore::api::object::{ObjectInfo,ObjectOptions}` or +`rustfs_ecstore::api::error::{Error,Result}` references. Scanner, notify, observability, and e2e `storage_compat.rs` boundaries must also stay narrow. Scanner must not restore grouped bucket compatibility exports for target, lifecycle, metadata, replication, or versioning modules. Notify diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index d1b9eff53..5e2c9ece2 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,17 +5,16 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block ## Current Context - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) -- Branch: `overtrue/arch-trait-import-compat-cleanup` -- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088`. -- Stacked on: `origin/main` after API-088 merged. +- Branch: `overtrue/arch-outer-compat-surface-prune` +- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089`. +- Stacked on: `origin/main` after API-089 merged. - PR type for this branch: `pure-move` - Runtime behavior changes: none. -- Rust code changes: move remaining ECStore method-resolution trait imports - from compatibility boundaries into direct call sites, and narrow scanner, - heal, and e2e compatibility helpers to local aliases and wrappers. -- CI/script changes: tighten the compatibility re-export guard while allowing - temporary ECStore method-resolution trait imports at call sites. -- Docs changes: record the API-089 trait import compatibility cleanup. +- Rust code changes: prune raw ECStore object/error facade aliases from outer + app/admin/storage compatibility boundaries. +- CI/script changes: guard app/admin/storage compatibility boundaries against + restoring raw ECStore object/error facade aliases. +- Docs changes: record the API-090 outer compatibility facade alias cleanup. ## Phase 0 Tasks @@ -279,6 +278,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block - Verification: RustFS and edge crate compile coverage, compatibility re-export residual scan, migration guard, formatting, diff hygiene, Rust risk scan, pre-commit quality gate, and three-expert review. +- [x] `API-090` Prune outer compat object/error facade aliases. + - Completed slice: replace app/admin/storage raw ECStore object/error facade + aliases with storage-api associated object aliases and local `StorageError` + aliases. + - Acceptance: app/admin/storage compatibility boundaries no longer refer to + `rustfs_ecstore::api::object::{ObjectInfo,ObjectOptions}` or + `rustfs_ecstore::api::error::{Error,Result}` while behavior stays + unchanged. + - Must preserve: lifecycle restore/options, object-lock deletion checks, + replication scheduling decisions, admin/storage config error matching, and + storage S3 error mapping. + - Verification: RustFS compile coverage, residual scan, migration guard, + formatting, diff hygiene, Rust risk scan, pre-commit quality gate, and + three-expert review. - [x] `G-012` Inventory placement and repair invariants. - Acceptance: [`placement-repair-invariants.md`](placement-repair-invariants.md) records @@ -3312,14 +3325,24 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | API-089 removes ECStore API re-export compatibility from the remaining app/admin/storage/scanner/heal/e2e boundaries while limiting direct imports to method-resolution traits. | -| Migration preservation | passed | Scanner, heal, e2e, app, admin, and storage consumers keep non-trait ECStore access behind local aliases, wrappers, or proxy statics with existing behavior preserved. | -| Testing/verification | passed | Targeted compile coverage, ECStore API re-export residual scan, migration guard, formatting, diff hygiene, Rust risk scan, full pre-commit, and three-expert review passed. | +| Quality/architecture | passed | API-090 replaces raw ECStore object/error facade aliases in outer app/admin/storage compatibility boundaries with storage-api object aliases and local StorageError aliases. | +| Migration preservation | passed | Lifecycle, object-lock, replication, admin config, and storage S3 error paths keep the same concrete ECStore contracts through narrower local names. | +| Testing/verification | passed | RustFS compile coverage, outer facade alias residual scan, migration guard, formatting, diff hygiene, Rust risk scan, full pre-commit, and three-expert review passed. | ## Verification Notes Passed before push: +- Issue #660 API-090 current slice: + - `cargo check -p rustfs`: passed. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `bash -n scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - Outer app/admin/storage object/error facade alias residual scan: passed. + - Rust added-line risk scan on changed Rust files and guard script: passed. + - `make pre-commit`: passed. + - Issue #660 API-089 current slice: - `cargo check -p rustfs -p rustfs-scanner -p rustfs-heal -p e2e_test`: passed. diff --git a/rustfs/src/admin/storage_compat.rs b/rustfs/src/admin/storage_compat.rs index e12f1ed94..415afe60b 100644 --- a/rustfs/src/admin/storage_compat.rs +++ b/rustfs/src/admin/storage_compat.rs @@ -23,15 +23,15 @@ pub(crate) type CollectMetricsOpts = rustfs_ecstore::api::metrics::CollectMetric pub(crate) type DiskStat = rustfs_ecstore::api::rebalance::DiskStat; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type EndpointServerPools = rustfs_ecstore::api::layout::EndpointServerPools; -pub(crate) type Error = rustfs_ecstore::api::error::Error; pub(crate) type MetricType = rustfs_ecstore::api::metrics::MetricType; pub(crate) type PeerRestClient = rustfs_ecstore::api::rpc::PeerRestClient; pub(crate) type RebalSaveOpt = rustfs_ecstore::api::rebalance::RebalSaveOpt; pub(crate) type RebalanceCleanupWarnings = rustfs_ecstore::api::rebalance::RebalanceCleanupWarnings; pub(crate) type RebalanceMeta = rustfs_ecstore::api::rebalance::RebalanceMeta; pub(crate) type RebalanceStats = rustfs_ecstore::api::rebalance::RebalanceStats; -pub(crate) type Result = rustfs_ecstore::api::error::Result; pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; +pub(crate) type Error = StorageError; +pub(crate) type Result = core::result::Result; pub(crate) type TierConfig = rustfs_ecstore::api::tier::tier_config::TierConfig; pub(crate) type TierCreds = rustfs_ecstore::api::tier::tier_admin::TierCreds; pub(crate) type TierType = rustfs_ecstore::api::tier::tier_config::TierType; diff --git a/rustfs/src/app/storage_compat.rs b/rustfs/src/app/storage_compat.rs index a57b10efe..9d34428c1 100644 --- a/rustfs/src/app/storage_compat.rs +++ b/rustfs/src/app/storage_compat.rs @@ -20,12 +20,14 @@ pub(crate) type DiskError = rustfs_ecstore::api::disk::error::DiskError; pub(crate) type DynReader = rustfs_ecstore::api::rio::DynReader; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type EndpointServerPools = rustfs_ecstore::api::layout::EndpointServerPools; -pub(crate) type Error = rustfs_ecstore::api::error::Error; pub(crate) type HashReader = rustfs_ecstore::api::rio::HashReader; pub(crate) type ObjectStoreResolver = dyn Fn() -> Option> + Send + Sync + 'static; +pub(crate) type ObjectInfo = ::ObjectInfo; +pub(crate) type ObjectOptions = ::ObjectOptions; pub(crate) type PoolDecommissionInfo = rustfs_ecstore::api::capacity::PoolDecommissionInfo; pub(crate) type PoolStatus = rustfs_ecstore::api::capacity::PoolStatus; pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; +pub(crate) type Error = StorageError; pub(crate) type TierConfigMgr = rustfs_ecstore::api::tier::tier::TierConfigMgr; pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption; pub(crate) type WritePlan = rustfs_ecstore::api::rio::WritePlan; @@ -112,7 +114,7 @@ pub(crate) mod lifecycle { .await } - pub(crate) async fn enqueue_transition_immediate(oi: &rustfs_ecstore::api::object::ObjectInfo, src: LcEventSrc) { + pub(crate) async fn enqueue_transition_immediate(oi: &super::super::ObjectInfo, src: LcEventSrc) { rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::enqueue_transition_immediate(oi, src).await; } @@ -120,7 +122,7 @@ pub(crate) mod lifecycle { version_id: &str, bucket: &str, object: &str, - ) -> Result { + ) -> Result { rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::post_restore_opts(version_id, bucket, object).await } @@ -318,7 +320,7 @@ pub(crate) mod object_lock { pub(crate) async fn check_object_lock_for_deletion( bucket: &str, - obj_info: &rustfs_ecstore::api::object::ObjectInfo, + obj_info: &super::super::ObjectInfo, bypass_governance: bool, ) -> Option { rustfs_ecstore::api::bucket::object_lock::objectlock_sys::check_object_lock_for_deletion( @@ -359,8 +361,8 @@ pub(crate) mod replication { pub(crate) async fn check_replicate_delete( bucket: &str, dobj: &rustfs_storage_api::ObjectToDelete, - oi: &rustfs_ecstore::api::object::ObjectInfo, - del_opts: &rustfs_ecstore::api::object::ObjectOptions, + oi: &super::ObjectInfo, + del_opts: &super::ObjectOptions, gerr: Option, ) -> ReplicateDecision { rustfs_ecstore::api::bucket::replication::check_replicate_delete(bucket, dobj, oi, del_opts, gerr).await @@ -371,7 +373,7 @@ pub(crate) mod replication { user_tags: String, status: rustfs_filemeta::ReplicationStatusType, op_type: rustfs_filemeta::ReplicationType, - opts: rustfs_ecstore::api::object::ObjectOptions, + opts: super::ObjectOptions, ) -> MustReplicateOptions { rustfs_ecstore::api::bucket::replication::get_must_replicate_options(user_defined, user_tags, status, op_type, opts) } @@ -381,7 +383,7 @@ pub(crate) mod replication { } pub(crate) async fn schedule_replication( - oi: rustfs_ecstore::api::object::ObjectInfo, + oi: super::ObjectInfo, store: Arc, dsc: ReplicateDecision, op_type: rustfs_filemeta::ReplicationType, diff --git a/rustfs/src/storage/storage_compat.rs b/rustfs/src/storage/storage_compat.rs index b5514e657..c109e34ff 100644 --- a/rustfs/src/storage/storage_compat.rs +++ b/rustfs/src/storage/storage_compat.rs @@ -36,7 +36,6 @@ pub(crate) type DiskError = rustfs_ecstore::api::disk::error::DiskError; pub(crate) type DiskInfoOptions = rustfs_ecstore::api::disk::DiskInfoOptions; pub(crate) type DiskStore = rustfs_ecstore::api::disk::DiskStore; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; -pub(crate) type Error = rustfs_ecstore::api::error::Error; pub(crate) type FileInfoVersions = rustfs_ecstore::api::disk::FileInfoVersions; pub(crate) type LocalPeerS3Client = rustfs_ecstore::api::rpc::LocalPeerS3Client; pub(crate) type MetricType = rustfs_ecstore::api::metrics::MetricType; @@ -44,8 +43,9 @@ pub(crate) type PolicySys = rustfs_ecstore::api::bucket::policy_sys::PolicySys; pub(crate) type ReadMultipleReq = rustfs_ecstore::api::disk::ReadMultipleReq; pub(crate) type ReadMultipleResp = rustfs_ecstore::api::disk::ReadMultipleResp; pub(crate) type ReadOptions = rustfs_ecstore::api::disk::ReadOptions; -pub(crate) type Result = rustfs_ecstore::api::error::Result; pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; +pub(crate) type Error = StorageError; +pub(crate) type Result = core::result::Result; pub(crate) type UpdateMetadataOpts = rustfs_ecstore::api::disk::UpdateMetadataOpts; pub(crate) type WalkDirOptions = rustfs_ecstore::api::disk::WalkDirOptions; pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption; diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index a23084861..6d1c5e60c 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -86,6 +86,7 @@ RUSTFS_STORAGE_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/rustfs_storage RUSTFS_STORAGE_OWNER_COMPAT_REEXPORT_HITS_FILE="${TMP_DIR}/rustfs_storage_owner_compat_reexport_hits.txt" RUSTFS_ADMIN_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/rustfs_admin_bucket_storage_compat_module_hits.txt" RUSTFS_APP_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/rustfs_app_bucket_storage_compat_module_hits.txt" +RUSTFS_OUTER_COMPAT_FACADE_ALIAS_HITS_FILE="${TMP_DIR}/rustfs_outer_compat_facade_alias_hits.txt" SCANNER_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/scanner_bucket_storage_compat_module_hits.txt" NOTIFY_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/notify_storage_compat_module_hits.txt" OBS_STORAGE_COMPAT_PASSTHROUGH_HITS_FILE="${TMP_DIR}/obs_storage_compat_passthrough_hits.txt" @@ -879,6 +880,18 @@ if [[ -s "$RUSTFS_APP_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE" ]]; then report_failure "RustFS app storage compatibility must expose bucket/client/storageclass contracts as explicit aliases: $(paste -sd '; ' "$RUSTFS_APP_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --no-heading 'rustfs_ecstore::api::(object::(ObjectInfo|ObjectOptions)|error::(Error|Result))' \ + rustfs/src/app/storage_compat.rs \ + rustfs/src/admin/storage_compat.rs \ + rustfs/src/storage/storage_compat.rs || true +) >"$RUSTFS_OUTER_COMPAT_FACADE_ALIAS_HITS_FILE" + +if [[ -s "$RUSTFS_OUTER_COMPAT_FACADE_ALIAS_HITS_FILE" ]]; then + report_failure "RustFS outer storage compatibility must use storage-api object aliases and local StorageError aliases instead of raw ECStore object/error facade aliases: $(paste -sd '; ' "$RUSTFS_OUTER_COMPAT_FACADE_ALIAS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --no-heading 'pub\(crate\)\s+use rustfs_ecstore::api::bucket::\{[^}]*\b(?:bucket_target_sys|lifecycle|metadata_sys|replication|versioning|versioning_sys)\b[^}]*\}\s*;' \