krata: reimplement console to utilize channels, and provide logs support

This commit is contained in:
Alex Zenla
2024-04-02 08:57:34 +00:00
parent 0fd6318c5f
commit 5ad2e40a7b
17 changed files with 309 additions and 31 deletions

View File

@ -0,0 +1,57 @@
use anyhow::Result;
use async_stream::stream;
use clap::Parser;
use krata::{
events::EventStream,
v1::control::{control_service_client::ControlServiceClient, ConsoleDataRequest},
};
use tokio::select;
use tokio_stream::{pending, StreamExt};
use tonic::transport::Channel;
use crate::console::StdioConsoleStream;
use super::resolve_guest;
#[derive(Parser)]
pub struct LogsCommand {
#[arg()]
guest: String,
#[arg(short, long)]
follow: bool,
}
impl LogsCommand {
pub async fn run(
self,
mut client: ControlServiceClient<Channel>,
events: EventStream,
) -> Result<()> {
let guest_id: String = resolve_guest(&mut client, &self.guest).await?;
let guest_id_stream = guest_id.clone();
let follow = self.follow;
let input = stream! {
yield ConsoleDataRequest { guest_id: guest_id_stream, data: Vec::new() };
if follow {
let mut pending = pending::<ConsoleDataRequest>();
while let Some(x) = pending.next().await {
yield x;
}
}
};
let output = client.console_data(input).await?.into_inner();
let stdout_handle =
tokio::task::spawn(async move { StdioConsoleStream::stdout(output).await });
let exit_hook_task = StdioConsoleStream::guest_exit_hook(guest_id.clone(), events).await?;
let code = select! {
x = stdout_handle => {
x??;
None
},
x = exit_hook_task => x?
};
StdioConsoleStream::restore_terminal_mode();
std::process::exit(code.unwrap_or(0));
}
}

View File

@ -2,6 +2,7 @@ pub mod attach;
pub mod destroy;
pub mod launch;
pub mod list;
pub mod logs;
pub mod resolve;
pub mod watch;
@ -16,7 +17,7 @@ use tonic::{transport::Channel, Request};
use self::{
attach::AttachCommand, destroy::DestroyCommand, launch::LauchCommand, list::ListCommand,
resolve::ResolveCommand, watch::WatchCommand,
logs::LogsCommand, resolve::ResolveCommand, watch::WatchCommand,
};
#[derive(Parser)]
@ -35,6 +36,7 @@ pub enum Commands {
Destroy(DestroyCommand),
List(ListCommand),
Attach(AttachCommand),
Logs(LogsCommand),
Watch(WatchCommand),
Resolve(ResolveCommand),
}
@ -57,6 +59,10 @@ impl ControlCommand {
attach.run(client, events).await?;
}
Commands::Logs(logs) => {
logs.run(client, events).await?;
}
Commands::List(list) => {
list.run(client, events).await?;
}