diff --git a/crates/ecstore/src/api/README.md b/crates/ecstore/src/api/README.md index 5e1452759..ddcef6b58 100644 --- a/crates/ecstore/src/api/README.md +++ b/crates/ecstore/src/api/README.md @@ -1,4 +1,4 @@ # ECStore API Layout -Reserved for facade and compatibility re-export ownership during the ECStore -internal layout migration. No runtime logic lives here yet. +Owns explicit facade and compatibility re-export paths during the ECStore +internal layout migration. No runtime logic lives here. diff --git a/crates/ecstore/src/api/mod.rs b/crates/ecstore/src/api/mod.rs new file mode 100644 index 000000000..a7aeac0fb --- /dev/null +++ b/crates/ecstore/src/api/mod.rs @@ -0,0 +1,49 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Explicit ECStore public facades for outer crate compatibility boundaries. + +pub mod admin { + pub use crate::admin_server_info::{get_local_server_property, get_server_info}; +} + +pub mod capacity { + pub use crate::pools::{ + PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free, path2_bucket_object, + path2_bucket_object_with_base_path, + }; + pub use crate::store_utils::is_reserved_or_invalid_bucket; +} + +pub mod layout { + pub use crate::disks_layout::DisksLayout; + pub use crate::endpoints::{EndpointServerPools, Endpoints, PoolEndpoints}; +} + +pub mod metrics { + pub use crate::metrics_realtime::{CollectMetricsOpts, MetricType, collect_local_metrics}; +} + +pub mod notification { + pub use crate::notification_sys::{ + NotificationPeerErr, NotificationSys, get_global_notification_sys, new_global_notification_sys, + }; +} + +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, + }; +} diff --git a/crates/ecstore/src/lib.rs b/crates/ecstore/src/lib.rs index 9b2195187..cc0134802 100644 --- a/crates/ecstore/src/lib.rs +++ b/crates/ecstore/src/lib.rs @@ -16,6 +16,7 @@ extern crate core; pub mod admin_server_info; +pub mod api; pub mod batch_processor; pub mod bitrot; pub mod bucket; diff --git a/crates/heal/src/heal/storage_compat.rs b/crates/heal/src/heal/storage_compat.rs index e3536010d..a7c225d6d 100644 --- a/crates/heal/src/heal/storage_compat.rs +++ b/crates/heal/src/heal/storage_compat.rs @@ -18,7 +18,7 @@ pub(crate) const RUSTFS_META_BUCKET: &str = rustfs_ecstore::disk::RUSTFS_META_BU pub(crate) type DiskError = rustfs_ecstore::disk::error::DiskError; pub(crate) type DiskStore = rustfs_ecstore::disk::DiskStore; -pub(crate) type ECStore = rustfs_ecstore::store::ECStore; +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; diff --git a/crates/heal/tests/common/storage_compat.rs b/crates/heal/tests/common/storage_compat.rs index b90629bd0..2f9a9a089 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::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}; -pub(crate) use rustfs_ecstore::endpoints::{EndpointServerPools, Endpoints, PoolEndpoints}; -pub(crate) use rustfs_ecstore::store::ECStore; -pub(crate) use rustfs_ecstore::store::init_local_disks; diff --git a/crates/iam/src/storage_compat.rs b/crates/iam/src/storage_compat.rs index 1f4f00f8d..97492d62c 100644 --- a/crates/iam/src/storage_compat.rs +++ b/crates/iam/src/storage_compat.rs @@ -19,7 +19,7 @@ pub(crate) const IAM_CONFIG_ROOT_PREFIX: &str = rustfs_ecstore::config::RUSTFS_C 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 IamStore = rustfs_ecstore::store::ECStore; +pub(crate) type IamStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type IamConfigObjectInfo = ::ObjectInfo; pub(crate) type IamConfigObjectOptions = ::ObjectOptions; @@ -64,14 +64,14 @@ pub(crate) struct IamNotificationPeerErr { pub(crate) err: Option, } -impl From for IamNotificationPeerErr { - fn from(value: rustfs_ecstore::notification_sys::NotificationPeerErr) -> Self { +impl From for IamNotificationPeerErr { + fn from(value: rustfs_ecstore::api::notification::NotificationPeerErr) -> Self { Self { err: value.err } } } pub(crate) async fn notify_iam_delete_policy(policy_name: &str) -> Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .delete_policy(policy_name) .await @@ -83,7 +83,7 @@ pub(crate) async fn notify_iam_delete_policy(policy_name: &str) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .load_policy(policy_name) .await @@ -95,7 +95,7 @@ pub(crate) async fn notify_iam_load_policy(policy_name: &str) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .delete_user(access_key) .await @@ -107,7 +107,7 @@ pub(crate) async fn notify_iam_delete_user(access_key: &str) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .load_user(access_key, temp) .await @@ -119,7 +119,7 @@ pub(crate) async fn notify_iam_load_user(access_key: &str, temp: bool) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .load_service_account(access_key) .await @@ -131,7 +131,7 @@ pub(crate) async fn notify_iam_load_service_account(access_key: &str) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .delete_service_account(access_key) .await @@ -143,7 +143,7 @@ pub(crate) async fn notify_iam_delete_service_account(access_key: &str) -> Vec Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys.load_group(group).await.into_iter().map(Into::into).collect(), None => Vec::new(), } @@ -154,7 +154,7 @@ pub(crate) async fn notify_iam_load_policy_mapping( user_type: u64, is_group: bool, ) -> Vec { - match rustfs_ecstore::notification_sys::get_global_notification_sys() { + match rustfs_ecstore::api::notification::get_global_notification_sys() { Some(notification_sys) => notification_sys .load_policy_mapping(user_or_group, user_type, is_group) .await diff --git a/crates/obs/src/storage_compat.rs b/crates/obs/src/storage_compat.rs index 3c2e60461..e5874edda 100644 --- a/crates/obs/src/storage_compat.rs +++ b/crates/obs/src/storage_compat.rs @@ -22,7 +22,7 @@ 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) type ObsStore = rustfs_ecstore::store::ECStore; +pub(crate) type ObsStore = rustfs_ecstore::api::storage::ECStore; type ObsStorageInfo = ::StorageInfo; #[derive(Debug, Clone, PartialEq)] @@ -50,11 +50,17 @@ pub(crate) fn resolve_obs_object_store_handle() -> Option> { } pub(crate) fn obs_total_usable_capacity_bytes(storage_info: &ObsStorageInfo) -> u64 { - usize_to_u64_saturating(rustfs_ecstore::pools::get_total_usable_capacity(&storage_info.disks, storage_info)) + usize_to_u64_saturating(rustfs_ecstore::api::capacity::get_total_usable_capacity( + &storage_info.disks, + storage_info, + )) } pub(crate) fn obs_total_usable_capacity_free_bytes(storage_info: &ObsStorageInfo) -> u64 { - usize_to_u64_saturating(rustfs_ecstore::pools::get_total_usable_capacity_free(&storage_info.disks, storage_info)) + usize_to_u64_saturating(rustfs_ecstore::api::capacity::get_total_usable_capacity_free( + &storage_info.disks, + storage_info, + )) } pub(crate) async fn obs_bucket_quota_limit_bytes(bucket: &str) -> u64 { diff --git a/crates/protocols/src/swift/storage_compat.rs b/crates/protocols/src/swift/storage_compat.rs index d71cb08da..d25f8625c 100644 --- a/crates/protocols/src/swift/storage_compat.rs +++ b/crates/protocols/src/swift/storage_compat.rs @@ -16,7 +16,7 @@ use std::sync::Arc; pub(super) type SwiftBucketMetadata = rustfs_ecstore::bucket::metadata::BucketMetadata; pub(super) type SwiftStorageResult = rustfs_ecstore::error::Result; -pub(super) type SwiftStore = rustfs_ecstore::store::ECStore; +pub(super) type SwiftStore = rustfs_ecstore::api::storage::ECStore; pub type SwiftGetObjectReader = ::GetObjectReader; pub type SwiftObjectInfo = ::ObjectInfo; pub type SwiftObjectOptions = ::ObjectOptions; diff --git a/crates/s3select-api/src/storage_compat.rs b/crates/s3select-api/src/storage_compat.rs index 7491c2196..386728e1a 100644 --- a/crates/s3select-api/src/storage_compat.rs +++ b/crates/s3select-api/src/storage_compat.rs @@ -13,7 +13,7 @@ // limitations under the License. pub(crate) type SelectStorageError = rustfs_ecstore::error::StorageError; -pub(crate) type SelectStore = rustfs_ecstore::store::ECStore; +pub(crate) type SelectStore = rustfs_ecstore::api::storage::ECStore; pub(crate) type SelectGetObjectReader = ::GetObjectReader; pub(crate) type SelectObjectInfo = ::ObjectInfo; pub(crate) type SelectObjectOptions = ::ObjectOptions; diff --git a/crates/scanner/src/storage_compat.rs b/crates/scanner/src/storage_compat.rs index 110816413..bcb75811f 100644 --- a/crates/scanner/src/storage_compat.rs +++ b/crates/scanner/src/storage_compat.rs @@ -24,7 +24,7 @@ pub(crate) const TRANSITION_COMPLETE: &str = rustfs_ecstore::bucket::lifecycle:: pub(crate) type Disk = rustfs_ecstore::disk::Disk; pub(crate) type DiskError = rustfs_ecstore::disk::error::DiskError; -pub(crate) type ECStore = rustfs_ecstore::store::ECStore; +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; @@ -69,15 +69,15 @@ pub(crate) fn resolve_scanner_object_store_handle() -> Option> { } pub(crate) fn is_reserved_or_invalid_bucket(bucket: &str, strict: bool) -> bool { - rustfs_ecstore::store_utils::is_reserved_or_invalid_bucket(bucket, strict) + rustfs_ecstore::api::capacity::is_reserved_or_invalid_bucket(bucket, strict) } pub(crate) fn path2_bucket_object(name: &str) -> (String, String) { - rustfs_ecstore::pools::path2_bucket_object(name) + rustfs_ecstore::api::capacity::path2_bucket_object(name) } pub(crate) fn path2_bucket_object_with_base_path(base_path: &str, path: &str) -> (String, String) { - rustfs_ecstore::pools::path2_bucket_object_with_base_path(base_path, path) + rustfs_ecstore::api::capacity::path2_bucket_object_with_base_path(base_path, path) } pub(crate) async fn is_erasure() -> bool { diff --git a/crates/scanner/tests/common/storage_compat.rs b/crates/scanner/tests/common/storage_compat.rs index b436db93b..f1415af4c 100644 --- a/crates/scanner/tests/common/storage_compat.rs +++ b/crates/scanner/tests/common/storage_compat.rs @@ -19,6 +19,10 @@ pub(crate) const STORAGE_FORMAT_FILE: &str = rustfs_ecstore::disk::STORAGE_FORMA pub(crate) type TransitionOptions = rustfs_ecstore::bucket::lifecycle::lifecycle::TransitionOptions; +pub(crate) use rustfs_ecstore::api::capacity::path2_bucket_object_with_base_path; +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, }; @@ -28,11 +32,7 @@ pub(crate) use rustfs_ecstore::bucket::metadata_sys::{ 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::endpoints::{EndpointServerPools, Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::global::GLOBAL_TierConfigMgr; -pub(crate) use rustfs_ecstore::pools::path2_bucket_object_with_base_path; -pub(crate) use rustfs_ecstore::store::ECStore; -pub(crate) use rustfs_ecstore::store::init_local_disks; 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}; diff --git a/docs/architecture/crate-boundaries.md b/docs/architecture/crate-boundaries.md index 79eb2e480..6f9d55294 100644 --- a/docs/architecture/crate-boundaries.md +++ b/docs/architecture/crate-boundaries.md @@ -126,6 +126,10 @@ directly for `ObjectIO`, `ObjectOperations`, `ListOperations`, the concrete compatibility traits only for internal implementation and 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. + ECStore internal consumers must use `rustfs-storage-api` lifecycle helper DTOs directly for `ExpirationOptions` and `TransitionedObject`; ECStore keeps the old lifecycle paths only as downstream compatibility re-exports. diff --git a/docs/architecture/migration-progress.md b/docs/architecture/migration-progress.md index f4774d2de..bb2a5c31d 100644 --- a/docs/architecture/migration-progress.md +++ b/docs/architecture/migration-progress.md @@ -389,6 +389,24 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block - Verification: focused heal/storage compile/tests, migration and layer guards, formatting, diff hygiene, full pre-commit, and three-expert review. +- [x] `API-072` Establish ECStore public facade for outer compatibility. + - Completed slice: add `rustfs_ecstore::api` facade groups for layout, + storage, admin, metrics, notification, and capacity helper surfaces, then + migrate RustFS, scanner, observability, IAM, heal, Swift, S3 Select, + heal-test, and scanner-test compatibility boundaries away from direct + ECStore module paths for those surfaces. + - Acceptance: selected outer `storage_compat.rs` boundaries no longer import + `rustfs_ecstore::{admin_server_info,endpoints,disks_layout,metrics_realtime,notification_sys,pools,store_utils,store}` + directly, and the migration guard rejects restoring those direct public + surface paths. + - Must preserve: endpoint and disks-layout types, ECStore owner type and + init helpers, admin server-info helpers, local metrics collection, + notification peer behavior, capacity helpers, bucket-name helpers, and all + runtime storage 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] `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 @@ -2889,14 +2907,27 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block | Expert | Status | Notes | |---|---|---| -| Quality/architecture | passed | R-056 through R-067 keep startup services as orchestration while moving KMS, IAM facade, bucket metadata, notification, auth, background, observability, audit, deadlock, and embedded optional ownership to focused startup modules, then narrowing internal owner and orchestration modules to crate visibility. | -| Migration preservation | passed | KMS singleton reuse/init behavior, embedded/main IAM wiring, bucket metadata migration/resync order, notification/auth/background/observability/audit/deadlock setup, readiness stages, public embedded API, startup compatibility paths, and log behavior stay unchanged. | -| Testing/verification | passed | Focused startup IAM/KMS/service/notification/audit checks, RustFS lib/bin check, architecture/layer/unsafe guards, formatting, diff hygiene, Rust risk scan, and pre-commit gate passed. | +| Quality/architecture | passed | API-072 adds an explicit ECStore facade for outer compatibility surfaces and routes storage, admin, scanner, observability, IAM, heal, Swift, S3 Select, and test compatibility imports through it. | +| Migration preservation | passed | ECStore owner types, endpoint layout types, capacity helpers, local metrics collection, notification peer behavior, and storage init helpers remain re-exported without runtime behavior changes. | +| Testing/verification | passed | ECStore and outer compatibility check suites, architecture/layer/unsafe guards, formatting, diff hygiene, Rust risk scan, and the full pre-commit gate passed. | ## Verification Notes Passed before push: +- Issue #660 API-072 current slice: + - `cargo check --tests -p rustfs-ecstore`: passed. + - `cargo check --tests -p rustfs -p rustfs-scanner -p rustfs-obs -p rustfs-iam -p rustfs-heal -p rustfs-protocols -p rustfs-s3select-api`: 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 R-056/R-067 current slice: - `cargo test -p rustfs --lib startup_kms -- --nocapture`: passed; 2 tests. diff --git a/rustfs/src/admin/storage_compat.rs b/rustfs/src/admin/storage_compat.rs index 0bc3bc037..a806b601c 100644 --- a/rustfs/src/admin/storage_compat.rs +++ b/rustfs/src/admin/storage_compat.rs @@ -12,6 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub(crate) use rustfs_ecstore::api::capacity::is_reserved_or_invalid_bucket; +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::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, @@ -23,22 +30,15 @@ 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::endpoints::EndpointServerPools; -#[cfg(test)] -pub(crate) use rustfs_ecstore::endpoints::{Endpoints, PoolEndpoints}; 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::metrics_realtime::{CollectMetricsOpts, MetricType, collect_local_metrics}; -pub(crate) use rustfs_ecstore::notification_sys::get_global_notification_sys; 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::store::ECStore; -pub(crate) use rustfs_ecstore::store_utils::is_reserved_or_invalid_bucket; 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}; diff --git a/rustfs/src/app/storage_compat.rs b/rustfs/src/app/storage_compat.rs index e052b78c7..bc165c63d 100644 --- a/rustfs/src/app/storage_compat.rs +++ b/rustfs/src/app/storage_compat.rs @@ -12,7 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) use rustfs_ecstore::admin_server_info::get_server_info; +pub(crate) use rustfs_ecstore::api::admin::get_server_info; +pub(crate) use rustfs_ecstore::api::capacity::{ + PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free, +}; +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; +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, @@ -30,9 +40,6 @@ pub(crate) use rustfs_ecstore::data_usage::{ 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::endpoints::EndpointServerPools; -#[cfg(test)] -pub(crate) use rustfs_ecstore::endpoints::{Endpoints, PoolEndpoints}; pub(crate) use rustfs_ecstore::error::{ Error, StorageError, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, }; @@ -41,19 +48,12 @@ 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, }; -pub(crate) use rustfs_ecstore::notification_sys::get_global_notification_sys; -pub(crate) use rustfs_ecstore::pools::{ - PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free, -}; #[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::store::ECStore; -#[cfg(test)] -pub(crate) use rustfs_ecstore::store::init_local_disks; pub(crate) use rustfs_ecstore::tier::tier::TierConfigMgr; #[cfg(test)] pub(crate) use rustfs_ecstore::tier::tier_config::{TierConfig, TierType}; diff --git a/rustfs/src/storage/storage_compat.rs b/rustfs/src/storage/storage_compat.rs index cf70e0b0b..3d9f0d759 100644 --- a/rustfs/src/storage/storage_compat.rs +++ b/rustfs/src/storage/storage_compat.rs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub(crate) use rustfs_ecstore::admin_server_info::get_local_server_property; +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::{ metadata, metadata_sys, object_lock, policy_sys, replication, tagging, utils, versioning, versioning_sys, }; @@ -30,14 +32,12 @@ pub(crate) use rustfs_ecstore::error::{ pub(crate) use rustfs_ecstore::global::{ GLOBAL_TierConfigMgr, get_global_lock_client, get_global_region, resolve_object_store_handle, }; -pub(crate) use rustfs_ecstore::metrics_realtime::{CollectMetricsOpts, MetricType, collect_local_metrics}; pub(crate) use rustfs_ecstore::rio::WriteEncryption; pub(crate) use rustfs_ecstore::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::store::{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 2e66cd037..7e98410f8 100644 --- a/rustfs/src/storage_compat.rs +++ b/rustfs/src/storage_compat.rs @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[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::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::{ @@ -20,18 +29,11 @@ pub(crate) use rustfs_ecstore::bucket::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}; -#[cfg(test)] -pub(crate) use rustfs_ecstore::disks_layout::DisksLayout; -pub(crate) use rustfs_ecstore::endpoints::EndpointServerPools; -#[cfg(test)] -pub(crate) use rustfs_ecstore::endpoints::{Endpoints, PoolEndpoints}; 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::notification_sys::new_global_notification_sys; pub(crate) use rustfs_ecstore::rpc::{TONIC_RPC_PREFIX, verify_rpc_signature}; pub(crate) use rustfs_ecstore::set_disk::get_lock_acquire_timeout; -pub(crate) use rustfs_ecstore::store::{ECStore, all_local_disk, init_local_disks, init_lock_clients, prewarm_local_disk_id_map}; diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index f7bbef114..11344df56 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -71,6 +71,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_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" RUSTFS_RUNTIME_SCALAR_STORAGE_COMPAT_HITS_FILE="${TMP_DIR}/rustfs_runtime_scalar_storage_compat_hits.txt" @@ -585,6 +586,19 @@ 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 'rustfs_ecstore::(?:admin_server_info|endpoints|disks_layout|metrics_realtime|notification_sys|pools|store_utils|store)::' \ + rustfs/src crates/*/src crates/*/tests fuzz/fuzz_targets \ + --glob '*storage_compat.rs' \ + --glob '!crates/ecstore/**' \ + --glob '!crates/e2e_test/**' || true +) >"$ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE" + +if [[ -s "$ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE" ]]; then + report_failure "outer storage compatibility boundaries must use rustfs_ecstore::api facade for ECStore public surfaces: $(paste -sd '; ' "$ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --no-heading '\bstorage_compat::ecstore\b|\bmod\s+ecstore\b' \