kratactl/cli/zone/
attach.rs

1use anyhow::Result;
2use clap::Parser;
3use krata::{events::EventStream, v1::control::control_service_client::ControlServiceClient};
4
5use tokio::select;
6use tonic::transport::Channel;
7
8use crate::console::StdioConsoleStream;
9
10use crate::cli::resolve_zone;
11
12#[derive(Parser)]
13#[command(about = "Attach to the zone console")]
14pub struct ZoneAttachCommand {
15    #[arg(help = "Zone to attach to, either the name or the uuid")]
16    zone: String,
17}
18
19impl ZoneAttachCommand {
20    pub async fn run(
21        self,
22        mut client: ControlServiceClient<Channel>,
23        events: EventStream,
24    ) -> Result<()> {
25        let zone_id: String = resolve_zone(&mut client, &self.zone).await?;
26        let input = StdioConsoleStream::stdin_stream(zone_id.clone(), false).await;
27        let output = client.attach_zone_console(input).await?.into_inner();
28        let stdout_handle =
29            tokio::task::spawn(async move { StdioConsoleStream::stdout(output, true).await });
30        let exit_hook_task = StdioConsoleStream::zone_exit_hook(zone_id.clone(), events).await?;
31        let code = select! {
32            x = stdout_handle => {
33                x??;
34                None
35            },
36            x = exit_hook_task => x?
37        };
38        StdioConsoleStream::restore_terminal_mode();
39        std::process::exit(code.unwrap_or(0));
40    }
41}