refactor: route ecstore storage api boundaries (#3892)

This commit is contained in:
Zhengchao An
2026-06-26 09:35:18 +08:00
committed by GitHub
parent 0b9c8a7731
commit c9614eb7cb
56 changed files with 389 additions and 206 deletions
@@ -33,9 +33,10 @@
//! ```
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use rustfs_ecstore::api::erasure::Erasure;
mod storage_api;
use std::hint::black_box;
use std::time::Duration;
use storage_api::Erasure;
/// Performance test data configuration
struct TestData {
+2 -1
View File
@@ -44,11 +44,12 @@
//! - SIMD optimization for different shard sizes
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use rustfs_ecstore::api::erasure::{BitrotReader, BitrotWriter, Erasure, calc_shard_size};
use rustfs_utils::HashAlgorithm;
mod storage_api;
use std::hint::black_box;
use std::io::Cursor;
use std::time::Duration;
use storage_api::{BitrotReader, BitrotWriter, Erasure, calc_shard_size};
use tokio::runtime::Runtime;
/// Benchmark configuration structure
@@ -13,11 +13,12 @@
// limitations under the License.
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
use rustfs_ecstore::api::erasure::{BitrotWriterWrapper, CustomWriter, Erasure};
use rustfs_utils::HashAlgorithm;
mod storage_api;
use std::io::Cursor;
use std::sync::Arc;
use std::time::Duration;
use storage_api::{BitrotWriterWrapper, CustomWriter, Erasure};
#[derive(Clone, Debug)]
struct BenchConfig {
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(unused_imports)]
pub(crate) use rustfs_ecstore::api::erasure::{
BitrotReader, BitrotWriter, BitrotWriterWrapper, CustomWriter, Erasure, calc_shard_size,
};
+1 -1
View File
@@ -18,6 +18,7 @@ use crate::rpc::{TonicInterceptor, gen_tonic_signature_interceptor, node_service
use crate::{disk::endpoint::Endpoint, runtime_sources};
use crate::data_usage::load_data_usage_cache;
use crate::storage_api_contracts::StorageAdminApi;
use rustfs_common::heal_channel::DriveState;
use rustfs_madmin::{
BackendDisks, Disk, ErasureSetInfo, ITEM_INITIALIZING, ITEM_OFFLINE, ITEM_ONLINE, InfoMessage, ServerProperties,
@@ -26,7 +27,6 @@ use rustfs_protos::{
models::{PingBody, PingBodyBuilder},
proto_gen::node_service::{PingRequest, PingResponse},
};
use rustfs_storage_api::StorageAdminApi;
use std::{
collections::{HashMap, HashSet},
time::Duration,
@@ -36,6 +36,10 @@ use crate::event_notification::{EventArgs, send_event};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions};
use crate::runtime_sources;
use crate::set_disk::{MAX_PARTS_COUNT, RUSTFS_MULTIPART_BUCKET_KEY, RUSTFS_MULTIPART_OBJECT_KEY, SetDisks};
use crate::storage_api_contracts::{
DeletedObject, ExpirationOptions, HTTPRangeSpec, ListOperations as _, MultipartOperations as _, ObjectOperations as _,
ObjectToDelete,
};
use crate::store::ECStore;
use crate::tier::warm_backend::WarmBackendGetOpts;
use async_channel::{Receiver as A_Receiver, Sender as A_Sender, bounded};
@@ -57,10 +61,6 @@ use rustfs_filemeta::{
VersionPurgeStatusType, get_file_info, is_restored_object_on_disk,
};
use rustfs_s3_types::EventName;
use rustfs_storage_api::{
DeletedObject, ExpirationOptions, HTTPRangeSpec, ListOperations as _, MultipartOperations as _, ObjectOperations as _,
ObjectToDelete,
};
use rustfs_utils::{get_env_i64, get_env_usize, path::encode_dir_object, string::strings_has_prefix_fold};
use s3s::dto::{
BucketLifecycleConfiguration, DefaultRetention, ExpirationStatus, ReplicationConfiguration, RestoreRequest,
@@ -387,7 +387,7 @@ pub trait ExpiryOp: 'static {
fn as_any(&self) -> &dyn Any;
}
pub use rustfs_storage_api::TransitionedObject;
pub use crate::storage_api_contracts::TransitionedObject;
struct FreeVersionTask(ObjectInfo);
@@ -2891,13 +2891,13 @@ mod tests {
use crate::object_api::{ObjectInfo, ObjectOptions, PutObjReader};
use crate::runtime_sources;
use crate::set_disk::{RUSTFS_MULTIPART_BUCKET_KEY, RUSTFS_MULTIPART_OBJECT_KEY};
use crate::storage_api_contracts::ExpirationOptions;
use crate::storage_api_contracts::{BucketOperations, BucketOptions, MakeBucketOptions, MultipartOperations as _};
use crate::store::ECStore;
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::ExpirationOptions;
use rustfs_storage_api::{BucketOperations, BucketOptions, MakeBucketOptions, MultipartOperations as _};
use s3s::dto::{BucketLifecycleConfiguration, ExpirationStatus, LifecycleExpiration, LifecycleRule, Timestamp};
use serial_test::serial;
use sha2::{Digest, Sha256};
@@ -4167,7 +4167,7 @@ mod tests {
&bucket,
object,
&upload.upload_id,
vec![rustfs_storage_api::CompletePart {
vec![crate::storage_api_contracts::CompletePart {
part_num: 1,
etag: second_part.etag.clone(),
checksum_crc32: None,
+1 -1
View File
@@ -934,7 +934,7 @@ impl Default for Event {
}
}
pub use rustfs_storage_api::ExpirationOptions;
pub use crate::storage_api_contracts::ExpirationOptions;
#[derive(Debug, Clone)]
pub struct TransitionOptions {
@@ -24,9 +24,11 @@ use crate::config::com::{delete_config, read_config, save_config};
use crate::disk::RUSTFS_META_BUCKET;
use crate::error::{Error, Result};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::storage_api_contracts::{
DeletedObject, HTTPRangeSpec, ListOperations as _, ObjectIO, ObjectOperations, ObjectToDelete,
};
use crate::store::ECStore;
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{DeletedObject, HTTPRangeSpec, ListOperations as _, ObjectIO, ObjectOperations, ObjectToDelete};
const LOG_COMPONENT_ECSTORE: &str = "ecstore";
const LOG_SUBSYSTEM_LIFECYCLE: &str = "lifecycle";
@@ -20,12 +20,11 @@ use tokio_util::sync::CancellationToken;
use crate::disk::RUSTFS_META_BUCKET;
use crate::error::Result;
use crate::object_api::ObjectInfo;
use crate::storage_api_contracts::{
BucketOperations, BucketOptions, ListOperations as _, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::store::ECStore;
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{
BucketOperations, BucketOptions, ListOperations as _, ObjectInfoOrErr as StorageObjectInfoOrErr,
WalkOptions as StorageWalkOptions,
};
pub const DEFAULT_FREE_VERSION_RECOVERY_LIMIT: usize = 1_000;
const DEFAULT_FREE_VERSION_RECOVERY_SCAN_LIMIT: usize = 10_000;
@@ -23,8 +23,8 @@ use crate::bucket::lifecycle::lifecycle::{self, ObjectOpts};
use crate::bucket::lifecycle::tier_delete_journal::persist_tier_delete_journal_entry;
use crate::client::signer_error::error_chain_contains_signer_header_marker;
use crate::runtime_sources;
use crate::storage_api_contracts::TransitionedObject;
use crate::store::ECStore;
use rustfs_storage_api::TransitionedObject;
use rustfs_utils::get_env_usize;
use sha2::{Digest, Sha256};
use std::any::Any;
+1 -1
View File
@@ -20,12 +20,12 @@ use crate::bucket::metadata::{BUCKET_LIFECYCLE_CONFIG, load_bucket_metadata_pars
use crate::bucket::utils::{deserialize, is_meta_bucketname};
use crate::error::{Error, Result, is_err_bucket_not_found};
use crate::runtime_sources;
use crate::storage_api_contracts::HealOperations as _;
use crate::store::ECStore;
use futures::future::join_all;
use lazy_static::lazy_static;
use rustfs_common::heal_channel::HealOpts;
use rustfs_policy::policy::BucketPolicy;
use rustfs_storage_api::HealOperations as _;
use s3s::dto::ReplicationConfiguration;
use s3s::dto::{
AccelerateConfiguration, BucketLifecycleConfiguration, BucketLoggingStatus, CORSConfiguration, NotificationConfiguration,
+4 -5
View File
@@ -19,16 +19,15 @@ use crate::bucket::replication::{decode_resync_file, encode_resync_file};
use crate::disk::{BUCKET_META_PREFIX, MIGRATING_META_BUCKET, RUSTFS_META_BUCKET};
use crate::error::Error;
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::storage_api_contracts::{
BucketOperations, BucketOptions, DeletedObject, HTTPRangeSpec, ListOperations, ObjectIO, ObjectOperations, ObjectToDelete,
StorageListObjectVersionsInfo, StorageListObjectsV2Info, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::storage_api_contracts::{EcstoreObjectIO, EcstoreObjectOperations};
use http::HeaderMap;
use rustfs_filemeta::FileInfo;
use rustfs_policy::auth::UserIdentity;
use rustfs_policy::policy::PolicyDoc;
use rustfs_storage_api::{
BucketOperations, BucketOptions, DeletedObject, HTTPRangeSpec, ListObjectVersionsInfo as StorageListObjectVersionsInfo,
ListObjectsV2Info as StorageListObjectsV2Info, ListOperations, ObjectIO, ObjectInfoOrErr as StorageObjectInfoOrErr,
ObjectOperations, ObjectToDelete, WalkOptions as StorageWalkOptions,
};
use rustfs_utils::path::SLASH_SEPARATOR;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
@@ -29,6 +29,7 @@ use crate::disk::BUCKET_META_PREFIX;
use crate::error::Error as EcstoreError;
use crate::object_api::{ObjectInfo, ObjectOptions};
use crate::runtime_sources;
use crate::storage_api_contracts::DeletedObject;
use crate::storage_api_contracts::EcstoreObjectIO;
use lazy_static::lazy_static;
use rustfs_filemeta::MrfOpKind;
@@ -44,7 +45,6 @@ use rustfs_filemeta::VersionPurgeStatusType;
use rustfs_filemeta::replication_statuses_map;
use rustfs_filemeta::version_purge_statuses_map;
use rustfs_filemeta::{REPLICATE_EXISTING, REPLICATE_HEAL, REPLICATE_HEAL_DELETE};
use rustfs_storage_api::DeletedObject;
use rustfs_utils::http::{SUFFIX_REPLICATION_TIMESTAMP, get_str};
use std::any::Any;
use std::sync::Arc;
@@ -31,6 +31,10 @@ use crate::event_notification::{EventArgs, send_event};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::runtime_sources;
use crate::set_disk::get_lock_acquire_timeout;
use crate::storage_api_contracts::{
DeletedObject, HTTPRangeSpec, ListOperations, NamespaceLocking as StorageNamespaceLocking, ObjectIO, ObjectOperations,
ObjectToDelete, StorageListObjectVersionsInfo, StorageListObjectsV2Info, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::storage_api_contracts::{EcstoreObjectIO, EcstoreObjectOperations};
use aws_sdk_s3::error::{ProvideErrorMetadata, SdkError};
use aws_sdk_s3::operation::head_object::{HeadObjectError, HeadObjectOutput};
@@ -56,11 +60,6 @@ use rustfs_filemeta::{
get_replication_state, parse_replicate_decision, replication_statuses_map, target_reset_header, version_purge_statuses_map,
};
use rustfs_s3_types::EventName;
use rustfs_storage_api::{
DeletedObject, HTTPRangeSpec, ListObjectVersionsInfo as StorageListObjectVersionsInfo,
ListObjectsV2Info as StorageListObjectsV2Info, ListOperations, NamespaceLocking as StorageNamespaceLocking, ObjectIO,
ObjectInfoOrErr as StorageObjectInfoOrErr, ObjectOperations, ObjectToDelete, WalkOptions as StorageWalkOptions,
};
use rustfs_utils::http::{
AMZ_BUCKET_REPLICATION_STATUS, AMZ_OBJECT_TAGGING, AMZ_TAGGING_DIRECTIVE, CONTENT_ENCODING, HeaderExt as _,
SSEC_ALGORITHM_HEADER, SSEC_KEY_HEADER, SSEC_KEY_MD5_HEADER, SUFFIX_OBJECTLOCK_LEGALHOLD_TIMESTAMP,
+1 -1
View File
@@ -26,12 +26,12 @@ use crate::client::{
credentials,
transition_api::{ReaderImpl, RequestMetadata, TransitionClient},
};
use crate::storage_api_contracts::BucketInfo;
use http::{HeaderMap, StatusCode};
use http_body_util::BodyExt;
use hyper::body::Body;
use hyper::body::Bytes;
use rustfs_config::MAX_S3_CLIENT_RESPONSE_SIZE;
use rustfs_storage_api::BucketInfo;
use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH;
use std::collections::HashMap;
use std::io::ErrorKind;
@@ -26,9 +26,9 @@ use tokio::io::BufReader;
use crate::error::ErrorResponse;
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions};
use crate::storage_api_contracts::HTTPRangeSpec;
use rustfs_filemeta::ObjectPartInfo;
use rustfs_rio::HashReader;
use rustfs_storage_api::HTTPRangeSpec;
use s3s::S3ErrorCode;
//#[derive(Clone)]
@@ -25,10 +25,10 @@ use crate::bucket::replication::{DeletedObjectReplicationInfo, check_replicate_d
use crate::bucket::versioning::VersioningApi;
use crate::bucket::versioning_sys::BucketVersioningSys;
use crate::object_api::ObjectOptions;
use crate::storage_api_contracts::{ObjectOperations as _, ObjectToDelete};
use crate::store::ECStore;
use rustfs_filemeta::{REPLICATE_INCOMING_DELETE, ReplicationState, version_purge_statuses_map};
use rustfs_lock::MAX_DELETE_LIST;
use rustfs_storage_api::{ObjectOperations as _, ObjectToDelete};
fn lifecycle_version_delete_replication_state(
replicate_decision_str: String,
+1 -1
View File
@@ -14,7 +14,7 @@
use std::collections::{BTreeMap, BTreeSet};
use rustfs_storage_api::{
use crate::storage_api_contracts::{
CapabilityStatus, DiskCapabilities, TopologyCapabilities, TopologyDisk, TopologyLabels, TopologyPool, TopologySet,
TopologySnapshot,
};
+6 -6
View File
@@ -18,6 +18,7 @@ use crate::error::{Error, Result};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::runtime_sources;
use crate::storage_api_contracts::EcstoreObjectIO;
use crate::storage_api_contracts::{DeletedObject, HTTPRangeSpec, ObjectIO, ObjectOperations, ObjectToDelete, StorageAdminApi};
use http::HeaderMap;
use rustfs_config::audit::{
AUDIT_AMQP_KEYS, AUDIT_AMQP_SUB_SYS, AUDIT_KAFKA_KEYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_KEYS, AUDIT_MQTT_SUB_SYS,
@@ -34,7 +35,6 @@ use rustfs_config::oidc::{IDENTITY_OPENID_KEYS, IDENTITY_OPENID_SUB_SYS, OIDC_RE
use rustfs_config::server_config::{Config, KVS};
use rustfs_config::{COMMENT_KEY, DEFAULT_DELIMITER, ENABLE_KEY, EnableState, RUSTFS_REGION};
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{DeletedObject, HTTPRangeSpec, ObjectIO, ObjectOperations, ObjectToDelete, StorageAdminApi};
use rustfs_utils::path::SLASH_SEPARATOR;
use serde_json::{Map, Value};
use std::collections::{HashMap, HashSet};
@@ -1315,6 +1315,8 @@ mod tests {
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::runtime_sources;
use crate::set_disk::SetDisks;
use crate::storage_api_contracts::NamespaceLocking as _;
use crate::storage_api_contracts::{HTTPRangeSpec, StorageAdminApi};
use http::HeaderMap;
use rustfs_config::audit::{AUDIT_AMQP_SUB_SYS, AUDIT_KAFKA_SUB_SYS, AUDIT_MQTT_SUB_SYS, AUDIT_WEBHOOK_SUB_SYS};
use rustfs_config::notify::{
@@ -1328,8 +1330,6 @@ mod tests {
use rustfs_lock::client::LockClient;
use rustfs_lock::client::local::LocalClient;
use rustfs_lock::{LockError, LockInfo, LockResponse, LockStats};
use rustfs_storage_api::NamespaceLocking as _;
use rustfs_storage_api::{HTTPRangeSpec, StorageAdminApi};
use serde_json::Value;
use serial_test::serial;
use std::collections::HashMap;
@@ -1498,7 +1498,7 @@ mod tests {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectIO for LockingConfigStorage {
impl crate::storage_api_contracts::ObjectIO for LockingConfigStorage {
type Error = Error;
type RangeSpec = HTTPRangeSpec;
type HeaderMap = HeaderMap;
@@ -1549,7 +1549,7 @@ mod tests {
}
#[async_trait::async_trait]
impl rustfs_storage_api::NamespaceLocking for LockingConfigStorage {
impl crate::storage_api_contracts::NamespaceLocking for LockingConfigStorage {
type Error = crate::error::Error;
type NamespaceLock = rustfs_lock::NamespaceLockWrapper;
@@ -1579,7 +1579,7 @@ mod tests {
async fn disk_set_inventory(
&self,
_selector: rustfs_storage_api::DiskSetSelector,
_selector: crate::storage_api_contracts::DiskSetSelector,
) -> Result<Vec<Option<crate::disk::DiskStore>>> {
panic!("unused in test")
}
+1 -1
View File
@@ -15,11 +15,11 @@
use crate::error::{Error, Result, is_err_data_movement_overwrite, is_err_object_not_found, is_err_version_not_found};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use crate::set_disk::SetDisks;
use crate::storage_api_contracts::{CompletePart, MultipartOperations as _, ObjectIO as _, ObjectOperations as _};
use crate::store::ECStore;
use bytes::Bytes;
use rustfs_filemeta::{FileInfo, FileInfoVersions, ObjectPartInfo};
use rustfs_rio::{ChecksumType, EtagResolvable, HashReader, HashReaderDetector, Index, TryGetIndex};
use rustfs_storage_api::{CompletePart, MultipartOperations as _, ObjectIO as _, ObjectOperations as _};
use rustfs_utils::http::AMZ_OBJECT_TAGGING;
use rustfs_utils::path::encode_dir_object;
use std::collections::{BTreeMap, HashMap};
+6 -2
View File
@@ -14,6 +14,7 @@
pub mod local_snapshot;
use crate::storage_api_contracts::{ListOperations as _, ObjectIO as _};
use crate::{
bucket::metadata_sys::get_replication_config,
config::com::read_config,
@@ -27,7 +28,6 @@ use rustfs_data_usage::{
BucketTargetUsageInfo, BucketUsageInfo, DataUsageCache, DataUsageEntry, DataUsageInfo, DiskUsageStatus, SizeSummary,
};
use rustfs_io_metrics::record_system_path_failure;
use rustfs_storage_api::{ListOperations as _, ObjectIO as _};
use rustfs_utils::path::SLASH_SEPARATOR;
use std::{
collections::{HashMap, HashSet, hash_map::Entry},
@@ -746,7 +746,11 @@ pub fn create_cache_entry_from_summary(summary: &SizeSummary) -> DataUsageEntry
}
/// Convert data usage cache to DataUsageInfo
pub fn cache_to_data_usage_info(cache: &DataUsageCache, path: &str, buckets: &[rustfs_storage_api::BucketInfo]) -> DataUsageInfo {
pub fn cache_to_data_usage_info(
cache: &DataUsageCache,
path: &str,
buckets: &[crate::storage_api_contracts::BucketInfo],
) -> DataUsageInfo {
let e = match cache.find(path) {
Some(e) => e,
None => return DataUsageInfo::default(),
+1 -1
View File
@@ -14,7 +14,7 @@
use crate::bucket::error::BucketMetadataError;
use crate::disk::error::DiskError;
use rustfs_storage_api::{HTTPRangeError, StorageErrorCode};
use crate::storage_api_contracts::{HTTPRangeError, StorageErrorCode};
use rustfs_utils::path::decode_dir_object;
use s3s::{S3Error, S3ErrorCode};
+1 -1
View File
@@ -14,6 +14,7 @@
use crate::admin_server_info::get_local_server_property;
use crate::runtime_sources;
use crate::storage_api_contracts::StorageAdminApi;
use chrono::Utc;
use rustfs_common::{heal_channel::DriveState, metrics::global_metrics};
use rustfs_io_metrics::internode_metrics::global_internode_metrics;
@@ -29,7 +30,6 @@ use rustfs_madmin::metrics::{
ScannerSourceCycleSnapshot as MadminScannerSourceCycleSnapshot, ScannerSourceWorkSnapshot as MadminScannerSourceWorkSnapshot,
ScannerUsageFreshnessSnapshot as MadminScannerUsageFreshnessSnapshot, TimedAction as MadminTimedAction,
};
use rustfs_storage_api::StorageAdminApi;
use rustfs_utils::os::get_drive_stats;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
+1 -1
View File
@@ -19,13 +19,13 @@ use crate::metrics_realtime::{CollectMetricsOpts, MetricType};
use crate::rebalance::RebalSaveOpt;
use crate::rpc::PeerRestClient;
use crate::runtime_sources;
use crate::storage_api_contracts::StorageAdminApi;
use futures::future::join_all;
use lazy_static::lazy_static;
use rustfs_madmin::health::{Cpus, MemInfo, OsInfo, Partitions, ProcInfo, SysConfig, SysErrors, SysServices};
use rustfs_madmin::metrics::RealtimeMetrics;
use rustfs_madmin::net::NetInfo;
use rustfs_madmin::{ItemState, ServerProperties, StorageInfo};
use rustfs_storage_api::StorageAdminApi;
use std::collections::hash_map::DefaultHasher;
use std::future::Future;
use std::hash::{Hash, Hasher};
+1 -1
View File
@@ -17,6 +17,7 @@ use crate::bucket::versioning::VersioningApi as _;
use crate::config::storageclass;
use crate::error::{Error, Result};
use crate::rio::{HashReader, LimitReader};
use crate::storage_api_contracts::{ExpirationOptions, HTTPRangeSpec, TransitionedObject};
use crate::store_utils::clean_metadata;
use crate::{bucket::lifecycle::bucket_lifecycle_audit::LcAuditEvent, bucket::lifecycle::lifecycle::TransitionOptions};
use bytes::Bytes;
@@ -27,7 +28,6 @@ use rustfs_filemeta::{
version_purge_statuses_map,
};
use rustfs_rio::Checksum;
use rustfs_storage_api::{ExpirationOptions, HTTPRangeSpec, TransitionedObject};
use rustfs_utils::CompressionAlgorithm;
use rustfs_utils::http::headers::AMZ_OBJECT_TAGGING;
use rustfs_utils::http::{AMZ_BUCKET_REPLICATION_STATUS, AMZ_RESTORE, AMZ_STORAGE_CLASS};
+1 -1
View File
@@ -1,5 +1,5 @@
use super::*;
use rustfs_storage_api::{
use crate::storage_api_contracts::{
HTTPPreconditions, ObjectLockRetentionOptions, ObjectPreconditionError, ObjectPreconditionPart, ObjectPreconditionState,
VersionMarker,
};
+4 -4
View File
@@ -39,6 +39,10 @@ use crate::object_api::{GetObjectReader, ObjectOptions};
use crate::rebalance::{REBAL_META_NAME, RebalanceMeta, is_rebalance_conflicting_with_decommission};
use crate::runtime_sources;
use crate::set_disk::{SetDisks, get_lock_acquire_timeout};
use crate::storage_api_contracts::{
BucketOperations, BucketOptions, HealOperations as _, MakeBucketOptions, NamespaceLocking as _, ObjectIO as _,
ObjectOperations as _, StorageAdminApi,
};
use crate::{sets::Sets, store::ECStore};
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
use futures::{StreamExt, future::BoxFuture, stream::FuturesUnordered};
@@ -49,10 +53,6 @@ use rmp_serde::Serializer;
use rustfs_common::defer;
use rustfs_common::heal_channel::HealOpts;
use rustfs_filemeta::{FileInfoVersions, MetaCacheEntries, MetaCacheEntry, MetadataResolutionParams};
use rustfs_storage_api::{
BucketOperations, BucketOptions, HealOperations as _, MakeBucketOptions, NamespaceLocking as _, ObjectIO as _,
ObjectOperations as _, 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};
+1 -1
View File
@@ -20,9 +20,9 @@ use crate::error::{Error, Result};
use crate::object_api::ObjectOptions;
use crate::set_disk::get_lock_acquire_timeout;
use crate::storage_api_contracts::EcstoreObjectIO;
use crate::storage_api_contracts::{NamespaceLocking as StorageNamespaceLocking, StorageAdminApi};
use crate::store::ECStore;
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{NamespaceLocking as StorageNamespaceLocking, StorageAdminApi};
use std::sync::Arc;
use time::OffsetDateTime;
use tracing::{debug, info};
+1 -1
View File
@@ -34,9 +34,9 @@ use crate::error::{Error, Result};
use crate::object_api::{GetObjectReader, ObjectOptions};
use crate::pools::ListCallback;
use crate::set_disk::SetDisks;
use crate::storage_api_contracts::ObjectOperations as _;
use crate::store::ECStore;
use rustfs_filemeta::MetaCacheEntry;
use rustfs_storage_api::ObjectOperations as _;
use rustfs_utils::path::encode_dir_object;
use std::sync::Arc;
use time::OffsetDateTime;
+1 -1
View File
@@ -7,9 +7,9 @@ use super::{
};
use crate::config::com::{read_config_with_metadata, save_config_with_opts};
use crate::error::is_err_operation_canceled;
use crate::storage_api_contracts::{HTTPRangeSpec, ObjectIO};
use http::HeaderMap;
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{HTTPRangeSpec, ObjectIO};
use std::{collections::HashSet, fmt, io::Cursor, sync::Arc};
use time::OffsetDateTime;
use tracing::{debug, info};
+1 -1
View File
@@ -3,9 +3,9 @@ use crate::data_usage::DATA_USAGE_CACHE_NAME;
use crate::error::{Error, Result, is_err_object_not_found, is_err_version_not_found};
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions};
use crate::set_disk::SetDisks;
use crate::storage_api_contracts::{HTTPRangeSpec, ObjectIO, ObjectOperations as _};
use http::HeaderMap;
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{HTTPRangeSpec, ObjectIO, ObjectOperations as _};
use rustfs_utils::path::encode_dir_object;
use std::future::Future;
use tokio::time::Duration;
@@ -54,10 +54,10 @@ use crate::data_usage::DATA_USAGE_CACHE_NAME;
use crate::disk::RUSTFS_META_BUCKET;
use crate::disk::error::DiskError;
use crate::error::{Error, Result};
use crate::storage_api_contracts::HTTPRangeSpec;
use rustfs_filemeta::FileInfo;
use rustfs_filemeta::TRANSITION_COMPLETE;
use rustfs_rio::Index;
use rustfs_storage_api::HTTPRangeSpec;
use s3s::dto::ReplicationConfiguration;
use serde::Serialize;
use std::io::Cursor;
+1 -1
View File
@@ -21,6 +21,7 @@ use crate::rpc::client::{
TonicInterceptor, gen_tonic_signature_interceptor, is_network_like_disk_error, node_service_time_out_client,
};
use crate::runtime_sources;
use crate::storage_api_contracts::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions};
use crate::store::all_local_disk;
use crate::store_utils::is_reserved_or_invalid_bucket;
use crate::{
@@ -38,7 +39,6 @@ use rustfs_protos::proto_gen::node_service::node_service_client::NodeServiceClie
use rustfs_protos::proto_gen::node_service::{
DeleteBucketRequest, GetBucketInfoRequest, HealBucketRequest, ListBucketRequest, MakeBucketRequest,
};
use rustfs_storage_api::{BucketInfo, BucketOptions, DeleteBucketOptions, MakeBucketOptions};
use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration};
use tokio::{net::TcpStream, sync::RwLock, time};
use tokio_util::sync::CancellationToken;
+29 -23
View File
@@ -42,6 +42,14 @@ use crate::get_diagnostics::{
use crate::object_api::ObjectOptions;
use crate::rpc::heal_bucket_local_on_disks;
use crate::runtime_sources;
use crate::storage_api_contracts::{
BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, ListMultipartsInfo,
ListPartsInfo, MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectToDelete, PartInfo,
};
use crate::storage_api_contracts::{
HTTPRangeSpec, StorageListObjectVersionsInfo, StorageListObjectsV2Info, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::storage_api_contracts::{MultipartOperations as _, NamespaceLocking as _, ObjectIO as _, ObjectOperations as _};
use crate::store_utils::is_reserved_or_invalid_bucket;
use crate::{
bucket::lifecycle::bucket_lifecycle_ops::{
@@ -88,15 +96,6 @@ use rustfs_object_capacity::capacity_scope::{
CapacityScope, CapacityScopeDisk, record_capacity_scope, record_global_dirty_scope,
};
use rustfs_s3_types::EventName;
use rustfs_storage_api::{
BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, ListMultipartsInfo,
ListPartsInfo, MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectToDelete, PartInfo,
};
use rustfs_storage_api::{
HTTPRangeSpec, ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsV2Info as StorageListObjectsV2Info,
ObjectInfoOrErr as StorageObjectInfoOrErr, WalkOptions as StorageWalkOptions,
};
use rustfs_storage_api::{MultipartOperations as _, NamespaceLocking as _, ObjectIO as _, ObjectOperations as _};
use rustfs_utils::http::headers::AMZ_OBJECT_TAGGING;
use rustfs_utils::http::headers::AMZ_STORAGE_CLASS;
use rustfs_utils::http::headers::{
@@ -1023,7 +1022,7 @@ fn classify_multipart_part_write_path(object_size: i64, block_size: usize) -> Sm
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectIO for SetDisks {
impl crate::storage_api_contracts::ObjectIO for SetDisks {
type Error = Error;
type RangeSpec = HTTPRangeSpec;
type HeaderMap = HeaderMap;
@@ -2011,7 +2010,7 @@ impl SetDisks {
}
#[async_trait::async_trait]
impl rustfs_storage_api::NamespaceLocking for SetDisks {
impl crate::storage_api_contracts::NamespaceLocking for SetDisks {
type Error = Error;
type NamespaceLock = NamespaceLockWrapper;
@@ -2267,7 +2266,7 @@ fn check_object_lock_retention_update(bucket: &str, object: &str, obj_info: &Obj
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectOperations for SetDisks {
impl crate::storage_api_contracts::ObjectOperations for SetDisks {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -3373,8 +3372,15 @@ impl rustfs_storage_api::ObjectOperations for SetDisks {
#[tracing::instrument(skip(self))]
async fn verify_object_integrity(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<()> {
let get_object_reader =
<Self as rustfs_storage_api::ObjectIO>::get_object_reader(self, bucket, object, None, HeaderMap::new(), opts).await?;
let get_object_reader = <Self as crate::storage_api_contracts::ObjectIO>::get_object_reader(
self,
bucket,
object,
None,
HeaderMap::new(),
opts,
)
.await?;
// Stream to sink to avoid loading entire object into memory during verification
let mut reader = get_object_reader.stream;
tokio::io::copy(&mut reader, &mut tokio::io::sink()).await?;
@@ -3497,7 +3503,7 @@ impl SetDisks {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ListOperations for SetDisks {
impl crate::storage_api_contracts::ListOperations for SetDisks {
type Error = Error;
type ListObjectsV2Info = ListObjectsV2Info;
type ListObjectVersionsInfo = ListObjectVersionsInfo;
@@ -3558,7 +3564,7 @@ impl rustfs_storage_api::ListOperations for SetDisks {
}
#[async_trait::async_trait]
impl rustfs_storage_api::MultipartOperations for SetDisks {
impl crate::storage_api_contracts::MultipartOperations for SetDisks {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -4666,7 +4672,7 @@ impl rustfs_storage_api::MultipartOperations for SetDisks {
}
#[async_trait::async_trait]
impl rustfs_storage_api::HealOperations for SetDisks {
impl crate::storage_api_contracts::HealOperations for SetDisks {
type Error = Error;
type HealResultItem = HealResultItem;
type HealOptions = HealOpts;
@@ -5621,6 +5627,10 @@ mod tests {
use crate::disk::health_state::RuntimeDriveHealthState;
use crate::endpoints::SetupType;
use crate::object_api::ObjectInfo;
use crate::storage_api_contracts::HealOperations as _;
use crate::storage_api_contracts::ListOperations as _;
use crate::storage_api_contracts::TransitionedObject;
use crate::storage_api_contracts::{CompletePart, NamespaceLocking as _, ObjectOperations as _};
use crate::store_init::save_format_file;
use crate::store_list_objects::ListPathOptions;
use rustfs_filemeta::ErasureInfo;
@@ -5628,10 +5638,6 @@ mod tests {
use rustfs_filemeta::ReplicationState;
use rustfs_lock::client::local::LocalClient;
use rustfs_lock::{LockError, LockInfo, LockResponse, LockStats};
use rustfs_storage_api::HealOperations as _;
use rustfs_storage_api::ListOperations as _;
use rustfs_storage_api::TransitionedObject;
use rustfs_storage_api::{CompletePart, NamespaceLocking as _, ObjectOperations as _};
use serial_test::serial;
use std::collections::HashMap;
use tempfile::TempDir;
@@ -7442,7 +7448,7 @@ mod tests {
..Default::default()
};
let opts = ObjectOptions {
object_lock_retention: Some(rustfs_storage_api::ObjectLockRetentionOptions {
object_lock_retention: Some(crate::storage_api_contracts::ObjectLockRetentionOptions {
mode: Some(s3s::dto::ObjectLockRetentionMode::COMPLIANCE.to_string()),
retain_until: Some(requested_until),
bypass_governance: true,
@@ -7477,7 +7483,7 @@ mod tests {
..Default::default()
};
let opts = ObjectOptions {
object_lock_retention: Some(rustfs_storage_api::ObjectLockRetentionOptions {
object_lock_retention: Some(crate::storage_api_contracts::ObjectLockRetentionOptions {
mode: Some(s3s::dto::ObjectLockRetentionMode::GOVERNANCE.to_string()),
retain_until: Some(requested_until),
bypass_governance: true,
+1 -1
View File
@@ -13,8 +13,8 @@
// limitations under the License.
use super::*;
use crate::storage_api_contracts::NamespaceLocking as _;
use rustfs_config::{DEFAULT_OBJECT_ZERO_COPY_ENABLE, ENV_OBJECT_ZERO_COPY_ENABLE};
use rustfs_storage_api::NamespaceLocking as _;
impl SetDisks {
#[tracing::instrument(skip(self, opts), fields(bucket = %bucket, object = %object, version_id = %version_id))]
+16 -17
View File
@@ -16,6 +16,14 @@
use crate::disk::error_reduce::count_errs;
use crate::error::{Error, Result};
use crate::layout::set_heal::{formats_to_drives_info, new_heal_format_sets};
use crate::storage_api_contracts::CompletePart;
use crate::storage_api_contracts::HTTPRangeSpec;
use crate::storage_api_contracts::{
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, DeletedObject, ListMultipartsInfo, ListPartsInfo,
MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectToDelete, PartInfo, StorageListObjectVersionsInfo,
StorageListObjectsV2Info, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::storage_api_contracts::{ObjectIO as _, ObjectOperations as _};
use crate::{
disk::{
DiskAPI, DiskOption, DiskStore,
@@ -41,15 +49,6 @@ use rustfs_filemeta::FileInfo;
use rustfs_lock::NamespaceLockWrapper;
use rustfs_lock::client::LockClient;
use rustfs_madmin::heal_commands::{HealDriveInfo, HealResultItem};
use rustfs_storage_api::CompletePart;
use rustfs_storage_api::HTTPRangeSpec;
use rustfs_storage_api::{
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, DeletedObject, ListMultipartsInfo,
ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsV2Info as StorageListObjectsV2Info, ListPartsInfo,
MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectInfoOrErr as StorageObjectInfoOrErr, ObjectToDelete, PartInfo,
WalkOptions as StorageWalkOptions,
};
use rustfs_storage_api::{ObjectIO as _, ObjectOperations as _};
use rustfs_utils::{crc_hash, path::path_join_buf, sip_hash};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;
@@ -401,7 +400,7 @@ fn apply_delete_objects_results(
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectIO for Sets {
impl crate::storage_api_contracts::ObjectIO for Sets {
type Error = Error;
type RangeSpec = HTTPRangeSpec;
type HeaderMap = HeaderMap;
@@ -494,7 +493,7 @@ impl BucketOperations for Sets {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectOperations for Sets {
impl crate::storage_api_contracts::ObjectOperations for Sets {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -702,7 +701,7 @@ impl rustfs_storage_api::ObjectOperations for Sets {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ListOperations for Sets {
impl crate::storage_api_contracts::ListOperations for Sets {
type Error = Error;
type ListObjectsV2Info = ListObjectsV2Info;
type ListObjectVersionsInfo = ListObjectVersionsInfo;
@@ -763,7 +762,7 @@ impl rustfs_storage_api::ListOperations for Sets {
}
#[async_trait::async_trait]
impl rustfs_storage_api::MultipartOperations for Sets {
impl crate::storage_api_contracts::MultipartOperations for Sets {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -877,7 +876,7 @@ impl rustfs_storage_api::MultipartOperations for Sets {
}
#[async_trait::async_trait]
impl rustfs_storage_api::HealOperations for Sets {
impl crate::storage_api_contracts::HealOperations for Sets {
type Error = Error;
type HealResultItem = HealResultItem;
type HealOptions = HealOpts;
@@ -1017,7 +1016,7 @@ impl rustfs_storage_api::HealOperations for Sets {
}
#[async_trait::async_trait]
impl rustfs_storage_api::NamespaceLocking for Sets {
impl crate::storage_api_contracts::NamespaceLocking for Sets {
type Error = Error;
type NamespaceLock = NamespaceLockWrapper;
@@ -1093,8 +1092,8 @@ async fn init_storage_disks_with_errors(
mod tests {
use super::*;
use crate::layout::endpoint::Endpoint;
use rustfs_storage_api::HealOperations as _;
use rustfs_storage_api::ListOperations as _;
use crate::storage_api_contracts::HealOperations as _;
use crate::storage_api_contracts::ListOperations as _;
#[test]
fn test_apply_delete_objects_results_preserves_original_order_for_out_of_order_batches() {
+16 -10
View File
@@ -1,10 +1,16 @@
use crate::error::Error;
use crate::object_api::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use rustfs_filemeta::FileInfo;
use rustfs_storage_api::{
DeletedObject, HTTPRangeSpec, ListObjectVersionsInfo as StorageListObjectVersionsInfo,
ListObjectsV2Info as StorageListObjectsV2Info, ObjectInfoOrErr as StorageObjectInfoOrErr, ObjectToDelete,
WalkOptions as StorageWalkOptions,
pub use rustfs_storage_api::{
BucketInfo, BucketOperations, BucketOptions, CapabilityStatus, CompletePart, DeleteBucketOptions, DeletedObject,
DiskCapabilities, DiskSetSelector, ExpirationOptions, HTTPPreconditions, HTTPRangeError, HTTPRangeSpec, HealOperations,
ListMultipartsInfo, ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsInfo,
ListObjectsV2Info as StorageListObjectsV2Info, ListOperations, ListPartsInfo, MakeBucketOptions, MultipartInfo,
MultipartOperations, MultipartUploadResult, NamespaceLocking, ObjectIO, ObjectInfoOrErr as StorageObjectInfoOrErr,
ObjectLockRetentionOptions, ObjectOperations, ObjectPreconditionError, ObjectPreconditionPart, ObjectPreconditionState,
ObjectToDelete, PartInfo, StorageAdminApi, StorageErrorCode, TopologyCapabilities, TopologyDisk, TopologyLabels,
TopologyPool, TopologySet, TopologySnapshot, TransitionedObject, VersionMarker, WalkOptions as StorageWalkOptions,
WalkVersionsSortOrder,
};
use std::fmt::Debug;
use tokio_util::sync::CancellationToken;
@@ -15,7 +21,7 @@ type ObjectInfoOrErr = StorageObjectInfoOrErr<ObjectInfo, Error>;
type WalkOptions = StorageWalkOptions<fn(&FileInfo) -> bool>;
pub(crate) trait EcstoreObjectIO:
rustfs_storage_api::ObjectIO<
ObjectIO<
Error = Error,
RangeSpec = HTTPRangeSpec,
HeaderMap = http::HeaderMap,
@@ -31,7 +37,7 @@ pub(crate) trait EcstoreObjectIO:
}
impl<T> EcstoreObjectIO for T where
T: rustfs_storage_api::ObjectIO<
T: ObjectIO<
Error = Error,
RangeSpec = HTTPRangeSpec,
HeaderMap = http::HeaderMap,
@@ -47,7 +53,7 @@ impl<T> EcstoreObjectIO for T where
}
pub(crate) trait EcstoreObjectOperations:
rustfs_storage_api::ObjectOperations<
ObjectOperations<
Error = Error,
ObjectInfo = ObjectInfo,
ObjectOptions = ObjectOptions,
@@ -61,7 +67,7 @@ pub(crate) trait EcstoreObjectOperations:
}
impl<T> EcstoreObjectOperations for T where
T: rustfs_storage_api::ObjectOperations<
T: ObjectOperations<
Error = Error,
ObjectInfo = ObjectInfo,
ObjectOptions = ObjectOptions,
@@ -75,7 +81,7 @@ impl<T> EcstoreObjectOperations for T where
}
pub(crate) trait EcstoreListOperations:
rustfs_storage_api::ListOperations<
ListOperations<
Error = Error,
ListObjectsV2Info = ListObjectsV2Info,
ListObjectVersionsInfo = ListObjectVersionsInfo,
@@ -90,7 +96,7 @@ pub(crate) trait EcstoreListOperations:
}
impl<T> EcstoreListOperations for T where
T: rustfs_storage_api::ListOperations<
T: ListOperations<
Error = Error,
ListObjectsV2Info = ListObjectsV2Info,
ListObjectVersionsInfo = ListObjectVersionsInfo,
+18 -16
View File
@@ -46,6 +46,13 @@ use crate::pools::PoolMeta;
use crate::rebalance::RebalanceMeta;
use crate::rpc::RemoteClient;
use crate::runtime_sources;
use crate::storage_api_contracts::{
BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, ListMultipartsInfo,
ListPartsInfo, MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectToDelete, PartInfo,
};
use crate::storage_api_contracts::{
HTTPRangeSpec, StorageListObjectVersionsInfo, StorageListObjectsV2Info, StorageObjectInfoOrErr, StorageWalkOptions,
};
use crate::store_init::{check_disk_fatal_errs, ec_drives_no_config};
use crate::tier::tier::TierConfigMgr;
use crate::{
@@ -66,14 +73,6 @@ use rustfs_config::server_config::Config;
use rustfs_filemeta::FileInfo;
use rustfs_lock::{LocalClient, LockClient, NamespaceLockWrapper};
use rustfs_madmin::heal_commands::HealResultItem;
use rustfs_storage_api::{
BucketInfo, BucketOperations, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, ListMultipartsInfo,
ListPartsInfo, MakeBucketOptions, MultipartInfo, MultipartUploadResult, ObjectToDelete, PartInfo,
};
use rustfs_storage_api::{
HTTPRangeSpec, ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsV2Info as StorageListObjectsV2Info,
ObjectInfoOrErr as StorageObjectInfoOrErr, WalkOptions as StorageWalkOptions,
};
use rustfs_utils::path::{decode_dir_object, encode_dir_object, path_join_buf};
use s3s::dto::{BucketVersioningStatus, ObjectLockConfiguration, ObjectLockEnabled, VersioningConfiguration};
use std::net::SocketAddr;
@@ -347,7 +346,7 @@ impl ECStore {
// }
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectIO for ECStore {
impl crate::storage_api_contracts::ObjectIO for ECStore {
type Error = Error;
type RangeSpec = HTTPRangeSpec;
type HeaderMap = HeaderMap;
@@ -408,7 +407,7 @@ impl BucketOperations for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ObjectOperations for ECStore {
impl crate::storage_api_contracts::ObjectOperations for ECStore {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -499,7 +498,7 @@ impl rustfs_storage_api::ObjectOperations for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::ListOperations for ECStore {
impl crate::storage_api_contracts::ListOperations for ECStore {
type Error = Error;
type ListObjectsV2Info = ListObjectsV2Info;
type ListObjectVersionsInfo = ListObjectVersionsInfo;
@@ -564,7 +563,7 @@ impl rustfs_storage_api::ListOperations for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::MultipartOperations for ECStore {
impl crate::storage_api_contracts::MultipartOperations for ECStore {
type Error = Error;
type ObjectInfo = ObjectInfo;
type ObjectOptions = ObjectOptions;
@@ -688,7 +687,7 @@ impl rustfs_storage_api::MultipartOperations for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::HealOperations for ECStore {
impl crate::storage_api_contracts::HealOperations for ECStore {
type Error = Error;
type HealResultItem = HealResultItem;
type HealOptions = HealOpts;
@@ -725,7 +724,7 @@ impl rustfs_storage_api::HealOperations for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::NamespaceLocking for ECStore {
impl crate::storage_api_contracts::NamespaceLocking for ECStore {
type Error = Error;
type NamespaceLock = NamespaceLockWrapper;
@@ -735,7 +734,7 @@ impl rustfs_storage_api::NamespaceLocking for ECStore {
}
#[async_trait::async_trait]
impl rustfs_storage_api::StorageAdminApi for ECStore {
impl crate::storage_api_contracts::StorageAdminApi for ECStore {
type BackendInfo = rustfs_madmin::BackendInfo;
type StorageInfo = rustfs_madmin::StorageInfo;
type Disk = DiskStore;
@@ -757,7 +756,10 @@ impl rustfs_storage_api::StorageAdminApi for ECStore {
}
#[instrument(skip(self))]
async fn disk_set_inventory(&self, selector: rustfs_storage_api::DiskSetSelector) -> Result<Vec<Option<Self::Disk>>> {
async fn disk_set_inventory(
&self,
selector: crate::storage_api_contracts::DiskSetSelector,
) -> Result<Vec<Option<Self::Disk>>> {
self.handle_get_disks(selector.pool_idx, selector.set_idx).await
}
+1 -1
View File
@@ -19,7 +19,7 @@ use crate::bucket::{
};
use crate::runtime_sources;
use crate::set_disk::get_lock_acquire_timeout;
use rustfs_storage_api::NamespaceLocking as _;
use crate::storage_api_contracts::NamespaceLocking as _;
fn should_override_created_from_metadata(created: OffsetDateTime) -> bool {
created != OffsetDateTime::UNIX_EPOCH
+1 -1
View File
@@ -13,7 +13,7 @@
// limitations under the License.
use super::*;
use rustfs_storage_api::HealOperations as _;
use crate::storage_api_contracts::HealOperations as _;
const LOG_COMPONENT_ECSTORE: &str = "ecstore";
const LOG_SUBSYSTEM_HEAL: &str = "heal";
+1 -1
View File
@@ -13,7 +13,7 @@
// limitations under the License.
use super::*;
use rustfs_storage_api::MultipartOperations as _;
use crate::storage_api_contracts::MultipartOperations as _;
impl ECStore {
#[instrument(skip(self))]
+10 -3
View File
@@ -17,11 +17,11 @@ use crate::set_disk::{
get_lock_acquire_timeout, get_object_lock_diag_slow_acquire_threshold, get_object_lock_diag_slow_hold_threshold,
is_lock_optimization_enabled, is_object_lock_diag_enabled,
};
use crate::storage_api_contracts::{ObjectIO as _, ObjectOperations as _};
use rustfs_io_metrics::{
record_object_lock_diag_acquire_duration, record_object_lock_diag_hold_duration, record_object_lock_diag_slow_acquire,
record_object_lock_diag_slow_hold,
};
use rustfs_storage_api::{ObjectIO as _, ObjectOperations as _};
use std::{
fmt,
pin::Pin,
@@ -1281,8 +1281,15 @@ impl ECStore {
}
pub(super) async fn handle_verify_object_integrity(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<()> {
let get_object_reader =
<Self as rustfs_storage_api::ObjectIO>::get_object_reader(self, bucket, object, None, HeaderMap::new(), opts).await?;
let get_object_reader = <Self as crate::storage_api_contracts::ObjectIO>::get_object_reader(
self,
bucket,
object,
None,
HeaderMap::new(),
opts,
)
.await?;
// Stream to sink to avoid loading entire object into memory during verification
let mut reader = get_object_reader.stream;
tokio::io::copy(&mut reader, &mut tokio::io::sink()).await?;
+1 -1
View File
@@ -15,7 +15,7 @@
use super::*;
use crate::layout::pool_space::{ServerPoolsAvailableSpace, build_server_pools_available_space};
use crate::runtime_sources;
use rustfs_storage_api::{NamespaceLocking as _, ObjectOperations as _, StorageAdminApi};
use crate::storage_api_contracts::{NamespaceLocking as _, ObjectOperations as _, StorageAdminApi};
pub(in crate::store) mod support;
use support::{
LatestObjectInfoCandidate, PoolErr, PoolObjInfo, RebalanceDeletePoolResult, pool_lookup_not_found_error,
+4 -5
View File
@@ -24,6 +24,10 @@ use crate::error::{
use crate::object_api::{ObjectInfo, ObjectOptions};
use crate::set_disk::SetDisks;
use crate::sets::Sets;
use crate::storage_api_contracts::{
ListObjectsInfo as StorageListObjectsInfo, ObjectOperations as _, StorageListObjectVersionsInfo, StorageListObjectsV2Info,
StorageObjectInfoOrErr, StorageWalkOptions, VersionMarker, WalkVersionsSortOrder,
};
use crate::store::ECStore;
use crate::store_utils::is_reserved_or_invalid_bucket;
use futures::future::join_all;
@@ -32,11 +36,6 @@ use rustfs_filemeta::{
MetaCacheEntries, MetaCacheEntriesSorted, MetaCacheEntriesSortedResult, MetaCacheEntry, MetadataResolutionParams,
merge_file_meta_versions,
};
use rustfs_storage_api::{
ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsInfo as StorageListObjectsInfo,
ListObjectsV2Info as StorageListObjectsV2Info, ObjectInfoOrErr as StorageObjectInfoOrErr, ObjectOperations as _,
VersionMarker, WalkOptions as StorageWalkOptions, WalkVersionsSortOrder,
};
use rustfs_utils::path::{self, SLASH_SEPARATOR, base_dir_from_prefix};
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
+1 -1
View File
@@ -38,6 +38,7 @@ use tracing::{debug, error, info, warn};
use crate::client::admin_handler_utils::AdminError;
use crate::error::{Error, Result, StorageError};
use crate::storage_api_contracts::{DeletedObject, HTTPRangeSpec, ObjectIO, ObjectOperations, ObjectToDelete};
use crate::tier::{
tier_admin::TierCreds,
tier_config::{TierConfig, TierType},
@@ -54,7 +55,6 @@ use crate::{
};
use rustfs_filemeta::FileInfo;
use rustfs_rio::HashReader;
use rustfs_storage_api::{DeletedObject, HTTPRangeSpec, ObjectIO, ObjectOperations, ObjectToDelete};
use rustfs_utils::path::{SLASH_SEPARATOR, path_join};
use s3s::S3ErrorCode;
@@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
mod storage_api;
use rustfs_common::heal_channel::HealOpts;
use rustfs_ecstore::api::object::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
use rustfs_ecstore::api::{disk::DiskStore, error::Error, storage::ECStore};
use rustfs_filemeta::FileInfo;
use rustfs_lock::NamespaceLockWrapper;
use rustfs_madmin::heal_commands::HealResultItem;
use rustfs_storage_api::{
CompletePart, DeletedObject, HTTPRangeSpec, HealOperations as StorageHealOperations, ListMultipartsInfo,
ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsV2Info as StorageListObjectsV2Info, ListPartsInfo,
MultipartInfo, MultipartOperations as StorageMultipartOperations, MultipartUploadResult,
NamespaceLocking as StorageNamespaceLocking, ObjectIO as StorageObjectIO, ObjectInfoOrErr as StorageObjectInfoOrErr,
ObjectOperations as StorageObjectOperations, ObjectToDelete, PartInfo, StorageAdminApi, WalkOptions as StorageWalkOptions,
use storage_api::{
CompletePart, DeletedObject, DiskStore, ECStore, Error, GetObjectReader, HTTPRangeSpec, ListMultipartsInfo, ListPartsInfo,
MultipartInfo, MultipartUploadResult, ObjectInfo, ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, StorageAdminApi,
StorageHealOperations, StorageListObjectVersionsInfo, StorageListObjectsV2Info, StorageListOperations,
StorageMultipartOperations, StorageNamespaceLocking, StorageObjectIO, StorageObjectInfoOrErr, StorageObjectOperations,
StorageWalkOptions,
};
use tokio_util::sync::CancellationToken;
@@ -82,7 +82,7 @@ where
fn storage_list_operations_type_name<T>() -> &'static str
where
T: rustfs_storage_api::ListOperations<
T: StorageListOperations<
Error = Error,
ListObjectsV2Info = ListObjectsV2Info,
ListObjectVersionsInfo = ListObjectVersionsInfo,
@@ -27,12 +27,12 @@
//!
//! For MinIO data: RUSTFS_LEGACY_TEST_ROOT=/path/to/minio (disk "test" and .minio.sys auto-detected).
use rustfs_ecstore::api::bitrot::create_bitrot_reader;
use rustfs_ecstore::api::disk::endpoint::Endpoint;
use rustfs_ecstore::api::disk::{DiskOption, STORAGE_FORMAT_FILE, new_disk};
mod storage_api;
use rustfs_filemeta::{FileInfoOpts, get_file_info};
use rustfs_utils::HashAlgorithm;
use std::path::PathBuf;
use storage_api::{DiskOption, Endpoint, STORAGE_FORMAT_FILE, create_bitrot_reader, new_disk};
use tokio::fs;
fn workspace_root() -> PathBuf {
@@ -4,14 +4,14 @@ use std::fs;
use std::io::Cursor;
use std::path::{Path, PathBuf};
use rustfs_ecstore::api::bitrot::create_bitrot_reader;
use rustfs_ecstore::api::disk::endpoint::Endpoint;
use rustfs_ecstore::api::disk::{DiskAPI as _, DiskOption, new_disk};
use rustfs_ecstore::api::erasure::Erasure;
use rustfs_ecstore::api::object::{GetObjectReader, ObjectInfo, ObjectOptions};
mod storage_api;
use rustfs_filemeta::{FileInfo, FileInfoOpts, get_file_info};
use serde::Deserialize;
use sha2::{Digest, Sha256};
use storage_api::{
DiskAPI as _, DiskOption, Endpoint, Erasure, GetObjectReader, ObjectInfo, ObjectOptions, create_bitrot_reader, new_disk,
};
use temp_env::async_with_vars;
use tokio::io::{AsyncReadExt, AsyncWrite};
+15
View File
@@ -0,0 +1,15 @@
#![allow(unused_imports)]
pub(crate) use rustfs_ecstore::api::bitrot::create_bitrot_reader;
pub(crate) use rustfs_ecstore::api::disk::{DiskAPI, DiskOption, DiskStore, STORAGE_FORMAT_FILE, endpoint::Endpoint, new_disk};
pub(crate) use rustfs_ecstore::api::erasure::Erasure;
pub(crate) use rustfs_ecstore::api::object::{GetObjectReader, ObjectInfo, ObjectOptions, PutObjReader};
pub(crate) use rustfs_ecstore::api::{error::Error, storage::ECStore};
pub(crate) use rustfs_storage_api::{
CompletePart, DeletedObject, HTTPRangeSpec, HealOperations as StorageHealOperations, ListMultipartsInfo,
ListObjectVersionsInfo as StorageListObjectVersionsInfo, ListObjectsV2Info as StorageListObjectsV2Info,
ListOperations as StorageListOperations, ListPartsInfo, MultipartInfo, MultipartOperations as StorageMultipartOperations,
MultipartUploadResult, NamespaceLocking as StorageNamespaceLocking, ObjectIO as StorageObjectIO,
ObjectInfoOrErr as StorageObjectInfoOrErr, ObjectOperations as StorageObjectOperations, ObjectToDelete, PartInfo,
StorageAdminApi, WalkOptions as StorageWalkOptions,
};
+2 -2
View File
@@ -35,8 +35,8 @@ pub(crate) type IamEcstoreError = EcstoreErrorType;
pub(crate) type IamStorageError = EcstoreStorageError;
pub(crate) type IamStorageResult<T> = EcstoreResultType<T>;
pub(crate) type IamStore = EcstoreStore;
pub(crate) type IamConfigObjectInfo = <IamStore as rustfs_storage_api::ObjectOperations>::ObjectInfo;
pub(crate) type IamConfigObjectOptions = <IamStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
pub(crate) type IamConfigObjectInfo = <IamStore as ObjectOperations>::ObjectInfo;
pub(crate) type IamConfigObjectOptions = <IamStore as ObjectOperations>::ObjectOptions;
pub(crate) type IamNotificationSys = EcstoreNotificationSys;
pub(crate) type IamEcstoreNotificationPeerErr = EcstoreNotificationPeerErr;
+4 -4
View File
@@ -26,10 +26,10 @@ pub(crate) use rustfs_storage_api::{
ObjectOperations,
};
pub type SwiftGetObjectReader = <SwiftStore as rustfs_storage_api::ObjectIO>::GetObjectReader;
pub type SwiftObjectInfo = <SwiftStore as rustfs_storage_api::ObjectOperations>::ObjectInfo;
pub type SwiftObjectOptions = <SwiftStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
pub type SwiftPutObjReader = <SwiftStore as rustfs_storage_api::ObjectIO>::PutObjectReader;
pub type SwiftGetObjectReader = <SwiftStore as ObjectIO>::GetObjectReader;
pub type SwiftObjectInfo = <SwiftStore as ObjectOperations>::ObjectInfo;
pub type SwiftObjectOptions = <SwiftStore as ObjectOperations>::ObjectOptions;
pub type SwiftPutObjReader = <SwiftStore as ObjectIO>::PutObjectReader;
pub(crate) async fn get_swift_bucket_metadata(bucket: &str) -> SwiftStorageResult<Arc<SwiftBucketMetadata>> {
get_swift_bucket_metadata_from_backend(bucket).await
+3 -3
View File
@@ -25,9 +25,9 @@ pub(crate) use rustfs_ecstore::api::set_disk::DEFAULT_READ_BUFFER_SIZE as SELECT
pub(crate) use rustfs_ecstore::api::storage::ECStore as SelectStore;
pub(crate) use rustfs_storage_api::{HTTPRangeSpec, ObjectIO, ObjectOperations};
pub(crate) type SelectGetObjectReader = <SelectStore as rustfs_storage_api::ObjectIO>::GetObjectReader;
pub(crate) type SelectObjectInfo = <SelectStore as rustfs_storage_api::ObjectOperations>::ObjectInfo;
pub(crate) type SelectObjectOptions = <SelectStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
pub(crate) type SelectGetObjectReader = <SelectStore as ObjectIO>::GetObjectReader;
pub(crate) type SelectObjectInfo = <SelectStore as ObjectOperations>::ObjectInfo;
pub(crate) type SelectObjectOptions = <SelectStore as ObjectOperations>::ObjectOptions;
pub(crate) fn resolve_select_object_store_handle() -> Option<Arc<SelectStore>> {
resolve_select_object_store_handle_from_backend()
+79 -8
View File
@@ -5,9 +5,9 @@ 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-storage-owner-import-boundaries`
- 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/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205/API-206/API-207/API-208/API-209/API-210/API-211/API-212/API-213/API-214/API-215/API-216/API-217/API-218/API-219/API-220/API-221/API-222/API-223/API-224`.
- Based on: API-224 branch; branch routes storage owner submodule storage contract imports through the owner-local `storage_api` boundary.
- Branch: `overtrue/arch-ecstore-storage-api-import-boundaries`
- 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/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161/API-162/API-163/API-164/API-165/API-166/API-167/API-168/API-169/API-170/API-171/API-172/API-173/API-174/API-175/API-176/API-177/API-178/API-179/API-180/API-181/API-182/API-183/API-184/API-185/API-186/API-187/API-188/API-189/API-190/API-191/API-192/API-193/API-194/API-195/API-196/API-197/API-198/API-199/API-200/API-201/API-202/API-203/API-204/API-205/API-206/API-207/API-208/API-209/API-210/API-211/API-212/API-213/API-214/API-215/API-216/API-217/API-218/API-219/API-220/API-221/API-222/API-223/API-224/API-225`.
- Based on: API-225 branch; branch routes ECStore internal storage contract imports through the owner-local `storage_api_contracts` boundary.
- PR type for this branch: `consumer-migration`
- Runtime behavior changes: none.
- Rust code changes: route replication pool, outbound TLS generation, runtime
@@ -61,8 +61,10 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
boundaries, and remaining IAM, notify, OBS metrics, Swift, S3 Select, e2e,
and fuzz ECStore/storage contract imports through local `storage_api`
boundaries, plus storage owner root ECStore facade and storage contract
aggregation through `rustfs/src/storage/storage_api.rs`, and storage owner
submodule storage contract imports through the same owner-local boundary.
aggregation through `rustfs/src/storage/storage_api.rs`, storage owner
submodule storage contract imports through the same owner-local boundary,
and ECStore internal storage contract imports through the owner-local
`storage_api_contracts` boundary.
- CI/script changes: lock completed owner and test/fuzz boundaries against
bare/glob imports, scattered raw ECStore facade subpaths, and startup
runtime/root-server/table/S3/app shared/app bucket/app ECStore/admin facade
@@ -72,8 +74,8 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
event-bridge thin module regressions, plus IAM runtime-source bypasses;
accept the reviewed AppContext resolver reverse dependencies in the layer
baseline, and block direct admin AppContext resolver consumers outside the
admin runtime-source boundary, block root, app usecase, and storage direct AppContext resolver consumers outside their runtime-source boundaries, catch grouped AppContext imports, reject app usecase storage wildcard imports, reject app-layer S3 DTO and ECFS wildcard imports, narrow the object-usecase ECFS layer baseline entry to `FS`, reject direct storage S3 API helper imports from app usecase files, reject direct storage helper imports from app select/usecase files, reject completed app/admin storage helper bypasses, reject app usecase bypasses for migrated storage IO/compression/set-disk helpers, reject app usecase/test bypasses for migrated storage error, ETag, and storage-class helpers, reject app root bucket owner facade bypasses from migrated app consumers, reject app/admin runtime/data-usage root facade regressions, reject admin root storage facade regressions from migrated admin consumers, reject root/server/startup direct storage facade regressions from migrated outer consumers, reject root/server/startup direct storage contract imports from migrated outer consumers, reject app/admin direct storage contract imports from migrated owner consumers, keep app S3 helper imports routed through `app::storage_api`, reject scanner/heal direct ECStore or storage contract imports outside their local `storage_api` boundaries, and reject external runtime/test/fuzz ECStore or storage contract imports outside their local `storage_api` boundaries, and reject storage owner direct ECStore/storage-api imports outside the owner-local `storage_api` boundary.
- Docs changes: record the API-136 through API-225 owner facade and lifecycle
admin runtime-source boundary, block root, app usecase, and storage direct AppContext resolver consumers outside their runtime-source boundaries, catch grouped AppContext imports, reject app usecase storage wildcard imports, reject app-layer S3 DTO and ECFS wildcard imports, narrow the object-usecase ECFS layer baseline entry to `FS`, reject direct storage S3 API helper imports from app usecase files, reject direct storage helper imports from app select/usecase files, reject completed app/admin storage helper bypasses, reject app usecase bypasses for migrated storage IO/compression/set-disk helpers, reject app usecase/test bypasses for migrated storage error, ETag, and storage-class helpers, reject app root bucket owner facade bypasses from migrated app consumers, reject app/admin runtime/data-usage root facade regressions, reject admin root storage facade regressions from migrated admin consumers, reject root/server/startup direct storage facade regressions from migrated outer consumers, reject root/server/startup direct storage contract imports from migrated outer consumers, reject app/admin direct storage contract imports from migrated owner consumers, keep app S3 helper imports routed through `app::storage_api`, reject scanner/heal direct ECStore or storage contract imports outside their local `storage_api` boundaries, reject external runtime/test/fuzz ECStore or storage contract imports outside their local `storage_api` boundaries, reject storage owner direct ECStore/storage-api imports outside the owner-local `storage_api` boundary, and reject ECStore internal direct storage-api imports outside the owner-local `storage_api_contracts` boundary.
- Docs changes: record the API-136 through API-226 owner facade and lifecycle
runtime-source cleanup.
## Phase 0 Tasks
@@ -5279,14 +5281,83 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
and layer guards, diff hygiene, residual storage owner import scan, Rust
risk scan, fast PR gate, and full PR gate before PR.
- [x] `API-226` Route ECStore storage contracts through storage_api_contracts boundary.
- Do: expose ECStore-used storage contract DTOs and traits from
`crates/ecstore/src/storage_api_contracts.rs`, then route ECStore internal
modules through that owner-local boundary instead of direct
`rustfs_storage_api` imports.
- Acceptance: ECStore internal modules no longer import
`rustfs_storage_api` directly, and migration rules reject direct ECStore
storage-api bypasses outside the reviewed owner-local boundary.
- Must preserve: ECStore object/list/multipart/heal/admin trait impls,
set-disk and sets storage behavior, lifecycle/tier/replication DTO usage,
config storage locking, peer S3 client bucket operations, range helpers,
and error-code mapping.
- Verification: focused ECStore compile coverage, formatting, migration and
layer guards, diff hygiene, residual ECStore storage contract scan, Rust
risk scan, fast PR gate, and full PR gate before PR.
- [x] `API-227` Normalize local storage-api boundary contract aliases.
- Do: replace raw fully qualified `rustfs_storage_api::...` paths inside
completed RustFS/app/admin/storage and external crate `storage_api`
boundaries with imported local aliases, and guard against regressions.
- Acceptance: completed local storage-api boundary files no longer keep raw
fully qualified storage contract paths internally; direct imports remain
only at the boundary edge.
- Must preserve: RustFS storage owner peer S3 bucket operations, topology
snapshots, app lifecycle/replication helper signatures, IAM config object
contract aliases, Swift object aliases, and S3 Select object aliases.
- Verification: RustFS test compile coverage, explicit IAM/S3 Select/Swift
compile coverage, formatting, migration and layer guards, diff hygiene,
residual raw-path scan, Rust risk scan, and full PR gate before PR.
- [x] `API-228` Route ECStore integration test API imports through a test boundary.
- Do: add `crates/ecstore/tests/storage_api.rs` as the integration-test
boundary for ECStore and storage-api symbols, then route ECStore contract,
MinIO fixture, and legacy bitrot tests through it.
- Acceptance: ECStore integration tests no longer import
`rustfs_ecstore::api` or `rustfs_storage_api` directly outside the
reviewed test boundary, and migration rules reject new bypasses.
- Must preserve: ECStore storage-api compatibility proofs, MinIO-generated
rio-v2 fixture reads, legacy bitrot reads, endpoint/disk creation, object
reader aliases, and storage contract trait bounds.
- Verification: focused ECStore integration tests, formatting, migration and
layer guards, diff hygiene, residual ECStore test API scan, Rust risk scan,
and full PR gate before PR.
- [x] `API-229` Route ECStore bench API imports through a bench boundary.
- Do: add `crates/ecstore/benches/storage_api/mod.rs` as the benchmark boundary
for ECStore erasure symbols, then route all ECStore benchmark facade
imports through it.
- Acceptance: ECStore benchmark crates no longer import
`rustfs_ecstore::api` directly outside the reviewed bench boundary, and
migration rules reject new bypasses.
- Must preserve: erasure SIMD, comparison, streaming decode, and single-block
non-inline benchmark behavior and direct erasure symbol usage.
- Verification: focused ECStore bench compile coverage, formatting,
migration and layer guards, diff hygiene, residual ECStore bench API scan,
Rust risk scan, and full PR gate before PR.
## Next PRs
1. `consumer-migration`: continue larger owner/external crate storage-boundary batches after API-225.
1. `consumer-migration`: continue larger owner/external crate storage-boundary batches after API-229.
## Pre-Push Review Log
| Expert | Status | Notes |
|---|---|---|
| Quality/architecture | pass | API-229 routes ECStore benchmark erasure facade imports through a bench-local storage_api boundary. |
| Migration preservation | pass | Erasure SIMD, comparison, streaming decode, and single-block non-inline benchmarks keep the same erasure implementations and behavior. |
| Testing/verification | pass | Focused ECStore bench compile coverage, migration guard, residual bench API scan, Rust risk scan, formatting, and diff hygiene passed; layer guard and full PR gate are planned before PR. |
| Quality/architecture | pass | API-228 routes ECStore integration-test ECStore/storage-api symbols through a test-local storage_api boundary. |
| Migration preservation | pass | Contract proofs, MinIO rio-v2 fixture reads, legacy bitrot reads, disk setup, object reader aliases, and trait bounds keep the same ECStore/storage-api implementations. |
| Testing/verification | pass | Focused ECStore integration tests, migration guard, residual ECStore test API scan, Rust risk scan, formatting, and diff hygiene passed; layer guard and full PR gate are planned before PR. |
| Quality/architecture | pass | API-227 normalizes completed local storage-api boundary internals to use imported local aliases instead of raw fully qualified contract paths. |
| Migration preservation | pass | Storage owner peer S3 operations, topology snapshots, app lifecycle/replication helpers, IAM config aliases, Swift aliases, and S3 Select aliases keep the same storage-api contracts. |
| Testing/verification | pass | RustFS test compile coverage, explicit IAM/S3 Select/Swift compile coverage, migration/layer guards, residual raw-path scan, formatting, and diff hygiene passed; full PR gate is planned before PR. |
| Quality/architecture | pass | API-226 routes ECStore internal storage contract imports through the owner-local storage_api_contracts boundary. |
| Migration preservation | pass | Object/list/multipart/heal/admin trait impls, set-disk/sets behavior, lifecycle/tier/replication DTOs, config storage, peer S3 client, range helpers, and error mappings keep the same storage contracts. |
| Testing/verification | pass | Focused ECStore/RustFS compile coverage, ECStore lib tests, migration/layer guards, residual import scan, Rust risk scan, formatting, and diff hygiene passed; full PR gate is planned before PR. |
| Quality/architecture | pass | API-225 routes remaining storage owner submodule storage contract imports through the owner-local storage_api boundary. |
| Migration preservation | pass | S3 handlers, options, access checks, prefix probing, RPC, and S3 API helper tests keep the same storage contract implementations. |
| Testing/verification | pass | Focused RustFS test compile coverage, migration guard, residual import scan, Rust risk scan, formatting, layer guard, fast PR gate, and full PR gate passed before PR. |
+4 -3
View File
@@ -17,6 +17,7 @@
pub(crate) use crate::storage::ECStore;
#[cfg(test)]
pub(crate) use crate::storage::{Endpoint, Endpoints, PoolEndpoints};
pub(crate) use rustfs_storage_api::{ObjectToDelete, TransitionedObject};
pub(crate) type EndpointServerPools = crate::storage::EndpointServerPools;
#[cfg(test)]
@@ -347,7 +348,7 @@ pub(crate) mod bucket {
version_id: Option<uuid::Uuid>,
versioned: bool,
suspended: bool,
transitioned: &rustfs_storage_api::TransitionedObject,
transitioned: &crate::app::storage_api::TransitionedObject,
) -> Option<Jentry> {
crate::storage::ecstore_bucket::lifecycle::tier_sweeper::transitioned_delete_journal_entry(
version_id,
@@ -358,7 +359,7 @@ pub(crate) mod bucket {
}
pub(crate) fn transitioned_force_delete_journal_entry(
transitioned: &rustfs_storage_api::TransitionedObject,
transitioned: &crate::app::storage_api::TransitionedObject,
) -> Option<Jentry> {
crate::storage::ecstore_bucket::lifecycle::tier_sweeper::transitioned_force_delete_journal_entry(transitioned)
}
@@ -543,7 +544,7 @@ pub(crate) mod bucket {
pub(crate) async fn check_replicate_delete(
bucket: &str,
dobj: &rustfs_storage_api::ObjectToDelete,
dobj: &crate::app::storage_api::ObjectToDelete,
oi: &crate::storage::StorageObjectInfo,
del_opts: &crate::storage::StorageObjectOptions,
gerr: Option<String>,
+21 -28
View File
@@ -17,18 +17,19 @@
use std::sync::Arc;
pub(crate) use rustfs_storage_api::{
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, HTTPPreconditions, HTTPRangeSpec, ListMultipartsInfo,
ListObjectVersionsInfo, ListObjectsV2Info, ListOperations, ListPartsInfo, MakeBucketOptions, ObjectLockRetentionOptions,
ObjectOperations, StorageAdminApi,
BucketInfo, BucketOperations, BucketOptions, DeleteBucketOptions, DeletedObject, DiskCapabilities, HTTPPreconditions,
HTTPRangeSpec, ListMultipartsInfo, ListObjectVersionsInfo, ListObjectsV2Info, ListOperations, ListPartsInfo,
MakeBucketOptions, ObjectIO, ObjectLockRetentionOptions, ObjectOperations, ObjectToDelete, StorageAdminApi,
TopologyCapabilities, TopologySnapshot,
};
#[cfg(test)]
pub(crate) use rustfs_storage_api::{MultipartInfo, PartInfo};
pub(crate) type StorageDeletedObject = rustfs_storage_api::DeletedObject;
pub(crate) type StorageDeletedObject = DeletedObject;
pub(crate) type StorageGetObjectReader = super::GetObjectReader;
pub(crate) type StorageObjectInfo = super::ObjectInfo;
pub(crate) type StorageObjectOptions = super::ObjectOptions;
pub(crate) type StorageObjectToDelete = rustfs_storage_api::ObjectToDelete;
pub(crate) type StorageObjectToDelete = ObjectToDelete;
pub(crate) type StoragePutObjReader = super::PutObjReader;
pub(crate) mod ecstore_admin {
@@ -623,14 +624,10 @@ pub(crate) trait StoragePeerS3ClientExt {
bucket: &str,
opts: &rustfs_common::heal_channel::HealOpts,
) -> DiskResult<rustfs_madmin::heal_commands::HealResultItem>;
async fn make_bucket(&self, bucket: &str, opts: &rustfs_storage_api::MakeBucketOptions) -> DiskResult<()>;
async fn list_bucket(&self, opts: &rustfs_storage_api::BucketOptions) -> DiskResult<Vec<rustfs_storage_api::BucketInfo>>;
async fn delete_bucket(&self, bucket: &str, opts: &rustfs_storage_api::DeleteBucketOptions) -> DiskResult<()>;
async fn get_bucket_info(
&self,
bucket: &str,
opts: &rustfs_storage_api::BucketOptions,
) -> DiskResult<rustfs_storage_api::BucketInfo>;
async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> DiskResult<()>;
async fn list_bucket(&self, opts: &BucketOptions) -> DiskResult<Vec<BucketInfo>>;
async fn delete_bucket(&self, bucket: &str, opts: &DeleteBucketOptions) -> DiskResult<()>;
async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> DiskResult<BucketInfo>;
}
impl StoragePeerS3ClientExt for LocalPeerS3Client {
@@ -642,23 +639,19 @@ impl StoragePeerS3ClientExt for LocalPeerS3Client {
ecstore_rpc::PeerS3Client::heal_bucket(self, bucket, opts).await
}
async fn make_bucket(&self, bucket: &str, opts: &rustfs_storage_api::MakeBucketOptions) -> DiskResult<()> {
async fn make_bucket(&self, bucket: &str, opts: &MakeBucketOptions) -> DiskResult<()> {
ecstore_rpc::PeerS3Client::make_bucket(self, bucket, opts).await
}
async fn list_bucket(&self, opts: &rustfs_storage_api::BucketOptions) -> DiskResult<Vec<rustfs_storage_api::BucketInfo>> {
async fn list_bucket(&self, opts: &BucketOptions) -> DiskResult<Vec<BucketInfo>> {
ecstore_rpc::PeerS3Client::list_bucket(self, opts).await
}
async fn delete_bucket(&self, bucket: &str, opts: &rustfs_storage_api::DeleteBucketOptions) -> DiskResult<()> {
async fn delete_bucket(&self, bucket: &str, opts: &DeleteBucketOptions) -> DiskResult<()> {
ecstore_rpc::PeerS3Client::delete_bucket(self, bucket, opts).await
}
async fn get_bucket_info(
&self,
bucket: &str,
opts: &rustfs_storage_api::BucketOptions,
) -> DiskResult<rustfs_storage_api::BucketInfo> {
async fn get_bucket_info(&self, bucket: &str, opts: &BucketOptions) -> DiskResult<BucketInfo> {
ecstore_rpc::PeerS3Client::get_bucket_info(self, bucket, opts).await
}
}
@@ -913,9 +906,9 @@ where
pub(crate) fn topology_snapshot_from_endpoint_pools_with_capabilities(
endpoint_pools: &EndpointServerPools,
capabilities: rustfs_storage_api::TopologyCapabilities,
disk_capabilities: rustfs_storage_api::DiskCapabilities,
) -> rustfs_storage_api::TopologySnapshot {
capabilities: TopologyCapabilities,
disk_capabilities: DiskCapabilities,
) -> TopologySnapshot {
ecstore_cluster::topology_snapshot_from_endpoint_pools_with_capabilities(endpoint_pools, capabilities, disk_capabilities)
}
@@ -953,7 +946,7 @@ impl StorageVersioningConfigExt for s3s::dto::VersioningConfiguration {
}
}
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 ObjectOptions = <ECStore as rustfs_storage_api::ObjectOperations>::ObjectOptions;
pub(crate) type PutObjReader = <ECStore as rustfs_storage_api::ObjectIO>::PutObjectReader;
pub(crate) type GetObjectReader = <ECStore as ObjectIO>::GetObjectReader;
pub(crate) type ObjectInfo = <ECStore as ObjectOperations>::ObjectInfo;
pub(crate) type ObjectOptions = <ECStore as ObjectOperations>::ObjectOptions;
pub(crate) type PutObjReader = <ECStore as ObjectIO>::PutObjectReader;
+61 -2
View File
@@ -64,6 +64,9 @@ ECSTORE_OBJECT_API_EXTERNAL_ALIAS_ACTUAL_FILE="${TMP_DIR}/ecstore_object_api_ext
ECSTORE_OBJECT_API_EXTERNAL_ALIAS_DIFF_FILE="${TMP_DIR}/ecstore_object_api_external_alias_diff.txt"
ECSTORE_OBJECT_API_UNAPPROVED_NAME_HITS_FILE="${TMP_DIR}/ecstore_object_api_unapproved_name_hits.txt"
STARTUP_PUBLIC_SHIM_HITS_FILE="${TMP_DIR}/startup_public_shim_hits.txt"
ECSTORE_TEST_DIRECT_API_HITS_FILE="${TMP_DIR}/ecstore_test_direct_api_hits.txt"
ECSTORE_BENCH_DIRECT_API_HITS_FILE="${TMP_DIR}/ecstore_bench_direct_api_hits.txt"
LOCAL_STORAGE_API_RAW_CONTRACT_PATH_HITS_FILE="${TMP_DIR}/local_storage_api_raw_contract_path_hits.txt"
STORE_API_DELETE_DTO_REEXPORTS_FILE="${TMP_DIR}/store_api_delete_dto_reexports.txt"
STORE_API_DELETE_DTO_INTERNAL_HITS_FILE="${TMP_DIR}/store_api_delete_dto_internal_hits.txt"
STORE_API_LIFECYCLE_HELPER_DEFINITION_HITS_FILE="${TMP_DIR}/store_api_lifecycle_helper_definition_hits.txt"
@@ -71,6 +74,7 @@ STORE_API_LIFECYCLE_HELPER_OLD_CONSUMER_HITS_FILE="${TMP_DIR}/store_api_lifecycl
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"
ECSTORE_DIRECT_STORAGE_API_SOURCE_HITS_FILE="${TMP_DIR}/ecstore_direct_storage_api_source_hits.txt"
DIRECT_ECSTORE_IMPORT_HITS_FILE="${TMP_DIR}/direct_ecstore_import_hits.txt"
ECSTORE_API_FACADE_REQUIRED_HITS_FILE="${TMP_DIR}/ecstore_api_facade_required_hits.txt"
ECSTORE_PUBLIC_FACADE_BYPASS_HITS_FILE="${TMP_DIR}/ecstore_public_facade_bypass_hits.txt"
@@ -632,11 +636,11 @@ fi
require_source_line \
"crates/ecstore/src/bucket/lifecycle/core.rs" \
"pub use rustfs_storage_api::ExpirationOptions;" \
"pub use crate::storage_api_contracts::ExpirationOptions;" \
"ECStore ExpirationOptions compatibility re-export"
require_source_line \
"crates/ecstore/src/bucket/lifecycle/bucket_lifecycle_ops.rs" \
"pub use rustfs_storage_api::TransitionedObject;" \
"pub use crate::storage_api_contracts::TransitionedObject;" \
"ECStore TransitionedObject compatibility re-export"
(
@@ -659,6 +663,42 @@ if [[ -s "$STORE_API_EXTERNAL_LIST_CONSUMER_HITS_FILE" ]]; then
report_failure "external list response consumers must use rustfs-storage-api contracts: $(paste -sd '; ' "$STORE_API_EXTERNAL_LIST_CONSUMER_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename '^use rustfs_storage_api|^pub use rustfs_storage_api|rustfs_storage_api::' \
crates/ecstore/src \
--glob '*.rs' \
--glob '!storage_api_contracts.rs' || true
) >"$ECSTORE_DIRECT_STORAGE_API_SOURCE_HITS_FILE"
if [[ -s "$ECSTORE_DIRECT_STORAGE_API_SOURCE_HITS_FILE" ]]; then
report_failure "ECStore modules must route storage-api symbols through crates/ecstore/src/storage_api_contracts.rs: $(paste -sd '; ' "$ECSTORE_DIRECT_STORAGE_API_SOURCE_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'rustfs_ecstore::api::|rustfs_storage_api' \
crates/ecstore/tests \
--glob '*.rs' |
rg -v '^crates/ecstore/tests/storage_api\.rs:' || true
) >"$ECSTORE_TEST_DIRECT_API_HITS_FILE"
if [[ -s "$ECSTORE_TEST_DIRECT_API_HITS_FILE" ]]; then
report_failure "ECStore integration tests must route ECStore and storage-api symbols through crates/ecstore/tests/storage_api.rs: $(paste -sd '; ' "$ECSTORE_TEST_DIRECT_API_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'rustfs_ecstore::api::|rustfs_storage_api' \
crates/ecstore/benches \
--glob '*.rs' |
rg -v '^crates/ecstore/benches/storage_api/mod\.rs:' || true
) >"$ECSTORE_BENCH_DIRECT_API_HITS_FILE"
if [[ -s "$ECSTORE_BENCH_DIRECT_API_HITS_FILE" ]]; then
report_failure "ECStore benches must route ECStore and storage-api symbols through crates/ecstore/benches/storage_api/mod.rs: $(paste -sd '; ' "$ECSTORE_BENCH_DIRECT_API_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
find crates/ecstore/src -type f -name '*.rs' -print0 |
@@ -981,6 +1021,25 @@ if [[ -s "$RUSTFS_STORAGE_OWNER_DIRECT_STORAGE_SOURCE_HITS_FILE" ]]; then
report_failure "RustFS storage owner modules must route ECStore and storage-api symbols through rustfs/src/storage/storage_api.rs: $(paste -sd '; ' "$RUSTFS_STORAGE_OWNER_DIRECT_STORAGE_SOURCE_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --with-filename 'rustfs_storage_api::[A-Za-z_]' \
rustfs/src/storage_api.rs \
rustfs/src/app/storage_api.rs \
rustfs/src/admin/storage_api.rs \
rustfs/src/storage/storage_api.rs \
crates/iam/src/storage_api.rs \
crates/protocols/src/swift/storage_api.rs \
crates/s3select-api/src/storage_api.rs \
crates/scanner/src/storage_api.rs \
crates/obs/src/metrics/storage_api.rs \
crates/heal/src/heal/storage_api.rs || true
) >"$LOCAL_STORAGE_API_RAW_CONTRACT_PATH_HITS_FILE"
if [[ -s "$LOCAL_STORAGE_API_RAW_CONTRACT_PATH_HITS_FILE" ]]; then
report_failure "local storage_api boundaries must import storage-api contracts once and use local aliases internally: $(paste -sd '; ' "$LOCAL_STORAGE_API_RAW_CONTRACT_PATH_HITS_FILE")"
fi
(
cd "$ROOT_DIR"
rg -n --no-heading 'pub\(crate\)\s+use rustfs_ecstore::api::bucket::\{[^}]*\b(?:bandwidth|bucket_target_sys|lifecycle|metadata|metadata_sys|quota|replication|target|utils|versioning|versioning_sys)\b[^}]*\}\s*;|pub\(crate\)\s+use rustfs_ecstore::api::bucket::(?:bandwidth|bucket_target_sys|lifecycle|metadata|metadata_sys|quota|replication|target|utils|versioning|versioning_sys)\s*;|pub\(crate\)\s+use rustfs_ecstore::api::config::\{[^}]*\bstorageclass\b[^}]*\}\s*;|pub\(crate\)\s+use rustfs_ecstore::api::config::storageclass\s*;' \