refactor: wrap bucket compat trait methods (#3706)

This commit is contained in:
安正超
2026-06-22 04:32:37 +08:00
committed by GitHub
parent b8a0fc4e04
commit 7eb9a4759e
16 changed files with 206 additions and 46 deletions
+2 -4
View File
@@ -39,8 +39,6 @@ use rustfs_config::{
ENV_SCANNER_CYCLE_MAX_OBJECTS, ENV_SCANNER_CYCLE_MAX_OBJECTS,
}; };
use rustfs_config::{ENV_SCANNER_CYCLE, ENV_SCANNER_SPEED, ENV_SCANNER_START_DELAY_SECS}; use rustfs_config::{ENV_SCANNER_CYCLE, ENV_SCANNER_SPEED, ENV_SCANNER_START_DELAY_SECS};
use rustfs_ecstore::api::bucket::lifecycle::lifecycle::Lifecycle as _;
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_storage_api::{BucketOperations, BucketOptions, NamespaceLocking as _}; use rustfs_storage_api::{BucketOperations, BucketOptions, NamespaceLocking as _};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::mpsc; use tokio::sync::mpsc;
@@ -49,8 +47,8 @@ use tokio_util::sync::CancellationToken;
use tracing::{debug, error, info, instrument, warn}; use tracing::{debug, error, info, instrument, warn};
use crate::storage_compat::{ use crate::storage_compat::{
ECStore, EcstoreError, RUSTFS_META_BUCKET, get_lifecycle_config, get_replication_config, is_erasure_sd, read_config, ECStore, EcstoreError, RUSTFS_META_BUCKET, ScannerLifecycleConfigExt as _, ScannerReplicationConfigExt as _,
replace_bucket_usage_memory_from_info, save_config, get_lifecycle_config, get_replication_config, is_erasure_sd, read_config, replace_bucket_usage_memory_from_info, save_config,
}; };
const LOG_COMPONENT_SCANNER: &str = "scanner"; const LOG_COMPONENT_SCANNER: &str = "scanner";
+4 -6
View File
@@ -39,9 +39,6 @@ use rustfs_common::metrics::{
IlmAction, Metric, Metrics, ScannerReplicationRepairKind, ScannerSourceWorkUpdate, ScannerWorkSource, UpdateCurrentPathFn, IlmAction, Metric, Metrics, ScannerReplicationRepairKind, ScannerSourceWorkUpdate, ScannerWorkSource, UpdateCurrentPathFn,
current_path_updater, global_metrics, current_path_updater, global_metrics,
}; };
use rustfs_ecstore::api::bucket::lifecycle::lifecycle::Lifecycle as _;
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_ecstore::api::disk::DiskAPI as _; use rustfs_ecstore::api::disk::DiskAPI as _;
use rustfs_filemeta::{ use rustfs_filemeta::{
MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams, ReplicateObjectInfo, ReplicationStatusType, ReplicationType, MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams, ReplicateObjectInfo, ReplicationStatusType, ReplicationType,
@@ -56,9 +53,10 @@ use tracing::{debug, error, warn};
use crate::storage_compat::{ use crate::storage_compat::{
BucketVersioningSys, Disk, DiskError, DiskInfoOptions, Evaluator, Event, LcEventSrc, ListPathRawOptions, ObjectOpts, BucketVersioningSys, Disk, DiskError, DiskInfoOptions, Evaluator, Event, LcEventSrc, ListPathRawOptions, ObjectOpts,
ReplicationConfig, ReplicationQueueAdmission, StorageError, apply_expiry_rule, apply_transition_rule, ReplicationConfig, ReplicationQueueAdmission, ScannerLifecycleConfigExt as _, ScannerReplicationConfigExt as _,
enqueue_global_newer_noncurrent, is_erasure, is_reserved_or_invalid_bucket, list_path_raw, path2_bucket_object, ScannerVersioningConfigExt as _, StorageError, apply_expiry_rule, apply_transition_rule, enqueue_global_newer_noncurrent,
path2_bucket_object_with_base_path, queue_replication_heal_internal, is_erasure, is_reserved_or_invalid_bucket, list_path_raw, path2_bucket_object, path2_bucket_object_with_base_path,
queue_replication_heal_internal,
}; };
use crate::{ScannerObjectInfo as ObjectInfo, ScannerObjectToDelete as ObjectToDelete}; use crate::{ScannerObjectInfo as ObjectInfo, ScannerObjectToDelete as ObjectToDelete};
+2 -4
View File
@@ -26,9 +26,6 @@ use rustfs_common::heal_channel::HealScanMode;
use rustfs_common::metrics::{Metric, Metrics, emit_scan_bucket_drive_complete, emit_scan_bucket_drive_partial, global_metrics}; use rustfs_common::metrics::{Metric, Metrics, emit_scan_bucket_drive_complete, emit_scan_bucket_drive_partial, global_metrics};
#[cfg(test)] #[cfg(test)]
use rustfs_config::{ENV_SCANNER_MAX_CONCURRENT_DISK_SCANS, ENV_SCANNER_MAX_CONCURRENT_SET_SCANS}; use rustfs_config::{ENV_SCANNER_MAX_CONCURRENT_DISK_SCANS, ENV_SCANNER_MAX_CONCURRENT_SET_SCANS};
use rustfs_ecstore::api::bucket::lifecycle::lifecycle::Lifecycle as _;
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_ecstore::api::disk::DiskAPI as _; use rustfs_ecstore::api::disk::DiskAPI as _;
use rustfs_filemeta::FileMeta; use rustfs_filemeta::FileMeta;
use rustfs_storage_api::{BucketInfo, BucketOperations, BucketOptions, DiskSetSelector, StorageAdminApi}; use rustfs_storage_api::{BucketInfo, BucketOperations, BucketOptions, DiskSetSelector, StorageAdminApi};
@@ -49,7 +46,8 @@ use tracing::{debug, error, warn};
use crate::ScannerObjectInfo as ObjectInfo; use crate::ScannerObjectInfo as ObjectInfo;
use crate::storage_compat::{ use crate::storage_compat::{
BucketTargetSys, BucketVersioningSys, Disk, DiskError, ECStore, EcstoreError as Error, EcstoreResult as Result, BucketTargetSys, BucketVersioningSys, Disk, DiskError, ECStore, EcstoreError as Error, EcstoreResult as Result,
ReplicationConfig, STORAGE_FORMAT_FILE, SetDisks, StorageError, enqueue_global_free_version, get_lifecycle_config, ReplicationConfig, STORAGE_FORMAT_FILE, ScannerLifecycleConfigExt as _, ScannerReplicationConfigExt as _,
ScannerVersioningConfigExt as _, SetDisks, StorageError, enqueue_global_free_version, get_lifecycle_config,
get_object_lock_config, get_replication_config, list_global_tiers, resolve_scanner_object_store_handle, storageclass, get_object_lock_config, get_replication_config, list_global_tiers, resolve_scanner_object_store_handle, storageclass,
}; };
+39
View File
@@ -94,6 +94,45 @@ pub(crate) async fn get_replication_config(
ecstore_bucket::metadata_sys::get_replication_config(bucket).await ecstore_bucket::metadata_sys::get_replication_config(bucket).await
} }
pub(crate) trait ScannerLifecycleConfigExt {
fn has_active_rules(&self, prefix: &str) -> bool;
}
impl ScannerLifecycleConfigExt for s3s::dto::BucketLifecycleConfiguration {
fn has_active_rules(&self, prefix: &str) -> bool {
<s3s::dto::BucketLifecycleConfiguration as ecstore_bucket::lifecycle::lifecycle::Lifecycle>::has_active_rules(
self, prefix,
)
}
}
pub(crate) trait ScannerReplicationConfigExt {
fn has_active_rules(&self, prefix: &str, recursive: bool) -> bool;
}
impl ScannerReplicationConfigExt for s3s::dto::ReplicationConfiguration {
fn has_active_rules(&self, prefix: &str, recursive: bool) -> bool {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::has_active_rules(
self, prefix, recursive,
)
}
}
pub(crate) trait ScannerVersioningConfigExt {
fn prefix_enabled(&self, prefix: &str) -> bool;
fn versioned(&self, prefix: &str) -> bool;
}
impl ScannerVersioningConfigExt for s3s::dto::VersioningConfiguration {
fn prefix_enabled(&self, prefix: &str) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::prefix_enabled(self, prefix)
}
fn versioned(&self, prefix: &str) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::versioned(self, prefix)
}
}
pub(crate) async fn apply_transition_rule(event: &Event, src: &LcEventSrc, oi: &ScannerObjectInfo) -> bool { pub(crate) async fn apply_transition_rule(event: &Event, src: &LcEventSrc, oi: &ScannerObjectInfo) -> bool {
ecstore_bucket::lifecycle::bucket_lifecycle_ops::apply_transition_rule(event, src, oi).await ecstore_bucket::lifecycle::bucket_lifecycle_ops::apply_transition_rule(event, src, oi).await
} }
+6
View File
@@ -197,6 +197,12 @@ behind local `ecstore_*` module aliases.
RustFS root runtime and e2e storage compatibility boundaries must follow the RustFS root runtime and e2e storage compatibility boundaries must follow the
same pattern, keeping raw ECStore facade access centralized behind local same pattern, keeping raw ECStore facade access centralized behind local
`ecstore_*` module aliases. `ecstore_*` module aliases.
Outer bucket lifecycle, replication, versioning, object-lock, and
restore-request trait method access must stay behind local compatibility traits
or wrapper functions. Non-compat sources must not import those ECStore bucket
API traits directly after the wrapper boundary is established. Remaining
temporary direct ECStore method-resolution imports are limited to disk, RPC peer
client, and warm-backend traits until their hot-path wrappers are isolated.
Scanner, notify, observability, and e2e `storage_compat.rs` boundaries must Scanner, notify, observability, and e2e `storage_compat.rs` boundaries must
also stay narrow. Scanner must not restore grouped bucket compatibility exports also stay narrow. Scanner must not restore grouped bucket compatibility exports
for target, lifecycle, metadata, replication, or versioning modules. Notify for target, lifecycle, metadata, replication, or versioning modules. Notify
+39 -12
View File
@@ -5,17 +5,17 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
## Current Context ## Current Context
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660) - Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
- Branch: `overtrue/arch-root-e2e-compat-raw-facade-prune` - Branch: `overtrue/arch-compat-trait-method-wrappers`
- 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/API-092/API-093/API-094`. - 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/API-092/API-093/API-094/API-095`.
- Stacked on: `overtrue/arch-outer-consumer-compat-raw-facade-prune` pending API-094 merge. - Stacked on: `overtrue/arch-root-e2e-compat-raw-facade-prune` pending API-095 merge.
- PR type for this branch: `pure-move` - PR type for this branch: `pure-move`
- Runtime behavior changes: none. - Runtime behavior changes: none.
- Rust code changes: centralize RustFS root runtime and e2e storage - Rust code changes: move remaining outer bucket lifecycle, replication,
compatibility raw ECStore facade paths behind local `ecstore_*` module versioning, object-lock, and restore-request trait method access behind
aliases. local compatibility traits and wrapper functions.
- CI/script changes: guard RustFS root runtime and e2e storage compatibility - CI/script changes: stop allowing those bucket trait imports as direct ECStore
boundaries against restoring scattered raw ECStore facade paths. exceptions outside compatibility boundaries.
- Docs changes: record the API-095 root/e2e facade path cleanup. - Docs changes: record the API-096 trait-method wrapper cleanup.
## Phase 0 Tasks ## Phase 0 Tasks
@@ -362,6 +362,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
- Verification: RustFS compile coverage, root/e2e raw facade path residual - Verification: RustFS compile coverage, root/e2e raw facade path residual
scan, migration guard, formatting, diff hygiene, Rust risk scan, scan, migration guard, formatting, diff hygiene, Rust risk scan,
pre-commit quality gate, and three-expert review. pre-commit quality gate, and three-expert review.
- [x] `API-096` Prune bucket trait method imports.
- Completed slice: move outer bucket lifecycle, replication, versioning,
object-lock, and restore-request method access behind local compatibility
traits and wrapper functions in app, admin, storage, and scanner
boundaries.
- Acceptance: non-compat RustFS, scanner, and heal sources no longer import
ECStore bucket API traits directly; the migration guard only keeps the
remaining disk/RPC/warm-backend method-resolution exceptions.
- Must preserve: app replication scheduling and restore validation, admin site
replication checks, storage object/versioning behavior, scanner lifecycle
and replication scans, and existing disk/RPC method-resolution behavior.
- Verification: RustFS/scanner/heal compile coverage, direct bucket trait
import 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. - [x] `G-012` Inventory placement and repair invariants.
- Acceptance: - Acceptance:
[`placement-repair-invariants.md`](placement-repair-invariants.md) records [`placement-repair-invariants.md`](placement-repair-invariants.md) records
@@ -3395,14 +3409,27 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
| Expert | Status | Notes | | Expert | Status | Notes |
|---|---|---| |---|---|---|
| Quality/architecture | passed | API-095 centralizes RustFS root runtime and e2e ECStore facade paths behind local `ecstore_*` module aliases without adding nested compatibility modules. | | Quality/architecture | pass | API-096 localizes bucket trait method access behind owner-local compatibility traits/wrappers without re-exporting ECStore traits or widening the facade. |
| Migration preservation | passed | Root runtime metadata/config/global/storage/RPC wrappers and e2e RPC harness aliases keep the same ECStore contracts. | | Migration preservation | pass | App/admin/storage/scanner call sites keep the same method names or direct wrapper calls; disk/RPC/warm-backend exceptions are unchanged. |
| Testing/verification | passed | RustFS compile coverage, root/e2e raw facade path residual scan, migration and layer guards, formatting, diff hygiene, Rust risk scan, full pre-commit, and three-expert review passed. | | Testing/verification | pass | Focused compile, residual scan, migration guard, formatting, diff hygiene, added-line risk scan, and full pre-commit passed. |
## Verification Notes ## Verification Notes
Passed before push: Passed before push:
- Issue #660 API-096 current slice:
- `cargo check -p rustfs -p rustfs-scanner -p rustfs-heal`: 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.
- Direct non-compat bucket trait import residual scan: passed.
- Added-line Rust risk scan: passed.
- `make pre-commit`: passed; nextest run
`a18de942-8181-48fa-adf0-e01c2a5d37c3`, 6354 passed, 111 skipped;
doctests passed.
- Issue #660 API-095 current slice: - Issue #660 API-095 current slice:
- `cargo check -p rustfs`: passed. - `cargo check -p rustfs`: passed.
- `cargo fmt --all --check`: passed. - `cargo fmt --all --check`: passed.
@@ -29,6 +29,7 @@ use crate::admin::storage_compat::replication::GLOBAL_REPLICATION_STATS;
use crate::admin::storage_compat::replication::{ResyncOpts, get_global_replication_pool}; use crate::admin::storage_compat::replication::{ResyncOpts, get_global_replication_pool};
use crate::admin::storage_compat::target::{ARN, BucketTarget, BucketTargetType, BucketTargets, Credentials}; use crate::admin::storage_compat::target::{ARN, BucketTarget, BucketTargetType, BucketTargets, Credentials};
use crate::admin::storage_compat::utils::{deserialize, serialize}; use crate::admin::storage_compat::utils::{deserialize, serialize};
use crate::admin::storage_compat::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
use crate::admin::storage_compat::{delete_admin_config, read_admin_config, save_admin_config}; use crate::admin::storage_compat::{delete_admin_config, read_admin_config, save_admin_config};
use crate::admin::storage_compat::{get_global_deployment_id, get_global_endpoints_opt, get_global_region, global_rustfs_port}; use crate::admin::storage_compat::{get_global_deployment_id, get_global_endpoints_opt, get_global_region, global_rustfs_port};
use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body}; use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body};
@@ -49,8 +50,6 @@ use rustfs_config::{
DEFAULT_CONSOLE_ADDRESS, DEFAULT_DELIMITER, DEFAULT_RUSTFS_TLS_PATH, ENV_RUSTFS_CONSOLE_ADDRESS, ENV_RUSTFS_TLS_PATH, DEFAULT_CONSOLE_ADDRESS, DEFAULT_DELIMITER, DEFAULT_RUSTFS_TLS_PATH, ENV_RUSTFS_CONSOLE_ADDRESS, ENV_RUSTFS_TLS_PATH,
MAX_ADMIN_REQUEST_BODY_SIZE, MAX_ADMIN_REQUEST_BODY_SIZE,
}; };
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_iam::error::is_err_no_such_service_account; use rustfs_iam::error::is_err_no_such_service_account;
use rustfs_iam::store::{MappedPolicy, UserType}; use rustfs_iam::store::{MappedPolicy, UserType};
use rustfs_iam::sys::{ use rustfs_iam::sys::{
+1 -2
View File
@@ -29,6 +29,7 @@ use crate::admin::storage_compat::replication::{
}; };
use crate::admin::storage_compat::target::{BucketTarget, BucketTargetType, BucketTargets}; use crate::admin::storage_compat::target::{BucketTarget, BucketTargetType, BucketTargets};
use crate::admin::storage_compat::versioning_sys::BucketVersioningSys; use crate::admin::storage_compat::versioning_sys::BucketVersioningSys;
use crate::admin::storage_compat::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
use crate::admin::storage_compat::{get_global_bucket_monitor, get_global_deployment_id, get_global_region}; use crate::admin::storage_compat::{get_global_bucket_monitor, get_global_deployment_id, get_global_region};
use crate::app::context::resolve_object_store_handle; use crate::app::context::resolve_object_store_handle;
use crate::app::object_usecase::DefaultObjectUsecase; use crate::app::object_usecase::DefaultObjectUsecase;
@@ -60,8 +61,6 @@ use rustfs_config::{
ENABLE_KEY, WEBHOOK_AUTH_TOKEN, WEBHOOK_CLIENT_CA, WEBHOOK_CLIENT_CERT, WEBHOOK_CLIENT_KEY, WEBHOOK_ENDPOINT, ENABLE_KEY, WEBHOOK_AUTH_TOKEN, WEBHOOK_CLIENT_CA, WEBHOOK_CLIENT_CERT, WEBHOOK_CLIENT_KEY, WEBHOOK_ENDPOINT,
WEBHOOK_SKIP_TLS_VERIFY, WEBHOOK_SKIP_TLS_VERIFY,
}; };
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_filemeta::{ReplicationStatusType, ReplicationType}; use rustfs_filemeta::{ReplicationStatusType, ReplicationType};
use rustfs_madmin::utils::parse_duration; use rustfs_madmin::utils::parse_duration;
use rustfs_notify::{Event as NotificationEvent, notification_system}; use rustfs_notify::{Event as NotificationEvent, notification_system};
+29
View File
@@ -55,6 +55,35 @@ pub(crate) type RebalStatus = crate::admin::storage_compat::ecstore_rebalance::R
#[cfg(test)] #[cfg(test)]
pub(crate) type RebalanceInfo = crate::admin::storage_compat::ecstore_rebalance::RebalanceInfo; pub(crate) type RebalanceInfo = crate::admin::storage_compat::ecstore_rebalance::RebalanceInfo;
pub(crate) trait AdminReplicationConfigExt {
fn filter_target_arns(&self, obj: &replication::ObjectOpts) -> Vec<String>;
fn has_existing_object_replication(&self, arn: &str) -> (bool, bool);
}
impl AdminReplicationConfigExt for s3s::dto::ReplicationConfiguration {
fn filter_target_arns(&self, obj: &replication::ObjectOpts) -> Vec<String> {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::filter_target_arns(
self, obj,
)
}
fn has_existing_object_replication(&self, arn: &str) -> (bool, bool) {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::has_existing_object_replication(
self, arn,
)
}
}
pub(crate) trait AdminVersioningConfigExt {
fn enabled(&self) -> bool;
}
impl AdminVersioningConfigExt for s3s::dto::VersioningConfiguration {
fn enabled(&self) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::enabled(self)
}
}
pub(crate) mod bandwidth { pub(crate) mod bandwidth {
pub(crate) mod monitor { pub(crate) mod monitor {
pub(crate) type BandwidthDetails = crate::admin::storage_compat::ecstore_bucket::bandwidth::monitor::BandwidthDetails; pub(crate) type BandwidthDetails = crate::admin::storage_compat::ecstore_bucket::bandwidth::monitor::BandwidthDetails;
+1 -2
View File
@@ -24,6 +24,7 @@ use crate::app::storage_compat::ECStore;
use crate::app::storage_compat::StorageError; use crate::app::storage_compat::StorageError;
use crate::app::storage_compat::get_global_notification_sys; use crate::app::storage_compat::get_global_notification_sys;
use crate::app::storage_compat::object_api_utils::to_s3s_etag; use crate::app::storage_compat::object_api_utils::to_s3s_etag;
use crate::app::storage_compat::{AppObjectLockConfigExt as _, AppVersioningConfigExt as _};
use crate::app::storage_compat::{ use crate::app::storage_compat::{
bucket_target_sys::BucketTargetSys, bucket_target_sys::BucketTargetSys,
lifecycle::bucket_lifecycle_ops::{ lifecycle::bucket_lifecycle_ops::{
@@ -57,8 +58,6 @@ use futures::StreamExt;
use http::StatusCode; use http::StatusCode;
use metrics::counter; use metrics::counter;
use rustfs_config::RUSTFS_REGION; use rustfs_config::RUSTFS_REGION;
use rustfs_ecstore::api::bucket::object_lock::ObjectLockApi as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_madmin::{SITE_REPL_API_VERSION, SRBucketMeta}; use rustfs_madmin::{SITE_REPL_API_VERSION, SRBucketMeta};
use rustfs_policy::policy::{ use rustfs_policy::policy::{
action::{Action, S3Action}, action::{Action, S3Action},
+5 -6
View File
@@ -52,6 +52,9 @@ use crate::app::storage_compat::ECStore;
use crate::app::storage_compat::object_api_utils::to_s3s_etag; use crate::app::storage_compat::object_api_utils::to_s3s_etag;
use crate::app::storage_compat::quota::checker::QuotaChecker; use crate::app::storage_compat::quota::checker::QuotaChecker;
use crate::app::storage_compat::storageclass; use crate::app::storage_compat::storageclass;
use crate::app::storage_compat::{
AppReplicationConfigExt as _, AppVersioningConfigExt as _, predict_lifecycle_expiration, validate_restore_request,
};
use crate::app::storage_compat::{DiskError, is_all_buckets_not_found}; use crate::app::storage_compat::{DiskError, is_all_buckets_not_found};
use crate::app::storage_compat::{DynReader, HashReader, WritePlan, wrap_reader}; use crate::app::storage_compat::{DynReader, HashReader, WritePlan, wrap_reader};
use crate::app::storage_compat::{ use crate::app::storage_compat::{
@@ -80,10 +83,6 @@ use crate::app::storage_compat::{
}; };
use crate::server::convert_ecstore_object_info; use crate::server::convert_ecstore_object_info;
use rustfs_concurrency::GetObjectQueueSnapshot; use rustfs_concurrency::GetObjectQueueSnapshot;
use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::RestoreRequestOps as _;
use rustfs_ecstore::api::bucket::lifecycle::lifecycle::Lifecycle as _;
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_filemeta::{ use rustfs_filemeta::{
REPLICATE_INCOMING_DELETE, ReplicateDecision, ReplicateTargetDecision, ReplicationState, ReplicationStatusType, REPLICATE_INCOMING_DELETE, ReplicateDecision, ReplicateTargetDecision, ReplicationState, ReplicationStatusType,
ReplicationType, RestoreStatusOps, VersionPurgeStatusType, parse_restore_obj_status, replication_statuses_map, ReplicationType, RestoreStatusOps, VersionPurgeStatusType, parse_restore_obj_status, replication_statuses_map,
@@ -1281,7 +1280,7 @@ async fn resolve_put_object_expiration(bucket: &str, obj_info: &ObjectInfo) -> O
}; };
let obj_opts = lifecycle::ObjectOpts::from_object_info(obj_info); let obj_opts = lifecycle::ObjectOpts::from_object_info(obj_info);
let event = lifecycle_config.predict_expiration(&obj_opts).await; let event = predict_lifecycle_expiration(&lifecycle_config, &obj_opts).await;
debug!( debug!(
bucket, bucket,
action = ?event.action, action = ?event.action,
@@ -4305,7 +4304,7 @@ impl DefaultObjectUsecase {
} }
// Validate restore request // Validate restore request
if let Err(e) = rreq.validate(store.clone()) { if let Err(e) = validate_restore_request(&rreq, store.clone()) {
return Err(S3Error::with_message( return Err(S3Error::with_message(
S3ErrorCode::Custom("ErrValidRestoreObject".into()), S3ErrorCode::Custom("ErrValidRestoreObject".into()),
format!("Restore object validation failed: {}", e), format!("Restore object validation failed: {}", e),
+53
View File
@@ -65,6 +65,59 @@ pub(crate) fn EndpointServerPools(pools: Vec<PoolEndpoints>) -> EndpointServerPo
crate::app::storage_compat::ecstore_layout::EndpointServerPools::from(pools) crate::app::storage_compat::ecstore_layout::EndpointServerPools::from(pools)
} }
pub(crate) trait AppObjectLockConfigExt {
fn enabled(&self) -> bool;
}
impl AppObjectLockConfigExt for s3s::dto::ObjectLockConfiguration {
fn enabled(&self) -> bool {
<s3s::dto::ObjectLockConfiguration as ecstore_bucket::object_lock::ObjectLockApi>::enabled(self)
}
}
pub(crate) trait AppReplicationConfigExt {
fn filter_target_arns(&self, obj: &replication::ObjectOpts) -> Vec<String>;
fn replicate(&self, opts: &replication::ObjectOpts) -> bool;
}
impl AppReplicationConfigExt for s3s::dto::ReplicationConfiguration {
fn filter_target_arns(&self, obj: &replication::ObjectOpts) -> Vec<String> {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::filter_target_arns(
self, obj,
)
}
fn replicate(&self, opts: &replication::ObjectOpts) -> bool {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::replicate(self, opts)
}
}
pub(crate) trait AppVersioningConfigExt {
fn prefix_enabled(&self, prefix: &str) -> bool;
fn suspended(&self) -> bool;
}
impl AppVersioningConfigExt for s3s::dto::VersioningConfiguration {
fn prefix_enabled(&self, prefix: &str) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::prefix_enabled(self, prefix)
}
fn suspended(&self) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::suspended(self)
}
}
pub(crate) async fn predict_lifecycle_expiration(
lifecycle: &s3s::dto::BucketLifecycleConfiguration,
obj: &lifecycle::lifecycle::ObjectOpts,
) -> lifecycle::lifecycle::Event {
ecstore_bucket::lifecycle::lifecycle::Lifecycle::predict_expiration(lifecycle, obj).await
}
pub(crate) fn validate_restore_request(request: &s3s::dto::RestoreRequest, api: Arc<ECStore>) -> std::io::Result<()> {
<s3s::dto::RestoreRequest as ecstore_bucket::lifecycle::bucket_lifecycle_ops::RestoreRequestOps>::validate(request, api)
}
pub(crate) async fn get_server_info(get_pools: bool) -> rustfs_madmin::InfoMessage { pub(crate) async fn get_server_info(get_pools: bool) -> rustfs_madmin::InfoMessage {
crate::app::storage_compat::ecstore_admin::get_server_info(get_pools).await crate::app::storage_compat::ecstore_admin::get_server_info(get_pools).await
} }
+1 -2
View File
@@ -29,12 +29,11 @@ use crate::storage::storage_compat::{
is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, record_replication_proxy, serialize, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, record_replication_proxy, serialize,
update_bucket_metadata_config, update_bucket_metadata_config,
}; };
use crate::storage::storage_compat::{StorageReplicationConfigExt as _, StorageVersioningConfigExt as _};
use crate::storage::{parse_object_lock_legal_hold, parse_object_lock_retention, validate_bucket_object_lock_enabled}; use crate::storage::{parse_object_lock_legal_hold, parse_object_lock_retention, validate_bucket_object_lock_enabled};
use crate::table_catalog; use crate::table_catalog;
use http::StatusCode; use http::StatusCode;
use metrics::{counter, histogram}; use metrics::{counter, histogram};
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_ecstore::api::bucket::versioning::VersioningApi as _;
use rustfs_io_metrics::record_s3_op; use rustfs_io_metrics::record_s3_op;
use rustfs_s3_ops::S3Operation; use rustfs_s3_ops::S3Operation;
use rustfs_storage_api::{BucketOperations, BucketOptions, ObjectLockRetentionOptions, ObjectOperations as _}; use rustfs_storage_api::{BucketOperations, BucketOptions, ObjectLockRetentionOptions, ObjectOperations as _};
+1 -1
View File
@@ -16,6 +16,7 @@ use crate::config::{RustFSBufferConfig, WorkloadProfile, get_global_buffer_confi
use crate::error::ApiError; use crate::error::ApiError;
use crate::server::cors; use crate::server::cors;
use crate::storage::ecfs::ListObjectUnorderedQuery; use crate::storage::ecfs::ListObjectUnorderedQuery;
use crate::storage::storage_compat::StorageReplicationConfigExt as _;
use crate::storage::storage_compat::{ use crate::storage::storage_compat::{
StorageError, add_object_lock_years, get_bucket_cors_config, get_bucket_object_lock_config, get_bucket_replication_config, StorageError, add_object_lock_years, get_bucket_cors_config, get_bucket_object_lock_config, get_bucket_replication_config,
resolve_object_store_handle, resolve_object_store_handle,
@@ -23,7 +24,6 @@ use crate::storage::storage_compat::{
use http::header::{IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_UNMODIFIED_SINCE}; use http::header::{IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_UNMODIFIED_SINCE};
use http::{HeaderMap, HeaderValue, StatusCode}; use http::{HeaderMap, HeaderValue, StatusCode};
use metrics::counter; use metrics::counter;
use rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt as _;
use rustfs_storage_api::{BucketOperations, BucketOptions}; use rustfs_storage_api::{BucketOperations, BucketOptions};
use rustfs_targets::EventName; use rustfs_targets::EventName;
use rustfs_targets::arn::{TargetID, TargetIDError}; use rustfs_targets::arn::{TargetID, TargetIDError};
+22
View File
@@ -242,6 +242,28 @@ pub(crate) async fn find_local_disk_by_ref(disk_ref: &str) -> Option<DiskStore>
ecstore_storage::find_local_disk_by_ref(disk_ref).await ecstore_storage::find_local_disk_by_ref(disk_ref).await
} }
pub(crate) trait StorageReplicationConfigExt {
fn has_active_rules(&self, prefix: &str, recursive: bool) -> bool;
}
impl StorageReplicationConfigExt for s3s::dto::ReplicationConfiguration {
fn has_active_rules(&self, prefix: &str, recursive: bool) -> bool {
<s3s::dto::ReplicationConfiguration as ecstore_bucket::replication::ReplicationConfigurationExt>::has_active_rules(
self, prefix, recursive,
)
}
}
pub(crate) trait StorageVersioningConfigExt {
fn enabled(&self) -> bool;
}
impl StorageVersioningConfigExt for s3s::dto::VersioningConfiguration {
fn enabled(&self) -> bool {
<s3s::dto::VersioningConfiguration as ecstore_bucket::versioning::VersioningApi>::enabled(self)
}
}
pub(crate) type GetObjectReader = <ECStore as rustfs_storage_api::ObjectIO>::GetObjectReader; pub(crate) type GetObjectReader = <ECStore as rustfs_storage_api::ObjectIO>::GetObjectReader;
pub(crate) type ObjectInfo = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectInfo; pub(crate) type ObjectInfo = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectInfo;
pub(crate) type ObjectOptions = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectOptions; pub(crate) type ObjectOptions = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
@@ -692,11 +692,6 @@ fi
--glob '!target/**' || true --glob '!target/**' || true
) | ) |
perl -ne ' perl -ne '
next if /\buse rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::RestoreRequestOps(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::bucket::lifecycle::lifecycle::Lifecycle(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::bucket::object_lock::ObjectLockApi(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::bucket::replication::ReplicationConfigurationExt(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::bucket::versioning::VersioningApi(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::disk::DiskAPI(?:\s+as\s+_)?;/; next if /\buse rustfs_ecstore::api::disk::DiskAPI(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::rpc::PeerS3Client(?:\s+as\s+_)?;/; next if /\buse rustfs_ecstore::api::rpc::PeerS3Client(?:\s+as\s+_)?;/;
next if /\buse rustfs_ecstore::api::tier::warm_backend::WarmBackend(?:\s+as\s+_)?;/; next if /\buse rustfs_ecstore::api::tier::warm_backend::WarmBackend(?:\s+as\s+_)?;/;