From 0985225448cd6af1a0945099bc8139d65399d352 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 09:09:11 +0800 Subject: [PATCH] refactor: consolidate ecstore public facade (#3678) * refactor: expand ecstore compatibility facade * test: enforce ecstore api facade imports * refactor: hide legacy ecstore layout modules * refactor: hide ecstore facade root modules --- crates/e2e_test/src/storage_compat.rs | 10 +- crates/ecstore/src/api/mod.rs | 95 +++++++++++++++ crates/ecstore/src/compress.rs | 1 - crates/ecstore/src/data_usage.rs | 8 +- crates/ecstore/src/disk/health_state.rs | 18 +-- crates/ecstore/src/lib.rs | 46 ++++---- crates/ecstore/src/rebalance.rs | 4 +- crates/ecstore/src/rpc/mod.rs | 12 +- crates/ecstore/src/rpc/remote_disk.rs | 2 +- crates/ecstore/src/store.rs | 10 +- crates/ecstore/src/store/rebalance.rs | 2 +- .../tests/ecstore_contract_compat_test.rs | 8 +- .../ecstore/tests/legacy_bitrot_read_test.rs | 4 +- .../tests/minio_generated_read_test.rs | 4 +- crates/heal/src/heal/storage_compat.rs | 22 ++-- crates/heal/tests/common/storage_compat.rs | 4 +- crates/iam/src/storage_compat.rs | 22 ++-- crates/notify/src/storage_compat.rs | 2 +- crates/obs/src/storage_compat.rs | 18 +-- crates/protocols/src/swift/storage_compat.rs | 10 +- crates/s3select-api/src/storage_compat.rs | 12 +- crates/scanner/src/storage_compat.rs | 50 ++++---- crates/scanner/tests/common/storage_compat.rs | 32 +++--- docs/architecture/crate-boundaries.md | 11 +- docs/architecture/migration-progress.md | 108 +++++++++++++++++- .../bucket_validation/storage_compat.rs | 2 +- .../path_containment/storage_compat.rs | 2 +- rustfs/src/admin/storage_compat.rs | 50 ++++---- rustfs/src/app/storage_compat.rs | 68 +++++------ rustfs/src/storage/storage_compat.rs | 24 ++-- rustfs/src/storage_compat.rs | 32 +++--- scripts/check_architecture_migration_rules.sh | 57 ++++++++- 32 files changed, 498 insertions(+), 252 deletions(-) diff --git a/crates/e2e_test/src/storage_compat.rs b/crates/e2e_test/src/storage_compat.rs index 395d640e9..93a09ae6f 100644 --- a/crates/e2e_test/src/storage_compat.rs +++ b/crates/e2e_test/src/storage_compat.rs @@ -14,11 +14,11 @@ #![allow(dead_code, unused_imports)] -pub(crate) type BucketTargetSys = rustfs_ecstore::bucket::bucket_target_sys::BucketTargetSys; -pub(crate) type TonicInterceptor = rustfs_ecstore::rpc::TonicInterceptor; -pub(crate) type VolumeInfo = rustfs_ecstore::disk::VolumeInfo; -pub(crate) type WalkDirOptions = rustfs_ecstore::disk::WalkDirOptions; +pub(crate) type BucketTargetSys = rustfs_ecstore::api::bucket::bucket_target_sys::BucketTargetSys; +pub(crate) type TonicInterceptor = rustfs_ecstore::api::rpc::TonicInterceptor; +pub(crate) type VolumeInfo = rustfs_ecstore::api::disk::VolumeInfo; +pub(crate) type WalkDirOptions = rustfs_ecstore::api::disk::WalkDirOptions; -pub(crate) use rustfs_ecstore::rpc::{ +pub(crate) use rustfs_ecstore::api::rpc::{ gen_tonic_signature_interceptor, node_service_time_out_client, node_service_time_out_client_no_auth, }; diff --git a/crates/ecstore/src/api/mod.rs b/crates/ecstore/src/api/mod.rs index a7aeac0fb..1b306d312 100644 --- a/crates/ecstore/src/api/mod.rs +++ b/crates/ecstore/src/api/mod.rs @@ -18,6 +18,17 @@ pub mod admin { pub use crate::admin_server_info::{get_local_server_property, get_server_info}; } +pub mod bucket { + pub use crate::bucket::{ + bandwidth, bucket_target_sys, lifecycle, metadata, metadata_sys, migration, object_lock, policy_sys, quota, replication, + tagging, target, utils, versioning, versioning_sys, + }; +} + +pub mod cache { + pub use crate::cache_value::metacache_set::{ListPathRawOptions, list_path_raw}; +} + pub mod capacity { pub use crate::pools::{ PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free, path2_bucket_object, @@ -26,6 +37,61 @@ pub mod capacity { pub use crate::store_utils::is_reserved_or_invalid_bucket; } +pub mod client { + pub use crate::client::{admin_handler_utils, object_api_utils, transition_api}; +} + +pub mod compression { + pub use crate::compress::{MIN_DISK_COMPRESSIBLE_SIZE, is_disk_compressible}; +} + +pub mod config { + pub use crate::config::{ + RUSTFS_CONFIG_PREFIX, com, init, init_global_config_sys, set_global_storage_class, storageclass, + try_migrate_server_config, + }; +} + +pub mod data_usage { + pub use crate::data_usage::{ + DATA_USAGE_CACHE_NAME, apply_bucket_usage_memory_overlay, load_data_usage_from_backend, + record_bucket_object_delete_memory, record_bucket_object_write_memory, replace_bucket_usage_memory_from_info, + }; +} + +pub mod disk { + pub use crate::disk::endpoint::Endpoint; + pub use crate::disk::error::DiskError; + pub use crate::disk::error_reduce::is_all_buckets_not_found; + pub use crate::disk::{ + BUCKET_META_PREFIX, DeleteOptions, Disk, DiskAPI, DiskInfoOptions, DiskOption, DiskStore, FileInfoVersions, + RUSTFS_META_BUCKET, ReadMultipleReq, ReadMultipleResp, ReadOptions, STORAGE_FORMAT_FILE, UpdateMetadataOpts, VolumeInfo, + WalkDirOptions, new_disk, + }; + pub use crate::disk::{endpoint, error, error_reduce}; +} + +pub mod error { + pub use crate::error::{ + Error, Result, StorageError, classify_system_path_failure_reason, is_err_bucket_not_found, is_err_object_not_found, + is_err_version_not_found, + }; +} + +pub mod event { + pub use crate::event_notification::{EventArgs, register_event_dispatch_hook}; +} + +pub mod global { + pub use crate::global::{ + GLOBAL_BOOT_TIME, GLOBAL_LOCAL_DISK_MAP, GLOBAL_TierConfigMgr, get_global_bucket_monitor, get_global_deployment_id, + get_global_endpoints_opt, get_global_lock_client, get_global_lock_clients, get_global_region, get_global_tier_config_mgr, + global_rustfs_port, is_dist_erasure, is_erasure, is_erasure_sd, is_first_cluster_node_local, new_object_layer_fn, + resolve_object_store_handle, set_global_endpoints, set_global_region, set_global_rustfs_port, set_object_store_resolver, + shutdown_background_services, update_erasure_type, + }; +} + pub mod layout { pub use crate::disks_layout::DisksLayout; pub use crate::endpoints::{EndpointServerPools, Endpoints, PoolEndpoints}; @@ -41,9 +107,38 @@ pub mod notification { }; } +pub mod rebalance { + pub use crate::rebalance::{ + DiskStat, RebalSaveOpt, RebalStatus, RebalanceCleanupWarnings, RebalanceInfo, RebalanceMeta, RebalanceStats, + }; +} + +pub mod rio { + pub use crate::rio::{ + DecryptReader, DynReader, EncryptReader, HardLimitReader, HashReader, WriteEncryption, WritePlan, boxed_reader, + compression_metadata_value, wrap_reader, + }; +} + +pub mod rpc { + pub use crate::rpc::{ + LocalPeerS3Client, PEER_RESTSIGNAL, PEER_RESTSUB_SYS, PeerRestClient, PeerS3Client, SERVICE_SIGNAL_REFRESH_CONFIG, + SERVICE_SIGNAL_RELOAD_DYNAMIC, TONIC_RPC_PREFIX, TonicInterceptor, gen_tonic_signature_interceptor, + node_service_time_out_client, node_service_time_out_client_no_auth, verify_rpc_signature, + }; +} + +pub mod set_disk { + pub use crate::set_disk::{DEFAULT_READ_BUFFER_SIZE, SetDisks, get_lock_acquire_timeout, is_valid_storage_class}; +} + pub mod storage { pub use crate::store::{ ECStore, all_local_disk, all_local_disk_path, find_local_disk_by_ref, init_local_disks, init_lock_clients, prewarm_local_disk_id_map, }; } + +pub mod tier { + pub use crate::tier::{tier, tier_admin, tier_config, tier_handlers, warm_backend}; +} diff --git a/crates/ecstore/src/compress.rs b/crates/ecstore/src/compress.rs index 0aa5623b7..b4187319b 100644 --- a/crates/ecstore/src/compress.rs +++ b/crates/ecstore/src/compress.rs @@ -215,7 +215,6 @@ fn is_disk_compressible_with_config(headers: &http::HeaderMap, object_name: &str #[cfg(test)] mod tests { use super::*; - use temp_env; #[test] fn test_parse_disk_compression_enabled() { diff --git a/crates/ecstore/src/data_usage.rs b/crates/ecstore/src/data_usage.rs index 469beca97..1411dd382 100644 --- a/crates/ecstore/src/data_usage.rs +++ b/crates/ecstore/src/data_usage.rs @@ -21,11 +21,7 @@ use crate::{ error::{Error, classify_system_path_failure_reason}, store::ECStore, }; -pub use local_snapshot::{ - DATA_USAGE_DIR, DATA_USAGE_STATE_DIR, LOCAL_USAGE_SNAPSHOT_VERSION, LocalUsageSnapshot, LocalUsageSnapshotMeta, - data_usage_dir, data_usage_state_dir, ensure_data_usage_layout, read_snapshot as read_local_snapshot, snapshot_file_name, - snapshot_object_path, snapshot_path, write_snapshot as write_local_snapshot, -}; +pub use local_snapshot::{LocalUsageSnapshot, read_snapshot as read_local_snapshot, snapshot_path}; use rustfs_data_usage::{ BucketTargetUsageInfo, BucketUsageInfo, DataUsageCache, DataUsageEntry, DataUsageInfo, DiskUsageStatus, SizeSummary, }; @@ -870,7 +866,7 @@ mod tests { #[test] fn aggregate_skips_corrupted_snapshot_and_preserves_other_disks() { - let mut good_snapshot = LocalUsageSnapshot::new(LocalUsageSnapshotMeta { + let mut good_snapshot = LocalUsageSnapshot::new(local_snapshot::LocalUsageSnapshotMeta { disk_id: "good-disk".to_string(), pool_index: Some(0), set_index: Some(0), diff --git a/crates/ecstore/src/disk/health_state.rs b/crates/ecstore/src/disk/health_state.rs index a2536000d..c242de4f4 100644 --- a/crates/ecstore/src/disk/health_state.rs +++ b/crates/ecstore/src/disk/health_state.rs @@ -60,17 +60,17 @@ impl RuntimeDriveHealthState { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum DriveRecoveryClass { - ShortOffline, - MediumOffline, - LongOffline, + Short, + Medium, + Long, } impl DriveRecoveryClass { pub fn as_str(self) -> &'static str { match self { - Self::ShortOffline => "short_offline", - Self::MediumOffline => "medium_offline", - Self::LongOffline => "long_offline", + Self::Short => "short_offline", + Self::Medium => "medium_offline", + Self::Long => "long_offline", } } } @@ -112,11 +112,11 @@ pub fn get_drive_long_offline_threshold() -> Duration { pub fn classify_drive_recovery(duration: Duration) -> DriveRecoveryClass { if duration <= get_drive_offline_grace_period() { - DriveRecoveryClass::ShortOffline + DriveRecoveryClass::Short } else if duration >= get_drive_long_offline_threshold() { - DriveRecoveryClass::LongOffline + DriveRecoveryClass::Long } else { - DriveRecoveryClass::MediumOffline + DriveRecoveryClass::Medium } } diff --git a/crates/ecstore/src/lib.rs b/crates/ecstore/src/lib.rs index cc0134802..7d25b1932 100644 --- a/crates/ecstore/src/lib.rs +++ b/crates/ecstore/src/lib.rs @@ -15,47 +15,47 @@ extern crate core; -pub mod admin_server_info; +mod admin_server_info; pub mod api; pub mod batch_processor; pub mod bitrot; -pub mod bucket; -pub mod cache_value; -pub mod compress; -pub mod config; +mod bucket; +mod cache_value; +mod compress; +mod config; mod data_movement; -pub mod data_usage; -pub mod disk; -pub mod disks_layout; -pub mod endpoints; +mod data_usage; +mod disk; +mod disks_layout; +mod endpoints; pub mod erasure_coding; -pub mod error; -pub mod global; +mod error; +mod global; pub(crate) mod layout; -pub mod metrics_realtime; -pub mod notification_sys; +mod metrics_realtime; +mod notification_sys; pub mod object_api; -pub mod pools; -pub mod rebalance; -pub mod rio; -pub mod rpc; -pub mod set_disk; +mod pools; +mod rebalance; +mod rio; +mod rpc; +mod set_disk; mod sets; mod storage_api_contracts; -pub mod store; +mod store; mod store_init; pub mod store_list_objects; -pub mod store_utils; +mod store_utils; // pub mod checksum; -pub mod client; +mod client; pub mod event; -pub mod event_notification; +mod event_notification; #[cfg(test)] mod pools_test; #[cfg(test)] mod store_test; -pub mod tier; +mod tier; pub use global::set_global_endpoints; pub use global::update_erasure_type; diff --git a/crates/ecstore/src/rebalance.rs b/crates/ecstore/src/rebalance.rs index 19ff68e5a..95b468c50 100644 --- a/crates/ecstore/src/rebalance.rs +++ b/crates/ecstore/src/rebalance.rs @@ -41,9 +41,7 @@ mod runtime; mod types; mod worker; -pub use types::{ - DiskStat, RStats, RebalSaveOpt, RebalStatus, RebalanceCleanupWarnings, RebalanceInfo, RebalanceMeta, RebalanceStats, -}; +pub use types::{DiskStat, RebalSaveOpt, RebalStatus, RebalanceCleanupWarnings, RebalanceInfo, RebalanceMeta, RebalanceStats}; use types::{RebalanceBucketConfigs, RebalanceBucketOutcome, RebalanceEntryOutcome}; #[cfg(test)] diff --git a/crates/ecstore/src/rpc/mod.rs b/crates/ecstore/src/rpc/mod.rs index a0ac57af5..a862b6777 100644 --- a/crates/ecstore/src/rpc/mod.rs +++ b/crates/ecstore/src/rpc/mod.rs @@ -25,14 +25,12 @@ pub use client::{ TonicInterceptor, gen_tonic_signature_interceptor, node_service_time_out_client, node_service_time_out_client_no_auth, }; pub use http_auth::{TONIC_RPC_PREFIX, build_auth_headers, gen_signature_headers, verify_rpc_signature}; -pub use internode_data_transport::{ - InternodeDataTransport, InternodeDataTransportCapabilities, ReadStreamRequest, TcpHttpInternodeDataTransport, - WalkDirStreamRequest, WriteStreamRequest, build_internode_data_transport, build_internode_data_transport_from_env, -}; +#[cfg(test)] +pub(crate) use internode_data_transport::TcpHttpInternodeDataTransport; +pub use internode_data_transport::build_internode_data_transport_from_env; pub use peer_rest_client::{ - PEER_RESTDRY_RUN, PEER_RESTSIGNAL, PEER_RESTSUB_SYS, PeerRestClient, SERVICE_SIGNAL_REFRESH_CONFIG, - SERVICE_SIGNAL_RELOAD_DYNAMIC, + PEER_RESTSIGNAL, PEER_RESTSUB_SYS, PeerRestClient, SERVICE_SIGNAL_REFRESH_CONFIG, SERVICE_SIGNAL_RELOAD_DYNAMIC, }; -pub use peer_s3_client::{LocalPeerS3Client, PeerS3Client, RemotePeerS3Client, S3PeerSys}; +pub use peer_s3_client::{LocalPeerS3Client, PeerS3Client, S3PeerSys}; pub use remote_disk::RemoteDisk; pub use remote_locker::RemoteClient; diff --git a/crates/ecstore/src/rpc/remote_disk.rs b/crates/ecstore/src/rpc/remote_disk.rs index c786f8462..285bdeab0 100644 --- a/crates/ecstore/src/rpc/remote_disk.rs +++ b/crates/ecstore/src/rpc/remote_disk.rs @@ -2263,7 +2263,7 @@ impl DiskAPI for RemoteDisk { #[cfg(test)] mod tests { use super::*; - use crate::rpc::{InternodeDataTransportCapabilities, TcpHttpInternodeDataTransport}; + use crate::rpc::internode_data_transport::{InternodeDataTransportCapabilities, TcpHttpInternodeDataTransport}; use rustfs_common::GLOBAL_CONN_MAP; use serde_json::Value; use std::io::{self as std_io, Write}; diff --git a/crates/ecstore/src/store.rs b/crates/ecstore/src/store.rs index 30b3f331a..a1c159201 100644 --- a/crates/ecstore/src/store.rs +++ b/crates/ecstore/src/store.rs @@ -104,8 +104,6 @@ type ListObjectVersionsInfo = StorageListObjectVersionsInfo; type ObjectInfoOrErr = StorageObjectInfoOrErr; type WalkOptions = StorageWalkOptions bool>; -pub use crate::layout::pool_space::{PoolAvailableSpace, ServerPoolsAvailableSpace, has_space_for}; - /// Check if a directory contains any xl.meta files (indicating actual S3 objects) /// This is used to determine if a bucket is empty for deletion purposes. async fn has_xlmeta_files(path: &std::path::Path) -> bool { @@ -176,8 +174,8 @@ mod rebalance; use peer::init_local_peer; pub use peer::{ - all_local_disk, all_local_disk_path, find_local_disk, find_local_disk_by_ref, get_disk_infos, get_disk_via_endpoint, - init_local_disks, init_lock_clients, prewarm_local_disk_id_map, + all_local_disk, all_local_disk_path, find_local_disk_by_ref, get_disk_infos, init_local_disks, init_lock_clients, + prewarm_local_disk_id_map, }; pub struct ECStore { @@ -788,14 +786,14 @@ mod tests { async fn test_has_space_for() { let disk_infos = vec![None, None]; // No actual disk info - let result = has_space_for(&disk_infos, 1024).await; + let result = crate::layout::pool_space::has_space_for(&disk_infos, 1024).await; // Should fail due to no valid disk info assert!(result.is_err()); } #[tokio::test] async fn test_find_local_disk() { - let result = find_local_disk(&"/nonexistent/path".to_string()).await; + let result = peer::find_local_disk(&"/nonexistent/path".to_string()).await; assert!(result.is_none(), "Should return None for nonexistent path"); } diff --git a/crates/ecstore/src/store/rebalance.rs b/crates/ecstore/src/store/rebalance.rs index 1917a5719..a13b48206 100644 --- a/crates/ecstore/src/store/rebalance.rs +++ b/crates/ecstore/src/store/rebalance.rs @@ -14,7 +14,7 @@ use super::*; use crate::config::get_global_storage_class; -use crate::layout::pool_space::build_server_pools_available_space; +use crate::layout::pool_space::{ServerPoolsAvailableSpace, build_server_pools_available_space}; use rustfs_storage_api::{NamespaceLocking as _, ObjectOperations as _, StorageAdminApi}; pub(in crate::store) mod support; use support::{ diff --git a/crates/ecstore/tests/ecstore_contract_compat_test.rs b/crates/ecstore/tests/ecstore_contract_compat_test.rs index e97b57b97..04f70fa36 100644 --- a/crates/ecstore/tests/ecstore_contract_compat_test.rs +++ b/crates/ecstore/tests/ecstore_contract_compat_test.rs @@ -13,12 +13,8 @@ // limitations under the License. use rustfs_common::heal_channel::HealOpts; -use rustfs_ecstore::{ - disk::DiskStore, - error::Error, - object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader}, - store::ECStore, -}; +use rustfs_ecstore::api::{disk::DiskStore, error::Error, storage::ECStore}; +use rustfs_ecstore::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader}; use rustfs_filemeta::FileInfo; use rustfs_lock::NamespaceLockWrapper; use rustfs_madmin::heal_commands::HealResultItem; diff --git a/crates/ecstore/tests/legacy_bitrot_read_test.rs b/crates/ecstore/tests/legacy_bitrot_read_test.rs index 7c9f2c7b4..a9a17d81f 100644 --- a/crates/ecstore/tests/legacy_bitrot_read_test.rs +++ b/crates/ecstore/tests/legacy_bitrot_read_test.rs @@ -27,9 +27,9 @@ //! //! For MinIO data: RUSTFS_LEGACY_TEST_ROOT=/path/to/minio (disk "test" and .minio.sys auto-detected). +use rustfs_ecstore::api::disk::endpoint::Endpoint; +use rustfs_ecstore::api::disk::{DiskOption, STORAGE_FORMAT_FILE, new_disk}; use rustfs_ecstore::bitrot::create_bitrot_reader; -use rustfs_ecstore::disk::endpoint::Endpoint; -use rustfs_ecstore::disk::{DiskOption, STORAGE_FORMAT_FILE, new_disk}; use rustfs_filemeta::{FileInfoOpts, get_file_info}; use rustfs_utils::HashAlgorithm; use std::path::PathBuf; diff --git a/crates/ecstore/tests/minio_generated_read_test.rs b/crates/ecstore/tests/minio_generated_read_test.rs index c56c2a493..feb816562 100644 --- a/crates/ecstore/tests/minio_generated_read_test.rs +++ b/crates/ecstore/tests/minio_generated_read_test.rs @@ -4,9 +4,9 @@ use std::fs; use std::io::Cursor; use std::path::{Path, PathBuf}; +use rustfs_ecstore::api::disk::endpoint::Endpoint; +use rustfs_ecstore::api::disk::{DiskAPI as _, DiskOption, new_disk}; use rustfs_ecstore::bitrot::create_bitrot_reader; -use rustfs_ecstore::disk::endpoint::Endpoint; -use rustfs_ecstore::disk::{DiskAPI as _, DiskOption, new_disk}; use rustfs_ecstore::erasure_coding::Erasure; use rustfs_ecstore::object_api::{GetObjectReader, ObjectInfo, ObjectOptions}; use rustfs_filemeta::{FileInfo, FileInfoOpts, get_file_info}; diff --git a/crates/heal/src/heal/storage_compat.rs b/crates/heal/src/heal/storage_compat.rs index a7c225d6d..6d60a1495 100644 --- a/crates/heal/src/heal/storage_compat.rs +++ b/crates/heal/src/heal/storage_compat.rs @@ -12,22 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) const DATA_USAGE_CACHE_NAME: &str = rustfs_ecstore::data_usage::DATA_USAGE_CACHE_NAME; -pub(crate) const BUCKET_META_PREFIX: &str = rustfs_ecstore::disk::BUCKET_META_PREFIX; -pub(crate) const RUSTFS_META_BUCKET: &str = rustfs_ecstore::disk::RUSTFS_META_BUCKET; +pub(crate) const DATA_USAGE_CACHE_NAME: &str = rustfs_ecstore::api::data_usage::DATA_USAGE_CACHE_NAME; +pub(crate) const BUCKET_META_PREFIX: &str = rustfs_ecstore::api::disk::BUCKET_META_PREFIX; +pub(crate) const RUSTFS_META_BUCKET: &str = rustfs_ecstore::api::disk::RUSTFS_META_BUCKET; -pub(crate) type DiskError = rustfs_ecstore::disk::error::DiskError; -pub(crate) type DiskStore = rustfs_ecstore::disk::DiskStore; +pub(crate) type DiskError = rustfs_ecstore::api::disk::error::DiskError; +pub(crate) type DiskStore = rustfs_ecstore::api::disk::DiskStore; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; -pub(crate) type EcstoreError = rustfs_ecstore::error::Error; -pub(crate) type Endpoint = rustfs_ecstore::disk::endpoint::Endpoint; -pub(crate) type StorageError = rustfs_ecstore::error::StorageError; +pub(crate) type EcstoreError = rustfs_ecstore::api::error::Error; +pub(crate) type Endpoint = rustfs_ecstore::api::disk::endpoint::Endpoint; +pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; -pub(crate) use rustfs_ecstore::disk::DiskAPI; -pub(crate) use rustfs_ecstore::global::GLOBAL_LOCAL_DISK_MAP; +pub(crate) use rustfs_ecstore::api::disk::DiskAPI; +pub(crate) use rustfs_ecstore::api::global::GLOBAL_LOCAL_DISK_MAP; #[cfg(test)] -pub(crate) use rustfs_ecstore::disk::{DiskOption, new_disk}; +pub(crate) use rustfs_ecstore::api::disk::{DiskOption, new_disk}; pub type HealObjectInfo = ::ObjectInfo; pub type HealObjectOptions = ::ObjectOptions; diff --git a/crates/heal/tests/common/storage_compat.rs b/crates/heal/tests/common/storage_compat.rs index 2f9a9a089..7bd273ac0 100644 --- a/crates/heal/tests/common/storage_compat.rs +++ b/crates/heal/tests/common/storage_compat.rs @@ -14,8 +14,8 @@ #![allow(unused_imports)] +pub(crate) use rustfs_ecstore::api::bucket::metadata_sys::init_bucket_metadata_sys; +pub(crate) use rustfs_ecstore::api::disk::{DiskStore, endpoint::Endpoint}; pub(crate) use rustfs_ecstore::api::layout::{EndpointServerPools, Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::api::storage::ECStore; pub(crate) use rustfs_ecstore::api::storage::init_local_disks; -pub(crate) use rustfs_ecstore::bucket::metadata_sys::init_bucket_metadata_sys; -pub(crate) use rustfs_ecstore::disk::{DiskStore, endpoint::Endpoint}; diff --git a/crates/iam/src/storage_compat.rs b/crates/iam/src/storage_compat.rs index 97492d62c..eda34b9c7 100644 --- a/crates/iam/src/storage_compat.rs +++ b/crates/iam/src/storage_compat.rs @@ -14,17 +14,17 @@ use std::sync::Arc; -pub(crate) const IAM_CONFIG_ROOT_PREFIX: &str = rustfs_ecstore::config::RUSTFS_CONFIG_PREFIX; +pub(crate) const IAM_CONFIG_ROOT_PREFIX: &str = rustfs_ecstore::api::config::RUSTFS_CONFIG_PREFIX; -pub(crate) type IamEcstoreError = rustfs_ecstore::error::Error; -pub(crate) type IamStorageError = rustfs_ecstore::error::StorageError; -pub(crate) type IamStorageResult = rustfs_ecstore::error::Result; +pub(crate) type IamEcstoreError = rustfs_ecstore::api::error::Error; +pub(crate) type IamStorageError = rustfs_ecstore::api::error::StorageError; +pub(crate) type IamStorageResult = rustfs_ecstore::api::error::Result; pub(crate) type IamStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type IamConfigObjectInfo = ::ObjectInfo; pub(crate) type IamConfigObjectOptions = ::ObjectOptions; pub(crate) async fn read_iam_config_no_lock(api: Arc, file: &str) -> IamStorageResult> { - rustfs_ecstore::config::com::read_config_no_lock(api, file).await + rustfs_ecstore::api::config::com::read_config_no_lock(api, file).await } pub(crate) async fn read_iam_config_with_metadata( @@ -32,11 +32,11 @@ pub(crate) async fn read_iam_config_with_metadata( file: &str, opts: &IamConfigObjectOptions, ) -> IamStorageResult<(Vec, IamConfigObjectInfo)> { - rustfs_ecstore::config::com::read_config_with_metadata(api, file, opts).await + rustfs_ecstore::api::config::com::read_config_with_metadata(api, file, opts).await } pub(crate) async fn save_iam_config(api: Arc, file: &str, data: Vec) -> IamStorageResult<()> { - rustfs_ecstore::config::com::save_config(api, file, data).await + rustfs_ecstore::api::config::com::save_config(api, file, data).await } pub(crate) async fn save_iam_config_with_opts( @@ -45,19 +45,19 @@ pub(crate) async fn save_iam_config_with_opts( data: Vec, opts: &IamConfigObjectOptions, ) -> IamStorageResult<()> { - rustfs_ecstore::config::com::save_config_with_opts(api, file, data, opts).await + rustfs_ecstore::api::config::com::save_config_with_opts(api, file, data, opts).await } pub(crate) async fn delete_iam_config(api: Arc, file: &str) -> IamStorageResult<()> { - rustfs_ecstore::config::com::delete_config(api, file).await + rustfs_ecstore::api::config::com::delete_config(api, file).await } pub(crate) fn classify_iam_system_path_failure_reason(err: &IamEcstoreError) -> &'static str { - rustfs_ecstore::error::classify_system_path_failure_reason(err) + rustfs_ecstore::api::error::classify_system_path_failure_reason(err) } pub(crate) async fn is_iam_first_cluster_node_local() -> bool { - rustfs_ecstore::global::is_first_cluster_node_local().await + rustfs_ecstore::api::global::is_first_cluster_node_local().await } pub(crate) struct IamNotificationPeerErr { diff --git a/crates/notify/src/storage_compat.rs b/crates/notify/src/storage_compat.rs index 308331108..bed0215d8 100644 --- a/crates/notify/src/storage_compat.rs +++ b/crates/notify/src/storage_compat.rs @@ -13,7 +13,7 @@ // limitations under the License. use rustfs_config::server_config::Config; -use rustfs_ecstore::{config, global}; +use rustfs_ecstore::api::{config, global}; #[derive(Debug)] pub(crate) enum NotifyConfigStoreError { diff --git a/crates/obs/src/storage_compat.rs b/crates/obs/src/storage_compat.rs index e5874edda..4fdc9f8cb 100644 --- a/crates/obs/src/storage_compat.rs +++ b/crates/obs/src/storage_compat.rs @@ -20,7 +20,7 @@ use rustfs_storage_api::StorageAdminApi; use std::sync::Arc; use std::time::Duration; -pub(crate) use rustfs_ecstore::data_usage::load_data_usage_from_backend as load_obs_data_usage_from_backend; +pub(crate) use rustfs_ecstore::api::data_usage::load_data_usage_from_backend as load_obs_data_usage_from_backend; pub(crate) type ObsStore = rustfs_ecstore::api::storage::ECStore; type ObsStorageInfo = ::StorageInfo; @@ -46,7 +46,7 @@ pub(crate) struct ObsIlmRuntimeSnapshot { } pub(crate) fn resolve_obs_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + rustfs_ecstore::api::global::resolve_object_store_handle() } pub(crate) fn obs_total_usable_capacity_bytes(storage_info: &ObsStorageInfo) -> u64 { @@ -64,7 +64,7 @@ pub(crate) fn obs_total_usable_capacity_free_bytes(storage_info: &ObsStorageInfo } pub(crate) async fn obs_bucket_quota_limit_bytes(bucket: &str) -> u64 { - rustfs_ecstore::bucket::metadata_sys::get_quota_config(bucket) + rustfs_ecstore::api::bucket::metadata_sys::get_quota_config(bucket) .await .ok() .and_then(|(quota, _)| quota.get_quota_limit()) @@ -72,11 +72,11 @@ pub(crate) async fn obs_bucket_quota_limit_bytes(bucket: &str) -> u64 { } pub(crate) fn obs_bucket_monitor_available() -> bool { - rustfs_ecstore::global::get_global_bucket_monitor().is_some() + rustfs_ecstore::api::global::get_global_bucket_monitor().is_some() } pub(crate) fn obs_bucket_replication_bandwidth_stats() -> Option> { - let monitor = rustfs_ecstore::global::get_global_bucket_monitor()?; + let monitor = rustfs_ecstore::api::global::get_global_bucket_monitor()?; Some( monitor .get_report(|_| true) @@ -94,12 +94,12 @@ pub(crate) fn obs_bucket_replication_bandwidth_stats() -> Option ObsIlmRuntimeSnapshot { let expiry_pending_tasks = { - let expiry = rustfs_ecstore::bucket::lifecycle::bucket_lifecycle_ops::GLOBAL_ExpiryState + let expiry = rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::GLOBAL_ExpiryState .read() .await; usize_to_u64_saturating(expiry.pending_tasks()) }; - let transition = &rustfs_ecstore::bucket::lifecycle::bucket_lifecycle_ops::GLOBAL_TransitionState; + let transition = &rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::GLOBAL_TransitionState; ObsIlmRuntimeSnapshot { expiry_pending_tasks, @@ -114,7 +114,7 @@ pub(crate) async fn obs_ilm_runtime_snapshot() -> ObsIlmRuntimeSnapshot { } pub(crate) async fn obs_bucket_replication_detail_stats() -> Vec { - let Some(stats) = rustfs_ecstore::bucket::replication::GLOBAL_REPLICATION_STATS.get() else { + let Some(stats) = rustfs_ecstore::api::bucket::replication::GLOBAL_REPLICATION_STATS.get() else { return Vec::new(); }; @@ -186,7 +186,7 @@ pub(crate) async fn obs_bucket_replication_detail_stats() -> Vec MetricReplicationStats { - let Some(stats) = rustfs_ecstore::bucket::replication::GLOBAL_REPLICATION_STATS.get() else { + let Some(stats) = rustfs_ecstore::api::bucket::replication::GLOBAL_REPLICATION_STATS.get() else { return MetricReplicationStats::default(); }; diff --git a/crates/protocols/src/swift/storage_compat.rs b/crates/protocols/src/swift/storage_compat.rs index d25f8625c..a603bc091 100644 --- a/crates/protocols/src/swift/storage_compat.rs +++ b/crates/protocols/src/swift/storage_compat.rs @@ -14,8 +14,8 @@ use std::sync::Arc; -pub(super) type SwiftBucketMetadata = rustfs_ecstore::bucket::metadata::BucketMetadata; -pub(super) type SwiftStorageResult = rustfs_ecstore::error::Result; +pub(super) type SwiftBucketMetadata = rustfs_ecstore::api::bucket::metadata::BucketMetadata; +pub(super) type SwiftStorageResult = rustfs_ecstore::api::error::Result; pub(super) type SwiftStore = rustfs_ecstore::api::storage::ECStore; pub type SwiftGetObjectReader = ::GetObjectReader; pub type SwiftObjectInfo = ::ObjectInfo; @@ -23,13 +23,13 @@ pub type SwiftObjectOptions = ::PutObjectReader; pub fn resolve_swift_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + rustfs_ecstore::api::global::resolve_object_store_handle() } pub async fn get_swift_bucket_metadata(bucket: &str) -> SwiftStorageResult> { - rustfs_ecstore::bucket::metadata_sys::get(bucket).await + rustfs_ecstore::api::bucket::metadata_sys::get(bucket).await } pub async fn set_swift_bucket_metadata(bucket: String, metadata: SwiftBucketMetadata) -> SwiftStorageResult<()> { - rustfs_ecstore::bucket::metadata_sys::set_bucket_metadata(bucket, metadata).await + rustfs_ecstore::api::bucket::metadata_sys::set_bucket_metadata(bucket, metadata).await } diff --git a/crates/s3select-api/src/storage_compat.rs b/crates/s3select-api/src/storage_compat.rs index 386728e1a..cf72264f9 100644 --- a/crates/s3select-api/src/storage_compat.rs +++ b/crates/s3select-api/src/storage_compat.rs @@ -12,30 +12,30 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) type SelectStorageError = rustfs_ecstore::error::StorageError; +pub(crate) type SelectStorageError = rustfs_ecstore::api::error::StorageError; pub(crate) type SelectStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type SelectGetObjectReader = ::GetObjectReader; pub(crate) type SelectObjectInfo = ::ObjectInfo; pub(crate) type SelectObjectOptions = ::ObjectOptions; -pub(crate) const SELECT_DEFAULT_READ_BUFFER_SIZE: usize = rustfs_ecstore::set_disk::DEFAULT_READ_BUFFER_SIZE; +pub(crate) const SELECT_DEFAULT_READ_BUFFER_SIZE: usize = rustfs_ecstore::api::set_disk::DEFAULT_READ_BUFFER_SIZE; pub(crate) fn select_default_read_buffer_size_u64() -> u64 { u64::try_from(SELECT_DEFAULT_READ_BUFFER_SIZE).unwrap_or(u64::MAX) } pub(crate) fn resolve_select_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + rustfs_ecstore::api::global::resolve_object_store_handle() } pub(crate) fn select_is_err_bucket_not_found(err: &SelectStorageError) -> bool { - rustfs_ecstore::error::is_err_bucket_not_found(err) + rustfs_ecstore::api::error::is_err_bucket_not_found(err) } pub(crate) fn select_is_err_object_not_found(err: &SelectStorageError) -> bool { - rustfs_ecstore::error::is_err_object_not_found(err) + rustfs_ecstore::api::error::is_err_object_not_found(err) } pub(crate) fn select_is_err_version_not_found(err: &SelectStorageError) -> bool { - rustfs_ecstore::error::is_err_version_not_found(err) + rustfs_ecstore::api::error::is_err_version_not_found(err) } diff --git a/crates/scanner/src/storage_compat.rs b/crates/scanner/src/storage_compat.rs index bcb75811f..3f2b1c6a5 100644 --- a/crates/scanner/src/storage_compat.rs +++ b/crates/scanner/src/storage_compat.rs @@ -17,21 +17,21 @@ use rustfs_storage_api::{HTTPRangeSpec, ObjectIO, ObjectToDelete}; use std::sync::Arc; use tokio_util::sync::CancellationToken; -pub(crate) const BUCKET_META_PREFIX: &str = rustfs_ecstore::disk::BUCKET_META_PREFIX; -pub(crate) const RUSTFS_META_BUCKET: &str = rustfs_ecstore::disk::RUSTFS_META_BUCKET; -pub(crate) const STORAGE_FORMAT_FILE: &str = rustfs_ecstore::disk::STORAGE_FORMAT_FILE; -pub(crate) const TRANSITION_COMPLETE: &str = rustfs_ecstore::bucket::lifecycle::lifecycle::TRANSITION_COMPLETE; +pub(crate) const BUCKET_META_PREFIX: &str = rustfs_ecstore::api::disk::BUCKET_META_PREFIX; +pub(crate) const RUSTFS_META_BUCKET: &str = rustfs_ecstore::api::disk::RUSTFS_META_BUCKET; +pub(crate) const STORAGE_FORMAT_FILE: &str = rustfs_ecstore::api::disk::STORAGE_FORMAT_FILE; +pub(crate) const TRANSITION_COMPLETE: &str = rustfs_ecstore::api::bucket::lifecycle::lifecycle::TRANSITION_COMPLETE; -pub(crate) type Disk = rustfs_ecstore::disk::Disk; -pub(crate) type DiskError = rustfs_ecstore::disk::error::DiskError; +pub(crate) type Disk = rustfs_ecstore::api::disk::Disk; +pub(crate) type DiskError = rustfs_ecstore::api::disk::error::DiskError; pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore; -pub(crate) type EcstoreError = rustfs_ecstore::error::Error; -pub(crate) type EcstoreResult = rustfs_ecstore::error::Result; -pub(crate) type ListPathRawOptions = rustfs_ecstore::cache_value::metacache_set::ListPathRawOptions; -pub(crate) type SetDisks = rustfs_ecstore::set_disk::SetDisks; -pub(crate) type StorageError = rustfs_ecstore::error::StorageError; +pub(crate) type EcstoreError = rustfs_ecstore::api::error::Error; +pub(crate) type EcstoreResult = rustfs_ecstore::api::error::Result; +pub(crate) type ListPathRawOptions = rustfs_ecstore::api::cache::ListPathRawOptions; +pub(crate) type SetDisks = rustfs_ecstore::api::set_disk::SetDisks; +pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError; -pub(crate) use rustfs_ecstore::bucket::{ +pub(crate) use rustfs_ecstore::api::bucket::{ bucket_target_sys::BucketTargetSys, lifecycle::{ bucket_lifecycle_audit::LcEventSrc, @@ -44,8 +44,8 @@ pub(crate) use rustfs_ecstore::bucket::{ versioning::VersioningApi, versioning_sys::BucketVersioningSys, }; -pub(crate) use rustfs_ecstore::disk::{DiskAPI, DiskInfoOptions}; -pub(crate) use rustfs_ecstore::global::GLOBAL_TierConfigMgr; +pub(crate) use rustfs_ecstore::api::disk::{DiskAPI, DiskInfoOptions}; +pub(crate) use rustfs_ecstore::api::global::GLOBAL_TierConfigMgr; pub type ScannerGetObjectReader = ::GetObjectReader; pub type ScannerObjectInfo = ::ObjectInfo; @@ -54,18 +54,18 @@ pub type ScannerObjectToDelete = ObjectToDelete; pub type ScannerPutObjReader = ::PutObjectReader; pub(crate) mod storageclass { - pub(crate) const RRS: &str = rustfs_ecstore::config::storageclass::RRS; - pub(crate) const STANDARD: &str = rustfs_ecstore::config::storageclass::STANDARD; + pub(crate) const RRS: &str = rustfs_ecstore::api::config::storageclass::RRS; + pub(crate) const STANDARD: &str = rustfs_ecstore::api::config::storageclass::STANDARD; } #[cfg(test)] -pub(crate) use rustfs_ecstore::config::init as init_ecstore_config_for_scanner_tests; +pub(crate) use rustfs_ecstore::api::config::init as init_ecstore_config_for_scanner_tests; #[cfg(test)] -pub(crate) use rustfs_ecstore::disk::{DiskOption, endpoint::Endpoint, new_disk}; +pub(crate) use rustfs_ecstore::api::disk::{DiskOption, endpoint::Endpoint, new_disk}; pub(crate) fn resolve_scanner_object_store_handle() -> Option> { - rustfs_ecstore::resolve_object_store_handle() + rustfs_ecstore::api::global::resolve_object_store_handle() } pub(crate) fn is_reserved_or_invalid_bucket(bucket: &str, strict: bool) -> bool { @@ -81,33 +81,33 @@ pub(crate) fn path2_bucket_object_with_base_path(base_path: &str, path: &str) -> } pub(crate) async fn is_erasure() -> bool { - rustfs_ecstore::global::is_erasure().await + rustfs_ecstore::api::global::is_erasure().await } pub(crate) async fn is_erasure_sd() -> bool { - rustfs_ecstore::global::is_erasure_sd().await + rustfs_ecstore::api::global::is_erasure_sd().await } pub(crate) async fn read_config(api: Arc, file: &str) -> EcstoreResult> where S: ScannerObjectIO, { - rustfs_ecstore::config::com::read_config(api, file).await + rustfs_ecstore::api::config::com::read_config(api, file).await } pub(crate) async fn save_config(api: Arc, file: &str, data: Vec) -> EcstoreResult<()> where S: ScannerObjectIO, { - rustfs_ecstore::config::com::save_config(api, file, data).await + rustfs_ecstore::api::config::com::save_config(api, file, data).await } pub(crate) async fn list_path_raw(rx: CancellationToken, opts: ListPathRawOptions) -> std::result::Result<(), DiskError> { - rustfs_ecstore::cache_value::metacache_set::list_path_raw(rx, opts).await + rustfs_ecstore::api::cache::list_path_raw(rx, opts).await } pub(crate) async fn replace_bucket_usage_memory_from_info(data_usage_info: &rustfs_data_usage::DataUsageInfo) { - rustfs_ecstore::data_usage::replace_bucket_usage_memory_from_info(data_usage_info).await; + rustfs_ecstore::api::data_usage::replace_bucket_usage_memory_from_info(data_usage_info).await; } pub trait ScannerObjectIO: diff --git a/crates/scanner/tests/common/storage_compat.rs b/crates/scanner/tests/common/storage_compat.rs index f1415af4c..e405aa7b7 100644 --- a/crates/scanner/tests/common/storage_compat.rs +++ b/crates/scanner/tests/common/storage_compat.rs @@ -14,25 +14,25 @@ #![allow(dead_code, unused_imports)] -pub(crate) const BUCKET_LIFECYCLE_CONFIG: &str = rustfs_ecstore::bucket::metadata::BUCKET_LIFECYCLE_CONFIG; -pub(crate) const STORAGE_FORMAT_FILE: &str = rustfs_ecstore::disk::STORAGE_FORMAT_FILE; +pub(crate) const BUCKET_LIFECYCLE_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_LIFECYCLE_CONFIG; +pub(crate) const STORAGE_FORMAT_FILE: &str = rustfs_ecstore::api::disk::STORAGE_FORMAT_FILE; -pub(crate) type TransitionOptions = rustfs_ecstore::bucket::lifecycle::lifecycle::TransitionOptions; +pub(crate) type TransitionOptions = rustfs_ecstore::api::bucket::lifecycle::lifecycle::TransitionOptions; +pub(crate) use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::{ + enqueue_transition_for_existing_objects, init_background_expiry, +}; +pub(crate) use rustfs_ecstore::api::bucket::metadata_sys::{ + get as get_bucket_metadata, init_bucket_metadata_sys, update as update_bucket_metadata, +}; +pub(crate) use rustfs_ecstore::api::bucket::versioning_sys::BucketVersioningSys; pub(crate) use rustfs_ecstore::api::capacity::path2_bucket_object_with_base_path; +pub(crate) use rustfs_ecstore::api::client::transition_api::{ReadCloser, ReaderImpl}; +pub(crate) use rustfs_ecstore::api::disk::{DiskAPI, DiskOption, endpoint::Endpoint, new_disk}; +pub(crate) use rustfs_ecstore::api::global::GLOBAL_TierConfigMgr; pub(crate) use rustfs_ecstore::api::layout::{EndpointServerPools, Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::api::storage::ECStore; pub(crate) use rustfs_ecstore::api::storage::init_local_disks; -pub(crate) use rustfs_ecstore::bucket::lifecycle::bucket_lifecycle_ops::{ - enqueue_transition_for_existing_objects, init_background_expiry, -}; -pub(crate) use rustfs_ecstore::bucket::metadata_sys::{ - get as get_bucket_metadata, init_bucket_metadata_sys, update as update_bucket_metadata, -}; -pub(crate) use rustfs_ecstore::bucket::versioning_sys::BucketVersioningSys; -pub(crate) use rustfs_ecstore::client::transition_api::{ReadCloser, ReaderImpl}; -pub(crate) use rustfs_ecstore::disk::{DiskAPI, DiskOption, endpoint::Endpoint, new_disk}; -pub(crate) use rustfs_ecstore::global::GLOBAL_TierConfigMgr; -pub(crate) use rustfs_ecstore::tier::tier_config::{TierConfig, TierMinIO, TierType}; -pub(crate) use rustfs_ecstore::tier::warm_backend::WarmBackendGetOpts; -pub(crate) use rustfs_ecstore::tier::warm_backend::{WarmBackend, build_transition_put_options}; +pub(crate) use rustfs_ecstore::api::tier::tier_config::{TierConfig, TierMinIO, TierType}; +pub(crate) use rustfs_ecstore::api::tier::warm_backend::WarmBackendGetOpts; +pub(crate) use rustfs_ecstore::api::tier::warm_backend::{WarmBackend, build_transition_put_options}; diff --git a/docs/architecture/crate-boundaries.md b/docs/architecture/crate-boundaries.md index a6b852577..a2332edb8 100644 --- a/docs/architecture/crate-boundaries.md +++ b/docs/architecture/crate-boundaries.md @@ -128,7 +128,16 @@ downstream compatibility. Outer compatibility boundary modules must use `rustfs_ecstore::api` for ECStore public facade surfaces such as layout, storage owner, admin, metrics, -notification, capacity, and bucket-name helpers. +notification, capacity, bucket/config helpers, disk/error contracts, global +state accessors, RPC constants/clients, reader helpers, tier helpers, and +rebalance status contracts. Any non-ECStore `storage_compat.rs` import from +`rustfs_ecstore` must route through the `rustfs_ecstore::api` facade. +The legacy ECStore root `endpoints` and `disks_layout` compatibility modules +must remain crate-private; public layout access goes through +`rustfs_ecstore::api::layout`. +Facade-covered ECStore root modules must remain crate-private after this +boundary is established; outer crates should use `rustfs_ecstore::api::*` +instead of legacy root module paths. RustFS startup internals must stay crate-private after the startup owner split. Only `startup_entrypoint` remains a public startup module for the binary diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index 6efda087f..a967391a3 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -407,6 +407,66 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block guards, formatting, diff hygiene, Rust risk scan, branch freshness check, pre-commit quality gate, and three-expert review. +- [x] `API-073` Expand ECStore public facade coverage. + - Completed slice: add `rustfs_ecstore::api` facade groups for bucket, + config, disk, error, event, global, RPC, set-disk, reader, client, tier, + data-usage, cache, compression, and rebalance compatibility surfaces, then + migrate all outer `storage_compat.rs` boundaries to those facade paths. + - Acceptance: RustFS, app/admin/storage runtime, scanner, heal, IAM, notify, + observability, Swift, S3 Select, e2e, test, and fuzz compatibility + boundaries no longer import those ECStore public surfaces through direct + pre-facade module paths, and the migration guard rejects restoring them. + - Must preserve: storage owner types, config IO, bucket metadata/lifecycle + helpers, disk/RPC/error contracts, global state accessors, reader wrappers, + tier helpers, rebalance status DTOs, test/fuzz harness behavior, and all + existing runtime behavior. + - Verification: affected package test-target compile, migration and layer + guards, formatting, diff hygiene, Rust risk scan, branch freshness check, + pre-commit quality gate, and three-expert review. + +- [x] `API-074` Enforce ECStore API facade for compatibility boundaries. + - Completed slice: extend the architecture migration guard so every + non-ECStore `storage_compat.rs` import from `rustfs_ecstore` must route + through `rustfs_ecstore::api`, not only the previously enumerated public + ECStore module paths. + - Acceptance: RustFS, app/admin/storage runtime, scanner, heal, IAM, notify, + observability, Swift, S3 Select, e2e, test, and fuzz compatibility + boundaries cannot reintroduce direct pre-facade ECStore paths through new + modules or grouped imports. + - Must preserve: no runtime behavior, type ownership, compatibility alias, or + ECStore public facade behavior changes. + - Verification: migration guard, direct old-path scan, formatting, diff + hygiene, branch freshness check, pre-commit quality gate, and three-expert + review. + +- [x] `API-075` Prune ECStore legacy layout root modules. + - Completed slice: make the legacy ECStore root `endpoints` and + `disks_layout` compatibility modules crate-private now that outer + compatibility boundaries use `rustfs_ecstore::api::layout`. + - Acceptance: `rustfs_ecstore::api::layout` remains the public facade for + endpoint pools and disk layout helpers, while migration rules reject + restoring the old root layout compatibility modules as public modules. + - Must preserve: endpoint layout types, disk layout helper behavior, ECStore + internal call sites, and all outer compatibility facade paths. + - Verification: ECStore and affected outer package compile, migration and + layer guards, formatting, diff hygiene, Rust risk scan, branch freshness + check, pre-commit quality gate, and three-expert review. + +- [x] `API-076` Prune facade-covered ECStore root modules. + - Completed slice: make facade-covered legacy ECStore root modules + crate-private after all in-repo outer compatibility boundaries route + through `rustfs_ecstore::api`. + - Acceptance: `rustfs_ecstore::api::*` remains the public facade for storage, + admin, config, metrics, notification, RPC, disk, error, tier, rebalance, + and layout helper surfaces, while migration rules reject restoring those + legacy root modules as public modules. + - Must preserve: ECStore internal module access, public `api` facade paths, + object API paths, bitrot and erasure coding test/bench paths, and storage + contract compatibility tests. + - Verification: ECStore and affected outer package compile, migration and + layer guards, formatting, diff hygiene, Rust risk scan, branch freshness + check, pre-commit quality gate, and three-expert review. + - [x] `TEST-PRTYPE-001` Check PR type enum consistency. - Acceptance: `./scripts/check_architecture_migration_rules.sh` parses the allowed PR types from [`crate-boundaries.md`](crate-boundaries.md) and fails @@ -2921,14 +2981,56 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | R-068 keeps the binary startup entrypoint public while making remaining startup compatibility shims crate-private and guarding that surface. | -| Migration preservation | passed | IAM readiness bootstrap, embedded readiness publication, optional runtime shutdown wiring, profiling shutdown behavior, and test-only IAM retry hook behavior stay in the same owner modules. | -| Testing/verification | passed | RustFS lib/bin check, focused startup checks, architecture/layer/unsafe guards, formatting, diff hygiene, Rust risk scan, and pre-commit gate passed. | +| Quality/architecture | passed | API-076 removes facade-covered legacy ECStore root modules from the public module surface while keeping the explicit `rustfs_ecstore::api` boundary as the supported compatibility path. | +| Migration preservation | passed | ECStore internal call sites, storage contract tests, object API, bitrot, erasure coding, and outer compatibility imports keep their behavior and names through retained facade paths. | +| Testing/verification | passed | ECStore/outer compile checks, bench compile, migration/layer/unsafe guards, formatting, diff hygiene, Rust risk scan, and pre-commit gate passed. | ## Verification Notes Passed before push: +- Issue #660 API-076 current slice: + - `cargo check --tests -p rustfs-ecstore -p rustfs -p rustfs-scanner -p rustfs-heal -p rustfs-iam -p rustfs-notify -p rustfs-obs -p rustfs-protocols -p rustfs-s3select-api -p e2e_test`: passed. + - `cargo check --benches -p rustfs-ecstore`: 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. + - `./scripts/check_layer_dependencies.sh`: passed. + - `./scripts/check_unsafe_code_allowances.sh`: passed. + - Rust risk scan on changed Rust files and guard script: passed. + - `make pre-commit`: passed; nextest ran 6341 tests with 6341 passed, 111 skipped, and doctests passed. + +- Issue #660 API-075 current slice: + - `cargo check --tests -p rustfs-ecstore -p rustfs -p rustfs-scanner -p rustfs-heal -p rustfs-iam -p rustfs-notify -p rustfs-obs -p rustfs-protocols -p rustfs-s3select-api -p e2e_test`: 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. + - Rust risk scan on changed Rust files and guard script: passed. + - `make pre-commit`: passed; nextest ran 6341 tests with 6341 passed, 111 skipped, and doctests passed. + +- Issue #660 API-074 current slice: + - `bash -n scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - Direct old ECStore path scan in non-ECStore `storage_compat.rs` boundaries: passed. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - `make pre-commit`: passed; nextest ran 6341 tests with 6341 passed, 111 skipped, and doctests passed. + +- Issue #660 API-073 current slice: + - `cargo check --tests -p rustfs-ecstore -p rustfs -p rustfs-scanner -p rustfs-heal -p rustfs-iam -p rustfs-notify -p rustfs-obs -p rustfs-protocols -p rustfs-s3select-api -p e2e_test`: passed. + - `cargo check --manifest-path fuzz/Cargo.toml --all-targets`: passed; Cargo refreshed the fuzz lockfile during verification and the generated lockfile change was not retained. + - `cargo fmt --all --check`: passed. + - `git diff --check`: passed. + - Direct old ECStore facade path scan in outer storage compatibility boundaries: passed. + - `bash -n scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_architecture_migration_rules.sh`: passed. + - `./scripts/check_layer_dependencies.sh`: passed. + - `./scripts/check_unsafe_code_allowances.sh`: passed. + - Rust risk scan on changed Rust files and guard script: passed. + - `make pre-commit`: passed; nextest ran 6341 tests with 6341 passed, 111 skipped, and doctests passed. + - Issue #660 R-068 current slice: - `cargo check -p rustfs --lib --bins`: passed. - `cargo test -p rustfs --lib startup_ -- --nocapture`: passed; 53 tests. diff --git a/fuzz/fuzz_targets/bucket_validation/storage_compat.rs b/fuzz/fuzz_targets/bucket_validation/storage_compat.rs index 138d844ac..0bc702d6d 100644 --- a/fuzz/fuzz_targets/bucket_validation/storage_compat.rs +++ b/fuzz/fuzz_targets/bucket_validation/storage_compat.rs @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) use rustfs_ecstore::bucket::utils::{ +pub(crate) use rustfs_ecstore::api::bucket::utils::{ check_bucket_and_object_names, check_list_objs_args, check_valid_bucket_name_strict, is_meta_bucketname, }; diff --git a/fuzz/fuzz_targets/path_containment/storage_compat.rs b/fuzz/fuzz_targets/path_containment/storage_compat.rs index 8eb98064f..f54cdf0e2 100644 --- a/fuzz/fuzz_targets/path_containment/storage_compat.rs +++ b/fuzz/fuzz_targets/path_containment/storage_compat.rs @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) use rustfs_ecstore::bucket::utils::{ +pub(crate) use rustfs_ecstore::api::bucket::utils::{ check_object_name_for_length_and_slash, has_bad_path_component, is_valid_object_prefix, }; diff --git a/rustfs/src/admin/storage_compat.rs b/rustfs/src/admin/storage_compat.rs index a806b601c..d8ea691a8 100644 --- a/rustfs/src/admin/storage_compat.rs +++ b/rustfs/src/admin/storage_compat.rs @@ -12,36 +12,40 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub(crate) use rustfs_ecstore::api::bucket::lifecycle::tier_last_day_stats::DailyAllTierStats; +pub(crate) use rustfs_ecstore::api::bucket::{ + bandwidth, bucket_target_sys, lifecycle, metadata, metadata_sys, quota, replication, target, utils, versioning, + versioning_sys, +}; pub(crate) use rustfs_ecstore::api::capacity::is_reserved_or_invalid_bucket; +pub(crate) use rustfs_ecstore::api::client::admin_handler_utils::AdminError; +pub(crate) use rustfs_ecstore::api::config::{com, init, set_global_storage_class, storageclass}; +pub(crate) use rustfs_ecstore::api::data_usage::load_data_usage_from_backend; +pub(crate) use rustfs_ecstore::api::disk::RUSTFS_META_BUCKET; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::disk::endpoint::Endpoint; +pub(crate) use rustfs_ecstore::api::error::{Error, StorageError}; +pub(crate) use rustfs_ecstore::api::global::{ + GLOBAL_BOOT_TIME, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, get_global_region, + global_rustfs_port, +}; pub(crate) use rustfs_ecstore::api::layout::EndpointServerPools; #[cfg(test)] pub(crate) use rustfs_ecstore::api::layout::{Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::api::metrics::{CollectMetricsOpts, MetricType, collect_local_metrics}; pub(crate) use rustfs_ecstore::api::notification::get_global_notification_sys; +pub(crate) use rustfs_ecstore::api::rebalance::{ + DiskStat, RebalSaveOpt, RebalanceCleanupWarnings, RebalanceMeta, RebalanceStats, +}; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::rebalance::{RebalStatus, RebalanceInfo}; +pub(crate) use rustfs_ecstore::api::rpc::PeerRestClient; pub(crate) use rustfs_ecstore::api::storage::ECStore; -pub(crate) use rustfs_ecstore::bucket::lifecycle::tier_last_day_stats::DailyAllTierStats; -pub(crate) use rustfs_ecstore::bucket::{ - bandwidth, bucket_target_sys, lifecycle, metadata, metadata_sys, quota, replication, target, utils, versioning, - versioning_sys, +pub(crate) use rustfs_ecstore::api::tier::tier::{ + ERR_TIER_BACKEND_IN_USE, ERR_TIER_BACKEND_NOT_EMPTY, ERR_TIER_MISSING_CREDENTIALS, }; -pub(crate) use rustfs_ecstore::client::admin_handler_utils::AdminError; -pub(crate) use rustfs_ecstore::config::{com, init, set_global_storage_class, storageclass}; -pub(crate) use rustfs_ecstore::data_usage::load_data_usage_from_backend; -pub(crate) use rustfs_ecstore::disk::RUSTFS_META_BUCKET; -#[cfg(test)] -pub(crate) use rustfs_ecstore::disk::endpoint::Endpoint; -pub(crate) use rustfs_ecstore::error::{Error, StorageError}; -pub(crate) use rustfs_ecstore::global::{ - GLOBAL_BOOT_TIME, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, get_global_region, - global_rustfs_port, -}; -pub(crate) use rustfs_ecstore::rebalance::{DiskStat, RebalSaveOpt, RebalanceCleanupWarnings, RebalanceMeta, RebalanceStats}; -#[cfg(test)] -pub(crate) use rustfs_ecstore::rebalance::{RebalStatus, RebalanceInfo}; -pub(crate) use rustfs_ecstore::rpc::PeerRestClient; -pub(crate) use rustfs_ecstore::tier::tier::{ERR_TIER_BACKEND_IN_USE, ERR_TIER_BACKEND_NOT_EMPTY, ERR_TIER_MISSING_CREDENTIALS}; -pub(crate) use rustfs_ecstore::tier::tier_admin::TierCreds; -pub(crate) use rustfs_ecstore::tier::tier_config::{TierConfig, TierType}; -pub(crate) use rustfs_ecstore::tier::tier_handlers::{ +pub(crate) use rustfs_ecstore::api::tier::tier_admin::TierCreds; +pub(crate) use rustfs_ecstore::api::tier::tier_config::{TierConfig, TierType}; +pub(crate) use rustfs_ecstore::api::tier::tier_handlers::{ ERR_TIER_ALREADY_EXISTS, ERR_TIER_CONNECT_ERR, ERR_TIER_INVALID_CREDENTIALS, ERR_TIER_NAME_NOT_UPPERCASE, ERR_TIER_NOT_FOUND, }; diff --git a/rustfs/src/app/storage_compat.rs b/rustfs/src/app/storage_compat.rs index bc165c63d..52befa42e 100644 --- a/rustfs/src/app/storage_compat.rs +++ b/rustfs/src/app/storage_compat.rs @@ -13,49 +13,49 @@ // limitations under the License. pub(crate) use rustfs_ecstore::api::admin::get_server_info; +pub(crate) use rustfs_ecstore::api::bucket::{ + bucket_target_sys, lifecycle, metadata, metadata_sys, object_lock, policy_sys, quota, replication, tagging, target, utils, + versioning, versioning_sys, +}; pub(crate) use rustfs_ecstore::api::capacity::{ PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free, }; +pub(crate) use rustfs_ecstore::api::client::object_api_utils; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::client::transition_api; +pub(crate) use rustfs_ecstore::api::compression::{MIN_DISK_COMPRESSIBLE_SIZE, is_disk_compressible}; +pub(crate) use rustfs_ecstore::api::config::storageclass; +pub(crate) use rustfs_ecstore::api::data_usage::{ + apply_bucket_usage_memory_overlay, load_data_usage_from_backend, record_bucket_object_delete_memory, + record_bucket_object_write_memory, +}; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::disk::endpoint::Endpoint; +pub(crate) use rustfs_ecstore::api::disk::error::DiskError; +pub(crate) use rustfs_ecstore::api::disk::error_reduce::is_all_buckets_not_found; +pub(crate) use rustfs_ecstore::api::error::{ + Error, StorageError, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, +}; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::global::GLOBAL_TierConfigMgr; +pub(crate) use rustfs_ecstore::api::global::{ + get_global_endpoints_opt, get_global_region, get_global_tier_config_mgr, new_object_layer_fn, set_object_store_resolver, +}; pub(crate) use rustfs_ecstore::api::layout::EndpointServerPools; #[cfg(test)] pub(crate) use rustfs_ecstore::api::layout::{Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::api::notification::get_global_notification_sys; +#[cfg(test)] +pub(crate) use rustfs_ecstore::api::rio::{DecryptReader, EncryptReader, HardLimitReader, boxed_reader}; +pub(crate) use rustfs_ecstore::api::rio::{ + DynReader, HashReader, WriteEncryption, WritePlan, compression_metadata_value, wrap_reader, +}; +pub(crate) use rustfs_ecstore::api::set_disk::{get_lock_acquire_timeout, is_valid_storage_class}; pub(crate) use rustfs_ecstore::api::storage::ECStore; #[cfg(test)] pub(crate) use rustfs_ecstore::api::storage::init_local_disks; -pub(crate) use rustfs_ecstore::bucket::{ - bucket_target_sys, lifecycle, metadata, metadata_sys, object_lock, policy_sys, quota, replication, tagging, target, utils, - versioning, versioning_sys, -}; -pub(crate) use rustfs_ecstore::client::object_api_utils; +pub(crate) use rustfs_ecstore::api::tier::tier::TierConfigMgr; #[cfg(test)] -pub(crate) use rustfs_ecstore::client::transition_api; -pub(crate) use rustfs_ecstore::compress::{MIN_DISK_COMPRESSIBLE_SIZE, is_disk_compressible}; -pub(crate) use rustfs_ecstore::config::storageclass; -pub(crate) use rustfs_ecstore::data_usage::{ - apply_bucket_usage_memory_overlay, load_data_usage_from_backend, record_bucket_object_delete_memory, - record_bucket_object_write_memory, -}; +pub(crate) use rustfs_ecstore::api::tier::tier_config::{TierConfig, TierType}; #[cfg(test)] -pub(crate) use rustfs_ecstore::disk::endpoint::Endpoint; -pub(crate) use rustfs_ecstore::disk::error::DiskError; -pub(crate) use rustfs_ecstore::disk::error_reduce::is_all_buckets_not_found; -pub(crate) use rustfs_ecstore::error::{ - Error, StorageError, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, -}; -#[cfg(test)] -pub(crate) use rustfs_ecstore::global::GLOBAL_TierConfigMgr; -pub(crate) use rustfs_ecstore::global::{ - get_global_endpoints_opt, get_global_region, get_global_tier_config_mgr, new_object_layer_fn, set_object_store_resolver, -}; -#[cfg(test)] -pub(crate) use rustfs_ecstore::rio::{DecryptReader, EncryptReader, HardLimitReader, boxed_reader}; -pub(crate) use rustfs_ecstore::rio::{ - DynReader, HashReader, WriteEncryption, WritePlan, compression_metadata_value, wrap_reader, -}; -pub(crate) use rustfs_ecstore::set_disk::{get_lock_acquire_timeout, is_valid_storage_class}; -pub(crate) use rustfs_ecstore::tier::tier::TierConfigMgr; -#[cfg(test)] -pub(crate) use rustfs_ecstore::tier::tier_config::{TierConfig, TierType}; -#[cfg(test)] -pub(crate) use rustfs_ecstore::tier::warm_backend::{WarmBackend, WarmBackendGetOpts}; +pub(crate) use rustfs_ecstore::api::tier::warm_backend::{WarmBackend, WarmBackendGetOpts}; diff --git a/rustfs/src/storage/storage_compat.rs b/rustfs/src/storage/storage_compat.rs index 3d9f0d759..416c0d741 100644 --- a/rustfs/src/storage/storage_compat.rs +++ b/rustfs/src/storage/storage_compat.rs @@ -13,31 +13,31 @@ // limitations under the License. pub(crate) use rustfs_ecstore::api::admin::get_local_server_property; -pub(crate) use rustfs_ecstore::api::metrics::{CollectMetricsOpts, MetricType, collect_local_metrics}; -pub(crate) use rustfs_ecstore::api::storage::{ECStore, all_local_disk_path, find_local_disk_by_ref}; -pub(crate) use rustfs_ecstore::bucket::{ +pub(crate) use rustfs_ecstore::api::bucket::{ metadata, metadata_sys, object_lock, policy_sys, replication, tagging, utils, versioning, versioning_sys, }; -pub(crate) use rustfs_ecstore::client::object_api_utils; +pub(crate) use rustfs_ecstore::api::client::object_api_utils; #[cfg(test)] -pub(crate) use rustfs_ecstore::config::com; -pub(crate) use rustfs_ecstore::disk::error::DiskError; -pub(crate) use rustfs_ecstore::disk::{ +pub(crate) use rustfs_ecstore::api::config::com; +pub(crate) use rustfs_ecstore::api::disk::error::DiskError; +pub(crate) use rustfs_ecstore::api::disk::{ DeleteOptions, DiskAPI, DiskInfoOptions, DiskStore, FileInfoVersions, ReadMultipleReq, ReadMultipleResp, ReadOptions, UpdateMetadataOpts, WalkDirOptions, }; -pub(crate) use rustfs_ecstore::error::{ +pub(crate) use rustfs_ecstore::api::error::{ Error, Result, StorageError, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, }; -pub(crate) use rustfs_ecstore::global::{ +pub(crate) use rustfs_ecstore::api::global::{ GLOBAL_TierConfigMgr, get_global_lock_client, get_global_region, resolve_object_store_handle, }; -pub(crate) use rustfs_ecstore::rio::WriteEncryption; -pub(crate) use rustfs_ecstore::rpc::{ +pub(crate) use rustfs_ecstore::api::metrics::{CollectMetricsOpts, MetricType, collect_local_metrics}; +pub(crate) use rustfs_ecstore::api::rio::WriteEncryption; +pub(crate) use rustfs_ecstore::api::rpc::{ LocalPeerS3Client, PEER_RESTSIGNAL, PEER_RESTSUB_SYS, PeerS3Client, SERVICE_SIGNAL_REFRESH_CONFIG, SERVICE_SIGNAL_RELOAD_DYNAMIC, verify_rpc_signature, }; -pub(crate) use rustfs_ecstore::set_disk::DEFAULT_READ_BUFFER_SIZE; +pub(crate) use rustfs_ecstore::api::set_disk::DEFAULT_READ_BUFFER_SIZE; +pub(crate) use rustfs_ecstore::api::storage::{ECStore, all_local_disk_path, find_local_disk_by_ref}; pub(crate) type GetObjectReader = ::GetObjectReader; pub(crate) type ObjectInfo = ::ObjectInfo; diff --git a/rustfs/src/storage_compat.rs b/rustfs/src/storage_compat.rs index 7e98410f8..2c7f6c6b2 100644 --- a/rustfs/src/storage_compat.rs +++ b/rustfs/src/storage_compat.rs @@ -12,28 +12,28 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub(crate) use rustfs_ecstore::api::bucket::metadata_sys::{get_global_bucket_metadata_sys, init_bucket_metadata_sys}; +pub(crate) use rustfs_ecstore::api::bucket::migration::{try_migrate_bucket_metadata, try_migrate_iam_config}; +pub(crate) use rustfs_ecstore::api::bucket::replication::{ + GLOBAL_REPLICATION_STATS, get_global_replication_pool, init_background_replication, +}; +pub(crate) use rustfs_ecstore::api::bucket::{metadata, metadata_sys, quota}; +pub(crate) use rustfs_ecstore::api::config::{com, init, init_global_config_sys, try_migrate_server_config}; +pub(crate) use rustfs_ecstore::api::disk::{DiskAPI, RUSTFS_META_BUCKET, endpoint::Endpoint}; +pub(crate) use rustfs_ecstore::api::error::{Error as EcstoreError, Result as EcstoreResult, StorageError}; +pub(crate) use rustfs_ecstore::api::event::{EventArgs as EcstoreEventArgs, register_event_dispatch_hook}; +pub(crate) use rustfs_ecstore::api::global::{ + get_global_endpoints_opt, get_global_lock_clients, get_global_region, is_dist_erasure, resolve_object_store_handle, + set_global_endpoints, set_global_region, set_global_rustfs_port, shutdown_background_services, update_erasure_type, +}; #[cfg(test)] pub(crate) use rustfs_ecstore::api::layout::DisksLayout; pub(crate) use rustfs_ecstore::api::layout::EndpointServerPools; #[cfg(test)] pub(crate) use rustfs_ecstore::api::layout::{Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::api::notification::new_global_notification_sys; +pub(crate) use rustfs_ecstore::api::rpc::{TONIC_RPC_PREFIX, verify_rpc_signature}; +pub(crate) use rustfs_ecstore::api::set_disk::get_lock_acquire_timeout; pub(crate) use rustfs_ecstore::api::storage::{ ECStore, all_local_disk, init_local_disks, init_lock_clients, prewarm_local_disk_id_map, }; -pub(crate) use rustfs_ecstore::bucket::metadata_sys::{get_global_bucket_metadata_sys, init_bucket_metadata_sys}; -pub(crate) use rustfs_ecstore::bucket::migration::{try_migrate_bucket_metadata, try_migrate_iam_config}; -pub(crate) use rustfs_ecstore::bucket::replication::{ - GLOBAL_REPLICATION_STATS, get_global_replication_pool, init_background_replication, -}; -pub(crate) use rustfs_ecstore::bucket::{metadata, metadata_sys, quota}; -pub(crate) use rustfs_ecstore::config::{com, init, init_global_config_sys, try_migrate_server_config}; -pub(crate) use rustfs_ecstore::disk::{DiskAPI, RUSTFS_META_BUCKET, endpoint::Endpoint}; -pub(crate) use rustfs_ecstore::error::{Error as EcstoreError, Result as EcstoreResult, StorageError}; -pub(crate) use rustfs_ecstore::event_notification::{EventArgs as EcstoreEventArgs, register_event_dispatch_hook}; -pub(crate) use rustfs_ecstore::global::{ - get_global_endpoints_opt, get_global_lock_clients, get_global_region, is_dist_erasure, resolve_object_store_handle, - set_global_endpoints, set_global_region, set_global_rustfs_port, shutdown_background_services, update_erasure_type, -}; -pub(crate) use rustfs_ecstore::rpc::{TONIC_RPC_PREFIX, verify_rpc_signature}; -pub(crate) use rustfs_ecstore::set_disk::get_lock_acquire_timeout; diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index bdf4d005b..25dc8dd1a 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -72,6 +72,7 @@ STORE_API_EXTERNAL_LIST_CONSUMER_HITS_FILE="${TMP_DIR}/store_api_external_list_c 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" +ECSTORE_API_FACADE_REQUIRED_HITS_FILE="${TMP_DIR}/ecstore_api_facade_required_hits.txt" ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_public_facade_bypass_hits.txt" TEST_HARNESS_NESTED_STORAGE_COMPAT_HITS_FILE="${TMP_DIR}/test_harness_nested_storage_compat_hits.txt" RUSTFS_NESTED_STORAGE_COMPAT_HITS_FILE="${TMP_DIR}/rustfs_nested_storage_compat_hits.txt" @@ -222,6 +223,41 @@ require_source_line \ "rustfs/src/lib.rs" \ "pub(crate) mod startup_iam;" \ "startup IAM shim crate-private module" +require_source_line \ + "crates/ecstore/src/lib.rs" \ + "mod disks_layout;" \ + "ECStore legacy disks-layout compatibility module crate-private visibility" +require_source_line \ + "crates/ecstore/src/lib.rs" \ + "mod endpoints;" \ + "ECStore legacy endpoint compatibility module crate-private visibility" +for ecstore_private_module in \ + admin_server_info \ + bucket \ + cache_value \ + client \ + compress \ + config \ + data_usage \ + disk \ + error \ + event_notification \ + global \ + metrics_realtime \ + notification_sys \ + pools \ + rebalance \ + rio \ + rpc \ + set_disk \ + store \ + store_utils \ + tier; do + require_source_line \ + "crates/ecstore/src/lib.rs" \ + "mod ${ecstore_private_module};" \ + "ECStore legacy ${ecstore_private_module} root module crate-private visibility" +done require_source_line \ "crates/storage-api/src/lib.rs" \ "pub use bucket::{BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, MakeBucketOptions, SRBucketDeleteOp};" \ @@ -606,11 +642,26 @@ fi ( cd "$ROOT_DIR" - rg -n --no-heading 'rustfs_ecstore::(?:admin_server_info|endpoints|disks_layout|metrics_realtime|notification_sys|pools|store_utils|store)::' \ + find rustfs/src crates fuzz/fuzz_targets -type f -name 'storage_compat.rs' \ + ! -path '*/crates/ecstore/*' -print0 | + xargs -0 perl -ne ' + if (/rustfs_ecstore::(?!api::)/) { + chomp; + print "$ARGV:$.:$_\n"; + } + ' || true +) >"$ECSTORE_API_FACADE_REQUIRED_HITS_FILE" + +if [[ -s "$ECSTORE_API_FACADE_REQUIRED_HITS_FILE" ]]; then + report_failure "outer storage compatibility boundaries must route ECStore imports through rustfs_ecstore::api: $(paste -sd '; ' "$ECSTORE_API_FACADE_REQUIRED_HITS_FILE")" +fi + +( + cd "$ROOT_DIR" + rg -n --no-heading 'rustfs_ecstore::(?:admin_server_info|bucket|cache_value|client|compress|config|data_usage|disk|disks_layout|endpoints|error|event_notification|global|metrics_realtime|notification_sys|pools|rebalance|rio|rpc|set_disk|store|store_utils|tier)::' \ rustfs/src crates/*/src crates/*/tests fuzz/fuzz_targets \ --glob '*storage_compat.rs' \ - --glob '!crates/ecstore/**' \ - --glob '!crates/e2e_test/**' || true + --glob '!crates/ecstore/**' || true ) >"$ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE" if [[ -s "$ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE" ]]; then