refactor: centralize storage compat facade paths (#3702)

This commit is contained in:
安正超
2026-06-22 01:20:22 +08:00
committed by GitHub
parent eb33e9f2ea
commit 2a18088ca5
4 changed files with 126 additions and 88 deletions
+3
View File
@@ -184,6 +184,9 @@ Outer compatibility function signatures must also use local aliases for ECStore
metadata, object-lock, lifecycle journal, monitor, and notification facade
types. The boundary may define the local alias, but call signatures must not
expose the raw ECStore facade path once narrowed.
The RustFS storage owner compatibility boundary must keep raw ECStore facade
paths centralized behind local `ecstore_*` module aliases rather than scattering
`rustfs_ecstore::api::...` references through its aliases and wrappers.
Scanner, notify, observability, and e2e `storage_compat.rs` boundaries must
also stay narrow. Scanner must not restore grouped bucket compatibility exports
for target, lifecycle, metadata, replication, or versioning modules. Notify
+34 -12
View File
@@ -5,17 +5,16 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-outer-compat-common-facade-prune`
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090`.
- Stacked on: `origin/main` after API-090 merged.
- Branch: `overtrue/arch-outer-compat-call-facade-prune`
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091`.
- Stacked on: `origin/main` after API-091 merged.
- PR type for this branch: `pure-move`
- Runtime behavior changes: none.
- Rust code changes: prune raw ECStore metadata/object-lock/lifecycle/monitor/
notification facade paths from outer app/admin/storage compatibility
signatures.
- CI/script changes: guard app/admin/storage compatibility signatures against
restoring raw ECStore facade paths for those narrowed types.
- Docs changes: record the API-091 outer compatibility signature alias cleanup.
- Rust code changes: centralize RustFS storage-owner raw ECStore facade paths
behind local `ecstore_*` module aliases.
- CI/script changes: guard the RustFS storage-owner compatibility boundary
against restoring scattered raw ECStore facade paths.
- Docs changes: record the API-092 storage-owner facade path cleanup.
## Phase 0 Tasks
@@ -307,6 +306,19 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
- Verification: RustFS compile coverage, signature residual scan, migration
guard, formatting, diff hygiene, Rust risk scan, pre-commit quality gate,
and three-expert review.
- [x] `API-092` Prune storage-owner raw facade paths.
- Completed slice: replace scattered raw `rustfs_ecstore::api::...` paths in
the RustFS storage-owner compatibility boundary with local `ecstore_*`
module aliases.
- Acceptance: `rustfs/src/storage/storage_compat.rs` no longer contains raw
`rustfs_ecstore::api::...` facade paths outside the centralized module alias
import.
- Must preserve: storage metadata, object-lock, replication stats, tagging,
RPC signature, metrics, tier reload, local disk lookup, and object I/O
associated type compatibility.
- Verification: RustFS compile coverage, storage-owner raw facade path
residual scan, migration guard, formatting, diff hygiene, Rust risk scan,
pre-commit quality gate, and three-expert review.
- [x] `G-012` Inventory placement and repair invariants.
- Acceptance:
[`placement-repair-invariants.md`](placement-repair-invariants.md) records
@@ -3340,14 +3352,24 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
| Expert | Status | Notes |
|---|---|---|
| Quality/architecture | passed | API-091 replaces raw ECStore facade paths in outer app/admin/storage compatibility signatures with local aliases. |
| Migration preservation | passed | Metadata-system, object-lock, lifecycle journal, bandwidth monitor, and notification-system access keep the same ECStore contracts through narrower local names. |
| Testing/verification | passed | RustFS compile coverage, signature residual scan, migration guard, formatting, diff hygiene, Rust risk scan, full pre-commit, and three-expert review passed. |
| Quality/architecture | passed | API-092 centralizes RustFS storage-owner ECStore facade paths behind local `ecstore_*` module aliases. |
| Migration preservation | passed | Storage metadata, object-lock, replication stats, tagging, RPC signature, metrics, tier reload, local disk lookup, and object I/O associated type compatibility keep the same ECStore contracts. |
| Testing/verification | passed | RustFS compile coverage, storage-owner raw facade path residual scan, migration guard, formatting, diff hygiene, Rust risk scan, full pre-commit, and three-expert review passed. |
## Verification Notes
Passed before push:
- Issue #660 API-092 current slice:
- `cargo check -p rustfs`: passed.
- `cargo fmt --all --check`: passed.
- `git diff --check`: passed.
- `bash -n scripts/check_architecture_migration_rules.sh`: passed.
- `./scripts/check_architecture_migration_rules.sh`: passed.
- RustFS storage-owner raw facade path residual scan: passed.
- Rust added-line risk scan on changed Rust files and guard script: passed.
- `make pre-commit`: passed.
- Issue #660 API-091 current slice:
- `cargo check -p rustfs`: passed.
- `cargo fmt --all --check`: passed.
+78 -76
View File
@@ -14,127 +14,133 @@
use std::sync::Arc;
pub(crate) const BUCKET_ACCELERATE_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_ACCELERATE_CONFIG;
pub(crate) const BUCKET_LOGGING_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_LOGGING_CONFIG;
pub(crate) const BUCKET_REQUEST_PAYMENT_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_REQUEST_PAYMENT_CONFIG;
pub(crate) const BUCKET_VERSIONING_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_VERSIONING_CONFIG;
pub(crate) const BUCKET_WEBSITE_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::BUCKET_WEBSITE_CONFIG;
pub(crate) const DEFAULT_READ_BUFFER_SIZE: usize = rustfs_ecstore::api::set_disk::DEFAULT_READ_BUFFER_SIZE;
pub(crate) const OBJECT_LOCK_CONFIG: &str = rustfs_ecstore::api::bucket::metadata::OBJECT_LOCK_CONFIG;
pub(crate) const PEER_RESTSIGNAL: &str = rustfs_ecstore::api::rpc::PEER_RESTSIGNAL;
pub(crate) const PEER_RESTSUB_SYS: &str = rustfs_ecstore::api::rpc::PEER_RESTSUB_SYS;
pub(crate) const SERVICE_SIGNAL_REFRESH_CONFIG: u64 = rustfs_ecstore::api::rpc::SERVICE_SIGNAL_REFRESH_CONFIG;
pub(crate) const SERVICE_SIGNAL_RELOAD_DYNAMIC: u64 = rustfs_ecstore::api::rpc::SERVICE_SIGNAL_RELOAD_DYNAMIC;
#[cfg(test)]
pub(crate) const STORAGE_CLASS_SUB_SYS: &str = rustfs_ecstore::api::config::com::STORAGE_CLASS_SUB_SYS;
use rustfs_ecstore::api::config as ecstore_config;
use rustfs_ecstore::api::{
admin as ecstore_admin, bucket as ecstore_bucket, client as ecstore_client, disk as ecstore_disk, error as ecstore_error,
global as ecstore_global, metrics as ecstore_metrics, rio as ecstore_rio, rpc as ecstore_rpc, set_disk as ecstore_set_disk,
storage as ecstore_storage,
};
pub(crate) type BucketMetadata = rustfs_ecstore::api::bucket::metadata::BucketMetadata;
pub(crate) const BUCKET_ACCELERATE_CONFIG: &str = ecstore_bucket::metadata::BUCKET_ACCELERATE_CONFIG;
pub(crate) const BUCKET_LOGGING_CONFIG: &str = ecstore_bucket::metadata::BUCKET_LOGGING_CONFIG;
pub(crate) const BUCKET_REQUEST_PAYMENT_CONFIG: &str = ecstore_bucket::metadata::BUCKET_REQUEST_PAYMENT_CONFIG;
pub(crate) const BUCKET_VERSIONING_CONFIG: &str = ecstore_bucket::metadata::BUCKET_VERSIONING_CONFIG;
pub(crate) const BUCKET_WEBSITE_CONFIG: &str = ecstore_bucket::metadata::BUCKET_WEBSITE_CONFIG;
pub(crate) const DEFAULT_READ_BUFFER_SIZE: usize = ecstore_set_disk::DEFAULT_READ_BUFFER_SIZE;
pub(crate) const OBJECT_LOCK_CONFIG: &str = ecstore_bucket::metadata::OBJECT_LOCK_CONFIG;
pub(crate) const PEER_RESTSIGNAL: &str = ecstore_rpc::PEER_RESTSIGNAL;
pub(crate) const PEER_RESTSUB_SYS: &str = ecstore_rpc::PEER_RESTSUB_SYS;
pub(crate) const SERVICE_SIGNAL_REFRESH_CONFIG: u64 = ecstore_rpc::SERVICE_SIGNAL_REFRESH_CONFIG;
pub(crate) const SERVICE_SIGNAL_RELOAD_DYNAMIC: u64 = ecstore_rpc::SERVICE_SIGNAL_RELOAD_DYNAMIC;
#[cfg(test)]
pub(crate) type BucketMetadataSys = rustfs_ecstore::api::bucket::metadata_sys::BucketMetadataSys;
pub(crate) type BucketVersioningSys = rustfs_ecstore::api::bucket::versioning_sys::BucketVersioningSys;
pub(crate) type CollectMetricsOpts = rustfs_ecstore::api::metrics::CollectMetricsOpts;
pub(crate) type DeleteOptions = rustfs_ecstore::api::disk::DeleteOptions;
pub(crate) type DiskError = rustfs_ecstore::api::disk::error::DiskError;
pub(crate) type DiskInfoOptions = rustfs_ecstore::api::disk::DiskInfoOptions;
pub(crate) type DiskStore = rustfs_ecstore::api::disk::DiskStore;
pub(crate) type ECStore = rustfs_ecstore::api::storage::ECStore;
pub(crate) type FileInfoVersions = rustfs_ecstore::api::disk::FileInfoVersions;
pub(crate) type LocalPeerS3Client = rustfs_ecstore::api::rpc::LocalPeerS3Client;
pub(crate) type MetricType = rustfs_ecstore::api::metrics::MetricType;
pub(crate) type ObjectLockBlockReason = rustfs_ecstore::api::bucket::object_lock::objectlock_sys::ObjectLockBlockReason;
pub(crate) type PolicySys = rustfs_ecstore::api::bucket::policy_sys::PolicySys;
pub(crate) type ReadMultipleReq = rustfs_ecstore::api::disk::ReadMultipleReq;
pub(crate) type ReadMultipleResp = rustfs_ecstore::api::disk::ReadMultipleResp;
pub(crate) type ReadOptions = rustfs_ecstore::api::disk::ReadOptions;
pub(crate) type StorageError = rustfs_ecstore::api::error::StorageError;
pub(crate) const STORAGE_CLASS_SUB_SYS: &str = ecstore_config::com::STORAGE_CLASS_SUB_SYS;
pub(crate) type BucketMetadata = ecstore_bucket::metadata::BucketMetadata;
#[cfg(test)]
pub(crate) type BucketMetadataSys = ecstore_bucket::metadata_sys::BucketMetadataSys;
pub(crate) type BucketVersioningSys = ecstore_bucket::versioning_sys::BucketVersioningSys;
pub(crate) type CollectMetricsOpts = ecstore_metrics::CollectMetricsOpts;
pub(crate) type DeleteOptions = ecstore_disk::DeleteOptions;
pub(crate) type DiskError = ecstore_disk::error::DiskError;
pub(crate) type DiskInfoOptions = ecstore_disk::DiskInfoOptions;
pub(crate) type DiskStore = ecstore_disk::DiskStore;
pub(crate) type ECStore = ecstore_storage::ECStore;
pub(crate) type FileInfoVersions = ecstore_disk::FileInfoVersions;
pub(crate) type LocalPeerS3Client = ecstore_rpc::LocalPeerS3Client;
pub(crate) type MetricType = ecstore_metrics::MetricType;
pub(crate) type ObjectLockBlockReason = ecstore_bucket::object_lock::objectlock_sys::ObjectLockBlockReason;
pub(crate) type PolicySys = ecstore_bucket::policy_sys::PolicySys;
pub(crate) type ReadMultipleReq = ecstore_disk::ReadMultipleReq;
pub(crate) type ReadMultipleResp = ecstore_disk::ReadMultipleResp;
pub(crate) type ReadOptions = ecstore_disk::ReadOptions;
pub(crate) type StorageError = ecstore_error::StorageError;
pub(crate) type Error = StorageError;
pub(crate) type Result<T> = core::result::Result<T, Error>;
pub(crate) type UpdateMetadataOpts = rustfs_ecstore::api::disk::UpdateMetadataOpts;
pub(crate) type WalkDirOptions = rustfs_ecstore::api::disk::WalkDirOptions;
pub(crate) type WriteEncryption = rustfs_ecstore::api::rio::WriteEncryption;
pub(crate) type UpdateMetadataOpts = ecstore_disk::UpdateMetadataOpts;
pub(crate) type WalkDirOptions = ecstore_disk::WalkDirOptions;
pub(crate) type WriteEncryption = ecstore_rio::WriteEncryption;
pub(crate) async fn get_local_server_property() -> rustfs_madmin::ServerProperties {
rustfs_ecstore::api::admin::get_local_server_property().await
ecstore_admin::get_local_server_property().await
}
pub(crate) async fn load_bucket_metadata(api: Arc<ECStore>, bucket: &str) -> Result<BucketMetadata> {
rustfs_ecstore::api::bucket::metadata::load_bucket_metadata(api, bucket).await
ecstore_bucket::metadata::load_bucket_metadata(api, bucket).await
}
#[cfg(test)]
pub(crate) fn bucket_metadata_sys_initialized() -> bool {
rustfs_ecstore::api::bucket::metadata_sys::GLOBAL_BucketMetadataSys
.get()
.is_some()
ecstore_bucket::metadata_sys::GLOBAL_BucketMetadataSys.get().is_some()
}
#[cfg(test)]
pub(crate) fn get_global_bucket_metadata_sys() -> Option<Arc<tokio::sync::RwLock<BucketMetadataSys>>> {
rustfs_ecstore::api::bucket::metadata_sys::get_global_bucket_metadata_sys()
ecstore_bucket::metadata_sys::get_global_bucket_metadata_sys()
}
pub(crate) async fn delete_bucket_metadata_config(bucket: &str, config_file: &str) -> Result<time::OffsetDateTime> {
rustfs_ecstore::api::bucket::metadata_sys::delete(bucket, config_file).await
ecstore_bucket::metadata_sys::delete(bucket, config_file).await
}
pub(crate) async fn get_bucket_metadata(bucket: &str) -> Result<Arc<BucketMetadata>> {
rustfs_ecstore::api::bucket::metadata_sys::get(bucket).await
ecstore_bucket::metadata_sys::get(bucket).await
}
pub(crate) async fn get_bucket_accelerate_config(
bucket: &str,
) -> Result<(s3s::dto::AccelerateConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_accelerate_config(bucket).await
ecstore_bucket::metadata_sys::get_accelerate_config(bucket).await
}
pub(crate) async fn get_bucket_policy_raw(bucket: &str) -> Result<(String, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_bucket_policy_raw(bucket).await
ecstore_bucket::metadata_sys::get_bucket_policy_raw(bucket).await
}
pub(crate) async fn get_bucket_cors_config(bucket: &str) -> Result<(s3s::dto::CORSConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_cors_config(bucket).await
ecstore_bucket::metadata_sys::get_cors_config(bucket).await
}
pub(crate) async fn get_bucket_logging_config(bucket: &str) -> Result<(s3s::dto::BucketLoggingStatus, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_logging_config(bucket).await
ecstore_bucket::metadata_sys::get_logging_config(bucket).await
}
pub(crate) async fn get_bucket_object_lock_config(
bucket: &str,
) -> Result<(s3s::dto::ObjectLockConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_object_lock_config(bucket).await
ecstore_bucket::metadata_sys::get_object_lock_config(bucket).await
}
pub(crate) async fn get_public_access_block_config(
bucket: &str,
) -> Result<(s3s::dto::PublicAccessBlockConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_public_access_block_config(bucket).await
ecstore_bucket::metadata_sys::get_public_access_block_config(bucket).await
}
pub(crate) async fn get_bucket_replication_config(
bucket: &str,
) -> Result<(s3s::dto::ReplicationConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_replication_config(bucket).await
ecstore_bucket::metadata_sys::get_replication_config(bucket).await
}
pub(crate) async fn get_bucket_request_payment_config(
bucket: &str,
) -> Result<(s3s::dto::RequestPaymentConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_request_payment_config(bucket).await
ecstore_bucket::metadata_sys::get_request_payment_config(bucket).await
}
pub(crate) async fn get_bucket_sse_config(
bucket: &str,
) -> Result<(s3s::dto::ServerSideEncryptionConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_sse_config(bucket).await
ecstore_bucket::metadata_sys::get_sse_config(bucket).await
}
pub(crate) async fn get_bucket_website_config(bucket: &str) -> Result<(s3s::dto::WebsiteConfiguration, time::OffsetDateTime)> {
rustfs_ecstore::api::bucket::metadata_sys::get_website_config(bucket).await
ecstore_bucket::metadata_sys::get_website_config(bucket).await
}
pub(crate) async fn set_bucket_metadata(bucket: String, bm: BucketMetadata) -> Result<()> {
rustfs_ecstore::api::bucket::metadata_sys::set_bucket_metadata(bucket, bm).await
ecstore_bucket::metadata_sys::set_bucket_metadata(bucket, bm).await
}
pub(crate) async fn update_bucket_metadata_config(
@@ -142,11 +148,11 @@ pub(crate) async fn update_bucket_metadata_config(
config_file: &str,
data: Vec<u8>,
) -> Result<time::OffsetDateTime> {
rustfs_ecstore::api::bucket::metadata_sys::update(bucket, config_file, data).await
ecstore_bucket::metadata_sys::update(bucket, config_file, data).await
}
pub(crate) fn add_object_lock_years(dt: time::OffsetDateTime, years: i32) -> time::OffsetDateTime {
rustfs_ecstore::api::bucket::object_lock::objectlock_sys::add_years(dt, years)
ecstore_bucket::object_lock::objectlock_sys::add_years(dt, years)
}
pub(crate) fn check_retention_for_modification(
@@ -155,7 +161,7 @@ pub(crate) fn check_retention_for_modification(
new_retain_until: Option<time::OffsetDateTime>,
bypass_governance: bool,
) -> Option<ObjectLockBlockReason> {
rustfs_ecstore::api::bucket::object_lock::objectlock_sys::check_retention_for_modification(
ecstore_bucket::object_lock::objectlock_sys::check_retention_for_modification(
user_defined,
new_mode,
new_retain_until,
@@ -164,80 +170,76 @@ pub(crate) fn check_retention_for_modification(
}
pub(crate) async fn record_replication_proxy(bucket: &str, api: &str, is_err: bool) {
if let Some(stats) = rustfs_ecstore::api::bucket::replication::GLOBAL_REPLICATION_STATS.get() {
if let Some(stats) = ecstore_bucket::replication::GLOBAL_REPLICATION_STATS.get() {
stats.inc_proxy(bucket, api, is_err).await;
}
}
pub(crate) fn decode_tags(tags: &str) -> Vec<s3s::dto::Tag> {
rustfs_ecstore::api::bucket::tagging::decode_tags(tags)
ecstore_bucket::tagging::decode_tags(tags)
}
pub(crate) fn decode_tags_to_map(tags: &str) -> std::collections::HashMap<String, String> {
rustfs_ecstore::api::bucket::tagging::decode_tags_to_map(tags)
ecstore_bucket::tagging::decode_tags_to_map(tags)
}
pub(crate) fn encode_tags(tags: Vec<s3s::dto::Tag>) -> String {
rustfs_ecstore::api::bucket::tagging::encode_tags(tags)
ecstore_bucket::tagging::encode_tags(tags)
}
pub(crate) fn serialize<T: s3s::xml::Serialize>(val: &T) -> s3s::xml::SerResult<Vec<u8>> {
rustfs_ecstore::api::bucket::utils::serialize(val)
ecstore_bucket::utils::serialize(val)
}
pub(crate) fn to_s3s_etag(etag: &str) -> s3s::dto::ETag {
rustfs_ecstore::api::client::object_api_utils::to_s3s_etag(etag)
ecstore_client::object_api_utils::to_s3s_etag(etag)
}
pub(crate) fn is_err_bucket_not_found(err: &Error) -> bool {
rustfs_ecstore::api::error::is_err_bucket_not_found(err)
ecstore_error::is_err_bucket_not_found(err)
}
pub(crate) fn is_err_object_not_found(err: &Error) -> bool {
rustfs_ecstore::api::error::is_err_object_not_found(err)
ecstore_error::is_err_object_not_found(err)
}
pub(crate) fn is_err_version_not_found(err: &Error) -> bool {
rustfs_ecstore::api::error::is_err_version_not_found(err)
ecstore_error::is_err_version_not_found(err)
}
pub(crate) fn get_global_lock_client() -> Option<Arc<dyn rustfs_lock::client::LockClient>> {
rustfs_ecstore::api::global::get_global_lock_client()
ecstore_global::get_global_lock_client()
}
pub(crate) fn get_global_region() -> Option<s3s::region::Region> {
rustfs_ecstore::api::global::get_global_region()
ecstore_global::get_global_region()
}
pub(crate) fn resolve_object_store_handle() -> Option<Arc<ECStore>> {
rustfs_ecstore::api::global::resolve_object_store_handle()
ecstore_global::resolve_object_store_handle()
}
pub(crate) async fn collect_local_metrics(
types: MetricType,
opts: &CollectMetricsOpts,
) -> rustfs_madmin::metrics::RealtimeMetrics {
rustfs_ecstore::api::metrics::collect_local_metrics(types, opts).await
ecstore_metrics::collect_local_metrics(types, opts).await
}
pub(crate) fn verify_rpc_signature(url: &str, method: &http::Method, headers: &http::HeaderMap) -> std::io::Result<()> {
rustfs_ecstore::api::rpc::verify_rpc_signature(url, method, headers)
ecstore_rpc::verify_rpc_signature(url, method, headers)
}
pub(crate) async fn reload_transition_tier_config(api: Arc<ECStore>) -> std::io::Result<()> {
rustfs_ecstore::api::global::GLOBAL_TierConfigMgr
.write()
.await
.reload(api)
.await
ecstore_global::GLOBAL_TierConfigMgr.write().await.reload(api).await
}
pub(crate) async fn all_local_disk_path() -> Vec<String> {
rustfs_ecstore::api::storage::all_local_disk_path().await
ecstore_storage::all_local_disk_path().await
}
pub(crate) async fn find_local_disk_by_ref(disk_ref: &str) -> Option<DiskStore> {
rustfs_ecstore::api::storage::find_local_disk_by_ref(disk_ref).await
ecstore_storage::find_local_disk_by_ref(disk_ref).await
}
pub(crate) type GetObjectReader = <ECStore as rustfs_storage_api::ObjectIO>::GetObjectReader;
@@ -88,6 +88,7 @@ RUSTFS_ADMIN_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/rustfs_admin_buc
RUSTFS_APP_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/rustfs_app_bucket_storage_compat_module_hits.txt"
RUSTFS_OUTER_COMPAT_FACADE_ALIAS_HITS_FILE="${TMP_DIR}/rustfs_outer_compat_facade_alias_hits.txt"
RUSTFS_OUTER_COMPAT_SIGNATURE_ALIAS_HITS_FILE="${TMP_DIR}/rustfs_outer_compat_signature_alias_hits.txt"
RUSTFS_STORAGE_COMPAT_RAW_FACADE_PATH_HITS_FILE="${TMP_DIR}/rustfs_storage_compat_raw_facade_path_hits.txt"
SCANNER_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/scanner_bucket_storage_compat_module_hits.txt"
NOTIFY_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/notify_storage_compat_module_hits.txt"
OBS_STORAGE_COMPAT_PASSTHROUGH_HITS_FILE="${TMP_DIR}/obs_storage_compat_passthrough_hits.txt"
@@ -905,6 +906,16 @@ if [[ -s "$RUSTFS_OUTER_COMPAT_SIGNATURE_ALIAS_HITS_FILE" ]]; then
report_failure "RustFS outer storage compatibility signatures must use local aliases for metadata, object-lock, lifecycle, monitor, and notification facade types: $(paste -sd '; ' "$RUSTFS_OUTER_COMPAT_SIGNATURE_ALIAS_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --no-heading 'rustfs_ecstore::api::' rustfs/src/storage/storage_compat.rs \
| rg -v '^[0-9]+:use rustfs_ecstore::api::\{|^[0-9]+:use rustfs_ecstore::api::config as ecstore_config;' || true
) >"$RUSTFS_STORAGE_COMPAT_RAW_FACADE_PATH_HITS_FILE"
if [[ -s "$RUSTFS_STORAGE_COMPAT_RAW_FACADE_PATH_HITS_FILE" ]]; then
report_failure "RustFS storage owner compatibility must use local ecstore_* module aliases instead of scattered raw ECStore facade paths: $(paste -sd '; ' "$RUSTFS_STORAGE_COMPAT_RAW_FACADE_PATH_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --no-heading 'pub\(crate\)\s+use rustfs_ecstore::api::bucket::\{[^}]*\b(?:bucket_target_sys|lifecycle|metadata_sys|replication|versioning|versioning_sys)\b[^}]*\}\s*;' \