From 8410929e86fde6287813c70f49bfc3eb7c33360d Mon Sep 17 00:00:00 2001 From: J H Date: Wed, 6 Mar 2024 10:55:21 -0700 Subject: [PATCH] feat: Add the stop/start loop for the service --- .../Systems/SystemForEmbassy/MainLoop.ts | 3 +- .../src/service/service_effect_handler.rs | 39 ++++++++++++++++--- sdk/lib/types.ts | 8 +++- sdk/lib/util/Overlay.ts | 10 +++-- sdk/lib/util/utils.ts | 5 ++- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts index 484e02c24..daf3ade70 100644 --- a/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts +++ b/container-runtime/src/Adapters/Systems/SystemForEmbassy/MainLoop.ts @@ -86,10 +86,11 @@ export class MainLoop { public async clean(options?: { timeout?: number }) { const { mainEvent, healthLoops, propertiesEvent } = this + const main = await mainEvent delete this.mainEvent delete this.healthLoops delete this.propertiesEvent - if (mainEvent) await (await mainEvent).daemon.term() + if (mainEvent) await main?.daemon.term() clearInterval(propertiesEvent) if (healthLoops) healthLoops.forEach((x) => clearInterval(x.interval)) } diff --git a/core/startos/src/service/service_effect_handler.rs b/core/startos/src/service/service_effect_handler.rs index c4a9584d3..55bc07916 100644 --- a/core/startos/src/service/service_effect_handler.rs +++ b/core/startos/src/service/service_effect_handler.rs @@ -7,7 +7,7 @@ use std::{ffi::OsString, time::Instant}; use chrono::Utc; use clap::builder::{TypedValueParser, ValueParserFactory}; use clap::Parser; -use imbl_value::json; +use imbl_value::{json, InternedString}; use models::{ActionId, HealthCheckId, ImageId, PackageId}; use patch_db::json_ptr::JsonPointer; use rpc_toolkit::{from_fn, from_fn_async, AnyContext, Context, Empty, HandlerExt, ParentHandler}; @@ -111,11 +111,15 @@ pub fn service_effect_handler() -> ParentHandler { .subcommand( "createOverlayedImage", from_fn_async(create_overlayed_image) - .with_custom_display_fn::(|_, path| { + .with_custom_display_fn::(|_, (path, _)| { Ok(println!("{}", path.display())) }) .with_remote_cli::(), ) + .subcommand( + "destroyOverlayedImage", + from_fn_async(destroy_overlayed_image).no_cli(), + ) .subcommand( "getSslCertificate", from_fn_async(get_ssl_certificate).no_cli(), @@ -668,7 +672,32 @@ async fn set_health(context: EffectContext, params: SetHealth) -> Result Result<(), Error> { + let ctx = ctx.deref()?; + if ctx + .persistent_container + .overlays + .lock() + .await + .remove(&guid) + .is_none() + { + tracing::warn!("Could not find a guard to remove on the destroy overlayed image; assumming that it already is removed and will be skipping"); + } + Ok(()) +} #[derive(serde::Deserialize, serde::Serialize, Parser)] #[serde(rename_all = "camelCase")] #[command(rename_all = "camelCase")] @@ -680,10 +709,10 @@ pub struct CreateOverlayedImageParams { pub async fn create_overlayed_image( ctx: EffectContext, CreateOverlayedImageParams { image_id }: CreateOverlayedImageParams, -) -> Result { +) -> Result<(PathBuf, InternedString), Error> { let ctx = ctx.deref()?; let path = Path::new("images") - .join(&*ARCH) + .join(*ARCH) .join(&image_id) .with_extension("squashfs"); if let Some(image) = ctx @@ -730,7 +759,7 @@ pub async fn create_overlayed_image( .lock() .await .insert(guid.clone(), guard); - Ok(container_mountpoint) + Ok((container_mountpoint, guid)) } else { Err(Error::new( eyre!("image {image_id} not found in s9pk"), diff --git a/sdk/lib/types.ts b/sdk/lib/types.ts index e0bc4a259..cb1946818 100644 --- a/sdk/lib/types.ts +++ b/sdk/lib/types.ts @@ -276,7 +276,13 @@ export type Effects = { }): Promise /** A low level api used by makeOverlay */ - createOverlayedImage(options: { imageId: string }): Promise + createOverlayedImage(options: { imageId: string }): Promise<[string, string]> + + /** A low level api used by destroyOverlay + makeOverlay:destroy */ + destroyOverlayedImage(options: { + imageId: string + guid: string + }): Promise /** Removes all network bindings */ clearBindings(): Promise diff --git a/sdk/lib/util/Overlay.ts b/sdk/lib/util/Overlay.ts index 5f928289d..36dbaead5 100644 --- a/sdk/lib/util/Overlay.ts +++ b/sdk/lib/util/Overlay.ts @@ -10,9 +10,10 @@ export class Overlay { readonly effects: T.Effects, readonly imageId: string, readonly rootfs: string, + readonly guid: string, ) {} static async of(effects: T.Effects, imageId: string) { - const rootfs = await effects.createOverlayedImage({ imageId }) + const [rootfs, guid] = await effects.createOverlayedImage({ imageId }) for (const dirPart of ["dev", "sys", "proc", "run"] as const) { await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true }) @@ -23,7 +24,7 @@ export class Overlay { ]) } - return new Overlay(effects, imageId, rootfs) + return new Overlay(effects, imageId, rootfs, guid) } async mount(options: MountOptions, path: string): Promise { @@ -51,8 +52,9 @@ export class Overlay { } async destroy() { - await execFile("umount", ["-R", this.rootfs]) - await fs.rm(this.rootfs, { recursive: true, force: true }) + const imageId = this.imageId + const guid = this.guid + await this.effects.destroyOverlayedImage({ imageId, guid }) } async exec( diff --git a/sdk/lib/util/utils.ts b/sdk/lib/util/utils.ts index af6ae89cb..cb5afae3d 100644 --- a/sdk/lib/util/utils.ts +++ b/sdk/lib/util/utils.ts @@ -246,7 +246,7 @@ export const createUtils = < console.error(data.toString()) }) - childProcess.on("close", (code: any) => { + childProcess.on("exit", (code: any) => { if (code === 0) { return resolve(null) } @@ -262,7 +262,7 @@ export const createUtils = < try { childProcess.kill(signal) - if (timeout <= NO_TIMEOUT) { + if (timeout > NO_TIMEOUT) { const didTimeout = await Promise.race([ new Promise((resolve) => setTimeout(resolve, timeout)).then( () => true, @@ -270,6 +270,7 @@ export const createUtils = < answer.then(() => false), ]) if (didTimeout) childProcess.kill(SIGKILL) + return } await answer } finally {