use std::process::Command;
+use std::path::Path;
use anyhow::{Error, format_err, bail};
-use serde_json::{json, Value};
+use serde_json::Value;
use proxmox::sys::linux::procfs;
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
-use crate::api2::types::*;
-use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_POWER_MANAGEMENT};
+use pbs_api_types::{NODE_SCHEMA, NodePowerCommand, PRIV_SYS_AUDIT, PRIV_SYS_POWER_MANAGEMENT};
+
+use crate::api2::types::{
+ NodeCpuInformation, NodeStatus, NodeMemoryCounters, NodeSwapCounters, NodeInformation,
+};
+
+impl std::convert::From<procfs::ProcFsCPUInfo> for NodeCpuInformation {
+ fn from(info: procfs::ProcFsCPUInfo) -> Self {
+ Self {
+ model: info.model,
+ sockets: info.sockets,
+ cpus: info.cpus,
+ }
+ }
+}
#[api(
input: {
},
},
returns: {
- type: Object,
- description: "Returns node memory, CPU and (root) disk usage",
- properties: {
- memory: {
- type: Object,
- description: "node memory usage counters",
- properties: {
- total: {
- description: "total memory",
- type: Integer,
- },
- used: {
- description: "total memory",
- type: Integer,
- },
- free: {
- description: "free memory",
- type: Integer,
- },
- },
- },
- cpu: {
- type: Number,
- description: "Total CPU usage since last query.",
- optional: true,
- },
- }
+ type: NodeStatus,
},
access: {
permission: &Permission::Privilege(&["system", "status"], PRIV_SYS_AUDIT, false),
},
)]
/// Read node memory, CPU and (root) disk usage
-fn get_usage(
+fn get_status(
_param: Value,
_info: &ApiMethod,
_rpcenv: &mut dyn RpcEnvironment,
-) -> Result<Value, Error> {
-
+) -> Result<NodeStatus, Error> {
let meminfo: procfs::ProcFsMemInfo = procfs::read_meminfo()?;
+ let memory = NodeMemoryCounters {
+ total: meminfo.memtotal,
+ used: meminfo.memused,
+ free: meminfo.memfree,
+ };
+
+ let swap = NodeSwapCounters {
+ total: meminfo.swaptotal,
+ used: meminfo.swapused,
+ free: meminfo.swapfree,
+ };
+
let kstat: procfs::ProcFsStat = procfs::read_proc_stat()?;
+ let cpu = kstat.cpu;
+ let wait = kstat.iowait_percent;
+
+ let loadavg = procfs::Loadavg::read()?;
+ let loadavg = [loadavg.one(), loadavg.five(), loadavg.fifteen()];
+
+ let cpuinfo = procfs::read_cpuinfo()?;
+ let cpuinfo = cpuinfo.into();
+
+ let uname = nix::sys::utsname::uname();
+ let kversion = format!(
+ "{} {} {}",
+ uname.sysname(),
+ uname.release(),
+ uname.version()
+ );
- Ok(json!({
- "memory": {
- "total": meminfo.memtotal,
- "used": meminfo.memused,
- "free": meminfo.memfree,
+ Ok(NodeStatus {
+ memory,
+ swap,
+ root: crate::tools::disks::disk_usage(Path::new("/"))?,
+ uptime: procfs::read_proc_uptime()?.0 as u64,
+ loadavg,
+ kversion,
+ cpuinfo,
+ cpu,
+ wait,
+ info: NodeInformation {
+ fingerprint: crate::cert_info()?.fingerprint()?,
},
- "cpu": kstat.cpu,
- }))
+ })
}
#[api(
NodePowerCommand::Shutdown => "poweroff",
};
- let output = Command::new("/bin/systemctl")
+ let output = Command::new("systemctl")
.arg(systemctl_command)
.output()
.map_err(|err| format_err!("failed to execute systemctl - {}", err))?;
}
pub const ROUTER: Router = Router::new()
- .get(&API_METHOD_GET_USAGE)
+ .get(&API_METHOD_GET_STATUS)
.post(&API_METHOD_REBOOT_OR_SHUTDOWN);