This commit is contained in:
weisd
2025-06-06 11:35:27 +08:00
parent 9384b831ec
commit db355bb26b
37 changed files with 2169 additions and 668 deletions
+2
View File
@@ -86,6 +86,8 @@ tower-http = { workspace = true, features = [
"cors",
] }
uuid = { workspace = true }
rustfs-filemeta.workspace = true
thiserror.workspace = true
[target.'cfg(target_os = "linux")'.dependencies]
libsystemd.workspace = true
+6 -6
View File
@@ -3,14 +3,14 @@ use crate::auth::check_key_valid;
use crate::auth::get_condition_values;
use crate::auth::get_session_token;
use bytes::Bytes;
use common::error::Error as ec_Error;
use ecstore::admin_server_info::get_server_info;
use ecstore::bucket::versioning_sys::BucketVersioningSys;
use ecstore::error::StorageError;
use ecstore::global::GLOBAL_ALlHealState;
use ecstore::heal::data_usage::load_data_usage_from_backend;
use ecstore::heal::heal_commands::HealOpts;
use ecstore::heal::heal_ops::new_heal_sequence;
use ecstore::metrics_realtime::{collect_local_metrics, CollectMetricsOpts, MetricType};
use ecstore::metrics_realtime::{CollectMetricsOpts, MetricType, collect_local_metrics};
use ecstore::new_object_layer_fn;
use ecstore::peer::is_reserved_or_invalid_bucket;
use ecstore::pools::{get_total_usable_capacity, get_total_usable_capacity_free};
@@ -26,14 +26,14 @@ use iam::store::MappedPolicy;
use madmin::metrics::RealtimeMetrics;
use madmin::utils::parse_duration;
use matchit::Params;
use policy::policy::Args;
use policy::policy::BucketPolicy;
use policy::policy::action::Action;
use policy::policy::action::S3Action;
use policy::policy::default::DEFAULT_POLICIES;
use policy::policy::Args;
use policy::policy::BucketPolicy;
use s3s::header::CONTENT_TYPE;
use s3s::stream::{ByteStream, DynByteStream};
use s3s::{s3_error, Body, S3Error, S3Request, S3Response, S3Result};
use s3s::{Body, S3Error, S3Request, S3Response, S3Result, s3_error};
use s3s::{S3ErrorCode, StdError};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
@@ -656,7 +656,7 @@ impl Operation for HealHandler {
#[derive(Default)]
struct HealResp {
resp_bytes: Vec<u8>,
_api_err: Option<ec_Error>,
_api_err: Option<StorageError>,
_err_body: String,
}
+4 -12
View File
@@ -1,7 +1,7 @@
use ecstore::{new_object_layer_fn, GLOBAL_Endpoints};
use ecstore::{GLOBAL_Endpoints, new_object_layer_fn};
use http::{HeaderMap, StatusCode};
use matchit::Params;
use s3s::{header::CONTENT_TYPE, s3_error, Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result};
use s3s::{Body, S3Error, S3ErrorCode, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error};
use serde::Deserialize;
use serde_urlencoded::from_bytes;
use tokio::sync::broadcast;
@@ -88,11 +88,7 @@ impl Operation for StatusPool {
let has_idx = {
if is_byid {
let a = query.pool.parse::<usize>().unwrap_or_default();
if a < endpoints.as_ref().len() {
Some(a)
} else {
None
}
if a < endpoints.as_ref().len() { Some(a) } else { None }
} else {
endpoints.get_pool_idx(&query.pool)
}
@@ -234,11 +230,7 @@ impl Operation for CancelDecommission {
let has_idx = {
if is_byid {
let a = query.pool.parse::<usize>().unwrap_or_default();
if a < endpoints.as_ref().len() {
Some(a)
} else {
None
}
if a < endpoints.as_ref().len() { Some(a) } else { None }
} else {
endpoints.get_pool_idx(&query.pool)
}
+4 -4
View File
@@ -1,14 +1,14 @@
use ecstore::{
config::error::is_err_config_not_found,
StorageAPI,
error::StorageError,
new_object_layer_fn,
notification_sys::get_global_notification_sys,
rebalance::{DiskStat, RebalSaveOpt},
store_api::BucketOptions,
StorageAPI,
};
use http::{HeaderMap, StatusCode};
use matchit::Params;
use s3s::{header::CONTENT_TYPE, s3_error, Body, S3Request, S3Response, S3Result};
use s3s::{Body, S3Request, S3Response, S3Result, header::CONTENT_TYPE, s3_error};
use serde::{Deserialize, Serialize};
use std::time::{Duration, SystemTime};
use tracing::warn;
@@ -133,7 +133,7 @@ impl Operation for RebalanceStatus {
let mut meta = RebalanceMeta::new();
if let Err(err) = meta.load(store.pools[0].clone()).await {
if is_err_config_not_found(&err) {
if err == StorageError::ConfigNotFound {
return Err(s3_error!(NoSuchResource, "Pool rebalance is not started"));
}
+1687
View File
File diff suppressed because it is too large Load Diff
+69 -289
View File
@@ -6,26 +6,25 @@ use ecstore::{
bucket::{metadata::load_bucket_metadata, metadata_sys},
disk::{
DeleteOptions, DiskAPI, DiskInfoOptions, DiskStore, FileInfoVersions, ReadMultipleReq, ReadOptions, UpdateMetadataOpts,
error::DiskError,
},
error::StorageError,
heal::{
data_usage_cache::DataUsageCache,
heal_commands::{get_local_background_heal_status, HealOpts},
heal_commands::{HealOpts, get_local_background_heal_status},
},
metrics_realtime::{collect_local_metrics, CollectMetricsOpts, MetricType},
metrics_realtime::{CollectMetricsOpts, MetricType, collect_local_metrics},
new_object_layer_fn,
peer::{LocalPeerS3Client, PeerS3Client},
store::{all_local_disk_path, find_local_disk},
store_api::{BucketOptions, DeleteBucketOptions, FileInfo, MakeBucketOptions, StorageAPI},
utils::err_to_proto_err,
store_api::{BucketOptions, DeleteBucketOptions, MakeBucketOptions, StorageAPI},
};
use futures::{Stream, StreamExt};
use futures_util::future::join_all;
use lock::{lock_args::LockArgs, Locker, GLOBAL_LOCAL_SERVER};
use lock::{GLOBAL_LOCAL_SERVER, Locker, lock_args::LockArgs};
use common::globals::GLOBAL_Local_Node_Name;
use ecstore::disk::error::is_err_eof;
use ecstore::metacache::writer::MetacacheReader;
use madmin::health::{
get_cpus, get_mem_info, get_os_info, get_partitions, get_proc_info, get_sys_config, get_sys_errors, get_sys_services,
};
@@ -35,6 +34,7 @@ use protos::{
proto_gen::node_service::{node_service_server::NodeService as Node, *},
};
use rmp_serde::{Deserializer, Serializer};
use rustfs_filemeta::{FileInfo, MetacacheReader};
use serde::{Deserialize, Serialize};
use tokio::spawn;
use tokio::sync::mpsc;
@@ -121,11 +121,8 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(HealBucketResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
&format!("decode HealOpts failed: {}", err),
)),
}))
error: Some(DiskError::other(format!("decode HealOpts failed: {}", err)).into()),
}));
}
};
@@ -137,7 +134,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(HealBucketResponse {
success: false,
error: Some(err_to_proto_err(&err, &format!("heal bucket failed: {}", err))),
error: Some(err.into()),
})),
}
}
@@ -152,11 +149,8 @@ impl Node for NodeService {
return Ok(tonic::Response::new(ListBucketResponse {
success: false,
bucket_infos: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
&format!("decode BucketOptions failed: {}", err),
)),
}))
error: Some(DiskError::other(format!("decode BucketOptions failed: {}", err)).into()),
}));
}
};
match self.local_peer.list_bucket(&options).await {
@@ -175,7 +169,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(ListBucketResponse {
success: false,
bucket_infos: Vec::new(),
error: Some(err_to_proto_err(&err, &format!("list bucket failed: {}", err))),
error: Some(err.into()),
})),
}
}
@@ -189,11 +183,8 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(MakeBucketResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
&format!("decode MakeBucketOptions failed: {}", err),
)),
}))
error: Some(DiskError::other(format!("decode MakeBucketOptions failed: {}", err)).into()),
}));
}
};
match self.local_peer.make_bucket(&request.name, &options).await {
@@ -203,7 +194,7 @@ impl Node for NodeService {
})),
Err(err) => Ok(tonic::Response::new(MakeBucketResponse {
success: false,
error: Some(err_to_proto_err(&err, &format!("make bucket failed: {}", err))),
error: Some(err.into()),
})),
}
}
@@ -218,11 +209,8 @@ impl Node for NodeService {
return Ok(tonic::Response::new(GetBucketInfoResponse {
success: false,
bucket_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
&format!("decode BucketOptions failed: {}", err),
)),
}))
error: Some(DiskError::other(format!("decode BucketOptions failed: {}", err)).into()),
}));
}
};
match self.local_peer.get_bucket_info(&request.bucket, &options).await {
@@ -233,10 +221,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(GetBucketInfoResponse {
success: false,
bucket_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
}));
}
};
@@ -250,7 +235,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(GetBucketInfoResponse {
success: false,
bucket_info: String::new(),
error: Some(err_to_proto_err(&err, &format!("get bucket info failed: {}", err))),
error: Some(err.into()),
})),
}
}
@@ -276,7 +261,7 @@ impl Node for NodeService {
})),
Err(err) => Ok(tonic::Response::new(DeleteBucketResponse {
success: false,
error: Some(err_to_proto_err(&err, &format!("delete bucket failed: {}", err))),
error: Some(err.into()),
})),
}
}
@@ -302,10 +287,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ReadAllResponse {
success: false,
data: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -326,10 +308,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(WriteAllResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -342,14 +321,7 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(DeleteResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode DeleteOptions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode DeleteOptions failed: {}", err)).into()),
}));
}
};
@@ -366,10 +338,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(DeleteResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -383,14 +352,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(VerifyFileResponse {
success: false,
check_parts_resp: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -402,10 +364,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(VerifyFileResponse {
success: false,
check_parts_resp: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
}));
}
};
@@ -425,10 +384,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(VerifyFileResponse {
success: false,
check_parts_resp: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -442,14 +398,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(CheckPartsResponse {
success: false,
check_parts_resp: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -461,10 +410,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(CheckPartsResponse {
success: false,
check_parts_resp: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
}));
}
};
@@ -484,10 +430,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(CheckPartsResponse {
success: false,
check_parts_resp: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -517,10 +460,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(RenamePartResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -544,10 +484,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(RenameFileResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -812,10 +749,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ListDirResponse {
success: false,
volumes: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -870,7 +804,7 @@ impl Node for NodeService {
}
}
Err(err) => {
if is_err_eof(&err) {
if rustfs_filemeta::is_io_eof(&err) {
break;
}
@@ -899,14 +833,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(RenameDataResponse {
success: false,
rename_data_resp: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -921,10 +848,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(RenameDataResponse {
success: false,
rename_data_resp: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
}));
}
};
@@ -944,10 +868,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(RenameDataResponse {
success: false,
rename_data_resp: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -968,10 +889,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(MakeVolumesResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -992,10 +910,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(MakeVolumeResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1025,10 +940,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ListVolumesResponse {
success: false,
volume_infos: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1046,10 +958,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(StatVolumeResponse {
success: false,
volume_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
})),
},
Err(err) => Ok(tonic::Response::new(StatVolumeResponse {
@@ -1062,10 +971,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(StatVolumeResponse {
success: false,
volume_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1086,10 +992,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(DeletePathsResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1102,14 +1005,7 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(UpdateMetadataResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -1118,14 +1014,7 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(UpdateMetadataResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode UpdateMetadataOpts failed: {}", err),
)),
error: Some(DiskError::other(format!("decode UpdateMetadataOpts failed: {}", err)).into()),
}));
}
};
@@ -1143,10 +1032,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(UpdateMetadataResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1159,14 +1045,7 @@ impl Node for NodeService {
Err(err) => {
return Ok(tonic::Response::new(WriteMetadataResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -1183,10 +1062,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(WriteMetadataResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1200,14 +1076,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(ReadVersionResponse {
success: false,
file_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode ReadOptions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode ReadOptions failed: {}", err)).into()),
}));
}
};
@@ -1224,10 +1093,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(ReadVersionResponse {
success: false,
file_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
})),
},
Err(err) => Ok(tonic::Response::new(ReadVersionResponse {
@@ -1240,10 +1106,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ReadVersionResponse {
success: false,
file_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1261,10 +1124,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(ReadXlResponse {
success: false,
raw_file_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
})),
},
Err(err) => Ok(tonic::Response::new(ReadXlResponse {
@@ -1277,10 +1137,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ReadXlResponse {
success: false,
raw_file_info: String::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1294,14 +1151,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(DeleteVersionResponse {
success: false,
raw_file_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfo failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfo failed: {}", err)).into()),
}));
}
};
@@ -1311,14 +1161,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(DeleteVersionResponse {
success: false,
raw_file_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode DeleteOptions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode DeleteOptions failed: {}", err)).into()),
}));
}
};
@@ -1335,10 +1178,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(DeleteVersionResponse {
success: false,
raw_file_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
})),
},
Err(err) => Ok(tonic::Response::new(DeleteVersionResponse {
@@ -1351,10 +1191,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(DeleteVersionResponse {
success: false,
raw_file_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1370,14 +1207,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(DeleteVersionsResponse {
success: false,
errors: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode FileInfoVersions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode FileInfoVersions failed: {}", err)).into()),
}));
}
};
@@ -1388,14 +1218,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(DeleteVersionsResponse {
success: false,
errors: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode DeleteOptions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode DeleteOptions failed: {}", err)).into()),
}));
}
};
@@ -1425,10 +1248,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(DeleteVersionsResponse {
success: false,
errors: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1442,14 +1262,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(ReadMultipleResponse {
success: false,
read_multiple_resps: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode ReadMultipleReq failed: {}", err),
)),
error: Some(DiskError::other(format!("decode ReadMultipleReq failed: {}", err)).into()),
}));
}
};
@@ -1476,10 +1289,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(ReadMultipleResponse {
success: false,
read_multiple_resps: Vec::new(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1500,10 +1310,7 @@ impl Node for NodeService {
} else {
Ok(tonic::Response::new(DeleteVolumeResponse {
success: false,
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1517,14 +1324,7 @@ impl Node for NodeService {
return Ok(tonic::Response::new(DiskInfoResponse {
success: false,
disk_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode DiskInfoOptions failed: {}", err),
)),
error: Some(DiskError::other(format!("decode DiskInfoOptions failed: {}", err)).into()),
}));
}
};
@@ -1538,10 +1338,7 @@ impl Node for NodeService {
Err(err) => Ok(tonic::Response::new(DiskInfoResponse {
success: false,
disk_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::from_string("encode data failed"),
&format!("encode data failed: {}", err),
)),
error: Some(DiskError::other(format!("encode data failed: {}", err)).into()),
})),
},
Err(err) => Ok(tonic::Response::new(DiskInfoResponse {
@@ -1554,10 +1351,7 @@ impl Node for NodeService {
Ok(tonic::Response::new(DiskInfoResponse {
success: false,
disk_info: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(Default::default(), Default::default(), Default::default())),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
}
}
@@ -1580,14 +1374,7 @@ impl Node for NodeService {
success: false,
update: "".to_string(),
data_usage_cache: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
&format!("decode DataUsageCache failed: {}", err),
)),
error: Some(DiskError::other(format!("decode DataUsageCache failed: {}", err)).into()),
}))
.await
.expect("working rx");
@@ -1645,14 +1432,7 @@ impl Node for NodeService {
success: false,
update: "".to_string(),
data_usage_cache: "".to_string(),
error: Some(err_to_proto_err(
&EcsError::new(StorageError::InvalidArgument(
Default::default(),
Default::default(),
Default::default(),
)),
"can not find disk",
)),
error: Some(DiskError::other("can not find disk".to_string()).into()),
}))
.await
.expect("working rx");
+13 -9
View File
@@ -2,6 +2,7 @@ mod admin;
mod auth;
mod config;
mod console;
mod error;
mod event;
mod grpc;
pub mod license;
@@ -11,9 +12,9 @@ mod service;
mod storage;
use crate::auth::IAMAuth;
use crate::console::{init_console_cfg, CONSOLE_CONFIG};
use crate::console::{CONSOLE_CONFIG, init_console_cfg};
// Ensure the correct path for parse_license is imported
use crate::server::{wait_for_shutdown, ServiceState, ServiceStateManager, ShutdownSignal, SHUTDOWN_TIMEOUT};
use crate::server::{SHUTDOWN_TIMEOUT, ServiceState, ServiceStateManager, ShutdownSignal, wait_for_shutdown};
use bytes::Bytes;
use chrono::Datelike;
use clap::Parser;
@@ -21,18 +22,18 @@ use common::{
error::{Error, Result},
globals::set_global_addr,
};
use ecstore::StorageAPI;
use ecstore::bucket::metadata_sys::init_bucket_metadata_sys;
use ecstore::config as ecconfig;
use ecstore::config::GLOBAL_ConfigSys;
use ecstore::heal::background_heal_ops::init_auto_heal;
use ecstore::store_api::BucketOptions;
use ecstore::utils::net;
use ecstore::StorageAPI;
use ecstore::{
endpoints::EndpointServerPools,
heal::data_scanner::init_data_scanner,
set_global_endpoints,
store::{init_local_disks, ECStore},
store::{ECStore, init_local_disks},
update_erasure_type,
};
use ecstore::{global::set_global_rustfs_port, notification_sys::new_global_notification_sys};
@@ -48,7 +49,7 @@ use iam::init_iam_sys;
use license::init_license;
use protos::proto_gen::node_service::node_service_server::NodeServiceServer;
use rustfs_config::{DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY, RUSTFS_TLS_CERT, RUSTFS_TLS_KEY};
use rustfs_obs::{init_obs, set_global_guard, SystemObserver};
use rustfs_obs::{SystemObserver, init_obs, set_global_guard};
use rustls::ServerConfig;
use s3s::{host::MultiDomain, service::S3ServiceBuilder};
use service::hybrid;
@@ -57,13 +58,13 @@ use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tokio::net::TcpListener;
use tokio::signal::unix::{signal, SignalKind};
use tokio::signal::unix::{SignalKind, signal};
use tokio_rustls::TlsAcceptor;
use tonic::{metadata::MetadataValue, Request, Status};
use tonic::{Request, Status, metadata::MetadataValue};
use tower_http::cors::CorsLayer;
use tower_http::trace::TraceLayer;
use tracing::{Span, instrument};
use tracing::{debug, error, info, warn};
use tracing::{instrument, Span};
const MI_B: usize = 1024 * 1024;
@@ -163,7 +164,10 @@ async fn run(opt: config::Opt) -> Result<()> {
info!(" RootUser: {}", opt.access_key.clone());
info!(" RootPass: {}", opt.secret_key.clone());
if DEFAULT_ACCESS_KEY.eq(&opt.access_key) && DEFAULT_SECRET_KEY.eq(&opt.secret_key) {
warn!("Detected default credentials '{}:{}', we recommend that you change these values with 'RUSTFS_ACCESS_KEY' and 'RUSTFS_SECRET_KEY' environment variables", DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY);
warn!(
"Detected default credentials '{}:{}', we recommend that you change these values with 'RUSTFS_ACCESS_KEY' and 'RUSTFS_SECRET_KEY' environment variables",
DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY
);
}
for (i, eps) in endpoint_pools.as_ref().iter().enumerate() {
+4 -6
View File
@@ -7,7 +7,7 @@ use policy::auth;
use policy::policy::action::{Action, S3Action};
use policy::policy::{Args, BucketPolicyArgs};
use s3s::access::{S3Access, S3AccessContext};
use s3s::{dto::*, s3_error, S3Error, S3ErrorCode, S3Request, S3Result};
use s3s::{S3Error, S3ErrorCode, S3Request, S3Result, dto::*, s3_error};
use std::collections::HashMap;
#[allow(dead_code)]
@@ -218,11 +218,9 @@ impl S3Access for FS {
let req_info = req.extensions.get_mut::<ReqInfo>().expect("ReqInfo not found");
let (src_bucket, src_key, version_id) = match &req.input.copy_source {
CopySource::AccessPoint { .. } => return Err(s3_error!(NotImplemented)),
CopySource::Bucket {
ref bucket,
ref key,
version_id,
} => (bucket.to_string(), key.to_string(), version_id.as_ref().map(|v| v.to_string())),
CopySource::Bucket { bucket, key, version_id } => {
(bucket.to_string(), key.to_string(), version_id.as_ref().map(|v| v.to_string()))
}
};
req_info.bucket = Some(src_bucket);
+26 -30
View File
@@ -1,6 +1,6 @@
use common::error::Error;
use ecstore::{disk::error::is_err_file_not_found, error::StorageError};
use s3s::{s3_error, S3Error, S3ErrorCode};
use ecstore::error::StorageError;
use s3s::{S3Error, S3ErrorCode, s3_error};
pub fn to_s3_error(err: Error) -> S3Error {
if let Some(storage_err) = err.downcast_ref::<StorageError>() {
return match storage_err {
@@ -56,18 +56,6 @@ pub fn to_s3_error(err: Error) -> S3Error {
StorageError::ObjectExistsAsDirectory(bucket, object) => {
s3_error!(InvalidArgument, "Object exists on :{} as directory {}", bucket, object)
}
StorageError::InsufficientReadQuorum => {
s3_error!(SlowDown, "Storage resources are insufficient for the read operation")
}
StorageError::InsufficientWriteQuorum => {
s3_error!(SlowDown, "Storage resources are insufficient for the write operation")
}
StorageError::DecommissionNotStarted => s3_error!(InvalidArgument, "Decommission Not Started"),
StorageError::DecommissionAlreadyRunning => s3_error!(InternalError, "Decommission already running"),
StorageError::VolumeNotFound(bucket) => {
s3_error!(NoSuchBucket, "bucket not found {}", bucket)
}
StorageError::InvalidPart(bucket, object, version_id) => {
s3_error!(
InvalidPart,
@@ -187,10 +175,12 @@ mod tests {
let s3_err = to_s3_error(err);
assert_eq!(*s3_err.code(), S3ErrorCode::ServiceUnavailable);
assert!(s3_err
.message()
.unwrap()
.contains("Storage reached its minimum free drive threshold"));
assert!(
s3_err
.message()
.unwrap()
.contains("Storage reached its minimum free drive threshold")
);
}
#[test]
@@ -257,10 +247,12 @@ mod tests {
let s3_err = to_s3_error(err);
assert_eq!(*s3_err.code(), S3ErrorCode::InvalidArgument);
assert!(s3_err
.message()
.unwrap()
.contains("Object name contains forward slash as prefix"));
assert!(
s3_err
.message()
.unwrap()
.contains("Object name contains forward slash as prefix")
);
assert!(s3_err.message().unwrap().contains("test-bucket"));
assert!(s3_err.message().unwrap().contains("/invalid-object"));
}
@@ -358,10 +350,12 @@ mod tests {
let s3_err = to_s3_error(err);
assert_eq!(*s3_err.code(), S3ErrorCode::SlowDown);
assert!(s3_err
.message()
.unwrap()
.contains("Storage resources are insufficient for the read operation"));
assert!(
s3_err
.message()
.unwrap()
.contains("Storage resources are insufficient for the read operation")
);
}
#[test]
@@ -371,10 +365,12 @@ mod tests {
let s3_err = to_s3_error(err);
assert_eq!(*s3_err.code(), S3ErrorCode::SlowDown);
assert!(s3_err
.message()
.unwrap()
.contains("Storage resources are insufficient for the write operation"));
assert!(
s3_err
.message()
.unwrap()
.contains("Storage resources are insufficient for the write operation")
);
}
#[test]