refactor: prune outer compat facade aliases (#3700)

This commit is contained in:
安正超
2026-06-21 23:33:44 +08:00
committed by GitHub
parent 6b3d96fde3
commit ef111a3e40
6 changed files with 67 additions and 24 deletions
+5
View File
@@ -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 storage-owner compatibility symbols must be local constants, type aliases, or
wrapper functions so storage-owned global state and helper access stays visible wrapper functions so storage-owned global state and helper access stays visible
at the boundary. 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 Scanner, notify, observability, and e2e `storage_compat.rs` boundaries must
also stay narrow. Scanner must not restore grouped bucket compatibility exports also stay narrow. Scanner must not restore grouped bucket compatibility exports
for target, lifecycle, metadata, replication, or versioning modules. Notify for target, lifecycle, metadata, replication, or versioning modules. Notify
+35 -12
View File
@@ -5,17 +5,16 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context ## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-trait-import-compat-cleanup` - 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`. - 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-088 merged. - Stacked on: `origin/main` after API-089 merged.
- PR type for this branch: `pure-move` - PR type for this branch: `pure-move`
- Runtime behavior changes: none. - Runtime behavior changes: none.
- Rust code changes: move remaining ECStore method-resolution trait imports - Rust code changes: prune raw ECStore object/error facade aliases from outer
from compatibility boundaries into direct call sites, and narrow scanner, app/admin/storage compatibility boundaries.
heal, and e2e compatibility helpers to local aliases and wrappers. - CI/script changes: guard app/admin/storage compatibility boundaries against
- CI/script changes: tighten the compatibility re-export guard while allowing restoring raw ECStore object/error facade aliases.
temporary ECStore method-resolution trait imports at call sites. - Docs changes: record the API-090 outer compatibility facade alias cleanup.
- Docs changes: record the API-089 trait import compatibility cleanup.
## Phase 0 Tasks ## Phase 0 Tasks
@@ -279,6 +278,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
- Verification: RustFS and edge crate compile coverage, compatibility - Verification: RustFS and edge crate compile coverage, compatibility
re-export residual scan, migration guard, formatting, diff hygiene, Rust re-export residual scan, migration guard, formatting, diff hygiene, Rust
risk scan, pre-commit quality gate, and three-expert review. 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. - [x] `G-012` Inventory placement and repair invariants.
- Acceptance: - Acceptance:
[`placement-repair-invariants.md`](placement-repair-invariants.md) records [`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 | | 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. | | 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 | Scanner, heal, e2e, app, admin, and storage consumers keep non-trait ECStore access behind local aliases, wrappers, or proxy statics with existing behavior preserved. | | 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 | 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. | | 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 ## Verification Notes
Passed before push: 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: - Issue #660 API-089 current slice:
- `cargo check -p rustfs -p rustfs-scanner -p rustfs-heal -p e2e_test`: - `cargo check -p rustfs -p rustfs-scanner -p rustfs-heal -p e2e_test`:
passed. passed.
+2 -2
View File
@@ -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 DiskStat = rustfs_ecstore::api::rebalance::DiskStat;
pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore;
pub(crate) type EndpointServerPools = rustfs_ecstore::api::layout::EndpointServerPools; 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 MetricType = rustfs_ecstore::api::metrics::MetricType;
pub(crate) type PeerRestClient = rustfs_ecstore::api::rpc::PeerRestClient; pub(crate) type PeerRestClient = rustfs_ecstore::api::rpc::PeerRestClient;
pub(crate) type RebalSaveOpt = rustfs_ecstore::api::rebalance::RebalSaveOpt; pub(crate) type RebalSaveOpt = rustfs_ecstore::api::rebalance::RebalSaveOpt;
pub(crate) type RebalanceCleanupWarnings = rustfs_ecstore::api::rebalance::RebalanceCleanupWarnings; pub(crate) type RebalanceCleanupWarnings = rustfs_ecstore::api::rebalance::RebalanceCleanupWarnings;
pub(crate) type RebalanceMeta = rustfs_ecstore::api::rebalance::RebalanceMeta; pub(crate) type RebalanceMeta = rustfs_ecstore::api::rebalance::RebalanceMeta;
pub(crate) type RebalanceStats = rustfs_ecstore::api::rebalance::RebalanceStats; pub(crate) type RebalanceStats = rustfs_ecstore::api::rebalance::RebalanceStats;
pub(crate) type Result<T> = rustfs_ecstore::api::error::Result<T>;
pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError;
pub(crate) type Error = StorageError;
pub(crate) type Result<T> = core::result::Result<T, Error>;
pub(crate) type TierConfig = rustfs_ecstore::api::tier::tier_config::TierConfig; 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 TierCreds = rustfs_ecstore::api::tier::tier_admin::TierCreds;
pub(crate) type TierType = rustfs_ecstore::api::tier::tier_config::TierType; pub(crate) type TierType = rustfs_ecstore::api::tier::tier_config::TierType;
+10 -8
View File
@@ -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 DynReader = rustfs_ecstore::api::rio::DynReader;
pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore;
pub(crate) type EndpointServerPools = rustfs_ecstore::api::layout::EndpointServerPools; 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 HashReader = rustfs_ecstore::api::rio::HashReader;
pub(crate) type ObjectStoreResolver = dyn Fn() -> Option<Arc<ECStore>> + Send + Sync + 'static; pub(crate) type ObjectStoreResolver = dyn Fn() -> Option<Arc<ECStore>> + Send + Sync + 'static;
pub(crate) type ObjectInfo = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectInfo;
pub(crate) type ObjectOptions = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
pub(crate) type PoolDecommissionInfo = rustfs_ecstore::api::capacity::PoolDecommissionInfo; pub(crate) type PoolDecommissionInfo = rustfs_ecstore::api::capacity::PoolDecommissionInfo;
pub(crate) type PoolStatus = rustfs_ecstore::api::capacity::PoolStatus; pub(crate) type PoolStatus = rustfs_ecstore::api::capacity::PoolStatus;
pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; 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 TierConfigMgr = rustfs_ecstore::api::tier::tier::TierConfigMgr;
pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption; pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption;
pub(crate) type WritePlan = rustfs_ecstore::api::rio::WritePlan; pub(crate) type WritePlan = rustfs_ecstore::api::rio::WritePlan;
@@ -112,7 +114,7 @@ pub(crate) mod lifecycle {
.await .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; 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, version_id: &str,
bucket: &str, bucket: &str,
object: &str, object: &str,
) -> Result<rustfs_ecstore::api::object::ObjectOptions, std::io::Error> { ) -> Result<super::super::ObjectOptions, std::io::Error> {
rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::post_restore_opts(version_id, bucket, object).await 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( pub(crate) async fn check_object_lock_for_deletion(
bucket: &str, bucket: &str,
obj_info: &rustfs_ecstore::api::object::ObjectInfo, obj_info: &super::super::ObjectInfo,
bypass_governance: bool, bypass_governance: bool,
) -> Option<ObjectLockBlockReason> { ) -> Option<ObjectLockBlockReason> {
rustfs_ecstore::api::bucket::object_lock::objectlock_sys::check_object_lock_for_deletion( 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( pub(crate) async fn check_replicate_delete(
bucket: &str, bucket: &str,
dobj: &rustfs_storage_api::ObjectToDelete, dobj: &rustfs_storage_api::ObjectToDelete,
oi: &rustfs_ecstore::api::object::ObjectInfo, oi: &super::ObjectInfo,
del_opts: &rustfs_ecstore::api::object::ObjectOptions, del_opts: &super::ObjectOptions,
gerr: Option<String>, gerr: Option<String>,
) -> ReplicateDecision { ) -> ReplicateDecision {
rustfs_ecstore::api::bucket::replication::check_replicate_delete(bucket, dobj, oi, del_opts, gerr).await 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, user_tags: String,
status: rustfs_filemeta::ReplicationStatusType, status: rustfs_filemeta::ReplicationStatusType,
op_type: rustfs_filemeta::ReplicationType, op_type: rustfs_filemeta::ReplicationType,
opts: rustfs_ecstore::api::object::ObjectOptions, opts: super::ObjectOptions,
) -> MustReplicateOptions { ) -> MustReplicateOptions {
rustfs_ecstore::api::bucket::replication::get_must_replicate_options(user_defined, user_tags, status, op_type, opts) 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( pub(crate) async fn schedule_replication(
oi: rustfs_ecstore::api::object::ObjectInfo, oi: super::ObjectInfo,
store: Arc<super::ECStore>, store: Arc<super::ECStore>,
dsc: ReplicateDecision, dsc: ReplicateDecision,
op_type: rustfs_filemeta::ReplicationType, op_type: rustfs_filemeta::ReplicationType,
+2 -2
View File
@@ -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 DiskInfoOptions = rustfs_ecstore::api::disk::DiskInfoOptions;
pub(crate) type DiskStore = rustfs_ecstore::api::disk::DiskStore; pub(crate) type DiskStore = rustfs_ecstore::api::disk::DiskStore;
pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; 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 FileInfoVersions = rustfs_ecstore::api::disk::FileInfoVersions;
pub(crate) type LocalPeerS3Client = rustfs_ecstore::api::rpc::LocalPeerS3Client; pub(crate) type LocalPeerS3Client = rustfs_ecstore::api::rpc::LocalPeerS3Client;
pub(crate) type MetricType = rustfs_ecstore::api::metrics::MetricType; 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 ReadMultipleReq = rustfs_ecstore::api::disk::ReadMultipleReq;
pub(crate) type ReadMultipleResp = rustfs_ecstore::api::disk::ReadMultipleResp; pub(crate) type ReadMultipleResp = rustfs_ecstore::api::disk::ReadMultipleResp;
pub(crate) type ReadOptions = rustfs_ecstore::api::disk::ReadOptions; pub(crate) type ReadOptions = rustfs_ecstore::api::disk::ReadOptions;
pub(crate) type Result<T> = rustfs_ecstore::api::error::Result<T>;
pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError;
pub(crate) type Error = StorageError;
pub(crate) type Result<T> = core::result::Result<T, Error>;
pub(crate) type UpdateMetadataOpts = rustfs_ecstore::api::disk::UpdateMetadataOpts; pub(crate) type UpdateMetadataOpts = rustfs_ecstore::api::disk::UpdateMetadataOpts;
pub(crate) type WalkDirOptions = rustfs_ecstore::api::disk::WalkDirOptions; pub(crate) type WalkDirOptions = rustfs_ecstore::api::disk::WalkDirOptions;
pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption; pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption;
@@ -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_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_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_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" 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" 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" 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")" 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 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" 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*;' \ 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*;' \