krata/crates/daemon/src/lib.rs

135 lines
4.3 KiB
Rust
Raw Normal View History

use std::{net::SocketAddr, path::PathBuf, str::FromStr};
use anyhow::Result;
use control::RuntimeControlService;
2024-03-14 14:03:11 +00:00
use db::GuestStore;
2024-03-06 15:57:56 +00:00
use event::{DaemonEventContext, DaemonEventGenerator};
use idm::{DaemonIdm, DaemonIdmHandle};
use krata::{dial::ControlDialAddress, v1::control::control_service_server::ControlServiceServer};
2024-03-14 14:03:11 +00:00
use kratart::Runtime;
use log::info;
use reconcile::guest::GuestReconciler;
2024-03-14 14:03:11 +00:00
use tokio::{
net::UnixListener,
sync::mpsc::{channel, Sender},
task::JoinHandle,
};
use tokio_stream::wrappers::UnixListenerStream;
use tonic::transport::{Identity, Server, ServerTlsConfig};
2024-03-14 14:03:11 +00:00
use uuid::Uuid;
pub mod control;
2024-03-14 14:03:11 +00:00
pub mod db;
2024-03-06 15:57:56 +00:00
pub mod event;
2024-03-28 07:36:48 +00:00
pub mod idm;
2024-03-14 14:03:11 +00:00
pub mod reconcile;
pub struct Daemon {
store: String,
runtime: Runtime,
2024-03-14 14:03:11 +00:00
guests: GuestStore,
2024-03-06 15:57:56 +00:00
events: DaemonEventContext,
2024-03-14 14:03:11 +00:00
guest_reconciler_task: JoinHandle<()>,
guest_reconciler_notify: Sender<Uuid>,
generator_task: JoinHandle<()>,
_idm: DaemonIdmHandle,
}
2024-03-14 14:03:11 +00:00
const GUEST_RECONCILER_QUEUE_LEN: usize = 1000;
impl Daemon {
pub async fn new(store: String, runtime: Runtime) -> Result<Self> {
2024-03-14 14:03:11 +00:00
let guests_db_path = format!("{}/guests.db", store);
let guests = GuestStore::open(&PathBuf::from(guests_db_path))?;
let (guest_reconciler_notify, guest_reconciler_receiver) =
channel::<Uuid>(GUEST_RECONCILER_QUEUE_LEN);
let idm = DaemonIdm::new().await?;
let idm = idm.launch().await?;
let (events, generator) =
DaemonEventGenerator::new(guests.clone(), guest_reconciler_notify.clone(), idm.clone())
.await?;
2024-03-14 14:03:11 +00:00
let runtime_for_reconciler = runtime.dupe().await?;
2024-04-02 00:56:18 +00:00
let guest_reconciler = GuestReconciler::new(
guests.clone(),
events.clone(),
runtime_for_reconciler,
guest_reconciler_notify.clone(),
)?;
2024-03-28 07:36:48 +00:00
let guest_reconciler_task = guest_reconciler.launch(guest_reconciler_receiver).await?;
let generator_task = generator.launch().await?;
2024-03-06 15:57:56 +00:00
Ok(Self {
store,
runtime,
2024-03-14 14:03:11 +00:00
guests,
2024-03-06 15:57:56 +00:00
events,
2024-03-28 07:36:48 +00:00
guest_reconciler_task,
2024-03-14 14:03:11 +00:00
guest_reconciler_notify,
2024-03-28 07:36:48 +00:00
generator_task,
_idm: idm,
2024-03-06 15:57:56 +00:00
})
}
pub async fn listen(&mut self, addr: ControlDialAddress) -> Result<()> {
2024-03-14 14:03:11 +00:00
let control_service = RuntimeControlService::new(
self.events.clone(),
self.runtime.clone(),
self.guests.clone(),
self.guest_reconciler_notify.clone(),
);
let mut server = Server::builder();
if let ControlDialAddress::Tls {
host: _,
port: _,
insecure,
} = &addr
{
let mut tls_config = ServerTlsConfig::new();
if !insecure {
let certificate_path = format!("{}/tls/daemon.pem", self.store);
let key_path = format!("{}/tls/daemon.key", self.store);
tls_config = tls_config.identity(Identity::from_pem(certificate_path, key_path));
}
server = server.tls_config(tls_config)?;
}
let server = server.add_service(ControlServiceServer::new(control_service));
info!("listening on address {}", addr);
match addr {
ControlDialAddress::UnixSocket { path } => {
let path = PathBuf::from(path);
if path.exists() {
tokio::fs::remove_file(&path).await?;
}
let listener = UnixListener::bind(path)?;
let stream = UnixListenerStream::new(listener);
server.serve_with_incoming(stream).await?;
}
ControlDialAddress::Tcp { host, port } => {
let address = format!("{}:{}", host, port);
server.serve(SocketAddr::from_str(&address)?).await?;
}
ControlDialAddress::Tls {
host,
port,
insecure: _,
} => {
let address = format!("{}:{}", host, port);
server.serve(SocketAddr::from_str(&address)?).await?;
}
}
Ok(())
}
}
2024-03-06 15:57:56 +00:00
impl Drop for Daemon {
fn drop(&mut self) {
2024-03-14 14:03:11 +00:00
self.guest_reconciler_task.abort();
self.generator_task.abort();
2024-03-06 15:57:56 +00:00
}
}