mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
daemon: rework to not use protobuf inside the crate
This commit is contained in:
parent
660b555be7
commit
71dcaa7b77
@ -16,7 +16,7 @@ members = [
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.0.2"
|
||||
version = "0.0.3"
|
||||
homepage = "https://krata.dev"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/edera-dev/krata"
|
||||
|
@ -16,7 +16,7 @@ cli-tables = { workspace = true }
|
||||
crossterm = { workspace = true }
|
||||
ctrlc = { workspace = true, features = ["termination"] }
|
||||
env_logger = { workspace = true }
|
||||
krata = { path = "../krata", version = "0.0.2" }
|
||||
krata = { path = "../krata", version = "0.0.3" }
|
||||
log = { workspace = true }
|
||||
prost-reflect = { workspace = true, features = ["serde"] }
|
||||
serde_json = { workspace = true }
|
||||
|
@ -16,8 +16,8 @@ bytes = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
krata = { path = "../krata", version = "0.0.2" }
|
||||
krata-runtime = { path = "../runtime", version = "0.0.2" }
|
||||
krata = { path = "../krata", version = "0.0.3" }
|
||||
krata-runtime = { path = "../runtime", version = "0.0.3" }
|
||||
log = { workspace = true }
|
||||
prost = { workspace = true }
|
||||
redb = { workspace = true }
|
||||
@ -33,6 +33,3 @@ name = "kratad"
|
||||
[[bin]]
|
||||
name = "kratad"
|
||||
path = "bin/daemon.rs"
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = { workspace = true }
|
||||
|
@ -1,8 +0,0 @@
|
||||
use std::io::Result;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
prost_build::Config::new()
|
||||
.extern_path(".krata.v1.common", "::krata::v1::common")
|
||||
.compile_protos(&["proto/kratad/db.proto"], &["proto/", "../krata/proto"])?;
|
||||
Ok(())
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package kratad.db;
|
||||
|
||||
import "krata/v1/common.proto";
|
||||
|
||||
message GuestEntry {
|
||||
string id = 1;
|
||||
krata.v1.common.Guest guest = 2;
|
||||
}
|
@ -21,10 +21,7 @@ use tokio_stream::StreamExt;
|
||||
use tonic::{Request, Response, Status, Streaming};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
db::{proto::GuestEntry, GuestStore},
|
||||
event::DaemonEventContext,
|
||||
};
|
||||
use crate::{db::GuestStore, event::DaemonEventContext};
|
||||
|
||||
pub struct ApiError {
|
||||
message: String,
|
||||
@ -96,19 +93,16 @@ impl ControlService for RuntimeControlService {
|
||||
self.guests
|
||||
.update(
|
||||
uuid,
|
||||
GuestEntry {
|
||||
Guest {
|
||||
id: uuid.to_string(),
|
||||
guest: Some(Guest {
|
||||
id: uuid.to_string(),
|
||||
state: Some(GuestState {
|
||||
status: GuestStatus::Starting.into(),
|
||||
network: None,
|
||||
exit_info: None,
|
||||
error_info: None,
|
||||
domid: u32::MAX,
|
||||
}),
|
||||
spec: Some(spec),
|
||||
state: Some(GuestState {
|
||||
status: GuestStatus::Starting.into(),
|
||||
network: None,
|
||||
exit_info: None,
|
||||
error_info: None,
|
||||
domid: u32::MAX,
|
||||
}),
|
||||
spec: Some(spec),
|
||||
},
|
||||
)
|
||||
.await
|
||||
@ -132,13 +126,7 @@ impl ControlService for RuntimeControlService {
|
||||
let uuid = Uuid::from_str(&request.guest_id).map_err(|error| ApiError {
|
||||
message: error.to_string(),
|
||||
})?;
|
||||
let Some(mut entry) = self.guests.read(uuid).await.map_err(ApiError::from)? else {
|
||||
return Err(ApiError {
|
||||
message: "guest not found".to_string(),
|
||||
}
|
||||
.into());
|
||||
};
|
||||
let Some(ref mut guest) = entry.guest else {
|
||||
let Some(mut guest) = self.guests.read(uuid).await.map_err(ApiError::from)? else {
|
||||
return Err(ApiError {
|
||||
message: "guest not found".to_string(),
|
||||
}
|
||||
@ -156,7 +144,7 @@ impl ControlService for RuntimeControlService {
|
||||
|
||||
guest.state.as_mut().unwrap().status = GuestStatus::Destroying.into();
|
||||
self.guests
|
||||
.update(uuid, entry)
|
||||
.update(uuid, guest)
|
||||
.await
|
||||
.map_err(ApiError::from)?;
|
||||
self.guest_reconciler_notify
|
||||
@ -174,10 +162,7 @@ impl ControlService for RuntimeControlService {
|
||||
) -> Result<Response<ListGuestsReply>, Status> {
|
||||
let _ = request.into_inner();
|
||||
let guests = self.guests.list().await.map_err(ApiError::from)?;
|
||||
let guests = guests
|
||||
.into_values()
|
||||
.filter_map(|entry| entry.guest)
|
||||
.collect::<Vec<Guest>>();
|
||||
let guests = guests.into_values().collect::<Vec<Guest>>();
|
||||
Ok(Response::new(ListGuestsReply { guests }))
|
||||
}
|
||||
|
||||
@ -189,7 +174,6 @@ impl ControlService for RuntimeControlService {
|
||||
let guests = self.guests.list().await.map_err(ApiError::from)?;
|
||||
let guests = guests
|
||||
.into_values()
|
||||
.filter_map(|entry| entry.guest)
|
||||
.filter(|x| {
|
||||
let comparison_spec = x.spec.as_ref().cloned().unwrap_or_default();
|
||||
(!request.name.is_empty() && comparison_spec.name == request.name)
|
||||
|
@ -1,9 +1,7 @@
|
||||
pub mod proto;
|
||||
|
||||
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||
|
||||
use self::proto::GuestEntry;
|
||||
use anyhow::Result;
|
||||
use krata::v1::common::Guest;
|
||||
use log::error;
|
||||
use prost::Message;
|
||||
use redb::{Database, ReadableTable, TableDefinition};
|
||||
@ -27,24 +25,24 @@ impl GuestStore {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn read(&self, id: Uuid) -> Result<Option<GuestEntry>> {
|
||||
pub async fn read(&self, id: Uuid) -> Result<Option<Guest>> {
|
||||
let read = self.database.begin_read()?;
|
||||
let table = read.open_table(GUESTS)?;
|
||||
let Some(entry) = table.get(id.to_u128_le())? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let bytes = entry.value();
|
||||
Ok(Some(GuestEntry::decode(bytes)?))
|
||||
Ok(Some(Guest::decode(bytes)?))
|
||||
}
|
||||
|
||||
pub async fn list(&self) -> Result<HashMap<Uuid, GuestEntry>> {
|
||||
let mut guests: HashMap<Uuid, GuestEntry> = HashMap::new();
|
||||
pub async fn list(&self) -> Result<HashMap<Uuid, Guest>> {
|
||||
let mut guests: HashMap<Uuid, Guest> = HashMap::new();
|
||||
let read = self.database.begin_read()?;
|
||||
let table = read.open_table(GUESTS)?;
|
||||
for result in table.iter()? {
|
||||
let (key, value) = result?;
|
||||
let uuid = Uuid::from_u128_le(key.value());
|
||||
let state = match GuestEntry::decode(value.value()) {
|
||||
let state = match Guest::decode(value.value()) {
|
||||
Ok(state) => state,
|
||||
Err(error) => {
|
||||
error!(
|
||||
@ -59,7 +57,7 @@ impl GuestStore {
|
||||
Ok(guests)
|
||||
}
|
||||
|
||||
pub async fn update(&self, id: Uuid, entry: GuestEntry) -> Result<()> {
|
||||
pub async fn update(&self, id: Uuid, entry: Guest) -> Result<()> {
|
||||
let write = self.database.begin_write()?;
|
||||
{
|
||||
let mut table = write.open_table(GUESTS)?;
|
@ -1 +0,0 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/kratad.db.rs"));
|
@ -124,11 +124,7 @@ impl DaemonEventGenerator {
|
||||
}
|
||||
|
||||
async fn handle_exit_code(&mut self, id: Uuid, code: i32) -> Result<()> {
|
||||
if let Some(mut entry) = self.guests.read(id).await? {
|
||||
let Some(ref mut guest) = entry.guest else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if let Some(mut guest) = self.guests.read(id).await? {
|
||||
guest.state = Some(GuestState {
|
||||
status: GuestStatus::Exited.into(),
|
||||
network: guest.state.clone().unwrap_or_default().network,
|
||||
@ -137,7 +133,7 @@ impl DaemonEventGenerator {
|
||||
domid: guest.state.clone().map(|x| x.domid).unwrap_or(u32::MAX),
|
||||
});
|
||||
|
||||
self.guests.update(id, entry).await?;
|
||||
self.guests.update(id, guest).await?;
|
||||
self.guest_reconciler_notify.send(id).await?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -67,12 +67,7 @@ impl GuestReconciler {
|
||||
trace!("reconciling runtime");
|
||||
let runtime_guests = self.runtime.list().await?;
|
||||
let stored_guests = self.guests.list().await?;
|
||||
for (uuid, mut stored_guest_entry) in stored_guests {
|
||||
let Some(ref mut stored_guest) = stored_guest_entry.guest else {
|
||||
warn!("removing unpopulated guest entry for guest {}", uuid);
|
||||
self.guests.remove(uuid).await?;
|
||||
continue;
|
||||
};
|
||||
for (uuid, mut stored_guest) in stored_guests {
|
||||
let previous_guest = stored_guest.clone();
|
||||
let runtime_guest = runtime_guests.iter().find(|x| x.uuid == uuid);
|
||||
match runtime_guest {
|
||||
@ -97,10 +92,10 @@ impl GuestReconciler {
|
||||
}
|
||||
}
|
||||
|
||||
let changed = *stored_guest != previous_guest;
|
||||
let changed = stored_guest != previous_guest;
|
||||
|
||||
if changed || initial {
|
||||
self.guests.update(uuid, stored_guest_entry).await?;
|
||||
self.guests.update(uuid, stored_guest).await?;
|
||||
if let Err(error) = self.reconcile(uuid).await {
|
||||
error!("failed to reconcile guest {}: {}", uuid, error);
|
||||
}
|
||||
@ -110,7 +105,7 @@ impl GuestReconciler {
|
||||
}
|
||||
|
||||
pub async fn reconcile(&self, uuid: Uuid) -> Result<()> {
|
||||
let Some(mut entry) = self.guests.read(uuid).await? else {
|
||||
let Some(mut guest) = self.guests.read(uuid).await? else {
|
||||
warn!(
|
||||
"notified of reconcile for guest {} but it didn't exist",
|
||||
uuid
|
||||
@ -120,18 +115,14 @@ impl GuestReconciler {
|
||||
|
||||
info!("reconciling guest {}", uuid);
|
||||
|
||||
let Some(ref mut guest) = entry.guest else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
self.events
|
||||
.send(DaemonEvent::GuestChanged(GuestChangedEvent {
|
||||
guest: Some(guest.clone()),
|
||||
}))?;
|
||||
|
||||
let result = match guest.state.as_ref().map(|x| x.status()).unwrap_or_default() {
|
||||
GuestStatus::Starting => self.start(uuid, guest).await,
|
||||
GuestStatus::Destroying | GuestStatus::Exited => self.destroy(uuid, guest).await,
|
||||
GuestStatus::Starting => self.start(uuid, &mut guest).await,
|
||||
GuestStatus::Destroying | GuestStatus::Exited => self.destroy(uuid, &mut guest).await,
|
||||
_ => Ok(false),
|
||||
};
|
||||
|
||||
@ -160,7 +151,7 @@ impl GuestReconciler {
|
||||
if destroyed {
|
||||
self.guests.remove(uuid).await?;
|
||||
} else {
|
||||
self.guests.update(uuid, entry.clone()).await?;
|
||||
self.guests.update(uuid, guest.clone()).await?;
|
||||
}
|
||||
|
||||
self.events.send(event)?;
|
||||
|
@ -13,8 +13,8 @@ anyhow = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
krata = { path = "../krata", version = "0.0.2" }
|
||||
krata-xenstore = { path = "../xen/xenstore", version = "0.0.2" }
|
||||
krata = { path = "../krata", version = "0.0.3" }
|
||||
krata-xenstore = { path = "../xen/xenstore", version = "0.0.3" }
|
||||
libc = { workspace = true }
|
||||
log = { workspace = true }
|
||||
nix = { workspace = true, features = ["ioctl", "process", "fs"] }
|
||||
|
@ -16,7 +16,7 @@ clap = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
etherparse = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
krata = { path = "../krata", version = "0.0.2" }
|
||||
krata = { path = "../krata", version = "0.0.3" }
|
||||
krata-advmac = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
log = { workspace = true }
|
||||
|
@ -12,18 +12,18 @@ resolver = "2"
|
||||
anyhow = { workspace = true }
|
||||
backhand = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
krata = { path = "../krata", version = "0.0.2" }
|
||||
krata = { path = "../krata", version = "0.0.3" }
|
||||
krata-advmac = { workspace = true }
|
||||
krata-oci = { path = "../oci", version = "0.0.2" }
|
||||
krata-oci = { path = "../oci", version = "0.0.3" }
|
||||
log = { workspace = true }
|
||||
loopdev-3 = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
krata-xenclient = { path = "../xen/xenclient", version = "0.0.2" }
|
||||
krata-xenevtchn = { path = "../xen/xenevtchn", version = "0.0.2" }
|
||||
krata-xengnt = { path = "../xen/xengnt", version = "0.0.2" }
|
||||
krata-xenstore = { path = "../xen/xenstore", version = "0.0.2" }
|
||||
krata-xenclient = { path = "../xen/xenclient", version = "0.0.3" }
|
||||
krata-xenevtchn = { path = "../xen/xenevtchn", version = "0.0.3" }
|
||||
krata-xengnt = { path = "../xen/xengnt", version = "0.0.3" }
|
||||
krata-xenstore = { path = "../xen/xenstore", version = "0.0.3" }
|
||||
|
||||
[lib]
|
||||
name = "kratart"
|
||||
|
@ -13,8 +13,8 @@ elf = { workspace = true }
|
||||
flate2 = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
log = { workspace = true }
|
||||
krata-xencall = { path = "../xencall", version = "0.0.2" }
|
||||
krata-xenstore = { path = "../xenstore", version = "0.0.2" }
|
||||
krata-xencall = { path = "../xencall", version = "0.0.3" }
|
||||
krata-xenstore = { path = "../xenstore", version = "0.0.3" }
|
||||
memchr = { workspace = true }
|
||||
slice-copy = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
Loading…
Reference in New Issue
Block a user