diff --git a/crates/heal/src/heal/storage_compat.rs b/crates/heal/src/heal/storage_compat.rs index e1566681f..7c7088586 100644 --- a/crates/heal/src/heal/storage_compat.rs +++ b/crates/heal/src/heal/storage_compat.rs @@ -12,7 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) use rustfs_ecstore::{ +pub(crate) mod ecstore { + #![allow(unused_imports)] + + pub(crate) use rustfs_ecstore::{data_usage, disk, error, global, store, store_api}; +} +pub(crate) use self::ecstore::{ data_usage::DATA_USAGE_CACHE_NAME, disk::{BUCKET_META_PREFIX, DiskAPI, DiskStore, RUSTFS_META_BUCKET, endpoint::Endpoint, error::DiskError}, error::{Error as EcstoreError, StorageError}, @@ -22,7 +27,7 @@ pub(crate) use rustfs_ecstore::{ }; #[cfg(test)] -pub(crate) use rustfs_ecstore::disk::{DiskOption, new_disk}; +pub(crate) use self::ecstore::disk::{DiskOption, new_disk}; pub type HealObjectInfo = EcstoreObjectInfo; pub type HealObjectOptions = EcstoreObjectOptions; diff --git a/crates/iam/src/store/storage_compat.rs b/crates/iam/src/store/storage_compat.rs index 45eaa9d95..d9e06d022 100644 --- a/crates/iam/src/store/storage_compat.rs +++ b/crates/iam/src/store/storage_compat.rs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use rustfs_ecstore::store_api::{ObjectInfo as EcstoreObjectInfo, ObjectOptions as EcstoreObjectOptions}; +mod ecstore { + pub(super) use rustfs_ecstore::store_api; +} -pub(super) type IamObjectInfo = EcstoreObjectInfo; -pub(super) type IamObjectOptions = EcstoreObjectOptions; +pub(super) type IamObjectInfo = ecstore::store_api::ObjectInfo; +pub(super) type IamObjectOptions = ecstore::store_api::ObjectOptions; diff --git a/crates/protocols/src/swift/storage_compat.rs b/crates/protocols/src/swift/storage_compat.rs index 21e51eaeb..cb9c345e2 100644 --- a/crates/protocols/src/swift/storage_compat.rs +++ b/crates/protocols/src/swift/storage_compat.rs @@ -12,7 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use rustfs_ecstore::{ +mod ecstore { + #![allow(unused_imports)] + + pub(super) use rustfs_ecstore::{bucket, error, resolve_object_store_handle, store, store_api}; +} +use self::ecstore::{ bucket::{metadata::BucketMetadata, metadata_sys}, error::Result as EcstoreResult, store::ECStore, @@ -29,7 +34,7 @@ pub type SwiftObjectOptions = EcstoreObjectOptions; pub type SwiftPutObjReader = EcstorePutObjReader; pub fn resolve_swift_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + ecstore::resolve_object_store_handle() } pub async fn get_swift_bucket_metadata(bucket: &str) -> EcstoreResult> { diff --git a/crates/scanner/src/storage_compat.rs b/crates/scanner/src/storage_compat.rs index 28ad82a39..e4a3d08ff 100644 --- a/crates/scanner/src/storage_compat.rs +++ b/crates/scanner/src/storage_compat.rs @@ -13,7 +13,15 @@ // limitations under the License. use http::HeaderMap; -pub(crate) use rustfs_ecstore::{ +pub(crate) mod ecstore { + #![allow(unused_imports)] + + pub(crate) use rustfs_ecstore::{ + bucket, cache_value, config, data_usage, disk, error, global, pools, resolve_object_store_handle, set_disk, store, + store_api, store_utils, + }; +} +pub(crate) use self::ecstore::{ bucket::{ bucket_target_sys::BucketTargetSys, lifecycle::{ @@ -51,7 +59,7 @@ use rustfs_storage_api::{HTTPRangeSpec, ObjectIO}; use std::sync::Arc; #[cfg(test)] -pub(crate) use rustfs_ecstore::{ +pub(crate) use self::ecstore::{ config::init as init_ecstore_config_for_scanner_tests, disk::{DiskOption, endpoint::Endpoint, new_disk}, }; @@ -63,7 +71,7 @@ pub type ScannerObjectToDelete = EcstoreObjectToDelete; pub type ScannerPutObjReader = EcstorePutObjReader; pub(crate) fn resolve_scanner_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + ecstore::resolve_object_store_handle() } pub trait ScannerObjectIO: diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index bcdc714cc..a9d90981b 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,17 +5,18 @@ 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-narrow-storage-compat-exports` -- Baseline: `origin/main` after `rustfs/rustfs#3573` merged as - `c098184c67a80ed9c8e31ac7fd2587fddfa1799e`. +- Branch: `overtrue/arch-remaining-storage-compat-exports` +- Baseline: `rustfs/rustfs#3576` head + `8255bd68539dc3c8cfc07a0ceb783ead67a02453`. - PR type for this branch: `consumer-migration` - Runtime behavior changes: no migration behavior change expected. -- Rust code changes: narrow RustFS, obs, notify, S3 Select, IAM, scanner/heal - test, e2e, and fuzz ECStore compatibility boundary modules from whole-crate - aliases to explicit re-export surfaces. ECStore-owned definitions and runtime +- Rust code changes: narrow remaining scanner, heal, Swift, and IAM store + ECStore compatibility boundary modules from direct ECStore imports to explicit + local `ecstore` re-export surfaces. ECStore-owned definitions and runtime behavior stay in ECStore. - CI/script changes: none. -- Docs changes: record the compatibility export surface cleanup slice. +- Docs changes: record the remaining compatibility export surface cleanup + slice. ## Phase 0 Tasks @@ -38,7 +39,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block `rustfs/src/admin/route_registration_test.rs`; add migration rules for public storage-api re-export coverage, ECStore compatibility-test coverage, and a production-source guard against reintroducing the removed - `StorageAPI` aggregate facade identifier. + `StorageAPI` aggregate facade identifier; add a source guard that rejects + direct `rustfs_ecstore` imports outside compatibility boundary modules. - Acceptance: architecture migration rules fail if the public storage-api contract re-export surface drifts or if ECStore compile-time compatibility tests for the remaining storage-admin and namespace-lock contracts are @@ -939,6 +941,28 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block formatting check, diff hygiene, direct import scan, risk scan, full pre-commit, and required three-expert review passed. +- [x] `API-034` Narrow remaining ECStore compatibility export surfaces. + - Current branch: `overtrue/arch-remaining-storage-compat-exports`. + - Completed slice: narrow the remaining scanner, heal, Swift, and IAM store + ECStore compatibility boundary modules from direct ECStore imports to + explicit local `ecstore` re-export surfaces while keeping existing local + semantic aliases unchanged; add a migration guard that rejects future direct + `rustfs_ecstore` imports outside compatibility boundary modules. + - Acceptance: direct `rustfs_ecstore` references in non-ECStore source are + limited to local compatibility boundary modules; business modules continue + to consume crate-local compatibility names, and migration rules reject + bypassing those boundaries. + - Must preserve: scanner cache/lifecycle/replication behavior, heal storage + and disk behavior, Swift object/bucket metadata behavior, IAM object-store + metadata behavior, and all ECStore-owned concrete type ownership. + - Risk defense: this slice changes compatibility import ownership only; it + does not move ECStore definitions, alter runtime control flow, mutate + metadata formats, change Swift/IAM semantics, or adjust scanner/heal + scheduling. + - Verification: focused scanner/heal/IAM compile, Swift feature compile, + migration/layer guards, formatting check, diff hygiene, direct import scan, + risk scan, full pre-commit, and required three-expert review passed. + ## Phase 8 Background Controller Tasks - [x] `BGC-001` Inventory background services. @@ -1209,24 +1233,37 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block 1. `pure-move`/`consumer-migration`: continue larger cleanup slices with the loss-prevention guards active for remaining ECStore compatibility contracts - outside the app/storage/admin scanner/heal/Swift/runtime/obs/notify/S3 - Select/IAM boundaries already cleaned. + outside the source/test compatibility boundaries already cleaned. ## Pre-Push Review Log | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | Runtime, server, startup, table catalog, obs, notify, S3 Select, IAM, scanner/heal integration tests, e2e helpers, and fuzz targets now use local compatibility boundaries for ECStore runtime imports. | -| Migration preservation | passed | ECStore remains the owner of backing types and behavior; startup/readiness, table catalog, notify, S3 Select, IAM, obs, test harness, and fuzz semantics are unchanged. | -| Testing/verification | passed | Focused scanner/heal/e2e and fuzz compile checks, guards, formatting check, diff hygiene, risk scan, and full `make pre-commit` passed. | +| Quality/architecture | passed | Scanner, heal, Swift, and IAM store now keep direct ECStore references inside local compatibility boundary modules with existing local semantic aliases preserved; guard coverage rejects new bypasses. | +| Migration preservation | passed | ECStore remains the owner of backing types and behavior; scanner, heal, Swift, and IAM runtime semantics are unchanged. | +| Testing/verification | passed | Focused scanner/heal/IAM compile, Swift feature compile, guards, formatting check, diff hygiene, risk scan, and full `make pre-commit` passed. | ## Verification Notes Passed before push: -- `cargo check --tests -p rustfs -p rustfs-obs -p rustfs-notify -p rustfs-s3select-api -p rustfs-iam`: +- `cargo check --tests -p rustfs-scanner -p rustfs-heal -p rustfs-iam`: passed. -- `cargo check --tests -p rustfs-scanner -p rustfs-heal -p e2e_test`: +- `cargo check --tests -p rustfs-protocols --features swift`: passed. +- `rg -n 'rustfs_ecstore' crates/scanner/src crates/heal/src crates/protocols/src/swift crates/iam/src/store --glob '*.rs'`: + remaining matches are deliberate compatibility boundary definitions. +- `./scripts/check_architecture_migration_rules.sh`: passed. +- `./scripts/check_layer_dependencies.sh`: passed. +- `cargo fmt --all --check`: passed. +- `git diff --check`: passed. +- Rust risk scan: passed; no new unwrap/expect, numeric casts, string error + public APIs, boxed public errors, production println/eprintln, or relaxed + ordering introduced in changed Rust files. +- `make pre-commit`: passed. + +Earlier API-033 verification retained in prior branch/PR: + +- `cargo check --tests -p rustfs -p rustfs-obs -p rustfs-notify -p rustfs-s3select-api -p rustfs-iam`: passed. - `cargo check --manifest-path fuzz/Cargo.toml --bins`: passed. - `rg -n 'rustfs_ecstore' rustfs/src crates/obs/src crates/notify/src crates/s3select-api/src crates/iam/src --glob '*.rs'`: diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 0bf00680d..b53d8a6df 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -60,6 +60,7 @@ STORE_API_LIST_RESPONSE_REEXPORTS_FILE="${TMP_DIR}/store_api_list_response_reexp STORE_API_EXTERNAL_LIST_CONSUMER_HITS_FILE="${TMP_DIR}/store_api_external_list_consumer_hits.txt" STORE_API_EXTERNAL_OPERATION_CONSUMER_HITS_FILE="${TMP_DIR}/store_api_external_operation_consumer_hits.txt" STORE_API_OBJECT_OPERATION_LOCAL_METHOD_HITS_FILE="${TMP_DIR}/store_api_object_operation_local_method_hits.txt" +DIRECT_ECSTORE_IMPORT_HITS_FILE="${TMP_DIR}/direct_ecstore_import_hits.txt" awk ' /^## PR Types$/ { @@ -320,6 +321,19 @@ if [[ -s "$STORE_API_EXTERNAL_OPERATION_CONSUMER_HITS_FILE" ]]; then report_failure "external operation consumers must use rustfs-storage-api traits: $(paste -sd '; ' "$STORE_API_EXTERNAL_OPERATION_CONSUMER_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --no-heading '\brustfs_ecstore::|\b(?:use|pub(?:\([^)]*\))? use) rustfs_ecstore\b' \ + rustfs/src crates fuzz/fuzz_targets \ + --glob '!crates/ecstore/**' \ + --glob '!**/storage_compat.rs' \ + --glob '!target/**' || true +) >"$DIRECT_ECSTORE_IMPORT_HITS_FILE" + +if [[ -s "$DIRECT_ECSTORE_IMPORT_HITS_FILE" ]]; then + report_failure "direct rustfs_ecstore imports outside compatibility boundaries are forbidden: $(paste -sd '; ' "$DIRECT_ECSTORE_IMPORT_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --no-heading 'async fn (get_object_reader|put_object|get_object_info|verify_object_integrity|copy_object|delete_object_version|delete_object|delete_objects|put_object_metadata|get_object_tags|put_object_tags|delete_object_tags|add_partial|transition_object|restore_transitioned_object|list_multipart_uploads|new_multipart_upload|copy_object_part|put_object_part|get_multipart_info|list_object_parts|abort_multipart_upload|complete_multipart_upload|heal_format|heal_bucket|heal_object|get_pool_and_set|check_abandoned_parts|new_ns_lock)\b' \