Feat/logging (#2602)

* wip: Working on something to help

* chore: Add in some of the logging now

* chore: fix the type to interned instead of id

* wip

* wip

* chore: fix the logging by moving levels

* Apply suggestions from code review

* mount at machine id for journal

* Persistant

* limit log size

* feat: Actually logging and mounting now

* fix: Get the logs from the previous versions of the boot

* Chore: Add the boot id

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Jade
2024-04-17 15:46:10 -06:00
committed by GitHub
parent 711c82472c
commit 9eff920989
10 changed files with 308 additions and 120 deletions

View File

@@ -13,7 +13,6 @@ use start_stop::StartStop;
use tokio::sync::Notify;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::core::rpc_continuations::RequestGuid;
use crate::db::model::package::{
InstalledState, PackageDataEntry, PackageState, PackageStateMatchModelRef, UpdatingState,
@@ -32,6 +31,10 @@ use crate::util::actor::concurrent::ConcurrentActor;
use crate::util::actor::Actor;
use crate::util::serde::Pem;
use crate::volume::data_dir;
use crate::{
context::{CliContext, RpcContext},
lxc::ContainerId,
};
mod action;
pub mod cli;
@@ -193,8 +196,8 @@ impl Service {
|db| {
db.as_public_mut()
.as_package_data_mut()
.as_idx_mut(&id)
.or_not_found(&id)?
.as_idx_mut(id)
.or_not_found(id)?
.as_state_info_mut()
.map_mutate(|s| {
if let PackageState::Updating(UpdatingState {
@@ -223,16 +226,12 @@ impl Service {
tracing::debug!("{e:?}")
})
{
if service
.uninstall(None)
.await
.map_err(|e| {
match service.uninstall(None).await {
Err(e) => {
tracing::error!("Error uninstalling service: {e}");
tracing::debug!("{e:?}")
})
.is_ok()
{
return Ok(None);
}
Ok(()) => return Ok(None),
}
}
}
@@ -299,10 +298,10 @@ impl Service {
}
pub async fn restore(
ctx: RpcContext,
s9pk: S9pk,
guard: impl GenericMountGuard,
progress: Option<InstallProgressHandles>,
_ctx: RpcContext,
_s9pk: S9pk,
_guard: impl GenericMountGuard,
_progress: Option<InstallProgressHandles>,
) -> Result<Self, Error> {
// TODO
Err(Error::new(eyre!("not yet implemented"), ErrorKind::Unknown))
@@ -341,21 +340,36 @@ impl Service {
.execute(ProcedureName::Uninit, to_value(&target_version)?, None) // TODO timeout
.await?;
let id = self.seed.persistent_container.s9pk.as_manifest().id.clone();
self.seed
.ctx
.db
.mutate(|d| d.as_public_mut().as_package_data_mut().remove(&id))
.await?;
self.shutdown().await
let ctx = self.seed.ctx.clone();
self.shutdown().await?;
if target_version.is_none() {
ctx.db
.mutate(|d| d.as_public_mut().as_package_data_mut().remove(&id))
.await?;
}
Ok(())
}
pub async fn backup(&self, _guard: impl GenericMountGuard) -> Result<BackupReturn, Error> {
// TODO
Err(Error::new(eyre!("not yet implemented"), ErrorKind::Unknown))
}
pub fn container_id(&self) -> Result<ContainerId, Error> {
let id = &self.seed.id;
let container_id = (*self
.seed
.persistent_container
.lxc_container
.get()
.or_not_found(format!("container for {id}"))?
.guid)
.clone();
Ok(container_id)
}
}
#[derive(Debug, Clone)]
struct RunningStatus {
pub struct RunningStatus {
health: OrdMap<HealthCheckId, HealthCheckResult>,
started: DateTime<Utc>,
}

View File

@@ -10,7 +10,7 @@ use imbl_value::InternedString;
use models::{ProcedureName, VolumeId};
use rpc_toolkit::{Empty, Server, ShutdownHandle};
use serde::de::DeserializeOwned;
use tokio::fs::File;
use tokio::fs::{create_dir_all, File};
use tokio::process::Command;
use tokio::sync::{oneshot, watch, Mutex, OnceCell};
use tracing::instrument;
@@ -39,8 +39,6 @@ use crate::ARCH;
const RPC_CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
struct ProcedureId(u64);
#[derive(Debug)]
pub struct ServiceState {
// This contains the start time and health check information for when the service is running. Note: Will be overwritting to the db,
@@ -99,7 +97,17 @@ pub struct PersistentContainer {
impl PersistentContainer {
#[instrument(skip_all)]
pub async fn new(ctx: &RpcContext, s9pk: S9pk, start: StartStop) -> Result<Self, Error> {
let lxc_container = ctx.lxc_manager.create(LxcConfig::default()).await?;
let lxc_container = ctx
.lxc_manager
.create(
Some(
&ctx.datadir
.join("package-data/logs")
.join(&s9pk.as_manifest().id),
),
LxcConfig::default(),
)
.await?;
let rpc_client = lxc_container.connect_rpc(Some(RPC_CONNECT_TIMEOUT)).await?;
let js_mount = MountGuard::mount(
&LoopDev::from(
@@ -114,6 +122,7 @@ impl PersistentContainer {
ReadOnly,
)
.await?;
let mut volumes = BTreeMap::new();
for volume in &s9pk.as_manifest().volumes {
let mountpoint = lxc_container
@@ -175,7 +184,7 @@ impl PersistentContainer {
if let Some(env) = s9pk
.as_archive()
.contents()
.get_path(Path::new("images").join(&*ARCH).join(&env_filename))
.get_path(Path::new("images").join(*ARCH).join(&env_filename))
.and_then(|e| e.as_file())
{
env.copy(&mut File::create(image_path.join(&env_filename)).await?)
@@ -185,7 +194,7 @@ impl PersistentContainer {
if let Some(json) = s9pk
.as_archive()
.contents()
.get_path(Path::new("images").join(&*ARCH).join(&json_filename))
.get_path(Path::new("images").join(*ARCH).join(&json_filename))
.and_then(|e| e.as_file())
{
json.copy(&mut File::create(image_path.join(&json_filename)).await?)
@@ -231,7 +240,7 @@ impl PersistentContainer {
.join(HOST_RPC_SERVER_SOCKET);
let (send, recv) = oneshot::channel();
let handle = NonDetachingJoinHandle::from(tokio::spawn(async move {
let (shutdown, fut) = match async {
let chown_status = async {
let res = server.run_unix(&path, |err| {
tracing::error!("error on unix socket {}: {err}", path.display())
})?;
@@ -241,9 +250,8 @@ impl PersistentContainer {
.invoke(ErrorKind::Filesystem)
.await?;
Ok::<_, Error>(res)
}
.await
{
};
let (shutdown, fut) = match chown_status.await {
Ok((shutdown, fut)) => (Ok(shutdown), Some(fut)),
Err(e) => (Err(e), None),
};

View File

@@ -32,9 +32,9 @@ use crate::util::serde::Pem;
pub type DownloadInstallFuture = BoxFuture<'static, Result<InstallFuture, Error>>;
pub type InstallFuture = BoxFuture<'static, Result<(), Error>>;
pub(super) struct InstallProgressHandles {
pub(super) finalization_progress: PhaseProgressTrackerHandle,
pub(super) progress_handle: FullProgressTrackerHandle,
pub struct InstallProgressHandles {
pub finalization_progress: PhaseProgressTrackerHandle,
pub progress_handle: FullProgressTrackerHandle,
}
/// This is the structure to contain all the services