From 2ff69ae21cad69eaf7d5969eb5267e6e974ef8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Tue, 16 Jun 2026 22:10:07 +0800 Subject: [PATCH] refactor: remove ecstore bucket DTO aliases (#3503) --- .../bucket/lifecycle/bucket_lifecycle_ops.rs | 5 +-- .../lifecycle/tier_free_version_recovery.rs | 3 +- crates/ecstore/src/bucket/migration.rs | 5 +-- crates/ecstore/src/client/api_list.rs | 2 +- crates/ecstore/src/data_usage.rs | 2 +- crates/ecstore/src/pools.rs | 7 +-- crates/ecstore/src/rpc/peer_s3_client.rs | 2 +- crates/ecstore/src/set_disk.rs | 8 ++-- crates/ecstore/src/sets.rs | 8 ++-- crates/ecstore/src/store.rs | 8 ++-- crates/ecstore/src/store_api.rs | 2 - crates/ecstore/src/store_api/traits.rs | 1 + docs/architecture/migration-progress.md | 43 ++++++++++--------- scripts/check_architecture_migration_rules.sh | 11 +++++ 14 files changed, 58 insertions(+), 49 deletions(-) diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index 7083e5405..8947baf53 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -2868,13 +2868,12 @@ mod tests { use crate::error::is_err_invalid_upload_id; use crate::set_disk::{RUSTFS_MULTIPART_BUCKET_KEY, RUSTFS_MULTIPART_OBJECT_KEY}; use crate::store::ECStore; - use crate::store_api::{ - BucketOperations, BucketOptions, MakeBucketOptions, MultipartOperations, ObjectInfo, ObjectOptions, PutObjReader, - }; + use crate::store_api::{BucketOperations, MultipartOperations, ObjectInfo, ObjectOptions, PutObjReader}; use futures::FutureExt; use rustfs_common::metrics::{IlmAction, global_metrics}; use rustfs_config::ENV_TRANSITION_WORKERS_ABSOLUTE_MAX; use rustfs_filemeta::{ReplicateDecision, VersionPurgeStatusType}; + use rustfs_storage_api::{BucketOptions, MakeBucketOptions}; use s3s::dto::{BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, Timestamp}; use serial_test::serial; use sha2::{Digest, Sha256}; diff --git a/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs b/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs index fa496b2db..28b3a3c9a 100644 --- a/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs +++ b/crates/ecstore/src/bucket/lifecycle/tier_free_version_recovery.rs @@ -20,7 +20,8 @@ use tokio_util::sync::CancellationToken; use crate::disk::RUSTFS_META_BUCKET; use crate::error::Result; use crate::store::ECStore; -use crate::store_api::{BucketOperations, BucketOptions, ListOperations, ObjectInfo, ObjectInfoOrErr, WalkOptions}; +use crate::store_api::{BucketOperations, ListOperations, ObjectInfo, ObjectInfoOrErr, WalkOptions}; +use rustfs_storage_api::BucketOptions; pub const DEFAULT_FREE_VERSION_RECOVERY_LIMIT: usize = 1_000; const DEFAULT_FREE_VERSION_RECOVERY_SCAN_LIMIT: usize = 10_000; diff --git a/crates/ecstore/src/bucket/migration.rs b/crates/ecstore/src/bucket/migration.rs index 3249b0d17..91e0596fe 100644 --- a/crates/ecstore/src/bucket/migration.rs +++ b/crates/ecstore/src/bucket/migration.rs @@ -17,12 +17,11 @@ use crate::bucket::metadata::BUCKET_METADATA_FILE; use crate::bucket::replication::{decode_resync_file, encode_resync_file}; use crate::disk::{BUCKET_META_PREFIX, MIGRATING_META_BUCKET, RUSTFS_META_BUCKET}; -use crate::store_api::{ - BucketOperations, BucketOptions, ListOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader, -}; +use crate::store_api::{BucketOperations, ListOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader}; use http::HeaderMap; use rustfs_policy::auth::UserIdentity; use rustfs_policy::policy::PolicyDoc; +use rustfs_storage_api::BucketOptions; use rustfs_utils::path::SLASH_SEPARATOR; use serde::{Deserialize, Serialize}; use std::sync::Arc; diff --git a/crates/ecstore/src/client/api_list.rs b/crates/ecstore/src/client/api_list.rs index 034f261ac..5e05c8c4e 100644 --- a/crates/ecstore/src/client/api_list.rs +++ b/crates/ecstore/src/client/api_list.rs @@ -26,12 +26,12 @@ use crate::client::{ credentials, transition_api::{ReaderImpl, RequestMetadata, TransitionClient}, }; -use crate::store_api::BucketInfo; use http::{HeaderMap, StatusCode}; use http_body_util::BodyExt; use hyper::body::Body; use hyper::body::Bytes; use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE; +use rustfs_storage_api::BucketInfo; use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH; use std::collections::HashMap; use std::io::ErrorKind; diff --git a/crates/ecstore/src/data_usage.rs b/crates/ecstore/src/data_usage.rs index b57c85baf..ab4250302 100644 --- a/crates/ecstore/src/data_usage.rs +++ b/crates/ecstore/src/data_usage.rs @@ -654,7 +654,7 @@ pub fn create_cache_entry_from_summary(summary: &SizeSummary) -> DataUsageEntry } /// Convert data usage cache to DataUsageInfo -pub fn cache_to_data_usage_info(cache: &DataUsageCache, path: &str, buckets: &[crate::store_api::BucketInfo]) -> DataUsageInfo { +pub fn cache_to_data_usage_info(cache: &DataUsageCache, path: &str, buckets: &[rustfs_storage_api::BucketInfo]) -> DataUsageInfo { let e = match cache.find(path) { Some(e) => e, None => return DataUsageInfo::default(), diff --git a/crates/ecstore/src/pools.rs b/crates/ecstore/src/pools.rs index 5577ac1c8..db6d7ea13 100644 --- a/crates/ecstore/src/pools.rs +++ b/crates/ecstore/src/pools.rs @@ -38,10 +38,7 @@ use crate::error::{ use crate::notification_sys::get_global_notification_sys; use crate::resolve_object_store_handle; use crate::set_disk::SetDisks; -use crate::store_api::{ - BucketOperations, BucketOptions, GetObjectReader, HealOperations, MakeBucketOptions, ObjectIO, ObjectOperations, - ObjectOptions, -}; +use crate::store_api::{BucketOperations, GetObjectReader, HealOperations, ObjectIO, ObjectOperations, ObjectOptions}; use crate::{global::GLOBAL_LifecycleSys, sets::Sets, store::ECStore}; use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; use futures::{StreamExt, future::BoxFuture, stream::FuturesUnordered}; @@ -53,7 +50,7 @@ use rustfs_common::defer; use rustfs_common::heal_channel::HealOpts; use rustfs_concurrency::workers::Workers; use rustfs_filemeta::{FileInfoVersions, MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams}; -use rustfs_storage_api::StorageAdminApi; +use rustfs_storage_api::{BucketOptions, MakeBucketOptions, StorageAdminApi}; use rustfs_utils::path::{encode_dir_object, path_join, path_to_bucket_object, path_to_bucket_object_with_base_path}; use s3s::dto::{BucketLifecycleConfiguration, DefaultRetention, ReplicationConfiguration}; use serde::{Deserialize, Serialize}; diff --git a/crates/ecstore/src/rpc/peer_s3_client.rs b/crates/ecstore/src/rpc/peer_s3_client.rs index 83f3dd690..9f046e5a1 100644 --- a/crates/ecstore/src/rpc/peer_s3_client.rs +++ b/crates/ecstore/src/rpc/peer_s3_client.rs @@ -29,7 +29,6 @@ use crate::{ disk_store::{DiskHealthTracker, get_drive_active_check_interval, get_drive_active_check_timeout}, }, endpoints::{EndpointServerPools, Node}, - store_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}, }; use async_trait::async_trait; use futures::future::join_all; @@ -39,6 +38,7 @@ use rustfs_protos::proto_gen::node_service::node_service_client::NodeServiceClie use rustfs_protos::proto_gen::node_service::{ DeleteBucketRequest, GetBucketInfoRequest, HealBucketRequest, ListBucketRequest, MakeBucketRequest, }; +use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration}; use tokio::{net::TcpStream, sync::RwLock, time}; use tokio_util::sync::CancellationToken; diff --git a/crates/ecstore/src/set_disk.rs b/crates/ecstore/src/set_disk.rs index 6bfa18d16..ca0c85c10 100644 --- a/crates/ecstore/src/set_disk.rs +++ b/crates/ecstore/src/set_disk.rs @@ -52,10 +52,9 @@ use crate::{ event_notification::{EventArgs, send_event}, global::{GLOBAL_LOCAL_DISK_MAP, GLOBAL_LOCAL_DISK_SET_DRIVES, get_global_deployment_id, is_dist_erasure}, store_api::{ - BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, GetObjectReader, - HTTPRangeSpec, HealOperations, ListMultipartsInfo, ListObjectsV2Info, ListOperations, MakeBucketOptions, MultipartInfo, - MultipartOperations, MultipartUploadResult, NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations, PartInfo, - PutObjReader, + BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListMultipartsInfo, + ListObjectsV2Info, ListOperations, MultipartInfo, MultipartOperations, MultipartUploadResult, NamespaceLocking, ObjectIO, + ObjectInfo, ObjectOperations, PartInfo, PutObjReader, }, store_init::load_format_erasure, }; @@ -87,6 +86,7 @@ use rustfs_object_capacity::capacity_scope::{ CapacityScope, CapacityScopeDisk, record_capacity_scope, record_global_dirty_scope, }; use rustfs_s3_types::EventName; +use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; use rustfs_utils::http::headers::AMZ_OBJECT_TAGGING; use rustfs_utils::http::headers::AMZ_STORAGE_CLASS; use rustfs_utils::http::headers::{ diff --git a/crates/ecstore/src/sets.rs b/crates/ecstore/src/sets.rs index 95d1cdece..3396f4985 100644 --- a/crates/ecstore/src/sets.rs +++ b/crates/ecstore/src/sets.rs @@ -28,10 +28,9 @@ use crate::{ global::{GLOBAL_LOCAL_DISK_SET_DRIVES, get_global_lock_clients, is_dist_erasure}, set_disk::SetDisks, store_api::{ - BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, GetObjectReader, - HTTPRangeSpec, HealOperations, ListMultipartsInfo, ListObjectVersionsInfo, ListObjectsV2Info, ListOperations, - MakeBucketOptions, MultipartInfo, MultipartOperations, MultipartUploadResult, NamespaceLocking, ObjectIO, ObjectInfo, - ObjectOperations, ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, + BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListMultipartsInfo, + ListObjectVersionsInfo, ListObjectsV2Info, ListOperations, MultipartInfo, MultipartOperations, MultipartUploadResult, + NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations, ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, }, store_init::{check_format_erasure_values, get_format_erasure_in_quorum, load_format_erasure_all, save_format_file}, }; @@ -49,6 +48,7 @@ use rustfs_filemeta::FileInfo; use rustfs_lock::NamespaceLockWrapper; use rustfs_lock::client::LockClient; use rustfs_madmin::heal_commands::{HealDriveInfo, HealResultItem}; +use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; use rustfs_utils::{crc_hash, path::path_join_buf, sip_hash}; use std::{collections::HashMap, sync::Arc}; use tokio::sync::RwLock; diff --git a/crates/ecstore/src/store.rs b/crates/ecstore/src/store.rs index 699dfe997..db15cb02d 100644 --- a/crates/ecstore/src/store.rs +++ b/crates/ecstore/src/store.rs @@ -65,10 +65,9 @@ use crate::{ rpc::S3PeerSys, sets::Sets, store_api::{ - BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, GetObjectReader, - HTTPRangeSpec, HealOperations, ListObjectsV2Info, ListOperations, MakeBucketOptions, MultipartOperations, - MultipartUploadResult, NamespaceLocking, ObjectInfo, ObjectOperations, ObjectOptions, ObjectToDelete, PartInfo, - PutObjReader, + BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectsV2Info, + ListOperations, MultipartOperations, MultipartUploadResult, NamespaceLocking, ObjectInfo, ObjectOperations, + ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, }, store_init, }; @@ -82,6 +81,7 @@ use rustfs_config::server_config::{Config, get_global_server_config, set_global_ use rustfs_filemeta::FileInfo; use rustfs_lock::{LocalClient, LockClient, NamespaceLockWrapper}; use rustfs_madmin::heal_commands::HealResultItem; +use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; use rustfs_utils::path::{decode_dir_object, encode_dir_object, path_join_buf}; use s3s::dto::{BucketVersioningStatus, ObjectLockConfiguration, ObjectLockEnabled, VersioningConfiguration}; use std::cmp::Ordering; diff --git a/crates/ecstore/src/store_api.rs b/crates/ecstore/src/store_api.rs index ef5b505dd..b69a31017 100644 --- a/crates/ecstore/src/store_api.rs +++ b/crates/ecstore/src/store_api.rs @@ -57,8 +57,6 @@ mod readers; mod traits; mod types; -pub(crate) use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; - pub use readers::*; pub use traits::*; pub use types::*; diff --git a/crates/ecstore/src/store_api/traits.rs b/crates/ecstore/src/store_api/traits.rs index 4d3e5ca66..2d8cad0a6 100644 --- a/crates/ecstore/src/store_api/traits.rs +++ b/crates/ecstore/src/store_api/traits.rs @@ -1,4 +1,5 @@ use super::*; +use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions}; #[async_trait::async_trait] pub trait ObjectIO: Send + Sync + Debug + 'static { diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 13ee715ae..06ac33f54 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -5,15 +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-storage-contract-guard-cleanup` -- Baseline: `origin/main` at `0f37c5675e2be5e42d1ef85a57ff9e744d412e91` +- Branch: `overtrue/arch-storage-dto-path-cleanup` +- Baseline: `origin/main` at `d094d919257861bb543eb4747412b90b617a6213` - PR type for this branch: `consumer-migration` - Runtime behavior changes: no external behavior change expected. -- Rust code changes: rename the remaining ECStore compatibility test away from - the stale storage-api facade name. -- CI/script changes: add a migration guard that rejects the old `StorageAPI` - aggregate facade identifier in production ECStore and RustFS source. -- Docs changes: record the post-facade loss-prevention cleanup slice. +- Rust code changes: remove the remaining ECStore-internal bucket DTO aliases + from `store_api` and import the shared bucket DTO contracts directly from + `rustfs_storage_api`. +- CI/script changes: add a migration guard that rejects reintroducing old + `ecstore::store_api` bucket DTO re-exports. +- Docs changes: record the post-facade bucket DTO path cleanup slice. ## Phase 0 Tasks @@ -359,6 +360,9 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block - Cleanup slice: migrate in-repo external consumers to `rustfs_storage_api`, keep ECStore implementation use crate-private, and remove the old public `ecstore::store_api` bucket DTO re-export. + - Completed follow-up slice: remove the remaining ECStore-internal bucket DTO + aliases from `store_api` and guard against restoring that compatibility + path. - Acceptance: `rustfs-storage-api` exports these DTOs, in-repo external consumers no longer use the old `rustfs_ecstore::store_api` DTO path, and `RUSTFS_COMPAT_TODO(API-003)` is removed from source and cleanup register. @@ -771,18 +775,17 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | Guard cleanup keeps ECStore contract coverage named after the remaining contracts and rejects old facade reintroduction in production source. | -| Migration preservation | passed | No runtime code path changes; this slice only renames the compatibility test and strengthens migration guardrails. | -| Testing/verification | passed | Focused contract test, compile checks, migration/layer guards, formatting, diff hygiene, Rust risk scan, and full `make pre-commit` passed. | +| Quality/architecture | passed | Direct bucket DTO imports leave ECStore `store_api` focused on operation traits and object/listing types; the guard prevents the old DTO alias from returning. | +| Migration preservation | passed | The slice changes type import paths and migration checks only; storage/listing behavior and operation trait contracts are unchanged. | +| Testing/verification | passed | Focused ECStore compile/test checks, migration/layer guards, formatting, diff hygiene, Rust risk scan, and full `make pre-commit` passed. | ## Verification Notes -Passed on `0f37c5675e2be5e42d1ef85a57ff9e744d412e91`: +Passed on `d094d919257861bb543eb4747412b90b617a6213`: - `cargo check -p rustfs-ecstore`: passed. - `cargo test -p rustfs-ecstore --test ecstore_contract_compat_test --no-fail-fast`: passed. -- `cargo check -p rustfs -p rustfs-ecstore`: passed. - `./scripts/check_architecture_migration_rules.sh`: passed. - `./scripts/check_layer_dependencies.sh`: passed. - `cargo fmt --all --check`: passed. @@ -793,16 +796,16 @@ Passed on `0f37c5675e2be5e42d1ef85a57ff9e744d412e91`: Notes: -- This slice is a post-facade cleanup after `rustfs/rustfs#3490` and - `rustfs/rustfs#3487` are both on `main`. -- The concrete storage operation traits, `StorageAdminApi`, and - `NamespaceLocking` remain available and covered. -- The slice does not move traits across crate boundaries or alter runtime - storage behavior. +- This slice follows `rustfs/rustfs#3501` and keeps the old aggregate facade + guard active. +- The shared bucket DTOs remain owned by `rustfs-storage-api`; ECStore + `store_api` keeps only ECStore operation traits and object/listing types. +- The slice does not move storage operation traits across crate boundaries or + alter runtime storage behavior. ## Handoff Notes -- Storage contract guard cleanup is in progress on a branch current with +- Storage DTO path cleanup is in progress on a branch current with `origin/main`. - After this lands, remaining storage work can continue from concrete operation - contracts with a guard against restoring the old aggregate facade identifier. + contracts and direct shared DTO imports. diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 79978ce19..7772ca49e 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -50,6 +50,7 @@ SOURCE_MARKERS_FILE="${TMP_DIR}/source_markers.txt" SOURCE_IDS_FILE="${TMP_DIR}/source_ids.txt" REGISTER_IDS_FILE="${TMP_DIR}/register_ids.txt" LEGACY_STORAGE_API_HITS_FILE="${TMP_DIR}/legacy_storage_api_hits.txt" +STORE_API_BUCKET_DTO_REEXPORTS_FILE="${TMP_DIR}/store_api_bucket_dto_reexports.txt" awk ' /^## PR Types$/ { @@ -196,6 +197,16 @@ if [[ -s "$LEGACY_STORAGE_API_HITS_FILE" ]]; then report_failure "old StorageAPI facade identifier reintroduced in production source: $(paste -sd '; ' "$LEGACY_STORAGE_API_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --no-heading 'pub(?:\(crate\))? use rustfs_storage_api::\{[^}]*\b(?:BucketInfo|BucketOptions|DeleteBucketOptions|MakeBucketOptions|SRBucketDeleteOp)\b' \ + crates/ecstore/src/store_api.rs || true +) >"$STORE_API_BUCKET_DTO_REEXPORTS_FILE" + +if [[ -s "$STORE_API_BUCKET_DTO_REEXPORTS_FILE" ]]; then + report_failure "old ecstore store_api bucket DTO re-export reintroduced: $(paste -sd '; ' "$STORE_API_BUCKET_DTO_REEXPORTS_FILE")" +fi + require_source_contains \ "crates/ecstore/src/store_api/traits.rs" \ "pub trait NamespaceLocking: Send + Sync + Debug + 'static" \