diff --git a/ecstore/src/bucket/object_lock/objectlock.rs b/ecstore/src/bucket/object_lock/objectlock.rs index f6f67d333..fc53170cf 100644 --- a/ecstore/src/bucket/object_lock/objectlock.rs +++ b/ecstore/src/bucket/object_lock/objectlock.rs @@ -9,36 +9,36 @@ use s3s::header::{X_AMZ_OBJECT_LOCK_LEGAL_HOLD, X_AMZ_OBJECT_LOCK_MODE, X_AMZ_OB //const AMZ_OBJECTLOCK_MODE: &str = "X-Amz-Object-Lock-Mode"; //const AMZ_OBJECTLOCK_LEGALHOLD: &str = "X-Amz-Object-Lock-Legal-Hold"; -const ERR_MALFORMED_BUCKET_OBJECT_CONFIG: &str = "invalid bucket object lock config"; -const ERR_INVALID_RETENTION_DATE: &str = "date must be provided in ISO 8601 format"; -const ERR_PAST_OBJECTLOCK_RETAIN_DATE: &str = "the retain until date must be in the future"; -const ERR_UNKNOWN_WORMMODE_DIRECTIVE: &str = "unknown WORM mode directive"; -const ERR_OBJECTLOCK_MISSING_CONTENT_MD5: &str = - "content-MD5 HTTP header is required for Put Object requests with Object Lock parameters"; -const ERR_OBJECTLOCK_INVALID_HEADERS: &str = - "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied"; -const ERR_MALFORMED_XML: &str = "the XML you provided was not well-formed or did not validate against our published schema"; +// Commented out unused constants to avoid dead code warnings +// const ERR_MALFORMED_BUCKET_OBJECT_CONFIG: &str = "invalid bucket object lock config"; +// const ERR_INVALID_RETENTION_DATE: &str = "date must be provided in ISO 8601 format"; +// const ERR_PAST_OBJECTLOCK_RETAIN_DATE: &str = "the retain until date must be in the future"; +// const ERR_UNKNOWN_WORMMODE_DIRECTIVE: &str = "unknown WORM mode directive"; +// const ERR_OBJECTLOCK_MISSING_CONTENT_MD5: &str = +// "content-MD5 HTTP header is required for Put Object requests with Object Lock parameters"; +// const ERR_OBJECTLOCK_INVALID_HEADERS: &str = +// "x-amz-object-lock-retain-until-date and x-amz-object-lock-mode must both be supplied"; +// const ERR_MALFORMED_XML: &str = "the XML you provided was not well-formed or did not validate against our published schema"; pub fn utc_now_ntp() -> OffsetDateTime { - return OffsetDateTime::now_utc(); + OffsetDateTime::now_utc() } pub fn get_object_retention_meta(meta: HashMap) -> ObjectLockRetention { - let mode: ObjectLockRetentionMode; let mut retain_until_date: Date = Date::from(OffsetDateTime::UNIX_EPOCH); let mut mode_str = meta.get(X_AMZ_OBJECT_LOCK_MODE.as_str().to_lowercase().as_str()); if mode_str.is_none() { mode_str = Some(&meta[X_AMZ_OBJECT_LOCK_MODE.as_str()]); } - if let Some(mode_str) = mode_str { - mode = parse_ret_mode(mode_str.as_str()); + let mode = if let Some(mode_str) = mode_str { + parse_ret_mode(mode_str.as_str()) } else { return ObjectLockRetention { mode: None, retain_until_date: None, }; - } + }; let mut till_str = meta.get(X_AMZ_OBJECT_LOCK_RETAIN_UNTIL_DATE.as_str().to_lowercase().as_str()); if till_str.is_none() { @@ -70,29 +70,17 @@ pub fn get_object_legalhold_meta(meta: HashMap) -> ObjectLockLeg } pub fn parse_ret_mode(mode_str: &str) -> ObjectLockRetentionMode { - let mode; match mode_str.to_uppercase().as_str() { - "GOVERNANCE" => { - mode = ObjectLockRetentionMode::from_static(ObjectLockRetentionMode::GOVERNANCE); - } - "COMPLIANCE" => { - mode = ObjectLockRetentionMode::from_static(ObjectLockRetentionMode::COMPLIANCE); - } + "GOVERNANCE" => ObjectLockRetentionMode::from_static(ObjectLockRetentionMode::GOVERNANCE), + "COMPLIANCE" => ObjectLockRetentionMode::from_static(ObjectLockRetentionMode::COMPLIANCE), _ => unreachable!(), } - mode } pub fn parse_legalhold_status(hold_str: &str) -> ObjectLockLegalHoldStatus { - let st; match hold_str { - "ON" => { - st = ObjectLockLegalHoldStatus::from_static(ObjectLockLegalHoldStatus::ON); - } - "OFF" => { - st = ObjectLockLegalHoldStatus::from_static(ObjectLockLegalHoldStatus::OFF); - } + "ON" => ObjectLockLegalHoldStatus::from_static(ObjectLockLegalHoldStatus::ON), + "OFF" => ObjectLockLegalHoldStatus::from_static(ObjectLockLegalHoldStatus::OFF), _ => unreachable!(), } - st } diff --git a/ecstore/src/checksum.rs b/ecstore/src/checksum.rs index 66d4bcb97..2c3ed30ce 100644 --- a/ecstore/src/checksum.rs +++ b/ecstore/src/checksum.rs @@ -218,6 +218,7 @@ impl ChecksumMode { Ok(Checksum { checksum_type: self.clone(), r: h.sum().as_bytes().to_vec(), + computed: false, }) } @@ -227,9 +228,10 @@ impl ChecksumMode { } #[derive(Default)] -struct Checksum { +pub struct Checksum { checksum_type: ChecksumMode, r: Vec, + computed: bool, } impl Checksum { @@ -238,18 +240,24 @@ impl Checksum { return Checksum { checksum_type: t, r: b.to_vec(), + computed: false, }; } Checksum::default() } + #[allow(dead_code)] fn new_checksum_string(t: ChecksumMode, s: &str) -> Result { let b = match base64_decode(s.as_bytes()) { Ok(b) => b, Err(err) => return Err(std::io::Error::other(err.to_string())), }; if t.is_set() && b.len() == t.raw_byte_len() { - return Ok(Checksum { checksum_type: t, r: b }); + return Ok(Checksum { + checksum_type: t, + r: b, + computed: false, + }); } Ok(Checksum::default()) } @@ -265,6 +273,7 @@ impl Checksum { base64_encode(&self.r) } + #[allow(dead_code)] fn raw(&self) -> Option> { if !self.is_set() { return None; diff --git a/ecstore/src/client/api_get_object.rs b/ecstore/src/client/api_get_object.rs index 587203a44..dd86a66f8 100644 --- a/ecstore/src/client/api_get_object.rs +++ b/ecstore/src/client/api_get_object.rs @@ -61,7 +61,7 @@ impl TransitionClient { } #[derive(Default)] -struct GetRequest { +pub struct GetRequest { pub buffer: Vec, pub offset: i64, pub did_offset_change: bool, @@ -72,7 +72,7 @@ struct GetRequest { pub setting_object_info: bool, } -struct GetResponse { +pub struct GetResponse { pub size: i64, //pub error: error, pub did_read: bool, @@ -80,7 +80,7 @@ struct GetResponse { } #[derive(Default)] -struct Object { +pub struct Object { //pub reqch: chan<- getRequest, //pub resch: <-chan getResponse, //pub cancel: context.CancelFunc, diff --git a/ecstore/src/client/api_remove.rs b/ecstore/src/client/api_remove.rs index 551c51f0d..f62c08897 100644 --- a/ecstore/src/client/api_remove.rs +++ b/ecstore/src/client/api_remove.rs @@ -27,7 +27,7 @@ use crate::{ use reader::hasher::{sum_md5_base64, sum_sha256_hex}; use rustfs_utils::hash::EMPTY_STRING_SHA256_HASH; -struct RemoveBucketOptions { +pub struct RemoveBucketOptions { forced_elete: bool, } @@ -426,7 +426,7 @@ impl TransitionClient { } #[derive(Debug, Default)] -struct RemoveObjectError { +pub struct RemoveObjectError { object_name: String, version_id: String, err: Option, diff --git a/ecstore/src/client/credentials.rs b/ecstore/src/client/credentials.rs index 53f8dc7a0..e08e7d8d9 100644 --- a/ecstore/src/client/credentials.rs +++ b/ecstore/src/client/credentials.rs @@ -84,7 +84,7 @@ pub struct CredContext { pub endpoint: String, } -trait Provider { +pub trait Provider { fn retrieve(&self) -> Value; fn retrieve_with_cred_context(&self, _: CredContext) -> Value; fn is_expired(&self) -> bool; diff --git a/ecstore/src/client/transition_api.rs b/ecstore/src/client/transition_api.rs index ce74cd9d9..957c43d26 100644 --- a/ecstore/src/client/transition_api.rs +++ b/ecstore/src/client/transition_api.rs @@ -116,7 +116,7 @@ pub struct Options { } #[derive(Clone, Debug, Default, PartialEq, Eq)] -enum BucketLookupType { +pub enum BucketLookupType { #[default] BucketLookupAuto, BucketLookupDNS, diff --git a/ecstore/src/error.rs b/ecstore/src/error.rs index 89accdb74..1e22948da 100644 --- a/ecstore/src/error.rs +++ b/ecstore/src/error.rs @@ -386,9 +386,9 @@ impl Clone for StorageError { // StorageError::InsufficientReadQuorum => StorageError::InsufficientReadQuorum, // StorageError::InsufficientWriteQuorum => StorageError::InsufficientWriteQuorum, StorageError::DecommissionNotStarted => StorageError::DecommissionNotStarted, - StorageError::DecommissionAlreadyRunning => StorageError::DecommissionAlreadyRunning, - StorageError::DoneForNow => StorageError::DoneForNow, StorageError::InvalidPart(a, b, c) => StorageError::InvalidPart(*a, b.clone(), c.clone()), + StorageError::DoneForNow => StorageError::DoneForNow, + StorageError::DecommissionAlreadyRunning => StorageError::DecommissionAlreadyRunning, StorageError::ErasureReadQuorum => StorageError::ErasureReadQuorum, StorageError::ErasureWriteQuorum => StorageError::ErasureWriteQuorum, StorageError::NotFirstDisk => StorageError::NotFirstDisk, @@ -795,7 +795,7 @@ pub fn error_resp_to_object_err(err: ErrorResponse, params: Vec<&str>) -> std::i let mut bucket = ""; let mut object = ""; let mut version_id = ""; - if params.len() >= 1 { + if !params.is_empty() { bucket = params[0]; } if params.len() >= 2 { @@ -809,9 +809,7 @@ pub fn error_resp_to_object_err(err: ErrorResponse, params: Vec<&str>) -> std::i return std::io::Error::other(ObjectApiError::BackendDown(format!("{}", err))); } - let err_ = std::io::Error::other(err.to_string()); let r_err = err; - let mut err = err_; let bucket = bucket.to_string(); let object = object.to_string(); let version_id = version_id.to_string(); @@ -832,75 +830,61 @@ pub fn error_resp_to_object_err(err: ErrorResponse, params: Vec<&str>) -> std::i /*S3ErrorCode::BucketAlreadyOwnedByYou => { err = Error::from(StorageError::BucketAlreadyOwnedByYou); }*/ - S3ErrorCode::BucketNotEmpty => { - err = std::io::Error::other(StorageError::BucketNotEmpty("".to_string()).to_string()); - } + S3ErrorCode::BucketNotEmpty => std::io::Error::other(StorageError::BucketNotEmpty("".to_string()).to_string()), /*S3ErrorCode::NoSuchBucketPolicy => { err = Error::from(StorageError::BucketPolicyNotFound); }*/ /*S3ErrorCode::NoSuchLifecycleConfiguration => { err = Error::from(StorageError::BucketLifecycleNotFound); }*/ - S3ErrorCode::InvalidBucketName => { - err = std::io::Error::other(StorageError::BucketNameInvalid(bucket)); - } + S3ErrorCode::InvalidBucketName => std::io::Error::other(StorageError::BucketNameInvalid(bucket)), S3ErrorCode::InvalidPart => { - err = std::io::Error::other(StorageError::InvalidPart(0, bucket, object /* , version_id */)); - } - S3ErrorCode::NoSuchBucket => { - err = std::io::Error::other(StorageError::BucketNotFound(bucket)); + std::io::Error::other(StorageError::InvalidPart(0, bucket, object /* , version_id */)) } + S3ErrorCode::NoSuchBucket => std::io::Error::other(StorageError::BucketNotFound(bucket)), S3ErrorCode::NoSuchKey => { - if object != "" { - err = std::io::Error::other(StorageError::ObjectNotFound(bucket, object)); + if !object.is_empty() { + std::io::Error::other(StorageError::ObjectNotFound(bucket, object)) } else { - err = std::io::Error::other(StorageError::BucketNotFound(bucket)); + std::io::Error::other(StorageError::BucketNotFound(bucket)) } } S3ErrorCode::NoSuchVersion => { - if object != "" { - err = std::io::Error::other(StorageError::ObjectNotFound(bucket, object)); //, version_id); + if !object.is_empty() { + std::io::Error::other(StorageError::ObjectNotFound(bucket, object)) //, version_id); } else { - err = std::io::Error::other(StorageError::BucketNotFound(bucket)); + std::io::Error::other(StorageError::BucketNotFound(bucket)) } } /*S3ErrorCode::XRustFsInvalidObjectName => { err = Error::from(StorageError::ObjectNameInvalid(bucket, object)); }*/ - S3ErrorCode::AccessDenied => { - err = std::io::Error::other(StorageError::PrefixAccessDenied(bucket, object)); - } + S3ErrorCode::AccessDenied => std::io::Error::other(StorageError::PrefixAccessDenied(bucket, object)), /*S3ErrorCode::XAmzContentSHA256Mismatch => { err = hash.SHA256Mismatch{}; }*/ - S3ErrorCode::NoSuchUpload => { - err = std::io::Error::other(StorageError::InvalidUploadID(bucket, object, version_id)); - } + S3ErrorCode::NoSuchUpload => std::io::Error::other(StorageError::InvalidUploadID(bucket, object, version_id)), /*S3ErrorCode::EntityTooSmall => { err = std::io::Error::other(StorageError::PartTooSmall); }*/ /*S3ErrorCode::ReplicationPermissionCheck => { err = std::io::Error::other(StorageError::ReplicationPermissionCheck); }*/ - _ => { - err = std::io::Error::other("err"); - } + _ => std::io::Error::other("err"), } - - err } pub fn storage_to_object_err(err: Error, params: Vec<&str>) -> S3Error { let storage_err = &err; let mut bucket: String = "".to_string(); let mut object: String = "".to_string(); - if params.len() >= 1 { + if !params.is_empty() { bucket = params[0].to_string(); } if params.len() >= 2 { object = decode_dir_object(params[1]); } - return match storage_err { + match storage_err { /*StorageError::NotImplemented => s3_error!(NotImplemented), StorageError::InvalidArgument(bucket, object, version_id) => { s3_error!(InvalidArgument, "Invalid arguments provided for {}/{}-{}", bucket, object, version_id) @@ -982,7 +966,7 @@ pub fn storage_to_object_err(err: Error, params: Vec<&str>) -> S3Error { } StorageError::DoneForNow => s3_error!(InternalError, "DoneForNow"),*/ _ => s3s::S3Error::with_message(S3ErrorCode::Custom("err".into()), err.to_string()), - }; + } } #[cfg(test)] diff --git a/ecstore/src/heal/data_usage_cache.rs b/ecstore/src/heal/data_usage_cache.rs index 8e1ffe4d1..f5286ac7c 100644 --- a/ecstore/src/heal/data_usage_cache.rs +++ b/ecstore/src/heal/data_usage_cache.rs @@ -146,11 +146,12 @@ impl TierStats { } } -#[derive(Clone)] +#[allow(dead_code)] struct AllTierStats { tiers: HashMap, } +#[allow(dead_code)] impl AllTierStats { pub fn new() -> Self { Self { tiers: HashMap::new() } diff --git a/ecstore/src/lib.rs b/ecstore/src/lib.rs index bca6aa68e..955287c77 100644 --- a/ecstore/src/lib.rs +++ b/ecstore/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + extern crate core; pub mod admin_server_info; diff --git a/ecstore/src/set_disk.rs b/ecstore/src/set_disk.rs index 89c14b562..4efd213de 100644 --- a/ecstore/src/set_disk.rs +++ b/ecstore/src/set_disk.rs @@ -3786,10 +3786,7 @@ impl SetDisks { }, ) .await; - if let Err(err) = obj { - //storagelogif(ctx, fmt.Errorf("Unable to update transition restore metadata for %s/%s(%s): %s", bucket, object, oi.VersionID, err)) - return Err(err); - } + obj?; Ok(()) } } diff --git a/ecstore/src/signer/request_signature_v4.rs b/ecstore/src/signer/request_signature_v4.rs index 592e50474..691240c49 100644 --- a/ecstore/src/signer/request_signature_v4.rs +++ b/ecstore/src/signer/request_signature_v4.rs @@ -163,9 +163,26 @@ fn get_signed_headers(req: &request::Builder, ignored_headers: &HashMap, hashed_payload: &str) -> String { let mut canonical_query_string = "".to_string(); if let Some(q) = req.uri_ref().unwrap().query() { - let mut query = q.split('&').map(|h| h.to_string()).collect::>(); - query.sort(); - canonical_query_string = query.join("&"); + // Parse query string into key-value pairs + let mut query_params: Vec<(String, String)> = Vec::new(); + for param in q.split('&') { + if let Some((key, value)) = param.split_once('=') { + query_params.push((key.to_string(), value.to_string())); + } else { + query_params.push((param.to_string(), "".to_string())); + } + } + + // Sort by key name + query_params.sort_by(|a, b| a.0.cmp(&b.0)); + + // Build canonical query string + let sorted_params: Vec = query_params + .iter() + .map(|(k, v)| if v.is_empty() { k.clone() } else { format!("{}={}", k, v) }) + .collect(); + + canonical_query_string = sorted_params.join("&"); canonical_query_string = canonical_query_string.replace("+", "%20"); } @@ -665,7 +682,7 @@ mod tests { concat!( "GET\n", "/test.txt\n", - "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20130524T000000Z&X-Amz-Expires=0000086400&X-Amz-SignedHeaders=host&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404\n", + "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20130524T000000Z&X-Amz-Expires=0000086400&X-Amz-SignedHeaders=host&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=98f1c9f47b39a4c40662680a9b029b046b7da5542c2e35d67edb8ff18d2ccf5c\n", "host:examplebucket.s3.amazonaws.com\n", "\n", "host\n", @@ -712,7 +729,7 @@ mod tests { concat!( "GET\n", "/mblock2/test.txt\n", - "delimiter=%2F&fetch-owner=true&prefix=mypre&encoding-type=url&max-keys=1&list-type=2&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20130524T000000Z&X-Amz-Expires=0000086400&X-Amz-SignedHeaders=host&X-Amz-Credential=rustfsadmin%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=e4af975e4a7e2c0449451740c7e9a425123681d2a8830bfb188789ea19618b20\n", + "delimiter=%2F&fetch-owner=true&prefix=mypre&encoding-type=url&max-keys=1&list-type=2&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20130524T000000Z&X-Amz-Expires=0000086400&X-Amz-SignedHeaders=host&X-Amz-Credential=rustfsadmin%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=30e6b8c920512f0d12cba77a7c39612bff7f5f8148f4dc35cdd18f4b15a12477\n", "host:192.168.1.11:9020\n", "\n", "host\n", diff --git a/ecstore/src/signer/utils.rs b/ecstore/src/signer/utils.rs index c446f515c..8ce8d3291 100644 --- a/ecstore/src/signer/utils.rs +++ b/ecstore/src/signer/utils.rs @@ -10,7 +10,7 @@ pub fn get_host_addr(req: &request::Builder) -> String { req_host = uri.host().unwrap().to_string(); } if let Some(host) = host { - if req_host != host.to_str().unwrap().to_string() { + if req_host != *host.to_str().unwrap() { return host.to_str().unwrap().to_string(); } } diff --git a/ecstore/src/store_init.rs b/ecstore/src/store_init.rs index 31fe9d433..b2efe19d5 100644 --- a/ecstore/src/store_init.rs +++ b/ecstore/src/store_init.rs @@ -15,7 +15,7 @@ use crate::{ use futures::future::join_all; use std::collections::{HashMap, hash_map::Entry}; -use tracing::{debug, info, warn}; +use tracing::{info, warn}; use uuid::Uuid; pub async fn init_disks(eps: &Endpoints, opt: &DiskOption) -> (Vec>, Vec>) { diff --git a/rustfs/src/admin/handlers/tier.rs b/rustfs/src/admin/handlers/tier.rs index 2069268f5..00435a0e6 100644 --- a/rustfs/src/admin/handlers/tier.rs +++ b/rustfs/src/admin/handlers/tier.rs @@ -1,20 +1,18 @@ -use std::str::from_utf8; +#![allow(unused_variables, unused_mut, unused_must_use)] use http::{HeaderMap, StatusCode}; //use iam::get_global_action_cred; use matchit::Params; use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error}; -use serde::Deserialize; use serde_urlencoded::from_bytes; -use tracing::{debug, info, warn}; +use tracing::{debug, warn}; use crate::{ - admin::{router::Operation, utils::has_space_be}, + admin::router::Operation, auth::{check_key_valid, get_session_token}, }; -use crypto::{decrypt_data, encrypt_data}; + use ecstore::{ - client::admin_handler_utils::AdminError, config::storageclass, global::GLOBAL_TierConfigMgr, tier::{ @@ -28,13 +26,30 @@ use ecstore::{ }, }; -#[derive(Debug, Deserialize, Default)] +#[derive(Debug, Clone, serde::Deserialize, Default)] pub struct AddTierQuery { #[serde(rename = "accessKey")] + #[allow(dead_code)] pub access_key: Option, + #[allow(dead_code)] pub status: Option, + #[serde(rename = "secretKey")] + #[allow(dead_code)] + pub secret_key: Option, + #[serde(rename = "serviceName")] + #[allow(dead_code)] + pub service_name: Option, + #[serde(rename = "sessionToken")] + #[allow(dead_code)] + pub session_token: Option, pub tier: Option, - pub force: String, + #[serde(rename = "tierName")] + #[allow(dead_code)] + pub tier_name: Option, + #[serde(rename = "tierType")] + #[allow(dead_code)] + pub tier_type: Option, + pub force: Option, } pub struct AddTier {} @@ -86,9 +101,12 @@ impl Operation for AddTier { debug!("add tier args {:?}", args); let mut force: bool = false; - let force_str = query.force; - if force_str != "" { - force = force_str.parse().unwrap(); + let force_str = query.force.clone().unwrap_or_default(); + if !force_str.is_empty() { + force = force_str.parse().map_err(|e| { + warn!("parse force failed, e: {:?}", e); + s3_error!(InvalidRequest, "parse force failed") + })?; } match args.name.as_str() { storageclass::STANDARD | storageclass::RRS => { @@ -221,9 +239,10 @@ impl Operation for EditTier { } } -#[derive(Debug, Deserialize, Default)] +#[derive(Debug, Clone, serde::Deserialize, Default)] pub struct BucketQuery { #[serde(rename = "bucket")] + #[allow(dead_code)] pub bucket: String, } pub struct ListTiers {} @@ -281,9 +300,12 @@ impl Operation for RemoveTier { // .ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?; let mut force: bool = false; - let force_str = query.force; - if force_str != "" { - force = force_str.parse().unwrap(); + let force_str = query.force.clone().unwrap_or_default(); + if !force_str.is_empty() { + force = force_str.parse().map_err(|e| { + warn!("parse force failed, e: {:?}", e); + s3_error!(InvalidRequest, "parse force failed") + })?; } let tier_name = params.get("tiername").map(|s| s.to_string()).unwrap_or_default(); @@ -346,7 +368,7 @@ impl Operation for VerifyTier { // .ok_or_else(|| S3Error::with_message(S3ErrorCode::InternalError, "get_global_action_cred failed"))?; let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await; - tier_config_mgr.verify(&query.tier.unwrap()); + tier_config_mgr.verify(&query.tier.unwrap()).await; let mut header = HeaderMap::new(); header.insert(CONTENT_TYPE, "application/json".parse().unwrap()); diff --git a/rustfs/src/storage/ecfs.rs b/rustfs/src/storage/ecfs.rs index d308fea41..2e0d8b67d 100644 --- a/rustfs/src/storage/ecfs.rs +++ b/rustfs/src/storage/ecfs.rs @@ -18,7 +18,7 @@ use chrono::Utc; use datafusion::arrow::csv::WriterBuilder as CsvWriterBuilder; use datafusion::arrow::json::WriterBuilder as JsonWriterBuilder; use datafusion::arrow::json::writer::JsonArray; -use ecstore::bucket::error::BucketMetadataError; + use ecstore::bucket::metadata::BUCKET_LIFECYCLE_CONFIG; use ecstore::bucket::metadata::BUCKET_NOTIFICATION_CONFIG; use ecstore::bucket::metadata::BUCKET_POLICY_CONFIG; @@ -56,8 +56,7 @@ use ecstore::store_api::PutObjReader; use ecstore::store_api::StorageAPI; // use ecstore::store_api::RESERVED_METADATA_PREFIX; use ecstore::bucket::lifecycle::bucket_lifecycle_ops::validate_transition_tier; -use futures::pin_mut; -use futures::{Stream, StreamExt}; +use futures::StreamExt; use http::HeaderMap; use lazy_static::lazy_static; use policy::auth; @@ -102,10 +101,7 @@ use tracing::info; use tracing::warn; use uuid::Uuid; -use ecstore::bucket::{ - lifecycle::{bucket_lifecycle_ops::ERR_INVALID_STORAGECLASS, lifecycle::Lifecycle}, - object_lock::objectlock_sys::BucketObjectLockSys, -}; +use ecstore::bucket::lifecycle::lifecycle::Lifecycle; macro_rules! try_ { ($result:expr) => { @@ -1733,18 +1729,12 @@ impl S3 for FS { if let Err(err) = input_cfg.validate(&rcfg).await { //return Err(S3Error::with_message(S3ErrorCode::Custom("BucketLockValidateFailed".into()), "bucket lock validate failed.")); - return Err(S3Error::with_message( - S3ErrorCode::Custom("ValidateFailed".into()), - format!("{}", err.to_string()), - )); + return Err(S3Error::with_message(S3ErrorCode::Custom("ValidateFailed".into()), err.to_string())); } if let Err(err) = validate_transition_tier(&input_cfg).await { //warn!("lifecycle_configuration add failed, err: {:?}", err); - return Err(S3Error::with_message( - S3ErrorCode::Custom("CustomError".into()), - format!("{}", err.to_string()), - )); + return Err(S3Error::with_message(S3ErrorCode::Custom("CustomError".into()), err.to_string())); } let data = try_!(serialize(&input_cfg));