refactor: move bucket operations contract (#3507)

This commit is contained in:
安正超
2026-06-17 09:10:38 +08:00
committed by GitHub
parent 5b36ef5556
commit ed55857bca
37 changed files with 130 additions and 107 deletions
@@ -2868,12 +2868,12 @@ mod tests {
use crate::error::is_err_invalid_upload_id;
use crate::set_disk::{RUSTFS_MULTIPART_BUCKET_KEY, RUSTFS_MULTIPART_OBJECT_KEY};
use crate::store::ECStore;
use crate::store_api::{BucketOperations, MultipartOperations, ObjectInfo, ObjectOptions, PutObjReader};
use crate::store_api::{MultipartOperations, ObjectInfo, ObjectOptions, PutObjReader};
use futures::FutureExt;
use rustfs_common::metrics::{IlmAction, global_metrics};
use rustfs_config::ENV_TRANSITION_WORKERS_ABSOLUTE_MAX;
use rustfs_filemeta::{ReplicateDecision, VersionPurgeStatusType};
use rustfs_storage_api::{BucketOptions, MakeBucketOptions};
use rustfs_storage_api::{BucketOperations, BucketOptions, MakeBucketOptions};
use s3s::dto::{BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, Timestamp};
use serial_test::serial;
use sha2::{Digest, Sha256};
@@ -20,8 +20,8 @@ use tokio_util::sync::CancellationToken;
use crate::disk::RUSTFS_META_BUCKET;
use crate::error::Result;
use crate::store::ECStore;
use crate::store_api::{BucketOperations, ListOperations, ObjectInfo, ObjectInfoOrErr, WalkOptions};
use rustfs_storage_api::BucketOptions;
use crate::store_api::{ListOperations, ObjectInfo, ObjectInfoOrErr, WalkOptions};
use rustfs_storage_api::{BucketOperations, BucketOptions};
pub const DEFAULT_FREE_VERSION_RECOVERY_LIMIT: usize = 1_000;
const DEFAULT_FREE_VERSION_RECOVERY_SCAN_LIMIT: usize = 10_000;
+3 -3
View File
@@ -17,11 +17,11 @@
use crate::bucket::metadata::BUCKET_METADATA_FILE;
use crate::bucket::replication::{decode_resync_file, encode_resync_file};
use crate::disk::{BUCKET_META_PREFIX, MIGRATING_META_BUCKET, RUSTFS_META_BUCKET};
use crate::store_api::{BucketOperations, ListOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader};
use crate::store_api::{ListOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader};
use http::HeaderMap;
use rustfs_policy::auth::UserIdentity;
use rustfs_policy::policy::PolicyDoc;
use rustfs_storage_api::BucketOptions;
use rustfs_storage_api::{BucketOperations, BucketOptions};
use rustfs_utils::path::SLASH_SEPARATOR;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
@@ -179,7 +179,7 @@ fn normalize_bucket_meta_blob(path: &str, data: &[u8]) -> std::result::Result<Op
/// Skips buckets that already exist in RustFS (idempotent).
pub async fn try_migrate_bucket_metadata<S>(store: Arc<S>)
where
S: BucketOperations + ObjectIO + ObjectOperations,
S: BucketOperations<Error = crate::error::Error> + ObjectIO + ObjectOperations,
{
let buckets_list = match store
.list_bucket(&BucketOptions {
+2 -2
View File
@@ -38,7 +38,7 @@ use crate::error::{
use crate::notification_sys::get_global_notification_sys;
use crate::resolve_object_store_handle;
use crate::set_disk::SetDisks;
use crate::store_api::{BucketOperations, GetObjectReader, HealOperations, ObjectIO, ObjectOperations, ObjectOptions};
use crate::store_api::{GetObjectReader, HealOperations, ObjectIO, ObjectOperations, ObjectOptions};
use crate::{global::GLOBAL_LifecycleSys, sets::Sets, store::ECStore};
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use futures::{StreamExt, future::BoxFuture, stream::FuturesUnordered};
@@ -50,7 +50,7 @@ use rustfs_common::defer;
use rustfs_common::heal_channel::HealOpts;
use rustfs_concurrency::workers::Workers;
use rustfs_filemeta::{FileInfoVersions, MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams};
use rustfs_storage_api::{BucketOptions, MakeBucketOptions, StorageAdminApi};
use rustfs_storage_api::{BucketOperations, BucketOptions, MakeBucketOptions, StorageAdminApi};
use rustfs_utils::path::{encode_dir_object, path_join, path_to_bucket_object, path_to_bucket_object_with_base_path};
use s3s::dto::{BucketLifecycleConfiguration, DefaultRetention, ReplicationConfiguration};
use serde::{Deserialize, Serialize};
+6 -4
View File
@@ -52,8 +52,8 @@ use crate::{
event_notification::{EventArgs, send_event},
global::{GLOBAL_LOCAL_DISK_MAP, GLOBAL_LOCAL_DISK_SET_DRIVES, get_global_deployment_id, is_dist_erasure},
store_api::{
BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectsV2Info,
ListOperations, MultipartOperations, NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations, PutObjReader,
CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectsV2Info, ListOperations,
MultipartOperations, NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations, PutObjReader,
},
store_init::load_format_erasure,
};
@@ -86,8 +86,8 @@ use rustfs_object_capacity::capacity_scope::{
};
use rustfs_s3_types::EventName;
use rustfs_storage_api::{
BucketInfo, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions, MultipartInfo,
MultipartUploadResult, PartInfo,
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions,
MultipartInfo, MultipartUploadResult, PartInfo,
};
use rustfs_utils::http::headers::AMZ_OBJECT_TAGGING;
use rustfs_utils::http::headers::AMZ_STORAGE_CLASS;
@@ -1667,6 +1667,8 @@ impl NamespaceLocking for SetDisks {
#[async_trait::async_trait]
impl BucketOperations for SetDisks {
type Error = Error;
#[tracing::instrument(skip(self))]
async fn make_bucket(&self, _bucket: &str, _opts: &MakeBucketOptions) -> Result<()> {
unimplemented!()
+7 -5
View File
@@ -28,9 +28,9 @@ use crate::{
global::{GLOBAL_LOCAL_DISK_SET_DRIVES, get_global_lock_clients, is_dist_erasure},
set_disk::SetDisks,
store_api::{
BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectVersionsInfo,
ListObjectsV2Info, ListOperations, MultipartOperations, NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations,
ObjectOptions, ObjectToDelete, PutObjReader,
CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectVersionsInfo, ListObjectsV2Info,
ListOperations, MultipartOperations, NamespaceLocking, ObjectIO, ObjectInfo, ObjectOperations, ObjectOptions,
ObjectToDelete, PutObjReader,
},
store_init::{check_format_erasure_values, get_format_erasure_in_quorum, load_format_erasure_all, save_format_file},
};
@@ -49,8 +49,8 @@ use rustfs_lock::NamespaceLockWrapper;
use rustfs_lock::client::LockClient;
use rustfs_madmin::heal_commands::{HealDriveInfo, HealResultItem};
use rustfs_storage_api::{
BucketInfo, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions, MultipartInfo,
MultipartUploadResult, PartInfo,
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions,
MultipartInfo, MultipartUploadResult, PartInfo,
};
use rustfs_utils::{crc_hash, path::path_join_buf, sip_hash};
use std::{collections::HashMap, sync::Arc};
@@ -423,6 +423,8 @@ impl ObjectIO for Sets {
#[async_trait::async_trait]
impl BucketOperations for Sets {
type Error = Error;
#[tracing::instrument(skip(self))]
async fn make_bucket(&self, _bucket: &str, _opts: &MakeBucketOptions) -> Result<()> {
unimplemented!()
+6 -5
View File
@@ -63,9 +63,8 @@ use crate::{
rpc::S3PeerSys,
sets::Sets,
store_api::{
BucketOperations, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectsV2Info,
ListOperations, MultipartOperations, NamespaceLocking, ObjectInfo, ObjectOperations, ObjectOptions, ObjectToDelete,
PutObjReader,
CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, HealOperations, ListObjectsV2Info, ListOperations,
MultipartOperations, NamespaceLocking, ObjectInfo, ObjectOperations, ObjectOptions, ObjectToDelete, PutObjReader,
},
store_init,
};
@@ -80,8 +79,8 @@ use rustfs_filemeta::FileInfo;
use rustfs_lock::{LocalClient, LockClient, NamespaceLockWrapper};
use rustfs_madmin::heal_commands::HealResultItem;
use rustfs_storage_api::{
BucketInfo, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions, MultipartInfo,
MultipartUploadResult, PartInfo,
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions,
MultipartInfo, MultipartUploadResult, PartInfo,
};
use rustfs_utils::path::{decode_dir_object, encode_dir_object, path_join_buf};
use s3s::dto::{BucketVersioningStatus, ObjectLockConfiguration, ObjectLockEnabled, VersioningConfiguration};
@@ -398,6 +397,8 @@ lazy_static! {
#[async_trait::async_trait]
impl BucketOperations for ECStore {
type Error = Error;
#[instrument(skip(self))]
async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> Result<()> {
self.handle_make_bucket(bucket, opts).await
+1 -13
View File
@@ -1,8 +1,5 @@
use super::*;
use rustfs_storage_api::{
BucketInfo, BucketOptions, DeleteBucketOptions, ListMultipartsInfo, ListPartsInfo, MakeBucketOptions, MultipartInfo,
MultipartUploadResult, PartInfo,
};
use rustfs_storage_api::{ListMultipartsInfo, ListPartsInfo, MultipartInfo, MultipartUploadResult, PartInfo};
#[async_trait::async_trait]
pub trait ObjectIO: Send + Sync + Debug + 'static {
@@ -18,15 +15,6 @@ pub trait ObjectIO: Send + Sync + Debug + 'static {
async fn put_object(&self, bucket: &str, object: &str, data: &mut PutObjReader, opts: &ObjectOptions) -> Result<ObjectInfo>;
}
/// Bucket-level storage operations.
#[async_trait::async_trait]
pub trait BucketOperations: Send + Sync + Debug {
async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> Result<()>;
async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> Result<BucketInfo>;
async fn list_bucket(&self, opts: &BucketOptions) -> Result<Vec<BucketInfo>>;
async fn delete_bucket(&self, bucket: &str, opts: &DeleteBucketOptions) -> Result<()>;
}
/// Object-level storage operations (beyond basic I/O in ObjectIO).
#[async_trait::async_trait]
#[allow(clippy::too_many_arguments)]
+2 -2
View File
@@ -19,10 +19,10 @@ use rustfs_ecstore::{
disk::{DiskStore, endpoint::Endpoint},
error::StorageError,
store::ECStore,
store_api::{BucketOperations, HealOperations, ListOperations, ObjectIO, ObjectOperations, ObjectOptions},
store_api::{HealOperations, ListOperations, ObjectIO, ObjectOperations, ObjectOptions},
};
use rustfs_madmin::heal_commands::HealResultItem;
use rustfs_storage_api::{BucketInfo, DiskSetSelector, StorageAdminApi};
use rustfs_storage_api::{BucketInfo, BucketOperations, DiskSetSelector, StorageAdminApi};
use std::sync::Arc;
use tracing::{debug, error, warn};
+2 -1
View File
@@ -18,13 +18,14 @@ use rustfs_ecstore::{
disk::endpoint::Endpoint,
endpoints::{EndpointServerPools, Endpoints, PoolEndpoints},
store::ECStore,
store_api::{BucketOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader},
store_api::{ObjectIO, ObjectOperations, ObjectOptions, PutObjReader},
};
use rustfs_heal::heal::{
manager::{HealConfig, HealManager},
storage::{ECStoreHealStorage, HealStorageAPI},
task::{HealOptions, HealPriority, HealRequest, HealTaskStatus, HealType},
};
use rustfs_storage_api::BucketOperations;
use serial_test::serial;
use std::{
path::{Path, PathBuf},
+1 -2
View File
@@ -36,11 +36,10 @@ use rustfs_ecstore::data_usage::load_data_usage_from_backend;
use rustfs_ecstore::global::get_global_bucket_monitor;
use rustfs_ecstore::pools::{get_total_usable_capacity, get_total_usable_capacity_free};
use rustfs_ecstore::resolve_object_store_handle;
use rustfs_ecstore::store_api::BucketOperations;
use rustfs_iam::{get_global_iam_sys, oidc::oidc_plugin_authn_metrics_snapshot};
use rustfs_io_metrics::internode_metrics::global_internode_metrics;
use rustfs_io_metrics::{ProcessStatusSnapshot, snapshot_process_resource_and_system};
use rustfs_storage_api::{BucketOptions, StorageAdminApi};
use rustfs_storage_api::{BucketOperations, BucketOptions, StorageAdminApi};
use std::collections::HashMap;
use std::time::Duration;
use sysinfo::{Networks, System};
+1 -2
View File
@@ -17,8 +17,7 @@
use super::{SwiftError, SwiftResult};
use rustfs_credentials::Credentials;
use rustfs_ecstore::resolve_object_store_handle;
use rustfs_ecstore::store_api::BucketOperations;
use rustfs_storage_api::MakeBucketOptions;
use rustfs_storage_api::{BucketOperations, MakeBucketOptions};
use s3s::dto::{Tag, Tagging};
use sha2::{Digest, Sha256};
use std::collections::HashMap;
+2 -2
View File
@@ -21,8 +21,8 @@ use super::types::Container;
use super::{SwiftError, SwiftResult};
use rustfs_credentials::Credentials;
use rustfs_ecstore::resolve_object_store_handle;
use rustfs_ecstore::store_api::{BucketOperations, ListOperations};
use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions};
use rustfs_ecstore::store_api::ListOperations;
use rustfs_storage_api::{BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, MakeBucketOptions};
use s3s::dto::{Tag, Tagging};
use sha2::{Digest, Sha256};
use tracing::{debug, error};
+2 -2
View File
@@ -55,9 +55,9 @@ use super::{SwiftError, SwiftResult};
use axum::http::HeaderMap;
use rustfs_credentials::Credentials;
use rustfs_ecstore::resolve_object_store_handle;
use rustfs_ecstore::store_api::{BucketOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader};
use rustfs_ecstore::store_api::{ObjectIO, ObjectOperations, ObjectOptions, PutObjReader};
use rustfs_rio::HashReader;
use rustfs_storage_api::BucketOptions;
use rustfs_storage_api::{BucketOperations, BucketOptions};
use std::collections::HashMap;
use tracing::debug;
use tracing::error;
+2 -2
View File
@@ -45,8 +45,8 @@ use rustfs_ecstore::disk::RUSTFS_META_BUCKET;
use rustfs_ecstore::error::Error as EcstoreError;
use rustfs_ecstore::global::is_erasure_sd;
use rustfs_ecstore::store::ECStore;
use rustfs_ecstore::store_api::{BucketOperations, NamespaceLocking as _, ObjectIO};
use rustfs_storage_api::BucketOptions;
use rustfs_ecstore::store_api::{NamespaceLocking as _, ObjectIO};
use rustfs_storage_api::{BucketOperations, BucketOptions};
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc;
use tokio::time::{Duration, Instant};
+2 -2
View File
@@ -41,10 +41,10 @@ use rustfs_ecstore::error::{Error, StorageError};
use rustfs_ecstore::global::GLOBAL_TierConfigMgr;
use rustfs_ecstore::resolve_object_store_handle;
use rustfs_ecstore::set_disk::SetDisks;
use rustfs_ecstore::store_api::{BucketOperations, ObjectIO, ObjectInfo};
use rustfs_ecstore::store_api::{ObjectIO, ObjectInfo};
use rustfs_ecstore::{error::Result, store::ECStore};
use rustfs_filemeta::FileMeta;
use rustfs_storage_api::{BucketInfo, BucketOptions, DiskSetSelector, StorageAdminApi};
use rustfs_storage_api::{BucketInfo, BucketOperations, BucketOptions, DiskSetSelector, StorageAdminApi};
use rustfs_utils::path::path_join_buf;
use s3s::dto::{BucketLifecycleConfiguration, ReplicationConfiguration};
use std::collections::{HashMap, HashSet};
@@ -28,7 +28,7 @@ use rustfs_ecstore::{
global::GLOBAL_TierConfigMgr,
pools::path2_bucket_object_with_base_path,
store::ECStore,
store_api::{BucketOperations, ListOperations, MultipartOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader},
store_api::{ListOperations, MultipartOperations, ObjectIO, ObjectOperations, ObjectOptions, PutObjReader},
tier::{
tier_config::{TierConfig, TierMinIO, TierType},
warm_backend::{WarmBackend, WarmBackendGetOpts, build_transition_put_options},
@@ -38,7 +38,7 @@ use rustfs_filemeta::FileMeta;
use rustfs_scanner::scanner::init_data_scanner;
use rustfs_scanner::scanner_folder::ScannerItem;
use rustfs_scanner::scanner_io::ScannerIODisk;
use rustfs_storage_api::MakeBucketOptions;
use rustfs_storage_api::{BucketOperations, MakeBucketOptions};
use rustfs_utils::path::path_join_buf;
use s3s::dto::RestoreRequest;
use serial_test::serial;
+13
View File
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
@@ -56,6 +58,17 @@ pub struct BucketInfo {
pub object_locking: bool,
}
/// Bucket-level storage operations.
#[async_trait::async_trait]
pub trait BucketOperations: Send + Sync + Debug {
type Error: std::error::Error + Send + Sync + 'static;
async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> Result<(), Self::Error>;
async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> Result<BucketInfo, Self::Error>;
async fn list_bucket(&self, opts: &BucketOptions) -> Result<Vec<BucketInfo>, Self::Error>;
async fn delete_bucket(&self, bucket: &str, opts: &DeleteBucketOptions) -> Result<(), Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
+1 -1
View File
@@ -20,6 +20,6 @@ pub mod error;
pub mod multipart;
pub use admin::{DiskSetSelector, StorageAdminApi};
pub use bucket::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions, SRBucketDeleteOp};
pub use bucket::{BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, MakeBucketOptions, SRBucketDeleteOp};
pub use error::{StorageErrorCode, StorageResult};
pub use multipart::{ListMultipartsInfo, ListPartsInfo, MultipartInfo, MultipartUploadResult, PartInfo};