diff --git a/Cargo.lock b/Cargo.lock index 026d0c23..0d17bba4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,26 @@ dependencies = [ "rand_core", ] +[[package]] +name = "darwin-libproc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb90051930c9a0f09e585762152048e23ac74d20c10590ef7cf01c0343c3046" +dependencies = [ + "darwin-libproc-sys", + "libc", + "memchr", +] + +[[package]] +name = "darwin-libproc-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57cebb5bde66eecdd30ddc4b9cd208238b15db4982ccc72db59d699ea10867c1" +dependencies = [ + "libc", +] + [[package]] name = "deranged" version = "0.3.11" @@ -551,6 +571,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "digest" version = "0.10.7" @@ -626,7 +657,7 @@ dependencies = [ "lock", "md-5", "netif", - "nix", + "nix 0.29.0", "num", "num_cpus", "openssl", @@ -1410,6 +1441,23 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "madmin" +version = "0.0.1" +dependencies = [ + "psutil", + "serde", +] + [[package]] name = "matchers" version = "0.1.0" @@ -1496,6 +1544,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + [[package]] name = "nix" version = "0.29.0" @@ -1815,6 +1874,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "platforms" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" + [[package]] name = "powerfmt" version = "0.2.0" @@ -1937,6 +2002,25 @@ dependencies = [ "tower 0.5.1", ] +[[package]] +name = "psutil" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e617cc9058daa5e1fe5a0d23ed745773a5ee354111dad1ec0235b0cc16b6730" +dependencies = [ + "cfg-if", + "darwin-libproc", + "derive_more", + "glob", + "mach2", + "nix 0.24.3", + "num_cpus", + "once_cell", + "platforms", + "thiserror", + "unescape", +] + [[package]] name = "quick-xml" version = "0.37.0" @@ -2146,6 +2230,7 @@ dependencies = [ "lazy_static", "lock", "log", + "madmin", "matchit 0.8.5", "mime", "netif", @@ -2902,6 +2987,12 @@ dependencies = [ "tz-rs", ] +[[package]] +name = "unescape" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" + [[package]] name = "unicode-ident" version = "1.0.13" diff --git a/Cargo.toml b/Cargo.toml index 47b00226..08539fe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "madmin", "rustfs", "ecstore", "e2e_test", @@ -20,6 +21,7 @@ rust-version = "1.75" version = "0.0.1" [workspace.dependencies] +madmin = { path = "./madmin" } async-trait = "0.1.83" backon = "1.2.0" bytes = "1.8.0" diff --git a/madmin/Cargo.toml b/madmin/Cargo.toml new file mode 100644 index 00000000..05e052f1 --- /dev/null +++ b/madmin/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "madmin" +edition.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[dependencies] +psutil = "3.3.0" +serde.workspace = true \ No newline at end of file diff --git a/madmin/src/health.rs b/madmin/src/health.rs new file mode 100644 index 00000000..f6d778a7 --- /dev/null +++ b/madmin/src/health.rs @@ -0,0 +1,51 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct NodeCommon { + pub addr: String, + pub error: String, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct Cpu { + vendor_id: String, + family: String, + model: String, + stepping: i32, + physical_id: String, + model_name: String, + mhz: f64, + cache_size: i32, + flags: Vec, + microcode: String, + cores: u64, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct CpuFreqStats { + name: String, + cpuinfo_current_frequency: Option, + cpuinfo_minimum_frequency: Option, + cpuinfo_maximum_frequency: Option, + cpuinfo_transition_latency: Option, + scaling_current_frequency: Option, + scaling_minimum_frequency: Option, + scaling_maximum_frequency: Option, + available_governors: String, + driver: String, + governor: String, + related_cpus: String, + set_speed: String, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct Cpus { + node_common: NodeCommon, + cpus: Vec, + cpu_freq_stats: Vec, +} + +pub fn get_cpus() -> Cpus { + // todo + Cpus::default() +} diff --git a/madmin/src/lib.rs b/madmin/src/lib.rs new file mode 100644 index 00000000..d36b2f8d --- /dev/null +++ b/madmin/src/lib.rs @@ -0,0 +1,2 @@ +pub mod health; +pub mod net; diff --git a/madmin/src/net/mod.rs b/madmin/src/net/mod.rs new file mode 100644 index 00000000..3f22342d --- /dev/null +++ b/madmin/src/net/mod.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; + +use crate::health::NodeCommon; + +pub mod net_linux; + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct NetInfo { + node_common: NodeCommon, + interface: String, + driver: String, + firmware_version: String, +} diff --git a/madmin/src/net/net_linux.rs b/madmin/src/net/net_linux.rs new file mode 100644 index 00000000..a206f708 --- /dev/null +++ b/madmin/src/net/net_linux.rs @@ -0,0 +1,9 @@ +use super::NetInfo; + +pub fn get_net_info(addr: &str, iface: &str) -> NetInfo { + let mut ni = NetInfo::default(); + ni.node_common.addr = addr.to_string(); + ni.interface = iface.to_string(); + + ni +} diff --git a/rustfs/Cargo.toml b/rustfs/Cargo.toml index f2818309..13365391 100644 --- a/rustfs/Cargo.toml +++ b/rustfs/Cargo.toml @@ -9,6 +9,7 @@ rust-version.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +madmin.workspace = true log.workspace = true async-trait.workspace = true bytes.workspace = true diff --git a/rustfs/src/grpc.rs b/rustfs/src/grpc.rs index fd7071fd..c05b3f63 100644 --- a/rustfs/src/grpc.rs +++ b/rustfs/src/grpc.rs @@ -16,6 +16,7 @@ use ecstore::{ use futures::{Stream, StreamExt}; use lock::{lock_args::LockArgs, Locker, GLOBAL_LOCAL_SERVER}; +use madmin::health::get_cpus; use protos::{ models::{PingBody, PingBodyBuilder}, proto_gen::node_service::{node_service_server::NodeService as Node, *}, @@ -1551,7 +1552,20 @@ impl Node for NodeService { } async fn get_cpus(&self, _request: Request) -> Result, Status> { - todo!() + let info = get_cpus(); + let mut buf = Vec::new(); + if let Err(err) = info.serialize(&mut Serializer::new(&mut buf)) { + return Ok(tonic::Response::new(GetCpusResponse { + success: false, + cpus: vec![], + error_info: Some(err.to_string()), + })); + } + Ok(tonic::Response::new(GetCpusResponse { + success: true, + cpus: buf, + error_info: None, + })) } async fn get_net_info(&self, _request: Request) -> Result, Status> { diff --git a/rustfs/src/peer_rest_client.rs b/rustfs/src/peer_rest_client.rs index 55e34996..24cee005 100644 --- a/rustfs/src/peer_rest_client.rs +++ b/rustfs/src/peer_rest_client.rs @@ -2,7 +2,11 @@ use std::io::Cursor; use common::error::{Error, Result}; use ecstore::{admin_server_info::ServerProperties, store_api::StorageInfo}; -use protos::{node_service_time_out_client, proto_gen::node_service::LocalStorageInfoRequest}; +use madmin::health::Cpus; +use protos::{ + node_service_time_out_client, + proto_gen::node_service::{GetCpusRequest, LocalStorageInfoRequest, ServerInfoRequest}, +}; use rmp_serde::Deserializer; use serde::Deserialize; use tonic::Request; @@ -33,15 +37,53 @@ impl PeerRestClient { } return Err(Error::msg("")); } - let info = response.storage_info; + let data = response.storage_info; - let mut buf = Deserializer::new(Cursor::new(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) -> Request { - todo!() + pub async fn server_info(&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(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 { + 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) } }