mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	feature(krata): prepare for workload rework (#276)
* chore(code): simple code cleanup * chore(code): additional code cleanup * feature(krata): rework api and make ip assignment persistent to database * rework and cleanup * fix daemon config references
This commit is contained in:
		@ -3,7 +3,7 @@ use clap::{Parser, ValueEnum};
 | 
			
		||||
use comfy_table::presets::UTF8_FULL_CONDENSED;
 | 
			
		||||
use comfy_table::{Cell, Table};
 | 
			
		||||
use krata::v1::control::{
 | 
			
		||||
    control_service_client::ControlServiceClient, HostCpuTopologyClass, HostCpuTopologyRequest,
 | 
			
		||||
    control_service_client::ControlServiceClient, GetHostCpuTopologyRequest, HostCpuTopologyClass,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
@ -31,7 +31,7 @@ pub struct HostCpuTopologyCommand {
 | 
			
		||||
impl HostCpuTopologyCommand {
 | 
			
		||||
    pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
 | 
			
		||||
        let response = client
 | 
			
		||||
            .get_host_cpu_topology(Request::new(HostCpuTopologyRequest {}))
 | 
			
		||||
            .get_host_cpu_topology(Request::new(GetHostCpuTopologyRequest {}))
 | 
			
		||||
            .await?
 | 
			
		||||
            .into_inner();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use krata::v1::control::{control_service_client::ControlServiceClient, IdentifyHostRequest};
 | 
			
		||||
use krata::v1::control::{control_service_client::ControlServiceClient, HostStatusRequest};
 | 
			
		||||
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
 | 
			
		||||
#[derive(Parser)]
 | 
			
		||||
#[command(about = "Identify information about the host")]
 | 
			
		||||
pub struct HostIdentifyCommand {}
 | 
			
		||||
#[command(about = "Get information about the host")]
 | 
			
		||||
pub struct HostStatusCommand {}
 | 
			
		||||
 | 
			
		||||
impl HostIdentifyCommand {
 | 
			
		||||
impl HostStatusCommand {
 | 
			
		||||
    pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
 | 
			
		||||
        let response = client
 | 
			
		||||
            .identify_host(Request::new(IdentifyHostRequest {}))
 | 
			
		||||
            .host_status(Request::new(HostStatusRequest {}))
 | 
			
		||||
            .await?
 | 
			
		||||
            .into_inner();
 | 
			
		||||
        println!("Host UUID: {}", response.host_uuid);
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ use krata::events::EventStream;
 | 
			
		||||
use krata::v1::control::control_service_client::ControlServiceClient;
 | 
			
		||||
 | 
			
		||||
use crate::cli::host::cpu_topology::HostCpuTopologyCommand;
 | 
			
		||||
use crate::cli::host::identify::HostIdentifyCommand;
 | 
			
		||||
use crate::cli::host::identify::HostStatusCommand;
 | 
			
		||||
use crate::cli::host::idm_snoop::HostIdmSnoopCommand;
 | 
			
		||||
 | 
			
		||||
pub mod cpu_topology;
 | 
			
		||||
@ -33,7 +33,7 @@ impl HostCommand {
 | 
			
		||||
#[derive(Subcommand)]
 | 
			
		||||
pub enum HostCommands {
 | 
			
		||||
    CpuTopology(HostCpuTopologyCommand),
 | 
			
		||||
    Identify(HostIdentifyCommand),
 | 
			
		||||
    Status(HostStatusCommand),
 | 
			
		||||
    IdmSnoop(HostIdmSnoopCommand),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,7 @@ impl HostCommands {
 | 
			
		||||
        match self {
 | 
			
		||||
            HostCommands::CpuTopology(cpu_topology) => cpu_topology.run(client).await,
 | 
			
		||||
 | 
			
		||||
            HostCommands::Identify(identify) => identify.run(client).await,
 | 
			
		||||
            HostCommands::Status(status) => status.run(client).await,
 | 
			
		||||
 | 
			
		||||
            HostCommands::IdmSnoop(snoop) => snoop.run(client, events).await,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ use clap::Parser;
 | 
			
		||||
use krata::{
 | 
			
		||||
    client::ControlClientProvider,
 | 
			
		||||
    events::EventStream,
 | 
			
		||||
    v1::control::{control_service_client::ControlServiceClient, ResolveZoneRequest},
 | 
			
		||||
    v1::control::{control_service_client::ControlServiceClient, ResolveZoneIdRequest},
 | 
			
		||||
};
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
 | 
			
		||||
@ -51,7 +51,7 @@ impl ControlCommand {
 | 
			
		||||
 | 
			
		||||
            ControlCommands::Device(device) => device.run(client, events).await,
 | 
			
		||||
 | 
			
		||||
            ControlCommands::Host(snoop) => snoop.run(client, events).await,
 | 
			
		||||
            ControlCommands::Host(host) => host.run(client, events).await,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -61,14 +61,14 @@ pub async fn resolve_zone(
 | 
			
		||||
    name: &str,
 | 
			
		||||
) -> Result<String> {
 | 
			
		||||
    let reply = client
 | 
			
		||||
        .resolve_zone(Request::new(ResolveZoneRequest {
 | 
			
		||||
        .resolve_zone_id(Request::new(ResolveZoneIdRequest {
 | 
			
		||||
            name: name.to_string(),
 | 
			
		||||
        }))
 | 
			
		||||
        .await?
 | 
			
		||||
        .into_inner();
 | 
			
		||||
 | 
			
		||||
    if let Some(zone) = reply.zone {
 | 
			
		||||
        Ok(zone.id)
 | 
			
		||||
    if !reply.zone_id.is_empty() {
 | 
			
		||||
        Ok(reply.zone_id)
 | 
			
		||||
    } else {
 | 
			
		||||
        Err(anyhow!("unable to resolve zone '{}'", name))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -2,20 +2,16 @@ use anyhow::Result;
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use krata::{
 | 
			
		||||
    events::EventStream,
 | 
			
		||||
    v1::{
 | 
			
		||||
        common::ZoneStatus,
 | 
			
		||||
        control::{
 | 
			
		||||
            control_service_client::ControlServiceClient, watch_events_reply::Event,
 | 
			
		||||
            DestroyZoneRequest,
 | 
			
		||||
        },
 | 
			
		||||
    v1::control::{
 | 
			
		||||
        control_service_client::ControlServiceClient, watch_events_reply::Event, DestroyZoneRequest,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::cli::resolve_zone;
 | 
			
		||||
use krata::v1::common::ZoneState;
 | 
			
		||||
use log::error;
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
 | 
			
		||||
use crate::cli::resolve_zone;
 | 
			
		||||
 | 
			
		||||
#[derive(Parser)]
 | 
			
		||||
#[command(about = "Destroy a zone")]
 | 
			
		||||
pub struct ZoneDestroyCommand {
 | 
			
		||||
@ -61,12 +57,12 @@ async fn wait_zone_destroyed(id: &str, events: EventStream) -> Result<()> {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let Some(state) = zone.state else {
 | 
			
		||||
        let Some(status) = zone.status else {
 | 
			
		||||
            continue;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if let Some(ref error) = state.error_info {
 | 
			
		||||
            if state.status() == ZoneStatus::Failed {
 | 
			
		||||
        if let Some(ref error) = status.error_status {
 | 
			
		||||
            if status.state() == ZoneState::Failed {
 | 
			
		||||
                error!("destroy failed: {}", error.message);
 | 
			
		||||
                std::process::exit(1);
 | 
			
		||||
            } else {
 | 
			
		||||
@ -74,7 +70,7 @@ async fn wait_zone_destroyed(id: &str, events: EventStream) -> Result<()> {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if state.status() == ZoneStatus::Destroyed {
 | 
			
		||||
        if status.state() == ZoneState::Destroyed {
 | 
			
		||||
            std::process::exit(0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ use anyhow::Result;
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use krata::v1::{
 | 
			
		||||
    common::{ZoneTaskSpec, ZoneTaskSpecEnvVar},
 | 
			
		||||
    control::{control_service_client::ControlServiceClient, ExecZoneRequest},
 | 
			
		||||
    control::{control_service_client::ControlServiceClient, ExecInsideZoneRequest},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
@ -34,7 +34,7 @@ pub struct ZoneExecCommand {
 | 
			
		||||
impl ZoneExecCommand {
 | 
			
		||||
    pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
 | 
			
		||||
        let zone_id: String = resolve_zone(&mut client, &self.zone).await?;
 | 
			
		||||
        let initial = ExecZoneRequest {
 | 
			
		||||
        let initial = ExecInsideZoneRequest {
 | 
			
		||||
            zone_id,
 | 
			
		||||
            task: Some(ZoneTaskSpec {
 | 
			
		||||
                environment: env_map(&self.env.unwrap_or_default())
 | 
			
		||||
@ -52,7 +52,10 @@ impl ZoneExecCommand {
 | 
			
		||||
 | 
			
		||||
        let stream = StdioConsoleStream::stdin_stream_exec(initial).await;
 | 
			
		||||
 | 
			
		||||
        let response = client.exec_zone(Request::new(stream)).await?.into_inner();
 | 
			
		||||
        let response = client
 | 
			
		||||
            .exec_inside_zone(Request::new(stream))
 | 
			
		||||
            .await?
 | 
			
		||||
            .into_inner();
 | 
			
		||||
 | 
			
		||||
        let code = StdioConsoleStream::exec_output(response).await?;
 | 
			
		||||
        std::process::exit(code);
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@ use krata::{
 | 
			
		||||
    v1::{
 | 
			
		||||
        common::{
 | 
			
		||||
            zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneOciImageSpec, ZoneSpec,
 | 
			
		||||
            ZoneSpecDevice, ZoneStatus, ZoneTaskSpec, ZoneTaskSpecEnvVar,
 | 
			
		||||
            ZoneSpecDevice, ZoneState, ZoneTaskSpec, ZoneTaskSpecEnvVar,
 | 
			
		||||
        },
 | 
			
		||||
        control::{
 | 
			
		||||
            control_service_client::ControlServiceClient, watch_events_reply::Event,
 | 
			
		||||
@ -120,7 +120,7 @@ impl ZoneLaunchCommand {
 | 
			
		||||
                image: Some(image),
 | 
			
		||||
                kernel,
 | 
			
		||||
                initrd,
 | 
			
		||||
                vcpus: self.cpus,
 | 
			
		||||
                cpus: self.cpus,
 | 
			
		||||
                mem: self.mem,
 | 
			
		||||
                task: Some(ZoneTaskSpec {
 | 
			
		||||
                    environment: env_map(&self.env.unwrap_or_default())
 | 
			
		||||
@ -209,12 +209,12 @@ async fn wait_zone_started(id: &str, events: EventStream) -> Result<()> {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let Some(state) = zone.state else {
 | 
			
		||||
                let Some(status) = zone.status else {
 | 
			
		||||
                    continue;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if let Some(ref error) = state.error_info {
 | 
			
		||||
                    if state.status() == ZoneStatus::Failed {
 | 
			
		||||
                if let Some(ref error) = status.error_status {
 | 
			
		||||
                    if status.state() == ZoneState::Failed {
 | 
			
		||||
                        error!("launch failed: {}", error.message);
 | 
			
		||||
                        std::process::exit(1);
 | 
			
		||||
                    } else {
 | 
			
		||||
@ -222,12 +222,12 @@ async fn wait_zone_started(id: &str, events: EventStream) -> Result<()> {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if state.status() == ZoneStatus::Destroyed {
 | 
			
		||||
                if status.state() == ZoneState::Destroyed {
 | 
			
		||||
                    error!("zone destroyed");
 | 
			
		||||
                    std::process::exit(1);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if state.status() == ZoneStatus::Started {
 | 
			
		||||
                if status.state() == ZoneState::Created {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -4,18 +4,19 @@ use comfy_table::{presets::UTF8_FULL_CONDENSED, Cell, Color, Table};
 | 
			
		||||
use krata::{
 | 
			
		||||
    events::EventStream,
 | 
			
		||||
    v1::{
 | 
			
		||||
        common::{Zone, ZoneStatus},
 | 
			
		||||
        common::Zone,
 | 
			
		||||
        control::{
 | 
			
		||||
            control_service_client::ControlServiceClient, ListZonesRequest, ResolveZoneRequest,
 | 
			
		||||
            control_service_client::ControlServiceClient, ListZonesRequest, ResolveZoneIdRequest,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::format::{kv2line, proto2dynamic, proto2kv, zone_simple_line, zone_state_text};
 | 
			
		||||
use krata::v1::common::ZoneState;
 | 
			
		||||
use krata::v1::control::GetZoneRequest;
 | 
			
		||||
use serde_json::Value;
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
 | 
			
		||||
use crate::format::{kv2line, proto2dynamic, proto2kv, zone_simple_line, zone_status_text};
 | 
			
		||||
 | 
			
		||||
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
 | 
			
		||||
enum ZoneListFormat {
 | 
			
		||||
    Table,
 | 
			
		||||
@ -44,11 +45,21 @@ impl ZoneListCommand {
 | 
			
		||||
    ) -> Result<()> {
 | 
			
		||||
        let mut zones = if let Some(ref zone) = self.zone {
 | 
			
		||||
            let reply = client
 | 
			
		||||
                .resolve_zone(Request::new(ResolveZoneRequest { name: zone.clone() }))
 | 
			
		||||
                .resolve_zone_id(Request::new(ResolveZoneIdRequest { name: zone.clone() }))
 | 
			
		||||
                .await?
 | 
			
		||||
                .into_inner();
 | 
			
		||||
            if let Some(zone) = reply.zone {
 | 
			
		||||
                vec![zone]
 | 
			
		||||
            if !reply.zone_id.is_empty() {
 | 
			
		||||
                let reply = client
 | 
			
		||||
                    .get_zone(Request::new(GetZoneRequest {
 | 
			
		||||
                        zone_id: reply.zone_id,
 | 
			
		||||
                    }))
 | 
			
		||||
                    .await?
 | 
			
		||||
                    .into_inner();
 | 
			
		||||
                if let Some(zone) = reply.zone {
 | 
			
		||||
                    vec![zone]
 | 
			
		||||
                } else {
 | 
			
		||||
                    return Err(anyhow!("unable to resolve zone '{}'", zone));
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                return Err(anyhow!("unable to resolve zone '{}'", zone));
 | 
			
		||||
            }
 | 
			
		||||
@ -115,30 +126,30 @@ impl ZoneListCommand {
 | 
			
		||||
        let mut table = Table::new();
 | 
			
		||||
        table.load_preset(UTF8_FULL_CONDENSED);
 | 
			
		||||
        table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
 | 
			
		||||
        table.set_header(vec!["name", "uuid", "status", "ipv4", "ipv6"]);
 | 
			
		||||
        table.set_header(vec!["name", "uuid", "state", "ipv4", "ipv6"]);
 | 
			
		||||
        for zone in zones {
 | 
			
		||||
            let ipv4 = zone
 | 
			
		||||
                .state
 | 
			
		||||
                .status
 | 
			
		||||
                .as_ref()
 | 
			
		||||
                .and_then(|x| x.network.as_ref())
 | 
			
		||||
                .and_then(|x| x.network_status.as_ref())
 | 
			
		||||
                .map(|x| x.zone_ipv4.as_str())
 | 
			
		||||
                .unwrap_or("n/a");
 | 
			
		||||
            let ipv6 = zone
 | 
			
		||||
                .state
 | 
			
		||||
                .status
 | 
			
		||||
                .as_ref()
 | 
			
		||||
                .and_then(|x| x.network.as_ref())
 | 
			
		||||
                .and_then(|x| x.network_status.as_ref())
 | 
			
		||||
                .map(|x| x.zone_ipv6.as_str())
 | 
			
		||||
                .unwrap_or("n/a");
 | 
			
		||||
            let Some(spec) = zone.spec else {
 | 
			
		||||
                continue;
 | 
			
		||||
            };
 | 
			
		||||
            let status = zone.state.as_ref().cloned().unwrap_or_default().status();
 | 
			
		||||
            let status_text = zone_status_text(status);
 | 
			
		||||
            let state = zone.status.as_ref().cloned().unwrap_or_default().state();
 | 
			
		||||
            let status_text = zone_state_text(state);
 | 
			
		||||
 | 
			
		||||
            let status_color = match status {
 | 
			
		||||
                ZoneStatus::Destroyed | ZoneStatus::Failed => Color::Red,
 | 
			
		||||
                ZoneStatus::Destroying | ZoneStatus::Exited | ZoneStatus::Starting => Color::Yellow,
 | 
			
		||||
                ZoneStatus::Started => Color::Green,
 | 
			
		||||
            let status_color = match state {
 | 
			
		||||
                ZoneState::Destroyed | ZoneState::Failed => Color::Red,
 | 
			
		||||
                ZoneState::Destroying | ZoneState::Exited | ZoneState::Creating => Color::Yellow,
 | 
			
		||||
                ZoneState::Created => Color::Green,
 | 
			
		||||
                _ => Color::Reset,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use krata::v1::control::{control_service_client::ControlServiceClient, ResolveZoneRequest};
 | 
			
		||||
use krata::v1::control::{control_service_client::ControlServiceClient, ResolveZoneIdRequest};
 | 
			
		||||
 | 
			
		||||
use tonic::{transport::Channel, Request};
 | 
			
		||||
 | 
			
		||||
@ -14,13 +14,13 @@ pub struct ZoneResolveCommand {
 | 
			
		||||
impl ZoneResolveCommand {
 | 
			
		||||
    pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
 | 
			
		||||
        let reply = client
 | 
			
		||||
            .resolve_zone(Request::new(ResolveZoneRequest {
 | 
			
		||||
            .resolve_zone_id(Request::new(ResolveZoneIdRequest {
 | 
			
		||||
                name: self.zone.clone(),
 | 
			
		||||
            }))
 | 
			
		||||
            .await?
 | 
			
		||||
            .into_inner();
 | 
			
		||||
        if let Some(zone) = reply.zone {
 | 
			
		||||
            println!("{}", zone.id);
 | 
			
		||||
        if !reply.zone_id.is_empty() {
 | 
			
		||||
            println!("{}", reply.zone_id);
 | 
			
		||||
        } else {
 | 
			
		||||
            std::process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ use ratatui::{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    format::zone_status_text,
 | 
			
		||||
    format::zone_state_text,
 | 
			
		||||
    metrics::{
 | 
			
		||||
        lookup_metric_value, MultiMetricCollector, MultiMetricCollectorHandle, MultiMetricState,
 | 
			
		||||
    },
 | 
			
		||||
@ -106,7 +106,7 @@ impl ZoneTopApp {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
@ -157,7 +157,7 @@ impl Widget for &mut ZoneTopApp {
 | 
			
		||||
                continue;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let Some(ref state) = ms.zone.state else {
 | 
			
		||||
            let Some(ref status) = ms.zone.status else {
 | 
			
		||||
                continue;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@ -177,7 +177,7 @@ impl Widget for &mut ZoneTopApp {
 | 
			
		||||
            let row = Row::new(vec![
 | 
			
		||||
                spec.name.clone(),
 | 
			
		||||
                ms.zone.id.clone(),
 | 
			
		||||
                zone_status_text(state.status()),
 | 
			
		||||
                zone_state_text(status.state()),
 | 
			
		||||
                memory_total.unwrap_or_default(),
 | 
			
		||||
                memory_used.unwrap_or_default(),
 | 
			
		||||
                memory_free.unwrap_or_default(),
 | 
			
		||||
 | 
			
		||||
@ -4,14 +4,12 @@ use crossterm::{
 | 
			
		||||
    terminal::{disable_raw_mode, enable_raw_mode, is_raw_mode_enabled},
 | 
			
		||||
    tty::IsTty,
 | 
			
		||||
};
 | 
			
		||||
use krata::v1::common::ZoneState;
 | 
			
		||||
use krata::{
 | 
			
		||||
    events::EventStream,
 | 
			
		||||
    v1::{
 | 
			
		||||
        common::ZoneStatus,
 | 
			
		||||
        control::{
 | 
			
		||||
            watch_events_reply::Event, ExecZoneReply, ExecZoneRequest, ZoneConsoleReply,
 | 
			
		||||
            ZoneConsoleRequest,
 | 
			
		||||
        },
 | 
			
		||||
    v1::control::{
 | 
			
		||||
        watch_events_reply::Event, ExecInsideZoneReply, ExecInsideZoneRequest, ZoneConsoleReply,
 | 
			
		||||
        ZoneConsoleRequest,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
use log::debug;
 | 
			
		||||
@ -49,8 +47,8 @@ impl StdioConsoleStream {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn stdin_stream_exec(
 | 
			
		||||
        initial: ExecZoneRequest,
 | 
			
		||||
    ) -> impl Stream<Item = ExecZoneRequest> {
 | 
			
		||||
        initial: ExecInsideZoneRequest,
 | 
			
		||||
    ) -> impl Stream<Item = ExecInsideZoneRequest> {
 | 
			
		||||
        let mut stdin = stdin();
 | 
			
		||||
        stream! {
 | 
			
		||||
            yield initial;
 | 
			
		||||
@ -68,7 +66,7 @@ impl StdioConsoleStream {
 | 
			
		||||
                if size == 1 && buffer[0] == 0x1d {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                yield ExecZoneRequest { zone_id: String::default(), task: None, data };
 | 
			
		||||
                yield ExecInsideZoneRequest { zone_id: String::default(), task: None, data };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -90,7 +88,7 @@ impl StdioConsoleStream {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn exec_output(mut stream: Streaming<ExecZoneReply>) -> Result<i32> {
 | 
			
		||||
    pub async fn exec_output(mut stream: Streaming<ExecInsideZoneReply>) -> Result<i32> {
 | 
			
		||||
        let mut stdout = stdout();
 | 
			
		||||
        let mut stderr = stderr();
 | 
			
		||||
        while let Some(reply) = stream.next().await {
 | 
			
		||||
@ -128,7 +126,7 @@ impl StdioConsoleStream {
 | 
			
		||||
                    continue;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                let Some(state) = zone.state else {
 | 
			
		||||
                let Some(status) = zone.status else {
 | 
			
		||||
                    continue;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
@ -136,12 +134,12 @@ impl StdioConsoleStream {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if let Some(exit_info) = state.exit_info {
 | 
			
		||||
                    return Some(exit_info.code);
 | 
			
		||||
                if let Some(exit_status) = status.exit_status {
 | 
			
		||||
                    return Some(exit_status.code);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let status = state.status();
 | 
			
		||||
                if status == ZoneStatus::Destroying || status == ZoneStatus::Destroyed {
 | 
			
		||||
                let state = status.state();
 | 
			
		||||
                if state == ZoneState::Destroying || state == ZoneState::Destroyed {
 | 
			
		||||
                    return Some(10);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -3,11 +3,12 @@ use std::{collections::HashMap, time::Duration};
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use fancy_duration::FancyDuration;
 | 
			
		||||
use human_bytes::human_bytes;
 | 
			
		||||
use krata::v1::common::{Zone, ZoneMetricFormat, ZoneMetricNode, ZoneStatus};
 | 
			
		||||
use prost_reflect::{DynamicMessage, ReflectMessage};
 | 
			
		||||
use prost_types::Value;
 | 
			
		||||
use termtree::Tree;
 | 
			
		||||
 | 
			
		||||
use krata::v1::common::{Zone, ZoneMetricFormat, ZoneMetricNode, ZoneState};
 | 
			
		||||
 | 
			
		||||
pub fn proto2dynamic(proto: impl ReflectMessage) -> Result<DynamicMessage> {
 | 
			
		||||
    Ok(DynamicMessage::decode(
 | 
			
		||||
        proto.descriptor(),
 | 
			
		||||
@ -75,30 +76,30 @@ pub fn kv2line(map: HashMap<String, String>) -> String {
 | 
			
		||||
        .join(" ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn zone_status_text(status: ZoneStatus) -> String {
 | 
			
		||||
pub fn zone_state_text(status: ZoneState) -> String {
 | 
			
		||||
    match status {
 | 
			
		||||
        ZoneStatus::Starting => "starting",
 | 
			
		||||
        ZoneStatus::Started => "started",
 | 
			
		||||
        ZoneStatus::Destroying => "destroying",
 | 
			
		||||
        ZoneStatus::Destroyed => "destroyed",
 | 
			
		||||
        ZoneStatus::Exited => "exited",
 | 
			
		||||
        ZoneStatus::Failed => "failed",
 | 
			
		||||
        ZoneState::Creating => "creating",
 | 
			
		||||
        ZoneState::Created => "created",
 | 
			
		||||
        ZoneState::Destroying => "destroying",
 | 
			
		||||
        ZoneState::Destroyed => "destroyed",
 | 
			
		||||
        ZoneState::Exited => "exited",
 | 
			
		||||
        ZoneState::Failed => "failed",
 | 
			
		||||
        _ => "unknown",
 | 
			
		||||
    }
 | 
			
		||||
    .to_string()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn zone_simple_line(zone: &Zone) -> String {
 | 
			
		||||
    let state = zone_status_text(
 | 
			
		||||
        zone.state
 | 
			
		||||
    let state = zone_state_text(
 | 
			
		||||
        zone.status
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .map(|x| x.status())
 | 
			
		||||
            .unwrap_or(ZoneStatus::Unknown),
 | 
			
		||||
            .map(|x| x.state())
 | 
			
		||||
            .unwrap_or(ZoneState::Unknown),
 | 
			
		||||
    );
 | 
			
		||||
    let name = zone.spec.as_ref().map(|x| x.name.as_str()).unwrap_or("");
 | 
			
		||||
    let network = zone.state.as_ref().and_then(|x| x.network.as_ref());
 | 
			
		||||
    let ipv4 = network.map(|x| x.zone_ipv4.as_str()).unwrap_or("");
 | 
			
		||||
    let ipv6 = network.map(|x| x.zone_ipv6.as_str()).unwrap_or("");
 | 
			
		||||
    let network_status = zone.status.as_ref().and_then(|x| x.network_status.as_ref());
 | 
			
		||||
    let ipv4 = network_status.map(|x| x.zone_ipv4.as_str()).unwrap_or("");
 | 
			
		||||
    let ipv6 = network_status.map(|x| x.zone_ipv6.as_str()).unwrap_or("");
 | 
			
		||||
    format!("{}\t{}\t{}\t{}\t{}", zone.id, state, name, ipv4, ipv6)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
use crate::format::metrics_value_pretty;
 | 
			
		||||
use anyhow::Result;
 | 
			
		||||
use krata::v1::common::ZoneState;
 | 
			
		||||
use krata::{
 | 
			
		||||
    events::EventStream,
 | 
			
		||||
    v1::{
 | 
			
		||||
        common::{Zone, ZoneMetricNode, ZoneStatus},
 | 
			
		||||
        common::{Zone, ZoneMetricNode},
 | 
			
		||||
        control::{
 | 
			
		||||
            control_service_client::ControlServiceClient, watch_events_reply::Event,
 | 
			
		||||
            ListZonesRequest, ReadZoneMetricsRequest,
 | 
			
		||||
@ -19,8 +21,6 @@ use tokio::{
 | 
			
		||||
};
 | 
			
		||||
use tonic::transport::Channel;
 | 
			
		||||
 | 
			
		||||
use crate::format::metrics_value_pretty;
 | 
			
		||||
 | 
			
		||||
pub struct MetricState {
 | 
			
		||||
    pub zone: Zone,
 | 
			
		||||
    pub root: Option<ZoneMetricNode>,
 | 
			
		||||
@ -86,11 +86,11 @@ impl MultiMetricCollector {
 | 
			
		||||
                            let Some(zone) = changed.zone else {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            };
 | 
			
		||||
                            let Some(ref state) = zone.state else {
 | 
			
		||||
                            let Some(ref status) = zone.status else {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            };
 | 
			
		||||
                            zones.retain(|x| x.id != zone.id);
 | 
			
		||||
                            if state.status() != ZoneStatus::Destroying {
 | 
			
		||||
                            if status.state() != ZoneState::Destroying {
 | 
			
		||||
                                zones.push(zone);
 | 
			
		||||
                            }
 | 
			
		||||
                        false
 | 
			
		||||
@ -112,11 +112,11 @@ impl MultiMetricCollector {
 | 
			
		||||
 | 
			
		||||
            let mut metrics = Vec::new();
 | 
			
		||||
            for zone in &zones {
 | 
			
		||||
                let Some(ref state) = zone.state else {
 | 
			
		||||
                let Some(ref status) = zone.status else {
 | 
			
		||||
                    continue;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if state.status() != ZoneStatus::Started {
 | 
			
		||||
                if status.state() != ZoneState::Created {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user