mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-08 22:33:22 +00:00
init NotificationSys
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
use clap::Parser;
|
||||
use const_str::concat;
|
||||
use ecstore::global::DEFAULT_PORT;
|
||||
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
/// Default port that a rustfs server listens on.
|
||||
///
|
||||
/// Used if no port is specified.
|
||||
pub const DEFAULT_PORT: u16 = 9000;
|
||||
|
||||
pub const DEFAULT_ACCESS_KEY: &str = "rustfsadmin";
|
||||
pub const DEFAULT_SECRET_KEY: &str = "rustfsadmin";
|
||||
|
||||
|
||||
+4
-2
@@ -13,7 +13,10 @@ use ecstore::{
|
||||
UpdateMetadataOpts, WalkDirOptions,
|
||||
},
|
||||
erasure::Writer,
|
||||
heal::{data_usage_cache::DataUsageCache, heal_commands::HealOpts},
|
||||
heal::{
|
||||
data_usage_cache::DataUsageCache,
|
||||
heal_commands::{get_local_background_heal_status, HealOpts},
|
||||
},
|
||||
new_object_layer_fn,
|
||||
peer::{LocalPeerS3Client, PeerS3Client},
|
||||
store::{all_local_disk_path, find_local_disk},
|
||||
@@ -25,7 +28,6 @@ use lock::{lock_args::LockArgs, Locker, GLOBAL_LOCAL_SERVER};
|
||||
use common::globals::GLOBAL_Local_Node_Name;
|
||||
use madmin::net::get_net_info;
|
||||
use madmin::{
|
||||
heal_command::get_local_background_heal_status,
|
||||
health::{
|
||||
get_cpus, get_mem_info, get_os_info, get_partitions, get_proc_info, get_sys_config, get_sys_errors, get_sys_services,
|
||||
},
|
||||
|
||||
+29
-8
@@ -1,16 +1,17 @@
|
||||
mod admin;
|
||||
mod config;
|
||||
mod grpc;
|
||||
#[allow(dead_code)]
|
||||
mod peer_rest_client;
|
||||
mod service;
|
||||
mod storage;
|
||||
|
||||
use clap::Parser;
|
||||
use common::error::{Error, Result};
|
||||
use ecstore::global::set_global_rustfs_port;
|
||||
use ecstore::heal::background_heal_ops::init_auto_heal;
|
||||
use ecstore::utils::net::{self, get_available_port};
|
||||
use ecstore::{
|
||||
endpoints::EndpointServerPools,
|
||||
heal::{background_heal_ops::init_auto_heal, data_scanner::init_data_scanner},
|
||||
heal::data_scanner::init_data_scanner,
|
||||
notification_sys::new_global_notification_sys,
|
||||
set_global_endpoints,
|
||||
store::{init_local_disks, ECStore},
|
||||
update_erasure_type,
|
||||
@@ -72,13 +73,27 @@ fn main() -> Result<()> {
|
||||
async fn run(opt: config::Opt) -> Result<()> {
|
||||
debug!("opt: {:?}", &opt);
|
||||
|
||||
let mut server_addr = net::check_local_server_addr(opt.address.as_str()).unwrap();
|
||||
|
||||
if server_addr.port() == 0 {
|
||||
server_addr.set_port(get_available_port());
|
||||
}
|
||||
|
||||
let server_port = server_addr.port();
|
||||
|
||||
let server_address = server_addr.to_string();
|
||||
|
||||
debug!("server_address {}", &server_address);
|
||||
|
||||
set_global_rustfs_port(server_port);
|
||||
|
||||
//监听地址,端口从参数中获取
|
||||
let listener = TcpListener::bind(opt.address.clone()).await?;
|
||||
let listener = TcpListener::bind(server_address.clone()).await?;
|
||||
//获取监听地址
|
||||
let local_addr: SocketAddr = listener.local_addr()?;
|
||||
|
||||
// 用于rpc
|
||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(opt.address.clone().as_str(), opt.volumes.clone())
|
||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
||||
.map_err(|err| Error::from_string(err.to_string()))?;
|
||||
|
||||
for (i, eps) in endpoint_pools.as_ref().iter().enumerate() {
|
||||
@@ -100,7 +115,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
// 本项目使用s3s库来实现s3服务
|
||||
let service = {
|
||||
let store = storage::ecfs::FS::new();
|
||||
// let mut b = S3ServiceBuilder::new(storage::ecfs::FS::new(opt.address.clone(), endpoint_pools).await?);
|
||||
// let mut b = S3ServiceBuilder::new(storage::ecfs::FS::new(server_address.clone(), endpoint_pools).await?);
|
||||
let mut b = S3ServiceBuilder::new(store.clone());
|
||||
//设置AK和SK
|
||||
//其中部份内容从config配置文件中读取
|
||||
@@ -183,7 +198,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
});
|
||||
|
||||
// init store
|
||||
let store = ECStore::new(opt.address.clone(), endpoint_pools.clone())
|
||||
let store = ECStore::new(server_address.clone(), endpoint_pools.clone())
|
||||
.await
|
||||
.map_err(|err| Error::from_string(err.to_string()))?;
|
||||
|
||||
@@ -192,6 +207,12 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
Error::from_string(err.to_string())
|
||||
})?;
|
||||
warn!(" init store success!");
|
||||
|
||||
new_global_notification_sys(endpoint_pools.clone()).await.map_err(|err| {
|
||||
error!("new_global_notification_sys faild {:?}", &err);
|
||||
Error::from_string(err.to_string())
|
||||
})?;
|
||||
|
||||
// init scanner
|
||||
init_data_scanner().await;
|
||||
// init auto heal
|
||||
|
||||
@@ -1,658 +0,0 @@
|
||||
use std::{collections::HashMap, io::Cursor, time::SystemTime};
|
||||
|
||||
use common::error::{Error, Result};
|
||||
use ecstore::{admin_server_info::ServerProperties, store_api::StorageInfo};
|
||||
use madmin::{
|
||||
heal_command::BgHealState,
|
||||
health::{Cpus, MemInfo, OsInfo, Partitions, ProcInfo, SysConfig, SysErrors, SysService},
|
||||
metrics::{CollectMetricsOpts, MetricType, RealtimeMetrics},
|
||||
net::NetInfo,
|
||||
};
|
||||
use protos::{
|
||||
node_service_time_out_client,
|
||||
proto_gen::node_service::{
|
||||
BackgroundHealStatusRequest, DeleteBucketMetadataRequest, DeletePolicyRequest, DeleteServiceAccountRequest,
|
||||
DeleteUserRequest, GetCpusRequest, GetMemInfoRequest, GetMetricsRequest, GetNetInfoRequest, GetOsInfoRequest,
|
||||
GetPartitionsRequest, GetProcInfoRequest, GetSeLinuxInfoRequest, GetSysConfigRequest, GetSysErrorsRequest,
|
||||
LoadBucketMetadataRequest, LoadGroupRequest, LoadPolicyMappingRequest, LoadPolicyRequest, LoadRebalanceMetaRequest,
|
||||
LoadServiceAccountRequest, LoadTransitionTierConfigRequest, LoadUserRequest, LocalStorageInfoRequest, Mss,
|
||||
ReloadPoolMetaRequest, ReloadSiteReplicationConfigRequest, ServerInfoRequest, SignalServiceRequest,
|
||||
StartProfilingRequest, StopRebalanceRequest,
|
||||
},
|
||||
};
|
||||
use rmp_serde::{Deserializer, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tonic::Request;
|
||||
|
||||
pub const PEER_RESTSIGNAL: &str = "signal";
|
||||
pub const PEER_RESTSUB_SYS: &str = "sub-sys";
|
||||
pub const PEER_RESTDRY_RUN: &str = "dry-run";
|
||||
|
||||
struct PeerRestClient {
|
||||
addr: String,
|
||||
}
|
||||
|
||||
impl PeerRestClient {
|
||||
pub fn new(url: url::Url) -> Self {
|
||||
Self {
|
||||
addr: format!("{}://{}:{}", url.scheme(), url.host_str().unwrap(), url.port().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PeerRestClient {
|
||||
pub async fn local_storage_info(&self) -> Result<StorageInfo> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LocalStorageInfoRequest { metrics: true });
|
||||
|
||||
let response = client.local_storage_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.storage_info;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let storage_info: StorageInfo = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(storage_info)
|
||||
}
|
||||
|
||||
pub async fn server_info(&self) -> Result<ServerProperties> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(ServerInfoRequest { metrics: true });
|
||||
|
||||
let response = client.server_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.server_properties;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let storage_properties: ServerProperties = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(storage_properties)
|
||||
}
|
||||
|
||||
pub async fn get_cpus(&self) -> Result<Cpus> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetCpusRequest {});
|
||||
|
||||
let response = client.get_cpus(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.cpus;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let cpus: Cpus = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(cpus)
|
||||
}
|
||||
|
||||
pub async fn get_net_info(&self) -> Result<NetInfo> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetNetInfoRequest {});
|
||||
|
||||
let response = client.get_net_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.net_info;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let net_info: NetInfo = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(net_info)
|
||||
}
|
||||
|
||||
pub async fn get_partitions(&self) -> Result<Partitions> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetPartitionsRequest {});
|
||||
|
||||
let response = client.get_partitions(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.partitions;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let partitions: Partitions = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(partitions)
|
||||
}
|
||||
|
||||
pub async fn get_os_info(&self) -> Result<OsInfo> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetOsInfoRequest {});
|
||||
|
||||
let response = client.get_os_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.os_info;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let os_info: OsInfo = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(os_info)
|
||||
}
|
||||
|
||||
pub async fn get_se_linux_info(&self) -> Result<SysService> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetSeLinuxInfoRequest {});
|
||||
|
||||
let response = client.get_se_linux_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.sys_services;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let sys_services: SysService = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(sys_services)
|
||||
}
|
||||
|
||||
pub async fn get_sys_config(&self) -> Result<SysConfig> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetSysConfigRequest {});
|
||||
|
||||
let response = client.get_sys_config(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.sys_config;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let sys_config: SysConfig = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(sys_config)
|
||||
}
|
||||
|
||||
pub async fn get_sys_errors(&self) -> Result<SysErrors> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetSysErrorsRequest {});
|
||||
|
||||
let response = client.get_sys_errors(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.sys_errors;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let sys_errors: SysErrors = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(sys_errors)
|
||||
}
|
||||
|
||||
pub async fn get_mem_info(&self) -> Result<MemInfo> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetMemInfoRequest {});
|
||||
|
||||
let response = client.get_mem_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.mem_info;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let mem_info: MemInfo = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(mem_info)
|
||||
}
|
||||
|
||||
pub async fn get_metrics(&self, t: MetricType, opts: &CollectMetricsOpts) -> Result<RealtimeMetrics> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let mut buf = Vec::new();
|
||||
opts.serialize(&mut Serializer::new(&mut buf))?;
|
||||
let request = Request::new(GetMetricsRequest {
|
||||
metric_type: t,
|
||||
opts: buf,
|
||||
});
|
||||
|
||||
let response = client.get_metrics(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.realtime_metrics;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let realtime_metrics: RealtimeMetrics = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(realtime_metrics)
|
||||
}
|
||||
|
||||
pub async fn get_proc_info(&self) -> Result<ProcInfo> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(GetProcInfoRequest {});
|
||||
|
||||
let response = client.get_proc_info(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.proc_info;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let proc_info: ProcInfo = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(proc_info)
|
||||
}
|
||||
|
||||
pub async fn start_profiling(&self, profiler: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(StartProfilingRequest {
|
||||
profiler: profiler.to_string(),
|
||||
});
|
||||
|
||||
let response = client.start_profiling(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn download_profile_data(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn get_bucket_stats(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn get_sr_metrics(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn get_all_bucket_stats(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn load_bucket_metadata(&self, bucket: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadBucketMetadataRequest {
|
||||
bucket: bucket.to_string(),
|
||||
});
|
||||
|
||||
let response = client.load_bucket_metadata(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_bucket_metadata(&self, bucket: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(DeleteBucketMetadataRequest {
|
||||
bucket: bucket.to_string(),
|
||||
});
|
||||
|
||||
let response = client.delete_bucket_metadata(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_policy(&self, policy: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(DeletePolicyRequest {
|
||||
policy_name: policy.to_string(),
|
||||
});
|
||||
|
||||
let response = client.delete_policy(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_policy(&self, policy: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadPolicyRequest {
|
||||
policy_name: policy.to_string(),
|
||||
});
|
||||
|
||||
let response = client.load_policy(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_policy_mapping(&self, user_or_group: &str, user_type: u64, is_group: bool) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadPolicyMappingRequest {
|
||||
user_or_group: user_or_group.to_string(),
|
||||
user_type,
|
||||
is_group,
|
||||
});
|
||||
|
||||
let response = client.load_policy_mapping(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_user(&self, access_key: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(DeleteUserRequest {
|
||||
access_key: access_key.to_string(),
|
||||
});
|
||||
|
||||
let response = client.delete_user(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_service_account(&self, access_key: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(DeleteServiceAccountRequest {
|
||||
access_key: access_key.to_string(),
|
||||
});
|
||||
|
||||
let response = client.delete_service_account(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_user(&self, access_key: &str, temp: bool) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadUserRequest {
|
||||
access_key: access_key.to_string(),
|
||||
temp,
|
||||
});
|
||||
|
||||
let response = client.load_user(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_service_account(&self, access_key: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadServiceAccountRequest {
|
||||
access_key: access_key.to_string(),
|
||||
});
|
||||
|
||||
let response = client.load_service_account(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_group(&self, group: &str) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadGroupRequest {
|
||||
group: group.to_string(),
|
||||
});
|
||||
|
||||
let response = client.load_group(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn reload_site_replication_config(&self) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(ReloadSiteReplicationConfigRequest {});
|
||||
|
||||
let response = client.reload_site_replication_config(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn signal_service(&self, sig: u64, sub_sys: &str, dry_run: bool, _exec_at: SystemTime) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let mut vars = HashMap::new();
|
||||
vars.insert(PEER_RESTSIGNAL.to_string(), sig.to_string());
|
||||
vars.insert(PEER_RESTSUB_SYS.to_string(), sub_sys.to_string());
|
||||
vars.insert(PEER_RESTDRY_RUN.to_string(), dry_run.to_string());
|
||||
let request = Request::new(SignalServiceRequest {
|
||||
vars: Some(Mss { value: vars }),
|
||||
});
|
||||
|
||||
let response = client.signal_service(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn background_heal_status(&self) -> Result<BgHealState> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(BackgroundHealStatusRequest {});
|
||||
|
||||
let response = client.background_heal_status(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
let data = response.bg_heal_state;
|
||||
|
||||
let mut buf = Deserializer::new(Cursor::new(data));
|
||||
let bg_heal_state: BgHealState = Deserialize::deserialize(&mut buf).unwrap();
|
||||
|
||||
Ok(bg_heal_state)
|
||||
}
|
||||
|
||||
pub async fn get_metacache_listing(&self) -> Result<()> {
|
||||
let mut _client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn update_metacache_listing(&self) -> Result<()> {
|
||||
let mut _client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn reload_pool_meta(&self) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(ReloadPoolMetaRequest {});
|
||||
|
||||
let response = client.reload_pool_meta(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn stop_rebalance(&self) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(StopRebalanceRequest {});
|
||||
|
||||
let response = client.stop_rebalance(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_rebalance_meta(&self, start_rebalance: bool) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadRebalanceMetaRequest { start_rebalance });
|
||||
|
||||
let response = client.load_rebalance_meta(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn load_transition_tier_config(&self) -> Result<()> {
|
||||
let mut client = node_service_time_out_client(&self.addr)
|
||||
.await
|
||||
.map_err(|err| Error::msg(err.to_string()))?;
|
||||
let request = Request::new(LoadTransitionTierConfigRequest {});
|
||||
|
||||
let response = client.load_transition_tier_config(request).await?.into_inner();
|
||||
if !response.success {
|
||||
if let Some(msg) = response.error_info {
|
||||
return Err(Error::msg(msg));
|
||||
}
|
||||
return Err(Error::msg(""));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
use super::options::del_opts;
|
||||
use super::options::extract_metadata;
|
||||
use super::options::put_opts;
|
||||
use bytes::Bytes;
|
||||
use common::error::Result;
|
||||
use ecstore::bucket::error::BucketMetadataError;
|
||||
@@ -16,9 +19,6 @@ use ecstore::bucket::tagging::decode_tags;
|
||||
use ecstore::bucket::tagging::encode_tags;
|
||||
use ecstore::bucket::versioning_sys::BucketVersioningSys;
|
||||
use ecstore::new_object_layer_fn;
|
||||
use ecstore::options::del_opts;
|
||||
use ecstore::options::extract_metadata;
|
||||
use ecstore::options::put_opts;
|
||||
use ecstore::store_api::BucketOptions;
|
||||
use ecstore::store_api::CompletePart;
|
||||
use ecstore::store_api::DeleteBucketOptions;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod acess;
|
||||
pub mod ecfs;
|
||||
pub mod error;
|
||||
pub mod options;
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
use ecstore::bucket::versioning_sys::BucketVersioningSys;
|
||||
use ecstore::error::{Error, Result};
|
||||
use ecstore::store_api::ObjectOptions;
|
||||
use ecstore::store_err::StorageError;
|
||||
use ecstore::utils::path::is_dir_object;
|
||||
use http::{HeaderMap, HeaderValue};
|
||||
use lazy_static::lazy_static;
|
||||
use std::collections::HashMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
pub async fn del_opts(
|
||||
bucket: &str,
|
||||
object: &str,
|
||||
vid: Option<String>,
|
||||
headers: &HeaderMap<HeaderValue>,
|
||||
metadata: Option<HashMap<String, String>>,
|
||||
) -> Result<ObjectOptions> {
|
||||
let versioned = BucketVersioningSys::prefix_enabled(bucket, object).await;
|
||||
let version_suspended = BucketVersioningSys::suspended(bucket).await;
|
||||
|
||||
// TODO: delete_prefix
|
||||
|
||||
let vid = vid.map(|v| v.as_str().trim().to_owned());
|
||||
|
||||
if let Some(ref id) = vid {
|
||||
if let Err(_err) = Uuid::parse_str(id.as_str()) {
|
||||
return Err(Error::new(StorageError::InvalidVersionID(
|
||||
bucket.to_owned(),
|
||||
object.to_owned(),
|
||||
id.clone(),
|
||||
)));
|
||||
}
|
||||
|
||||
if !versioned {
|
||||
return Err(Error::new(StorageError::InvalidArgument(
|
||||
bucket.to_owned(),
|
||||
object.to_owned(),
|
||||
id.clone(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
let mut opts = put_opts_from_headers(headers, metadata)
|
||||
.map_err(|err| Error::new(StorageError::InvalidArgument(bucket.to_owned(), object.to_owned(), err.to_string())))?;
|
||||
|
||||
opts.version_id = {
|
||||
if is_dir_object(object) && vid.is_none() {
|
||||
Some(Uuid::nil().to_string())
|
||||
} else {
|
||||
vid
|
||||
}
|
||||
};
|
||||
opts.version_suspended = version_suspended;
|
||||
opts.versioned = versioned;
|
||||
|
||||
Ok(opts)
|
||||
}
|
||||
|
||||
pub async fn put_opts(
|
||||
bucket: &str,
|
||||
object: &str,
|
||||
vid: Option<String>,
|
||||
headers: &HeaderMap<HeaderValue>,
|
||||
metadata: Option<HashMap<String, String>>,
|
||||
) -> Result<ObjectOptions> {
|
||||
let versioned = BucketVersioningSys::prefix_enabled(bucket, object).await;
|
||||
let version_suspended = BucketVersioningSys::prefix_suspended(bucket, object).await;
|
||||
|
||||
let vid = vid.map(|v| v.as_str().trim().to_owned());
|
||||
|
||||
if let Some(ref id) = vid {
|
||||
if let Err(_err) = Uuid::parse_str(id.as_str()) {
|
||||
return Err(Error::new(StorageError::InvalidVersionID(
|
||||
bucket.to_owned(),
|
||||
object.to_owned(),
|
||||
id.clone(),
|
||||
)));
|
||||
}
|
||||
|
||||
if !versioned {
|
||||
return Err(Error::new(StorageError::InvalidArgument(
|
||||
bucket.to_owned(),
|
||||
object.to_owned(),
|
||||
id.clone(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
let mut opts = put_opts_from_headers(headers, metadata)
|
||||
.map_err(|err| Error::new(StorageError::InvalidArgument(bucket.to_owned(), object.to_owned(), err.to_string())))?;
|
||||
|
||||
opts.version_id = {
|
||||
if is_dir_object(object) && vid.is_none() {
|
||||
Some(Uuid::nil().to_string())
|
||||
} else {
|
||||
vid
|
||||
}
|
||||
};
|
||||
opts.version_suspended = version_suspended;
|
||||
opts.versioned = versioned;
|
||||
|
||||
Ok(opts)
|
||||
}
|
||||
|
||||
pub fn put_opts_from_headers(
|
||||
headers: &HeaderMap<HeaderValue>,
|
||||
metadata: Option<HashMap<String, String>>,
|
||||
) -> Result<ObjectOptions> {
|
||||
let metadata = metadata.unwrap_or_default();
|
||||
|
||||
get_default_opts(headers, metadata, false)
|
||||
}
|
||||
|
||||
fn get_default_opts(
|
||||
_headers: &HeaderMap<HeaderValue>,
|
||||
metadata: HashMap<String, String>,
|
||||
_copy_source: bool,
|
||||
) -> Result<ObjectOptions> {
|
||||
Ok(ObjectOptions {
|
||||
user_defined: metadata.clone(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn extract_metadata(headers: &HeaderMap<HeaderValue>) -> HashMap<String, String> {
|
||||
let mut metadata = HashMap::new();
|
||||
|
||||
extract_metadata_from_mime(headers, &mut metadata);
|
||||
|
||||
metadata
|
||||
}
|
||||
|
||||
fn extract_metadata_from_mime(headers: &HeaderMap<HeaderValue>, metadata: &mut HashMap<String, String>) {
|
||||
for (k, v) in headers.iter() {
|
||||
if k.as_str().starts_with("x-amz-meta-") {
|
||||
metadata.insert(k.to_string(), String::from_utf8_lossy(v.as_bytes()).to_string());
|
||||
continue;
|
||||
}
|
||||
|
||||
if k.as_str().starts_with("x-rustfs-meta-") {
|
||||
metadata.insert(k.to_string(), String::from_utf8_lossy(v.as_bytes()).to_string());
|
||||
continue;
|
||||
}
|
||||
|
||||
for hd in SUPPORTED_HEADERS.iter() {
|
||||
if k.as_str() == *hd {
|
||||
metadata.insert(k.to_string(), String::from_utf8_lossy(v.as_bytes()).to_string());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !metadata.contains_key("content-type") {
|
||||
metadata.insert("content-type".to_owned(), "binary/octet-stream".to_owned());
|
||||
}
|
||||
}
|
||||
lazy_static! {
|
||||
static ref SUPPORTED_HEADERS: Vec<&'static str> = vec![
|
||||
"content-type",
|
||||
"cache-control",
|
||||
"content-language",
|
||||
"content-encoding",
|
||||
"content-disposition",
|
||||
"x-amz-storage-class",
|
||||
"x-amz-tagging",
|
||||
"expires",
|
||||
"x-amz-replication-status"
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user