mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-04 05:31:32 +00:00
feat: idm v2 (#102)
* feat: rebuild idm to separate transport from content * feat: fast guest lookup table and host identification
This commit is contained in:
@ -6,10 +6,11 @@ use crate::{
|
||||
use anyhow::Result;
|
||||
use cgroups_rs::Cgroup;
|
||||
use krata::idm::{
|
||||
client::IdmClient,
|
||||
protocol::{
|
||||
idm_event::Event, idm_request::Request, idm_response::Response, IdmEvent, IdmExitEvent,
|
||||
IdmMetricsResponse, IdmPingResponse, IdmRequest,
|
||||
client::IdmInternalClient,
|
||||
internal::{
|
||||
event::Event as EventType, request::Request as RequestType,
|
||||
response::Response as ResponseType, Event, ExitEvent, MetricsResponse, PingResponse,
|
||||
Request, Response,
|
||||
},
|
||||
};
|
||||
use log::debug;
|
||||
@ -17,14 +18,18 @@ use nix::unistd::Pid;
|
||||
use tokio::{select, sync::broadcast};
|
||||
|
||||
pub struct GuestBackground {
|
||||
idm: IdmClient,
|
||||
idm: IdmInternalClient,
|
||||
child: Pid,
|
||||
_cgroup: Cgroup,
|
||||
wait: ChildWait,
|
||||
}
|
||||
|
||||
impl GuestBackground {
|
||||
pub async fn new(idm: IdmClient, cgroup: Cgroup, child: Pid) -> Result<GuestBackground> {
|
||||
pub async fn new(
|
||||
idm: IdmInternalClient,
|
||||
cgroup: Cgroup,
|
||||
child: Pid,
|
||||
) -> Result<GuestBackground> {
|
||||
Ok(GuestBackground {
|
||||
idm,
|
||||
child,
|
||||
@ -54,8 +59,8 @@ impl GuestBackground {
|
||||
},
|
||||
|
||||
x = requests_subscription.recv() => match x {
|
||||
Ok(request) => {
|
||||
self.handle_idm_request(request).await?;
|
||||
Ok((id, request)) => {
|
||||
self.handle_idm_request(id, request).await?;
|
||||
},
|
||||
|
||||
Err(broadcast::error::RecvError::Closed) => {
|
||||
@ -79,22 +84,27 @@ impl GuestBackground {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_idm_request(&mut self, packet: IdmRequest) -> Result<()> {
|
||||
let id = packet.id;
|
||||
|
||||
async fn handle_idm_request(&mut self, id: u64, packet: Request) -> Result<()> {
|
||||
match packet.request {
|
||||
Some(Request::Ping(_)) => {
|
||||
Some(RequestType::Ping(_)) => {
|
||||
self.idm
|
||||
.respond(id, Response::Ping(IdmPingResponse {}))
|
||||
.respond(
|
||||
id,
|
||||
Response {
|
||||
response: Some(ResponseType::Ping(PingResponse {})),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Some(Request::Metrics(_)) => {
|
||||
Some(RequestType::Metrics(_)) => {
|
||||
let metrics = MetricsCollector::new()?;
|
||||
let root = metrics.collect()?;
|
||||
let response = IdmMetricsResponse { root: Some(root) };
|
||||
let response = Response {
|
||||
response: Some(ResponseType::Metrics(MetricsResponse { root: Some(root) })),
|
||||
};
|
||||
|
||||
self.idm.respond(id, Response::Metrics(response)).await?;
|
||||
self.idm.respond(id, response).await?;
|
||||
}
|
||||
|
||||
None => {}
|
||||
@ -105,8 +115,8 @@ impl GuestBackground {
|
||||
async fn child_event(&mut self, event: ChildEvent) -> Result<()> {
|
||||
if event.pid == self.child {
|
||||
self.idm
|
||||
.emit(IdmEvent {
|
||||
event: Some(Event::Exit(IdmExitEvent { code: event.status })),
|
||||
.emit(Event {
|
||||
event: Some(EventType::Exit(ExitEvent { code: event.status })),
|
||||
})
|
||||
.await?;
|
||||
death(event.status).await?;
|
||||
|
@ -3,7 +3,8 @@ use cgroups_rs::{Cgroup, CgroupPid};
|
||||
use futures::stream::TryStreamExt;
|
||||
use ipnetwork::IpNetwork;
|
||||
use krata::ethtool::EthtoolHandle;
|
||||
use krata::idm::client::IdmClient;
|
||||
use krata::idm::client::IdmInternalClient;
|
||||
use krata::idm::internal::INTERNAL_IDM_CHANNEL;
|
||||
use krata::launchcfg::{LaunchInfo, LaunchNetwork, LaunchPackedFormat};
|
||||
use libc::{sethostname, setsid, TIOCSCTTY};
|
||||
use log::{trace, warn};
|
||||
@ -77,7 +78,7 @@ impl GuestInit {
|
||||
Err(error) => warn!("failed to open console: {}", error),
|
||||
};
|
||||
|
||||
let idm = IdmClient::open("/dev/hvc1")
|
||||
let idm = IdmInternalClient::open(INTERNAL_IDM_CHANNEL, "/dev/hvc1")
|
||||
.await
|
||||
.map_err(|x| anyhow!("failed to open idm client: {}", x))?;
|
||||
self.mount_config_image().await?;
|
||||
@ -438,7 +439,12 @@ impl GuestInit {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run(&mut self, config: &Config, launch: &LaunchInfo, idm: IdmClient) -> Result<()> {
|
||||
async fn run(
|
||||
&mut self,
|
||||
config: &Config,
|
||||
launch: &LaunchInfo,
|
||||
idm: IdmInternalClient,
|
||||
) -> Result<()> {
|
||||
let mut cmd = match config.cmd() {
|
||||
None => vec![],
|
||||
Some(value) => value.clone(),
|
||||
@ -560,7 +566,7 @@ impl GuestInit {
|
||||
|
||||
async fn fork_and_exec(
|
||||
&mut self,
|
||||
idm: IdmClient,
|
||||
idm: IdmInternalClient,
|
||||
cgroup: Cgroup,
|
||||
working_dir: String,
|
||||
path: CString,
|
||||
@ -596,7 +602,12 @@ impl GuestInit {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn background(&mut self, idm: IdmClient, cgroup: Cgroup, executed: Pid) -> Result<()> {
|
||||
async fn background(
|
||||
&mut self,
|
||||
idm: IdmInternalClient,
|
||||
cgroup: Cgroup,
|
||||
executed: Pid,
|
||||
) -> Result<()> {
|
||||
let mut background = GuestBackground::new(idm, cgroup, executed).await?;
|
||||
background.run().await?;
|
||||
Ok(())
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{ops::Add, path::Path};
|
||||
|
||||
use anyhow::Result;
|
||||
use krata::idm::protocol::{IdmMetricFormat, IdmMetricNode};
|
||||
use krata::idm::internal::{MetricFormat, MetricNode};
|
||||
use sysinfo::Process;
|
||||
|
||||
pub struct MetricsCollector {}
|
||||
@ -11,9 +11,9 @@ impl MetricsCollector {
|
||||
Ok(MetricsCollector {})
|
||||
}
|
||||
|
||||
pub fn collect(&self) -> Result<IdmMetricNode> {
|
||||
pub fn collect(&self) -> Result<MetricNode> {
|
||||
let mut sysinfo = sysinfo::System::new();
|
||||
Ok(IdmMetricNode::structural(
|
||||
Ok(MetricNode::structural(
|
||||
"guest",
|
||||
vec![
|
||||
self.collect_system(&mut sysinfo)?,
|
||||
@ -22,22 +22,22 @@ impl MetricsCollector {
|
||||
))
|
||||
}
|
||||
|
||||
fn collect_system(&self, sysinfo: &mut sysinfo::System) -> Result<IdmMetricNode> {
|
||||
fn collect_system(&self, sysinfo: &mut sysinfo::System) -> Result<MetricNode> {
|
||||
sysinfo.refresh_memory();
|
||||
Ok(IdmMetricNode::structural(
|
||||
Ok(MetricNode::structural(
|
||||
"system",
|
||||
vec![IdmMetricNode::structural(
|
||||
vec![MetricNode::structural(
|
||||
"memory",
|
||||
vec![
|
||||
IdmMetricNode::value("total", sysinfo.total_memory(), IdmMetricFormat::Bytes),
|
||||
IdmMetricNode::value("used", sysinfo.used_memory(), IdmMetricFormat::Bytes),
|
||||
IdmMetricNode::value("free", sysinfo.free_memory(), IdmMetricFormat::Bytes),
|
||||
MetricNode::value("total", sysinfo.total_memory(), MetricFormat::Bytes),
|
||||
MetricNode::value("used", sysinfo.used_memory(), MetricFormat::Bytes),
|
||||
MetricNode::value("free", sysinfo.free_memory(), MetricFormat::Bytes),
|
||||
],
|
||||
)],
|
||||
))
|
||||
}
|
||||
|
||||
fn collect_processes(&self, sysinfo: &mut sysinfo::System) -> Result<IdmMetricNode> {
|
||||
fn collect_processes(&self, sysinfo: &mut sysinfo::System) -> Result<MetricNode> {
|
||||
sysinfo.refresh_processes();
|
||||
let mut processes = Vec::new();
|
||||
let mut sysinfo_processes = sysinfo.processes().values().collect::<Vec<_>>();
|
||||
@ -48,71 +48,68 @@ impl MetricsCollector {
|
||||
}
|
||||
processes.push(MetricsCollector::process_node(process)?);
|
||||
}
|
||||
Ok(IdmMetricNode::structural("process", processes))
|
||||
Ok(MetricNode::structural("process", processes))
|
||||
}
|
||||
|
||||
fn process_node(process: &Process) -> Result<IdmMetricNode> {
|
||||
fn process_node(process: &Process) -> Result<MetricNode> {
|
||||
let mut metrics = vec![];
|
||||
|
||||
if let Some(parent) = process.parent() {
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"parent",
|
||||
parent.as_u32() as u64,
|
||||
IdmMetricFormat::Integer,
|
||||
MetricFormat::Integer,
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(exe) = process.exe().and_then(path_as_str) {
|
||||
metrics.push(IdmMetricNode::raw_value("executable", exe));
|
||||
metrics.push(MetricNode::raw_value("executable", exe));
|
||||
}
|
||||
|
||||
if let Some(working_directory) = process.cwd().and_then(path_as_str) {
|
||||
metrics.push(IdmMetricNode::raw_value("cwd", working_directory));
|
||||
metrics.push(MetricNode::raw_value("cwd", working_directory));
|
||||
}
|
||||
|
||||
let cmdline = process.cmd().to_vec();
|
||||
metrics.push(IdmMetricNode::raw_value("cmdline", cmdline));
|
||||
metrics.push(IdmMetricNode::structural(
|
||||
metrics.push(MetricNode::raw_value("cmdline", cmdline));
|
||||
metrics.push(MetricNode::structural(
|
||||
"memory",
|
||||
vec![
|
||||
IdmMetricNode::value("resident", process.memory(), IdmMetricFormat::Bytes),
|
||||
IdmMetricNode::value("virtual", process.virtual_memory(), IdmMetricFormat::Bytes),
|
||||
MetricNode::value("resident", process.memory(), MetricFormat::Bytes),
|
||||
MetricNode::value("virtual", process.virtual_memory(), MetricFormat::Bytes),
|
||||
],
|
||||
));
|
||||
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"lifetime",
|
||||
process.run_time(),
|
||||
IdmMetricFormat::DurationSeconds,
|
||||
MetricFormat::DurationSeconds,
|
||||
));
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"uid",
|
||||
process.user_id().map(|x| (*x).add(0)).unwrap_or(0) as f64,
|
||||
IdmMetricFormat::Integer,
|
||||
MetricFormat::Integer,
|
||||
));
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"gid",
|
||||
process.group_id().map(|x| (*x).add(0)).unwrap_or(0) as f64,
|
||||
IdmMetricFormat::Integer,
|
||||
MetricFormat::Integer,
|
||||
));
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"euid",
|
||||
process
|
||||
.effective_user_id()
|
||||
.map(|x| (*x).add(0))
|
||||
.unwrap_or(0) as f64,
|
||||
IdmMetricFormat::Integer,
|
||||
MetricFormat::Integer,
|
||||
));
|
||||
metrics.push(IdmMetricNode::value(
|
||||
metrics.push(MetricNode::value(
|
||||
"egid",
|
||||
process.effective_group_id().map(|x| x.add(0)).unwrap_or(0) as f64,
|
||||
IdmMetricFormat::Integer,
|
||||
MetricFormat::Integer,
|
||||
));
|
||||
|
||||
Ok(IdmMetricNode::structural(
|
||||
process.pid().to_string(),
|
||||
metrics,
|
||||
))
|
||||
Ok(MetricNode::structural(process.pid().to_string(), metrics))
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user