mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 05:10:55 +00:00
feature(ctl): add --format option to host status and improve cpu topology format (#355)
This commit is contained in:
parent
adb7b29354
commit
7f5609a846
@ -23,7 +23,7 @@ enum DeviceListFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(about = "List the devices on the isolation engine")]
|
#[command(about = "List device information")]
|
||||||
pub struct DeviceListCommand {
|
pub struct DeviceListCommand {
|
||||||
#[arg(short, long, default_value = "table", help = "Output format")]
|
#[arg(short, long, default_value = "table", help = "Output format")]
|
||||||
format: DeviceListFormat,
|
format: DeviceListFormat,
|
||||||
|
@ -5,7 +5,9 @@ use comfy_table::{Cell, Table};
|
|||||||
use krata::v1::control::{
|
use krata::v1::control::{
|
||||||
control_service_client::ControlServiceClient, GetHostCpuTopologyRequest, HostCpuTopologyClass,
|
control_service_client::ControlServiceClient, GetHostCpuTopologyRequest, HostCpuTopologyClass,
|
||||||
};
|
};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::format::{kv2line, proto2dynamic, proto2kv};
|
||||||
use tonic::{transport::Channel, Request};
|
use tonic::{transport::Channel, Request};
|
||||||
|
|
||||||
fn class_to_str(input: HostCpuTopologyClass) -> String {
|
fn class_to_str(input: HostCpuTopologyClass) -> String {
|
||||||
@ -19,6 +21,11 @@ fn class_to_str(input: HostCpuTopologyClass) -> String {
|
|||||||
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||||
enum HostCpuTopologyFormat {
|
enum HostCpuTopologyFormat {
|
||||||
Table,
|
Table,
|
||||||
|
Json,
|
||||||
|
JsonPretty,
|
||||||
|
Jsonl,
|
||||||
|
Yaml,
|
||||||
|
KeyValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@ -35,24 +42,61 @@ impl HostCpuTopologyCommand {
|
|||||||
.await?
|
.await?
|
||||||
.into_inner();
|
.into_inner();
|
||||||
|
|
||||||
let mut table = Table::new();
|
match self.format {
|
||||||
table.load_preset(UTF8_FULL_CONDENSED);
|
HostCpuTopologyFormat::Table => {
|
||||||
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
|
let mut table = Table::new();
|
||||||
table.set_header(vec!["id", "node", "socket", "core", "thread", "class"]);
|
table.load_preset(UTF8_FULL_CONDENSED);
|
||||||
|
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
|
||||||
|
table.set_header(vec!["id", "node", "socket", "core", "thread", "class"]);
|
||||||
|
|
||||||
for (i, cpu) in response.cpus.iter().enumerate() {
|
for (i, cpu) in response.cpus.iter().enumerate() {
|
||||||
table.add_row(vec![
|
table.add_row(vec![
|
||||||
Cell::new(i),
|
Cell::new(i),
|
||||||
Cell::new(cpu.node),
|
Cell::new(cpu.node),
|
||||||
Cell::new(cpu.socket),
|
Cell::new(cpu.socket),
|
||||||
Cell::new(cpu.core),
|
Cell::new(cpu.core),
|
||||||
Cell::new(cpu.thread),
|
Cell::new(cpu.thread),
|
||||||
Cell::new(class_to_str(cpu.class())),
|
Cell::new(class_to_str(cpu.class())),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !table.is_empty() {
|
if !table.is_empty() {
|
||||||
println!("{}", table);
|
println!("{}", table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HostCpuTopologyFormat::Json
|
||||||
|
| HostCpuTopologyFormat::JsonPretty
|
||||||
|
| HostCpuTopologyFormat::Yaml => {
|
||||||
|
let mut values = Vec::new();
|
||||||
|
for cpu in response.cpus {
|
||||||
|
let message = proto2dynamic(cpu)?;
|
||||||
|
values.push(serde_json::to_value(message)?);
|
||||||
|
}
|
||||||
|
let value = Value::Array(values);
|
||||||
|
let encoded = if self.format == HostCpuTopologyFormat::JsonPretty {
|
||||||
|
serde_json::to_string_pretty(&value)?
|
||||||
|
} else if self.format == HostCpuTopologyFormat::Yaml {
|
||||||
|
serde_yaml::to_string(&value)?
|
||||||
|
} else {
|
||||||
|
serde_json::to_string(&value)?
|
||||||
|
};
|
||||||
|
println!("{}", encoded.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
HostCpuTopologyFormat::Jsonl => {
|
||||||
|
for cpu in response.cpus {
|
||||||
|
let message = proto2dynamic(cpu)?;
|
||||||
|
println!("{}", serde_json::to_string(&message)?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HostCpuTopologyFormat::KeyValue => {
|
||||||
|
for cpu in response.cpus {
|
||||||
|
let kvs = proto2kv(cpu)?;
|
||||||
|
println!("{}", kv2line(kvs),);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
use clap::Parser;
|
|
||||||
use krata::v1::control::{control_service_client::ControlServiceClient, HostStatusRequest};
|
|
||||||
|
|
||||||
use tonic::{transport::Channel, Request};
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[command(about = "Get information about the host")]
|
|
||||||
pub struct HostStatusCommand {}
|
|
||||||
|
|
||||||
impl HostStatusCommand {
|
|
||||||
pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
|
|
||||||
let response = client
|
|
||||||
.host_status(Request::new(HostStatusRequest {}))
|
|
||||||
.await?
|
|
||||||
.into_inner();
|
|
||||||
println!("Host UUID: {}", response.host_uuid);
|
|
||||||
println!("Host Domain: {}", response.host_domid);
|
|
||||||
println!("Krata Version: {}", response.krata_version);
|
|
||||||
println!("Host IPv4: {}", response.host_ipv4);
|
|
||||||
println!("Host IPv6: {}", response.host_ipv6);
|
|
||||||
println!("Host Ethernet Address: {}", response.host_mac);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,13 +7,13 @@ use krata::v1::control::control_service_client::ControlServiceClient;
|
|||||||
|
|
||||||
use crate::cli::host::cpu_topology::HostCpuTopologyCommand;
|
use crate::cli::host::cpu_topology::HostCpuTopologyCommand;
|
||||||
use crate::cli::host::hv_console::HostHvConsoleCommand;
|
use crate::cli::host::hv_console::HostHvConsoleCommand;
|
||||||
use crate::cli::host::identify::HostStatusCommand;
|
|
||||||
use crate::cli::host::idm_snoop::HostIdmSnoopCommand;
|
use crate::cli::host::idm_snoop::HostIdmSnoopCommand;
|
||||||
|
use crate::cli::host::status::HostStatusCommand;
|
||||||
|
|
||||||
pub mod cpu_topology;
|
pub mod cpu_topology;
|
||||||
pub mod hv_console;
|
pub mod hv_console;
|
||||||
pub mod identify;
|
|
||||||
pub mod idm_snoop;
|
pub mod idm_snoop;
|
||||||
|
pub mod status;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(about = "Manage the host of the isolation engine")]
|
#[command(about = "Manage the host of the isolation engine")]
|
||||||
|
60
crates/ctl/src/cli/host/status.rs
Normal file
60
crates/ctl/src/cli/host/status.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use clap::{Parser, ValueEnum};
|
||||||
|
use krata::v1::control::{control_service_client::ControlServiceClient, HostStatusRequest};
|
||||||
|
|
||||||
|
use crate::format::{kv2line, proto2dynamic, proto2kv};
|
||||||
|
use tonic::{transport::Channel, Request};
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||||
|
enum HostStatusFormat {
|
||||||
|
Simple,
|
||||||
|
Json,
|
||||||
|
JsonPretty,
|
||||||
|
Yaml,
|
||||||
|
KeyValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(about = "Get information about the host")]
|
||||||
|
pub struct HostStatusCommand {
|
||||||
|
#[arg(short, long, default_value = "simple", help = "Output format")]
|
||||||
|
format: HostStatusFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostStatusCommand {
|
||||||
|
pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
|
||||||
|
let response = client
|
||||||
|
.host_status(Request::new(HostStatusRequest {}))
|
||||||
|
.await?
|
||||||
|
.into_inner();
|
||||||
|
match self.format {
|
||||||
|
HostStatusFormat::Simple => {
|
||||||
|
println!("Host UUID: {}", response.host_uuid);
|
||||||
|
println!("Host Domain: {}", response.host_domid);
|
||||||
|
println!("Krata Version: {}", response.krata_version);
|
||||||
|
println!("Host IPv4: {}", response.host_ipv4);
|
||||||
|
println!("Host IPv6: {}", response.host_ipv6);
|
||||||
|
println!("Host Ethernet Address: {}", response.host_mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
HostStatusFormat::Json | HostStatusFormat::JsonPretty | HostStatusFormat::Yaml => {
|
||||||
|
let message = proto2dynamic(response)?;
|
||||||
|
let value = serde_json::to_value(message)?;
|
||||||
|
let encoded = if self.format == HostStatusFormat::JsonPretty {
|
||||||
|
serde_json::to_string_pretty(&value)?
|
||||||
|
} else if self.format == HostStatusFormat::Yaml {
|
||||||
|
serde_yaml::to_string(&value)?
|
||||||
|
} else {
|
||||||
|
serde_json::to_string(&value)?
|
||||||
|
};
|
||||||
|
println!("{}", encoded.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
HostStatusFormat::KeyValue => {
|
||||||
|
let kvs = proto2kv(response)?;
|
||||||
|
println!("{}", kv2line(kvs),);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ enum ZoneListFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(about = "List the zones on the isolation engine")]
|
#[command(about = "List zone information")]
|
||||||
pub struct ZoneListCommand {
|
pub struct ZoneListCommand {
|
||||||
#[arg(short, long, default_value = "table", help = "Output format")]
|
#[arg(short, long, default_value = "table", help = "Output format")]
|
||||||
format: ZoneListFormat,
|
format: ZoneListFormat,
|
||||||
|
Loading…
Reference in New Issue
Block a user