mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 05:10:55 +00:00
krata: event-based network backend startup and api enhancements
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use krata::v1::control::control_service_client::ControlServiceClient;
|
||||
use krata::{events::EventStream, v1::control::control_service_client::ControlServiceClient};
|
||||
|
||||
use tokio::select;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
use crate::{console::StdioConsoleStream, events::EventStream};
|
||||
use crate::console::StdioConsoleStream;
|
||||
|
||||
use super::resolve_guest;
|
||||
|
||||
|
@ -1,17 +1,20 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use krata::v1::{
|
||||
common::GuestStatus,
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
||||
DestroyGuestRequest,
|
||||
use krata::{
|
||||
events::EventStream,
|
||||
v1::{
|
||||
common::GuestStatus,
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
||||
DestroyGuestRequest,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use log::error;
|
||||
use tonic::{transport::Channel, Request};
|
||||
|
||||
use crate::{cli::resolve_guest, events::EventStream};
|
||||
use crate::cli::resolve_guest;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct DestroyCommand {
|
||||
|
@ -2,20 +2,24 @@ use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use krata::v1::{
|
||||
common::{
|
||||
guest_image_spec::Image, GuestEnvVar, GuestImageSpec, GuestOciImageSpec, GuestSpec,
|
||||
GuestStatus,
|
||||
},
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, watch_events_reply::Event, CreateGuestRequest,
|
||||
use krata::{
|
||||
events::EventStream,
|
||||
v1::{
|
||||
common::{
|
||||
guest_image_spec::Image, GuestImageSpec, GuestOciImageSpec, GuestSpec, GuestStatus,
|
||||
GuestTaskSpec, GuestTaskSpecEnvVar,
|
||||
},
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
||||
CreateGuestRequest,
|
||||
},
|
||||
},
|
||||
};
|
||||
use log::error;
|
||||
use tokio::select;
|
||||
use tonic::{transport::Channel, Request};
|
||||
|
||||
use crate::{console::StdioConsoleStream, events::EventStream};
|
||||
use crate::console::StdioConsoleStream;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct LauchCommand {
|
||||
@ -51,14 +55,17 @@ impl LauchCommand {
|
||||
}),
|
||||
vcpus: self.cpus,
|
||||
mem: self.mem,
|
||||
env: env_map(&self.env.unwrap_or_default())
|
||||
.iter()
|
||||
.map(|(key, value)| GuestEnvVar {
|
||||
key: key.clone(),
|
||||
value: value.clone(),
|
||||
})
|
||||
.collect(),
|
||||
run: self.run,
|
||||
task: Some(GuestTaskSpec {
|
||||
environment: env_map(&self.env.unwrap_or_default())
|
||||
.iter()
|
||||
.map(|(key, value)| GuestTaskSpecEnvVar {
|
||||
key: key.clone(),
|
||||
value: value.clone(),
|
||||
})
|
||||
.collect(),
|
||||
command: self.run,
|
||||
}),
|
||||
annotations: vec![],
|
||||
}),
|
||||
};
|
||||
let response = client
|
||||
|
@ -1,20 +1,20 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use cli_tables::Table;
|
||||
use krata::v1::{
|
||||
common::{guest_image_spec::Image, Guest},
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, ListGuestsRequest, ResolveGuestRequest,
|
||||
use krata::{
|
||||
events::EventStream,
|
||||
v1::{
|
||||
common::{guest_image_spec::Image, Guest},
|
||||
control::{
|
||||
control_service_client::ControlServiceClient, ListGuestsRequest, ResolveGuestRequest,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
use serde_json::Value;
|
||||
use tonic::{transport::Channel, Request};
|
||||
|
||||
use crate::{
|
||||
events::EventStream,
|
||||
format::{guest_state_text, kv2line, proto2dynamic, proto2kv},
|
||||
};
|
||||
use crate::format::{guest_state_text, kv2line, proto2dynamic, proto2kv};
|
||||
|
||||
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||
enum ListFormat {
|
||||
@ -106,13 +106,13 @@ impl ListCommand {
|
||||
.state
|
||||
.as_ref()
|
||||
.and_then(|x| x.network.as_ref())
|
||||
.map(|x| x.ipv4.as_str())
|
||||
.map(|x| x.guest_ipv4.as_str())
|
||||
.unwrap_or("unknown");
|
||||
let ipv6 = guest
|
||||
.state
|
||||
.as_ref()
|
||||
.and_then(|x| x.network.as_ref())
|
||||
.map(|x| x.ipv6.as_str())
|
||||
.map(|x| x.guest_ipv6.as_str())
|
||||
.unwrap_or("unknown");
|
||||
let Some(spec) = guest.spec else {
|
||||
continue;
|
||||
|
@ -7,13 +7,15 @@ pub mod watch;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{Parser, Subcommand};
|
||||
use krata::v1::control::{
|
||||
control_service_client::ControlServiceClient, ResolveGuestRequest, WatchEventsRequest,
|
||||
use krata::{
|
||||
client::ControlClientProvider,
|
||||
events::EventStream,
|
||||
v1::control::{
|
||||
control_service_client::ControlServiceClient, ResolveGuestRequest, WatchEventsRequest,
|
||||
},
|
||||
};
|
||||
use tonic::{transport::Channel, Request};
|
||||
|
||||
use crate::{client::ControlClientProvider, events::EventStream};
|
||||
|
||||
use self::{
|
||||
attach::AttachCommand, destroy::DestroyCommand, launch::LauchCommand, list::ListCommand,
|
||||
resolve::ResolveCommand, watch::WatchCommand,
|
||||
|
@ -1,13 +1,13 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, ValueEnum};
|
||||
use krata::v1::{common::Guest, control::watch_events_reply::Event};
|
||||
use krata::{
|
||||
events::EventStream,
|
||||
v1::{common::Guest, control::watch_events_reply::Event},
|
||||
};
|
||||
use prost_reflect::ReflectMessage;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
events::EventStream,
|
||||
format::{guest_state_text, kv2line, proto2dynamic, proto2kv},
|
||||
};
|
||||
use crate::format::{guest_state_text, kv2line, proto2dynamic, proto2kv};
|
||||
|
||||
#[derive(ValueEnum, Clone, Debug, PartialEq, Eq)]
|
||||
enum WatchFormat {
|
||||
|
@ -1,61 +0,0 @@
|
||||
#[cfg(not(unix))]
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use krata::{dial::ControlDialAddress, v1::control::control_service_client::ControlServiceClient};
|
||||
#[cfg(unix)]
|
||||
use tokio::net::UnixStream;
|
||||
#[cfg(unix)]
|
||||
use tonic::transport::Uri;
|
||||
use tonic::transport::{Channel, ClientTlsConfig, Endpoint};
|
||||
#[cfg(unix)]
|
||||
use tower::service_fn;
|
||||
|
||||
pub struct ControlClientProvider {}
|
||||
|
||||
impl ControlClientProvider {
|
||||
pub async fn dial(addr: ControlDialAddress) -> Result<ControlServiceClient<Channel>> {
|
||||
let channel = match addr {
|
||||
ControlDialAddress::UnixSocket { path } => {
|
||||
#[cfg(not(unix))]
|
||||
return Err(anyhow!(
|
||||
"unix sockets are not supported on this platform (path {})",
|
||||
path
|
||||
));
|
||||
#[cfg(unix)]
|
||||
ControlClientProvider::dial_unix_socket(path).await?
|
||||
}
|
||||
|
||||
ControlDialAddress::Tcp { host, port } => {
|
||||
Endpoint::try_from(format!("http://{}:{}", host, port))?
|
||||
.connect()
|
||||
.await?
|
||||
}
|
||||
|
||||
ControlDialAddress::Tls {
|
||||
host,
|
||||
port,
|
||||
insecure: _,
|
||||
} => {
|
||||
let tls_config = ClientTlsConfig::new().domain_name(&host);
|
||||
let address = format!("https://{}:{}", host, port);
|
||||
Channel::from_shared(address)?
|
||||
.tls_config(tls_config)?
|
||||
.connect()
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ControlServiceClient::new(channel))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn dial_unix_socket(path: String) -> Result<Channel> {
|
||||
// This URL is not actually used but is required to be specified.
|
||||
Ok(Endpoint::try_from(format!("unix://localhost/{}", path))?
|
||||
.connect_with_connector(service_fn(|uri: Uri| {
|
||||
let path = uri.path().to_string();
|
||||
UnixStream::connect(path)
|
||||
}))
|
||||
.await?)
|
||||
}
|
||||
}
|
@ -4,9 +4,12 @@ use crossterm::{
|
||||
terminal::{disable_raw_mode, enable_raw_mode, is_raw_mode_enabled},
|
||||
tty::IsTty,
|
||||
};
|
||||
use krata::v1::{
|
||||
common::GuestStatus,
|
||||
control::{watch_events_reply::Event, ConsoleDataReply, ConsoleDataRequest},
|
||||
use krata::{
|
||||
events::EventStream,
|
||||
v1::{
|
||||
common::GuestStatus,
|
||||
control::{watch_events_reply::Event, ConsoleDataReply, ConsoleDataRequest},
|
||||
},
|
||||
};
|
||||
use log::debug;
|
||||
use tokio::{
|
||||
@ -16,8 +19,6 @@ use tokio::{
|
||||
use tokio_stream::{Stream, StreamExt};
|
||||
use tonic::Streaming;
|
||||
|
||||
use crate::events::EventStream;
|
||||
|
||||
pub struct StdioConsoleStream;
|
||||
|
||||
impl StdioConsoleStream {
|
||||
|
@ -1,57 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use krata::v1::control::{watch_events_reply::Event, WatchEventsReply};
|
||||
use log::trace;
|
||||
use tokio::{sync::broadcast, task::JoinHandle};
|
||||
use tokio_stream::StreamExt;
|
||||
use tonic::Streaming;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EventStream {
|
||||
sender: Arc<broadcast::Sender<Event>>,
|
||||
task: Arc<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
impl EventStream {
|
||||
pub async fn open(mut events: Streaming<WatchEventsReply>) -> Result<Self> {
|
||||
let (sender, _) = broadcast::channel(1000);
|
||||
let emit = sender.clone();
|
||||
let task = tokio::task::spawn(async move {
|
||||
loop {
|
||||
let Some(result) = events.next().await else {
|
||||
break;
|
||||
};
|
||||
|
||||
let reply = match result {
|
||||
Ok(reply) => reply,
|
||||
Err(error) => {
|
||||
trace!("event stream processing failed: {}", error);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let Some(event) = reply.event else {
|
||||
continue;
|
||||
};
|
||||
let _ = emit.send(event);
|
||||
}
|
||||
});
|
||||
Ok(Self {
|
||||
sender: Arc::new(sender),
|
||||
task: Arc::new(task),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn subscribe(&self) -> broadcast::Receiver<Event> {
|
||||
self.sender.subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EventStream {
|
||||
fn drop(&mut self) {
|
||||
if Arc::strong_count(&self.task) <= 1 {
|
||||
self.task.abort();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
pub mod cli;
|
||||
pub mod client;
|
||||
pub mod console;
|
||||
pub mod events;
|
||||
pub mod format;
|
||||
|
Reference in New Issue
Block a user