diff --git a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs index e575f0837..279055b1b 100644 --- a/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs +++ b/crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs @@ -22,6 +22,10 @@ use crate::bucket::lifecycle::lifecycle::{ self, Lifecycle, ObjectOpts, TransitionOptions, abort_incomplete_multipart_upload_due, }; use crate::bucket::lifecycle::replication_sink; +use crate::bucket::lifecycle::replication_sink::{ + ReplicateDecision, ReplicationState, ReplicationStatusType, VersionPurgeStatusType, replication_statuses_map, + version_purge_statuses_map, +}; use crate::bucket::lifecycle::tier_delete_journal::{process_tier_delete_journal_entry, run_tier_delete_journal_recovery_loop}; use crate::bucket::lifecycle::tier_free_version_recovery::{DEFAULT_FREE_VERSION_RECOVERY_LIMIT, recover_tier_free_versions}; use crate::bucket::lifecycle::tier_last_day_stats::{DailyAllTierStats, LastDayTierStats}; @@ -57,10 +61,7 @@ use rustfs_config::{ ENV_TRANSITION_WORKERS_ABSOLUTE_MAX, }; use rustfs_data_usage::TierStats; -use rustfs_filemeta::{ - FileInfo, FileInfoOpts, NULL_VERSION_ID, ReplicateDecision, ReplicationState, RestoreStatusOps, VersionPurgeStatusType, - get_file_info, is_restored_object_on_disk, -}; +use rustfs_filemeta::{FileInfo, FileInfoOpts, NULL_VERSION_ID, RestoreStatusOps, get_file_info, is_restored_object_on_disk}; use rustfs_utils::{get_env_i64, get_env_usize, path::encode_dir_object, string::strings_has_prefix_fold}; use s3s::dto::{ BucketLifecycleConfiguration, DefaultRetention, ExpirationStatus, ObjectLockConfiguration, RestoreRequest, @@ -2890,12 +2891,12 @@ fn should_reuse_lifecycle_delete_replication_state(oi: &ObjectInfo, version_dele if version_delete { oi.version_purge_status == VersionPurgeStatusType::Pending && !state.purge_targets.is_empty() } else { - oi.replication_status == rustfs_replication::ReplicationStatusType::Pending && !state.targets.is_empty() + oi.replication_status == ReplicationStatusType::Pending && !state.targets.is_empty() } } fn lifecycle_version_purge_state_from_completed_targets(oi: &ObjectInfo) -> Option { - if oi.replication_status != rustfs_replication::ReplicationStatusType::Completed { + if oi.replication_status != ReplicationStatusType::Completed { return None; } @@ -2909,7 +2910,7 @@ fn lifecycle_version_purge_state_from_completed_targets(oi: &ObjectInfo) -> Opti Some(ReplicationState { replicate_decision_str: oi.replication_decision.clone(), version_purge_status_internal: Some(pending_status.clone()), - purge_targets: rustfs_replication::version_purge_statuses_map(&pending_status), + purge_targets: version_purge_statuses_map(&pending_status), ..Default::default() }) } @@ -2955,10 +2956,10 @@ fn replication_state_for_delete(dsc: ReplicateDecision, version_delete: bool) -> }; if version_delete { state.version_purge_status_internal = pending_status.clone(); - state.purge_targets = rustfs_replication::version_purge_statuses_map(pending_status.as_deref().unwrap_or_default()); + state.purge_targets = version_purge_statuses_map(pending_status.as_deref().unwrap_or_default()); } else { state.replication_status_internal = pending_status.clone(); - state.targets = rustfs_replication::replication_statuses_map(pending_status.as_deref().unwrap_or_default()); + state.targets = replication_statuses_map(pending_status.as_deref().unwrap_or_default()); } state } @@ -2998,6 +2999,9 @@ mod tests { should_reuse_lifecycle_delete_replication_state, transitioned_cleanup_tuple, }; use crate::bucket::lifecycle::bucket_lifecycle_audit::LcEventSrc; + use crate::bucket::lifecycle::replication_sink::{ + ReplicateDecision, ReplicateTargetDecision, ReplicationStatusType, VersionPurgeStatusType, + }; use crate::bucket::lifecycle::runtime_boundary as runtime_sources; use crate::bucket::lifecycle::tier_sweeper::Jentry; use crate::bucket::metadata::BUCKET_LIFECYCLE_CONFIG; @@ -3017,7 +3021,6 @@ mod tests { use futures::FutureExt; use rustfs_common::metrics::{IlmAction, global_metrics}; use rustfs_config::ENV_TRANSITION_WORKERS_ABSOLUTE_MAX; - use rustfs_replication::{ReplicateDecision, ReplicationStatusType, VersionPurgeStatusType}; use s3s::dto::{ BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, MetadataEntry, OutputLocation, RestoreRequest, RestoreRequestType, S3Location, Timestamp, Transition, TransitionStorageClass, @@ -3915,7 +3918,7 @@ mod tests { fn replication_state_for_delete_uses_replication_targets_for_current_delete() { let arn = "arn:aws:s3:::target-bucket"; let mut dsc = ReplicateDecision::default(); - dsc.set(rustfs_replication::ReplicateTargetDecision::new(arn.to_string(), true, false)); + dsc.set(ReplicateTargetDecision::new(arn.to_string(), true, false)); let state = replication_state_for_delete(dsc, false); @@ -3928,7 +3931,7 @@ mod tests { fn replication_state_for_delete_uses_purge_targets_for_version_delete() { let arn = "arn:aws:s3:::target-bucket"; let mut dsc = ReplicateDecision::default(); - dsc.set(rustfs_replication::ReplicateTargetDecision::new(arn.to_string(), true, false)); + dsc.set(ReplicateTargetDecision::new(arn.to_string(), true, false)); let state = replication_state_for_delete(dsc, true); @@ -3953,7 +3956,7 @@ mod tests { #[test] fn lifecycle_delete_replication_state_does_not_reuse_put_replication_for_version_delete() { let oi = ObjectInfo { - replication_status: rustfs_replication::ReplicationStatusType::Completed, + replication_status: ReplicationStatusType::Completed, replication_status_internal: Some("arn:aws:s3:::target=COMPLETED;".to_string()), replication_decision: "arn:aws:s3:::target=true;false;arn:aws:s3:::target;".to_string(), ..Default::default() @@ -3968,7 +3971,7 @@ mod tests { #[test] fn lifecycle_version_purge_state_from_completed_targets_derives_pending_purge_targets() { let oi = ObjectInfo { - replication_status: rustfs_replication::ReplicationStatusType::Completed, + replication_status: ReplicationStatusType::Completed, replication_status_internal: Some("arn:aws:s3:::target=COMPLETED;".to_string()), replication_decision: "arn:aws:s3:::target=true;false;arn:aws:s3:::target;".to_string(), ..Default::default() diff --git a/crates/ecstore/src/bucket/lifecycle/core.rs b/crates/ecstore/src/bucket/lifecycle/core.rs index c662e0b25..f3c277eac 100644 --- a/crates/ecstore/src/bucket/lifecycle/core.rs +++ b/crates/ecstore/src/bucket/lifecycle/core.rs @@ -13,7 +13,6 @@ // limitations under the License. use rustfs_config::{DEFAULT_ILM_PROCESS_TIME_SECS, ENV_ILM_PROCESS_TIME, ENV_ILM_PROCESS_TIME_DEPRECATED}; -use rustfs_replication::{ReplicationStatusType, VersionPurgeStatusType}; use s3s::dto::{ BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, LifecycleRuleFilter, NoncurrentVersionTransition, ObjectLockConfiguration, ObjectLockEnabled, RestoreRequest, Transition, @@ -26,6 +25,7 @@ use time::{self, Duration, OffsetDateTime}; use tracing::debug; use uuid::Uuid; +use crate::bucket::lifecycle::replication_sink::{ReplicationStatusType, VersionPurgeStatusType}; use crate::bucket::lifecycle::rule::{NoncurrentVersionTransitionOps, TransitionOps}; use crate::object_api::ObjectInfo; diff --git a/crates/ecstore/src/bucket/lifecycle/evaluator.rs b/crates/ecstore/src/bucket/lifecycle/evaluator.rs index fdb199438..8ee3509db 100644 --- a/crates/ecstore/src/bucket/lifecycle/evaluator.rs +++ b/crates/ecstore/src/bucket/lifecycle/evaluator.rs @@ -170,7 +170,6 @@ mod tests { use std::sync::Arc; use rustfs_common::metrics::IlmAction; - use rustfs_replication::{ReplicationStatusType, VersionPurgeStatusType}; use s3s::dto::{ BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, Transition, TransitionStorageClass, }; @@ -178,6 +177,7 @@ mod tests { use uuid::Uuid; use super::*; + use crate::bucket::lifecycle::replication_sink::{ReplicationStatusType, VersionPurgeStatusType}; fn expired_marker_lifecycle() -> Arc { Arc::new(BucketLifecycleConfiguration { expiry_updated_at: None, diff --git a/crates/ecstore/src/bucket/lifecycle/replication_sink.rs b/crates/ecstore/src/bucket/lifecycle/replication_sink.rs index 85a06032a..fab063750 100644 --- a/crates/ecstore/src/bucket/lifecycle/replication_sink.rs +++ b/crates/ecstore/src/bucket/lifecycle/replication_sink.rs @@ -13,9 +13,14 @@ // limitations under the License. use rustfs_common::metrics::IlmAction; -use rustfs_replication::{ReplicateDecision, ReplicationStatusType}; use crate::bucket::lifecycle::lifecycle::ObjectOpts; +#[cfg(test)] +pub(crate) use crate::bucket::replication::ReplicateTargetDecision; +pub(crate) use crate::bucket::replication::{ + ReplicateDecision, ReplicationState, ReplicationStatusType, VersionPurgeStatusType, replication_statuses_map, + version_purge_statuses_map, +}; use crate::bucket::replication::{ReplicationLifecycleBridge, ReplicationLifecycleConfig}; use crate::object_api::{ObjectInfo, ObjectOptions}; use crate::storage_api_contracts::object::{DeletedObject, ObjectToDelete}; @@ -70,7 +75,6 @@ mod tests { use std::collections::HashMap; use rustfs_common::metrics::IlmAction; - use rustfs_replication::{ReplicationStatusType, VersionPurgeStatusType}; use super::*; diff --git a/crates/ecstore/src/bucket/replication/mod.rs b/crates/ecstore/src/bucket/replication/mod.rs index 10b0cdec0..e640a221e 100644 --- a/crates/ecstore/src/bucket/replication/mod.rs +++ b/crates/ecstore/src/bucket/replication/mod.rs @@ -44,6 +44,12 @@ mod runtime_boundary; pub use config::{ObjectOpts, ReplicationConfigurationExt}; pub use datatypes::ResyncStatusType; +#[cfg(test)] +pub(crate) use replication_filemeta_boundary::ReplicateTargetDecision; +pub(crate) use replication_filemeta_boundary::{ + ReplicateDecision, ReplicationState, ReplicationStatusType, VersionPurgeStatusType, replication_statuses_map, + version_purge_statuses_map, +}; pub(crate) use replication_lifecycle_bridge::{ReplicationLifecycleBridge, ReplicationLifecycleConfig}; pub(crate) use replication_migration_bridge::ReplicationMigrationBridge; pub use replication_object_bridge::ReplicationObjectBridge; diff --git a/crates/scanner/src/lib.rs b/crates/scanner/src/lib.rs index 763c43412..214ea83d8 100644 --- a/crates/scanner/src/lib.rs +++ b/crates/scanner/src/lib.rs @@ -154,6 +154,7 @@ pub(crate) type ObjectOpts = EcstoreObjectOpts; pub(crate) type ReplicationHealObject = ScannerReplicationHealObject; pub(crate) type ReplicationHealQueueResult = ScannerReplicationHealResult; pub(crate) type ReplicationQueueAdmission = ScannerReplicationQueueAdmission; +pub(crate) type ReplicationStatusType = storage_api::ReplicationStatusType; pub(crate) type ScanGuard = EcstoreScanGuard; pub(crate) type SetDisks = EcstoreSetDisks; pub(crate) type StorageError = EcstoreStorageError; diff --git a/crates/scanner/src/scanner_folder.rs b/crates/scanner/src/scanner_folder.rs index d9fd92c7a..3386440d6 100644 --- a/crates/scanner/src/scanner_folder.rs +++ b/crates/scanner/src/scanner_folder.rs @@ -42,7 +42,6 @@ use rustfs_common::metrics::{ current_path_updater, global_metrics, }; use rustfs_filemeta::{MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams}; -use rustfs_replication::ReplicationStatusType; use rustfs_utils::path::{SLASH_SEPARATOR, path_join_buf}; use s3s::dto::{BucketLifecycleConfiguration, ObjectLockConfiguration}; use time::OffsetDateTime; @@ -53,10 +52,11 @@ use tracing::{debug, error, warn}; use crate::{ BucketVersioningSys, Disk, DiskError, DiskInfoOptions, Evaluator, Event, LcEventSrc, ListPathRawOptions, ObjectOpts, - ReplicationConfig, ReplicationHealObject, ReplicationQueueAdmission, ScannerDiskExt as _, ScannerLifecycleConfigExt as _, - ScannerVersioningConfigExt as _, StorageError, apply_expiry_rule, apply_transition_rule, enqueue_runtime_newer_noncurrent, - is_reserved_or_invalid_bucket, list_path_raw, path2_bucket_object, path2_bucket_object_with_base_path, - queue_replication_heal, scanner_is_erasure, scanner_replication_config_for_lifecycle_eval, + ReplicationConfig, ReplicationHealObject, ReplicationQueueAdmission, ReplicationStatusType, ScannerDiskExt as _, + ScannerLifecycleConfigExt as _, ScannerVersioningConfigExt as _, StorageError, apply_expiry_rule, apply_transition_rule, + enqueue_runtime_newer_noncurrent, is_reserved_or_invalid_bucket, list_path_raw, path2_bucket_object, + path2_bucket_object_with_base_path, queue_replication_heal, scanner_is_erasure, + scanner_replication_config_for_lifecycle_eval, }; use crate::{ScannerObjectInfo as ObjectInfo, ScannerObjectToDelete as ObjectToDelete}; @@ -2862,9 +2862,9 @@ mod tests { use crate::SCANNER_SLEEPER; use super::*; + use crate::storage_api::VersionPurgeStatusType; use crate::{DiskOption, Endpoint, new_disk}; use rustfs_filemeta::{FileInfo, FileMeta}; - use rustfs_replication::VersionPurgeStatusType; use serial_test::serial; #[cfg(unix)] use std::os::unix::fs::{PermissionsExt, symlink}; diff --git a/crates/scanner/src/storage_api.rs b/crates/scanner/src/storage_api.rs index 545f823d3..fb136ac1c 100644 --- a/crates/scanner/src/storage_api.rs +++ b/crates/scanner/src/storage_api.rs @@ -15,7 +15,8 @@ use std::collections::HashMap; use std::sync::Arc; -use rustfs_replication::{ReplicateObjectInfo, ReplicationStatusType, ReplicationType, VersionPurgeStatusType}; +use rustfs_replication::{ReplicateObjectInfo, ReplicationType}; +pub(crate) use rustfs_replication::{ReplicationStatusType, VersionPurgeStatusType}; use serde::{Deserialize, Serialize}; pub(crate) use rustfs_ecstore::api::bucket::bucket_target_sys::BucketTargetSys as EcstoreBucketTargetSys; diff --git a/rustfs/src/admin/router.rs b/rustfs/src/admin/router.rs index 14d264a82..fea7298c6 100644 --- a/rustfs/src/admin/router.rs +++ b/rustfs/src/admin/router.rs @@ -15,7 +15,7 @@ use super::storage_api::bucket::bandwidth::monitor::BandwidthDetails; use super::storage_api::bucket::metadata::BUCKET_TARGETS_FILE; use super::storage_api::bucket::metadata_sys; -use super::storage_api::bucket::replication::{self, BucketReplicationResyncStatus, BucketStats}; +use super::storage_api::bucket::replication::{self, BucketReplicationResyncStatus, BucketStats, ReplicationStatusType}; use super::storage_api::bucket::target::{BucketTarget, BucketTargetType, BucketTargets}; use super::storage_api::bucket::target_sys::{ BucketTargetSys, PutObjectOptions, RemoveObjectOptions, S3ClientError, TargetClient, @@ -62,7 +62,6 @@ use rustfs_config::{ use rustfs_madmin::utils::parse_duration; use rustfs_notify::{Event as NotificationEvent, notification_system}; use rustfs_policy::policy::action::{Action, S3Action}; -use rustfs_replication::ReplicationStatusType; use rustfs_s3_types::EventName; use rustfs_signer::pre_sign_v4; use rustfs_utils::egress::validate_outbound_url; diff --git a/rustfs/src/admin/storage_api.rs b/rustfs/src/admin/storage_api.rs index c9143c630..94020c4d0 100644 --- a/rustfs/src/admin/storage_api.rs +++ b/rustfs/src/admin/storage_api.rs @@ -309,6 +309,7 @@ pub(crate) mod quota { pub(crate) mod replication { pub(crate) type BucketReplicationResyncStatus = super::ecstore_bucket::replication::BucketReplicationResyncStatus; pub(crate) type BucketStats = super::ecstore_bucket::replication::BucketStats; + pub(crate) type ReplicationStatusType = rustfs_replication::ReplicationStatusType; pub(crate) type ResyncOpts = super::ecstore_bucket::replication::ResyncOpts; #[cfg(test)] pub(crate) type ResyncStatusType = super::ecstore_bucket::replication::ResyncStatusType; diff --git a/rustfs/src/storage/mod.rs b/rustfs/src/storage/mod.rs index 9d5dade90..e9edde377 100644 --- a/rustfs/src/storage/mod.rs +++ b/rustfs/src/storage/mod.rs @@ -53,24 +53,24 @@ pub(crate) use storage_api::{ FileReader, FileWriter, GetObjectReader, HashReader, LocalPeerS3Client, MetricType, NotificationSys, OBJECT_LOCK_CONFIG, ObjectInfo, ObjectLockBlockReason, ObjectOptions, ObjectPartInfo, PEER_RESTSIGNAL, PEER_RESTSUB_SYS, PolicySys, PoolEndpoints, PutObjReader, QuotaError, RUSTFS_META_BUCKET, RawFileInfo, ReadMultipleReq, ReadMultipleResp, ReadOptions, - RenameDataResp, ReplicationStats, Result, SERVICE_SIGNAL_REFRESH_CONFIG, SERVICE_SIGNAL_RELOAD_DYNAMIC, SetupType, - StorageDeletedObject, StorageDiskRpcExt, StorageError, StorageGetObjectReader, StorageObjectInfo, StorageObjectOptions, - StorageObjectToDelete, StoragePeerS3ClientExt, StoragePutObjReader, StorageReplicationConfigExt, StorageVersioningConfigExt, - TONIC_RPC_PREFIX, TierConfigMgr, UpdateMetadataOpts, VolumeInfo, WalkDirOptions, WorkloadAdmissionSnapshotProviderRef, - WriteEncryption, WritePlan, access_consumer, add_object_lock_years, all_local_disk, all_local_disk_path, - check_retention_for_modification, collect_local_metrics, compression_metadata_value, contract, decode_tags, - decode_tags_to_map, delete_bucket_metadata_config, disk_drive_path, disk_endpoint, ecfs_consumer, ecfs_extend_consumer, - ecstore_admin, ecstore_bucket, ecstore_capacity, ecstore_client, ecstore_cluster, ecstore_compression, ecstore_config, - ecstore_data_usage, ecstore_disk, ecstore_error, ecstore_event, ecstore_layout, ecstore_metrics, ecstore_notification, - ecstore_rebalance, ecstore_rio, ecstore_rpc, ecstore_set_disk, ecstore_storage, ecstore_tier, encode_tags, - find_local_disk_by_ref, get_bucket_accelerate_config, get_bucket_cors_config, get_bucket_logging_config, get_bucket_metadata, - get_bucket_notification_config, get_bucket_object_lock_config, get_bucket_policy_raw, get_bucket_replication_config, - get_bucket_request_payment_config, get_bucket_sse_config, get_bucket_website_config, get_local_server_property, - get_lock_acquire_timeout, get_public_access_block_config, head_prefix_consumer, helper_consumer, init_background_replication, - init_bucket_metadata_sys, init_ecstore_config, init_local_disks, init_lock_clients, is_all_buckets_not_found, - is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, is_valid_storage_class, load_bucket_metadata, - options_consumer, prewarm_local_disk_id_map, read_config, record_replication_proxy, rpc_consumer, runtime_sources_consumer, - s3_api_consumer, save_config, serialize, set_bucket_metadata, table_catalog_path_hash, to_s3s_etag, + RenameDataResp, ReplicationStats, ReplicationStatusType, Result, SERVICE_SIGNAL_REFRESH_CONFIG, + SERVICE_SIGNAL_RELOAD_DYNAMIC, SetupType, StorageDeletedObject, StorageDiskRpcExt, StorageError, StorageGetObjectReader, + StorageObjectInfo, StorageObjectOptions, StorageObjectToDelete, StoragePeerS3ClientExt, StoragePutObjReader, + StorageReplicationConfigExt, StorageVersioningConfigExt, TONIC_RPC_PREFIX, TierConfigMgr, UpdateMetadataOpts, VolumeInfo, + WalkDirOptions, WorkloadAdmissionSnapshotProviderRef, WriteEncryption, WritePlan, access_consumer, add_object_lock_years, + all_local_disk, all_local_disk_path, check_retention_for_modification, collect_local_metrics, compression_metadata_value, + contract, decode_tags, decode_tags_to_map, delete_bucket_metadata_config, disk_drive_path, disk_endpoint, ecfs_consumer, + ecfs_extend_consumer, ecstore_admin, ecstore_bucket, ecstore_capacity, ecstore_client, ecstore_cluster, ecstore_compression, + ecstore_config, ecstore_data_usage, ecstore_disk, ecstore_error, ecstore_event, ecstore_layout, ecstore_metrics, + ecstore_notification, ecstore_rebalance, ecstore_rio, ecstore_rpc, ecstore_set_disk, ecstore_storage, ecstore_tier, + encode_tags, find_local_disk_by_ref, get_bucket_accelerate_config, get_bucket_cors_config, get_bucket_logging_config, + get_bucket_metadata, get_bucket_notification_config, get_bucket_object_lock_config, get_bucket_policy_raw, + get_bucket_replication_config, get_bucket_request_payment_config, get_bucket_sse_config, get_bucket_website_config, + get_local_server_property, get_lock_acquire_timeout, get_public_access_block_config, head_prefix_consumer, helper_consumer, + init_background_replication, init_bucket_metadata_sys, init_ecstore_config, init_local_disks, init_lock_clients, + is_all_buckets_not_found, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found, is_valid_storage_class, + load_bucket_metadata, options_consumer, prewarm_local_disk_id_map, read_config, record_replication_proxy, rpc_consumer, + runtime_sources_consumer, s3_api_consumer, save_config, serialize, set_bucket_metadata, table_catalog_path_hash, to_s3s_etag, topology_snapshot_from_endpoint_pools_with_capabilities, try_migrate_bucket_metadata, try_migrate_iam_config, try_migrate_server_config, update_bucket_metadata_config, verify_rpc_signature, wrap_reader, }; diff --git a/rustfs/src/storage/options.rs b/rustfs/src/storage/options.rs index f13df7d7d..adc84d550 100644 --- a/rustfs/src/storage/options.rs +++ b/rustfs/src/storage/options.rs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::{BucketVersioningSys, Result, StorageError}; +use super::{BucketVersioningSys, ReplicationStatusType, Result, StorageError}; use crate::storage::storage_api::options_consumer::contract::{object::HTTPPreconditions, range::HTTPRangeSpec}; use http::header::{IF_MATCH, IF_NONE_MATCH}; use http::{HeaderMap, HeaderValue}; -use rustfs_replication::ReplicationStatusType; use rustfs_utils::http::{ AMZ_BUCKET_REPLICATION_STATUS, SUFFIX_FORCE_DELETE, SUFFIX_REPLICATION_ACTUAL_OBJECT_SIZE, SUFFIX_REPLICATION_SSEC_CRC, SUFFIX_SOURCE_DELETEMARKER, SUFFIX_SOURCE_MTIME, SUFFIX_SOURCE_REPLICATION_REQUEST, SUFFIX_SOURCE_VERSION_ID, get_header, @@ -814,13 +813,12 @@ mod tests { use super::super::StorageError; use super::{ - ENV_REJECT_ARCHIVE_CONTENT_ENCODING, SUPPORTED_HEADERS, copy_dst_opts, copy_src_opts, del_opts, + ENV_REJECT_ARCHIVE_CONTENT_ENCODING, ReplicationStatusType, SUPPORTED_HEADERS, copy_dst_opts, copy_src_opts, del_opts, detect_content_type_from_object_name, extract_metadata, extract_metadata_from_mime, extract_metadata_from_mime_with_object_name, filter_object_metadata, get_complete_multipart_upload_opts, get_default_opts, get_opts, parse_copy_source_range, put_opts, put_opts_from_headers, validate_archive_content_encoding, }; use http::{HeaderMap, HeaderValue}; - use rustfs_replication::ReplicationStatusType; use rustfs_utils::http::{ AMZ_BUCKET_REPLICATION_STATUS, AMZ_OBJECT_LOCK_LEGAL_HOLD_LOWER, AMZ_OBJECT_LOCK_MODE_LOWER, AMZ_OBJECT_LOCK_RETAIN_UNTIL_DATE_LOWER, SUFFIX_FORCE_DELETE, SUFFIX_SOURCE_MTIME, SUFFIX_SOURCE_REPLICATION_REQUEST, diff --git a/rustfs/src/storage/storage_api.rs b/rustfs/src/storage/storage_api.rs index 378de5c7c..376c584a9 100644 --- a/rustfs/src/storage/storage_api.rs +++ b/rustfs/src/storage/storage_api.rs @@ -518,6 +518,7 @@ pub(crate) type ReadMultipleReq = ecstore_disk::ReadMultipleReq; pub(crate) type ReadMultipleResp = ecstore_disk::ReadMultipleResp; pub(crate) type ReadOptions = ecstore_disk::ReadOptions; pub(crate) type RenameDataResp = ecstore_disk::RenameDataResp; +pub(crate) type ReplicationStatusType = rustfs_replication::ReplicationStatusType; pub(crate) type ReplicationStats = StorageReplicationStatsHandle; pub(crate) type SetupType = ecstore_layout::SetupType; pub(crate) type StorageError = ecstore_error::StorageError; diff --git a/scripts/check_architecture_migration_rules.sh b/scripts/check_architecture_migration_rules.sh index 1ac540b94..84337d5d9 100755 --- a/scripts/check_architecture_migration_rules.sh +++ b/scripts/check_architecture_migration_rules.sh @@ -136,6 +136,7 @@ LIFECYCLE_METADATA_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/lifecycle_metadata_boun LIFECYCLE_TAGGING_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/lifecycle_tagging_boundary_bypass_hits.txt" LIFECYCLE_OBJECT_LOCK_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/lifecycle_object_lock_boundary_bypass_hits.txt" LIFECYCLE_REPLICATION_SINK_BYPASS_HITS_FILE="${TMP_DIR}/lifecycle_replication_sink_bypass_hits.txt" +LIFECYCLE_REPLICATION_CRATE_BYPASS_HITS_FILE="${TMP_DIR}/lifecycle_replication_crate_bypass_hits.txt" STORE_API_EXTERNAL_LIST_CONSUMER_HITS_FILE="${TMP_DIR}/store_api_external_list_consumer_hits.txt" 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" @@ -213,10 +214,13 @@ REPLICATION_OBJECT_DECISION_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/replication_ob REPLICATION_OBJECT_COMPARE_CONTRACT_BACKSLIDE_HITS_FILE="${TMP_DIR}/replication_object_compare_contract_backslide_hits.txt" REPLICATION_MRF_WIRE_FORMAT_BACKSLIDE_HITS_FILE="${TMP_DIR}/replication_mrf_wire_format_backslide_hits.txt" STORAGE_REPLICATION_HANDLE_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/storage_replication_handle_boundary_bypass_hits.txt" +STORAGE_REPLICATION_CRATE_BYPASS_HITS_FILE="${TMP_DIR}/storage_replication_crate_bypass_hits.txt" ADMIN_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/admin_replication_dto_boundary_bypass_hits.txt" +ADMIN_REPLICATION_CRATE_BYPASS_HITS_FILE="${TMP_DIR}/admin_replication_crate_bypass_hits.txt" APP_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/app_replication_dto_boundary_bypass_hits.txt" APP_REPLICATION_CRATE_BYPASS_HITS_FILE="${TMP_DIR}/app_replication_crate_bypass_hits.txt" SCANNER_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/scanner_replication_dto_boundary_bypass_hits.txt" +SCANNER_REPLICATION_CRATE_BYPASS_HITS_FILE="${TMP_DIR}/scanner_replication_crate_bypass_hits.txt" OBS_REPLICATION_STATS_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/obs_replication_stats_boundary_bypass_hits.txt" REPLICATION_BANDWIDTH_BOUNDARY_BYPASS_HITS_FILE="${TMP_DIR}/replication_bandwidth_boundary_bypass_hits.txt" REPLICATION_CONFIG_STORE_BYPASS_HITS_FILE="${TMP_DIR}/replication_config_store_bypass_hits.txt" @@ -934,6 +938,22 @@ if [[ -s "$LIFECYCLE_REPLICATION_SINK_BYPASS_HITS_FILE" ]]; then report_failure "lifecycle replication scheduling must stay behind lifecycle replication_sink: $(paste -sd '; ' "$LIFECYCLE_REPLICATION_SINK_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + { + rg -n --with-filename 'rustfs_replication::|use\s+rustfs_replication\b' \ + crates/ecstore/src/bucket/lifecycle \ + --glob '*.rs' || true + rg -n -U --with-filename 'rustfs_filemeta::\{[^}]*\b(ReplicateDecision|ReplicationState|ReplicationStatusType|VersionPurgeStatusType|replication_statuses_map|version_purge_statuses_map)\b|use\s+rustfs_filemeta::(ReplicateDecision|ReplicationState|ReplicationStatusType|VersionPurgeStatusType)\b' \ + crates/ecstore/src/bucket/lifecycle \ + --glob '*.rs' || true + } +) >"$LIFECYCLE_REPLICATION_CRATE_BYPASS_HITS_FILE" + +if [[ -s "$LIFECYCLE_REPLICATION_CRATE_BYPASS_HITS_FILE" ]]; then + report_failure "lifecycle replication status/state contracts must stay behind lifecycle replication_sink: $(paste -sd '; ' "$LIFECYCLE_REPLICATION_CRATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" rg -n --no-heading 'rustfs_ecstore::store_api(?:::\{[^}]*\b(?:ListObjectVersionsInfo|ListObjectsV2Info|ObjectInfoOrErr)\b|::(?:ListObjectVersionsInfo|ListObjectsV2Info|ObjectInfoOrErr)\b)' \ @@ -2804,6 +2824,18 @@ if [[ -s "$STORAGE_REPLICATION_HANDLE_BOUNDARY_BYPASS_HITS_FILE" ]]; then report_failure "RustFS replication pool/stat handles must stay behind rustfs/src/storage/storage_api.rs: $(paste -sd '; ' "$STORAGE_REPLICATION_HANDLE_BOUNDARY_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename 'rustfs_replication::|use\s+rustfs_replication\b' \ + rustfs/src/storage \ + --glob '*.rs' \ + --glob '!rustfs/src/storage/storage_api.rs' || true +) >"$STORAGE_REPLICATION_CRATE_BYPASS_HITS_FILE" + +if [[ -s "$STORAGE_REPLICATION_CRATE_BYPASS_HITS_FILE" ]]; then + report_failure "RustFS storage replication crate access must stay behind rustfs/src/storage/storage_api.rs: $(paste -sd '; ' "$STORAGE_REPLICATION_CRATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" { @@ -2826,6 +2858,18 @@ if [[ -s "$ADMIN_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE" ]]; then report_failure "admin replication ObjectOpts/ResyncOpts construction must stay behind rustfs/src/admin/storage_api.rs: $(paste -sd '; ' "$ADMIN_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename 'rustfs_replication::|use\s+rustfs_replication\b' \ + rustfs/src/admin \ + --glob '*.rs' \ + --glob '!rustfs/src/admin/storage_api.rs' || true +) >"$ADMIN_REPLICATION_CRATE_BYPASS_HITS_FILE" + +if [[ -s "$ADMIN_REPLICATION_CRATE_BYPASS_HITS_FILE" ]]; then + report_failure "admin replication crate access must stay behind rustfs/src/admin/storage_api.rs: $(paste -sd '; ' "$ADMIN_REPLICATION_CRATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" { @@ -2889,6 +2933,18 @@ if [[ -s "$SCANNER_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE" ]]; then report_failure "scanner replication queue DTO access must stay behind crates/scanner/src/storage_api.rs: $(paste -sd '; ' "$SCANNER_REPLICATION_DTO_BOUNDARY_BYPASS_HITS_FILE")" fi +( + cd "$ROOT_DIR" + rg -n --with-filename 'rustfs_replication::|use\s+rustfs_replication\b' \ + crates/scanner/src crates/scanner/tests \ + --glob '*.rs' \ + --glob '!crates/scanner/src/storage_api.rs' || true +) >"$SCANNER_REPLICATION_CRATE_BYPASS_HITS_FILE" + +if [[ -s "$SCANNER_REPLICATION_CRATE_BYPASS_HITS_FILE" ]]; then + report_failure "scanner replication crate access must stay behind crates/scanner/src/storage_api.rs: $(paste -sd '; ' "$SCANNER_REPLICATION_CRATE_BYPASS_HITS_FILE")" +fi + ( cd "$ROOT_DIR" {