diff --git a/container-runtime/src/Adapters/Systems/SystemForStartOs.ts b/container-runtime/src/Adapters/Systems/SystemForStartOs.ts index e10434032..e7f09952a 100644 --- a/container-runtime/src/Adapters/Systems/SystemForStartOs.ts +++ b/container-runtime/src/Adapters/Systems/SystemForStartOs.ts @@ -123,9 +123,9 @@ export class SystemForStartOs implements System { return this.abi.uninit({ effects, nextVersion }) } case "/main/start": { + if (this.onTerm) await this.onTerm() const started = async (onTerm: () => Promise) => { await effects.setMainStatus({ status: "running" }) - if (this.onTerm) await this.onTerm() this.onTerm = onTerm } const daemons = await ( @@ -135,10 +135,11 @@ export class SystemForStartOs implements System { }) ).build() this.onTerm = daemons.term + return } case "/main/stop": { - await effects.setMainStatus({ status: "stopped" }) if (this.onTerm) await this.onTerm() + await effects.setMainStatus({ status: "stopped" }) delete this.onTerm return duration(30, "s") } @@ -183,6 +184,7 @@ export class SystemForStartOs implements System { return dependencyConfig.update(options.input as any) // TODO } } + return } throw new Error(`Method ${options.procedure} not implemented.`) } diff --git a/core/startos/src/service/mod.rs b/core/startos/src/service/mod.rs index 2eecc565e..92564b8e4 100644 --- a/core/startos/src/service/mod.rs +++ b/core/startos/src/service/mod.rs @@ -485,7 +485,7 @@ impl Actor for ServiceActor { let mut current = seed.persistent_container.state.subscribe(); loop { - let kinds = dbg!(current.borrow().kinds()); + let kinds = current.borrow().kinds(); if let Err(e) = async { let main_status = match ( @@ -493,6 +493,14 @@ impl Actor for ServiceActor { kinds.desired_state, kinds.running_status, ) { + (Some(TransitionKind::Restarting), StartStop::Stop, Some(_)) => { + seed.persistent_container.stop().await?; + MainStatus::Restarting + } + (Some(TransitionKind::Restarting), StartStop::Start, _) => { + seed.persistent_container.start().await?; + MainStatus::Restarting + } (Some(TransitionKind::Restarting), _, _) => MainStatus::Restarting, (Some(TransitionKind::Restoring), _, _) => MainStatus::Restoring, (Some(TransitionKind::BackingUp), _, Some(status)) => { @@ -523,6 +531,30 @@ impl Actor for ServiceActor { .mutate(|d| { if let Some(i) = d.as_public_mut().as_package_data_mut().as_idx_mut(&id) { + let previous = i.as_status().as_main().de()?; + let previous_health = previous.health(); + let previous_started = previous.started(); + let mut main_status = main_status; + match &mut main_status { + &mut MainStatus::Running { ref mut health, .. } + | &mut MainStatus::BackingUp { ref mut health, .. } => { + *health = previous_health.unwrap_or(health).clone(); + } + _ => (), + }; + match &mut main_status { + MainStatus::Running { + ref mut started, .. + } => { + *started = previous_started.unwrap_or(*started); + } + MainStatus::BackingUp { + ref mut started, .. + } => { + *started = previous_started.map(Some).unwrap_or(*started); + } + _ => (), + }; i.as_status_mut().as_main_mut().ser(&main_status)?; } Ok(()) diff --git a/core/startos/src/service/service_effect_handler.rs b/core/startos/src/service/service_effect_handler.rs index 28a611854..bcd6da7d1 100644 --- a/core/startos/src/service/service_effect_handler.rs +++ b/core/startos/src/service/service_effect_handler.rs @@ -936,7 +936,6 @@ async fn stopped(context: EffectContext, params: ParamsMaybePackageId) -> Result Ok(json!(matches!(package, MainStatus::Stopped))) } async fn running(context: EffectContext, params: ParamsPackageId) -> Result { - dbg!("Starting the running {params:?}"); let context = context.deref()?; let peeked = context.seed.ctx.db.peek().await; let package_id = params.package_id; @@ -956,9 +955,7 @@ async fn restart( WithProcedureId { procedure_id, .. }: WithProcedureId, ) -> Result<(), Error> { let context = context.deref()?; - dbg!("here"); context.restart(procedure_id).await?; - dbg!("here"); Ok(()) } @@ -1032,12 +1029,11 @@ struct SetMainStatus { status: SetMainStatusStatus, } async fn set_main_status(context: EffectContext, params: SetMainStatus) -> Result { - dbg!(format!("Status for main will be is {params:?}")); let context = context.deref()?; match params.status { SetMainStatusStatus::Running => context.seed.started(), SetMainStatusStatus::Stopped => context.seed.stopped(), - SetMainStatusStatus::Starting => context.seed.stopped(), + SetMainStatusStatus::Starting => context.seed.started(), } Ok(Value::Null) } diff --git a/sdk/Makefile b/sdk/Makefile index 091f4c7bb..4d01fa3d7 100644 --- a/sdk/Makefile +++ b/sdk/Makefile @@ -25,7 +25,7 @@ dist: $(TS_FILES) package.json node_modules README.md LICENSE cp LICENSE dist/LICENSE touch dist -full-bundle: clean bundle +full-bundle: bundle check: npm run check @@ -36,7 +36,7 @@ fmt: node_modules node_modules: package.json npm ci -publish: clean bundle package.json README.md LICENSE +publish: bundle package.json README.md LICENSE cd dist && npm publish --access=public link: bundle diff --git a/sdk/lib/mainFn/Daemons.ts b/sdk/lib/mainFn/Daemons.ts index d51d444a8..f48dd51c0 100644 --- a/sdk/lib/mainFn/Daemons.ts +++ b/sdk/lib/mainFn/Daemons.ts @@ -154,7 +154,7 @@ export class Daemons { this.healthDaemons.forEach((x) => x.addWatcher(() => this.updateMainHealth()), ) - return { + const built = { term: async (options?: { signal?: Signals; timeout?: number }) => { try { await Promise.all(this.healthDaemons.map((x) => x.term(options))) @@ -163,6 +163,8 @@ export class Daemons { } }, } + this.started(() => built.term()) + return built } private updateMainHealth() { diff --git a/sdk/lib/mainFn/HealthDaemon.ts b/sdk/lib/mainFn/HealthDaemon.ts index 84e9e34d7..48f3fab55 100644 --- a/sdk/lib/mainFn/HealthDaemon.ts +++ b/sdk/lib/mainFn/HealthDaemon.ts @@ -132,14 +132,14 @@ export class HealthDaemon { this.effects.setHealth({ result: status, message: health.message, - id: display, + id: this.id, name: display, }) } else { this.effects.setHealth({ result: health.status, message: health.message || "", - id: display, + id: this.id, name: display, }) } diff --git a/sdk/lib/util/Overlay.ts b/sdk/lib/util/Overlay.ts index fbc854c57..4d6d36b34 100644 --- a/sdk/lib/util/Overlay.ts +++ b/sdk/lib/util/Overlay.ts @@ -27,12 +27,11 @@ export class Overlay { } for (const dirPart of shared) { - await fs.mkdir(`${rootfs}/${dirPart}`, { recursive: true }) - await execFile("mount", [ - "--rbind", - `/${dirPart}`, - `${rootfs}/${dirPart}`, - ]) + const from = `/${dirPart}` + const to = `${rootfs}/${dirPart}` + await fs.mkdir(from, { recursive: true }) + await fs.mkdir(to, { recursive: true }) + await execFile("mount", ["--rbind", from, to]) } return new Overlay(effects, id, rootfs, guid) @@ -48,22 +47,22 @@ export class Overlay { ? options.subpath : `/${options.subpath}` : "/" - await execFile("mount", [ - "--bind", - `/media/startos/volumes/${options.id}${subpath}`, - path, - ]) + const from = `/media/startos/volumes/${options.id}${subpath}` + + await fs.mkdir(from, { recursive: true }) + await fs.mkdir(path, { recursive: true }) + await await execFile("mount", ["--bind", from, path]) } else if (options.type === "assets") { const subpath = options.subpath ? options.subpath.startsWith("/") ? options.subpath : `/${options.subpath}` : "/" - await execFile("mount", [ - "--bind", - `/media/startos/assets/${options.id}${subpath}`, - path, - ]) + const from = `/media/startos/assets/${options.id}${subpath}` + + await fs.mkdir(from, { recursive: true }) + await fs.mkdir(path, { recursive: true }) + await execFile("mount", ["--bind", from, path]) } else if (options.type === "pointer") { await this.effects.mount({ location: path, target: options }) } else if (options.type === "backup") { @@ -72,11 +71,11 @@ export class Overlay { ? options.subpath : `/${options.subpath}` : "/" - await execFile("mount", [ - "--bind", - `/media/startos/backup${subpath}`, - path, - ]) + const from = `/media/startos/backup${subpath}` + + await fs.mkdir(from, { recursive: true }) + await fs.mkdir(path, { recursive: true }) + await execFile("mount", ["--bind", from, path]) } else { throw new Error(`unknown type ${(options as any).type}`) }