daemon: rework to not use protobuf inside the crate

This commit is contained in:
Alex Zenla 2024-03-30 09:29:03 +00:00
parent 660b555be7
commit 71dcaa7b77
No known key found for this signature in database
GPG Key ID: 067B238899B51269
14 changed files with 43 additions and 96 deletions

View File

@ -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"

View File

@ -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 }

View File

@ -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 }

View File

@ -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(())
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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)?;

View File

@ -1 +0,0 @@
include!(concat!(env!("OUT_DIR"), "/kratad.db.rs"));

View File

@ -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(())

View File

@ -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)?;

View File

@ -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"] }

View File

@ -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 }

View File

@ -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"

View File

@ -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 }