rework installing page and add cancel install button (#2915)

* rework installing page and add cancel install button

* actually call cancel endpoint

* fix two bugs

* include translations in progress component

* cancellable installs

* fix: comments (#2916)

* fix: comments

* delete comments

* ensure trailing slash and no qp for new registry url

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* fix raspi

* bump sdk

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
This commit is contained in:
Matt Hill
2025-04-30 13:50:08 -06:00
committed by GitHub
parent 5c473eb9cc
commit e6f0067728
37 changed files with 431 additions and 269 deletions

View File

@@ -25,7 +25,7 @@ import {
import * as patterns from "../../base/lib/util/patterns"
import { BackupSync, Backups } from "./backup/Backups"
import { smtpInputSpec } from "../../base/lib/actions/input/inputSpecConstants"
import { CommandController, Daemons } from "./mainFn/Daemons"
import { CommandController, Daemon, Daemons } from "./mainFn/Daemons"
import { HealthCheck } from "./health/HealthCheck"
import { checkPortListening } from "./health/checkFns/checkPortListening"
import { checkWebUrl, runHealthScript } from "./health/checkFns"
@@ -734,6 +734,11 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
spec: Spec,
) => InputSpec.of<Spec, Store>(spec),
},
Daemon: {
get of() {
return Daemon.of<Manifest>()
},
},
Daemons: {
of(
effects: Effects,

View File

@@ -1,5 +1,6 @@
import * as T from "../../../base/lib/types"
import { asError } from "../../../base/lib/util/asError"
import { Drop } from "../util"
import { ExecSpawnable, MountOptions, SubContainer } from "../util/SubContainer"
import { CommandController } from "./CommandController"
import { Mounts } from "./Mounts"
@@ -11,12 +12,14 @@ const MAX_TIMEOUT_MS = 30000
* and the others state of running, where it will keep a living running command
*/
export class Daemon<Manifest extends T.SDKManifest> {
export class Daemon<Manifest extends T.SDKManifest> extends Drop {
private commandController: CommandController<Manifest> | null = null
private shouldBeRunning = false
constructor(
private startCommand: () => Promise<CommandController<Manifest>>,
) {}
) {
super()
}
get subContainerHandle(): undefined | ExecSpawnable {
return this.commandController?.subContainerHandle
}
@@ -88,4 +91,7 @@ export class Daemon<Manifest extends T.SDKManifest> {
.catch((e) => console.error(asError(e)))
this.commandController = null
}
onDrop(): void {
this.stop().catch((e) => console.error(asError(e)))
}
}

View File

@@ -51,21 +51,26 @@ export type Ready = {
type DaemonsParams<
Manifest extends T.SDKManifest,
Ids extends string,
Command extends string,
Id extends string,
> = {
/** The command line command to start the daemon */
command: T.CommandType
/** Information about the subcontainer in which the daemon runs */
subcontainer: SubContainer<Manifest>
env?: Record<string, string>
ready: Ready
/** An array of IDs of prior daemons whose successful initializations are required before this daemon will initialize */
requires: Exclude<Ids, Id>[]
sigtermTimeout?: number
onStdout?: (chunk: Buffer | string | any) => void
onStderr?: (chunk: Buffer | string | any) => void
}
> =
| {
/** The command line command to start the daemon */
command: T.CommandType
/** Information about the subcontainer in which the daemon runs */
subcontainer: SubContainer<Manifest>
env?: Record<string, string>
ready: Ready
/** An array of IDs of prior daemons whose successful initializations are required before this daemon will initialize */
requires: Exclude<Ids, Id>[]
sigtermTimeout?: number
onStdout?: (chunk: Buffer | string | any) => void
onStderr?: (chunk: Buffer | string | any) => void
}
| {
daemon: Daemon<Manifest>
ready: Ready
requires: Exclude<Ids, Id>[]
}
type ErrorDuplicateId<Id extends string> = `The id '${Id}' is already used`
@@ -136,27 +141,23 @@ export class Daemons<Manifest extends T.SDKManifest, Ids extends string>
* @param newDaemon
* @returns
*/
addDaemon<Id extends string, Command extends string>(
addDaemon<Id extends string>(
// prettier-ignore
id:
"" extends Id ? never :
ErrorDuplicateId<Id> extends Id ? never :
Id extends Ids ? ErrorDuplicateId<Id> :
Id,
options: DaemonsParams<Manifest, Ids, Command, Id>,
options: DaemonsParams<Manifest, Ids, Id>,
) {
const daemonIndex = this.daemons.length
const daemon = Daemon.of()(
this.effects,
options.subcontainer,
options.command,
{
...options,
},
)
const daemon =
"daemon" in options
? Promise.resolve(options.daemon)
: Daemon.of()(this.effects, options.subcontainer, options.command, {
...options,
})
const healthDaemon = new HealthDaemon(
daemon,
daemonIndex,
options.requires
.map((x) => this.ids.indexOf(x))
.filter((x) => x >= 0)
@@ -165,7 +166,6 @@ export class Daemons<Manifest extends T.SDKManifest, Ids extends string>
this.ids,
options.ready,
this.effects,
options.sigtermTimeout,
)
const daemons = this.daemons.concat(daemon)
const ids = [...this.ids, id] as (Ids | Id)[]
@@ -184,7 +184,7 @@ export class Daemons<Manifest extends T.SDKManifest, Ids extends string>
try {
this.healthChecks.forEach((health) => health.stop())
for (let result of await Promise.allSettled(
this.healthDaemons.map((x) => x.term({ timeout: x.sigtermTimeout })),
this.healthDaemons.map((x) => x.term()),
)) {
if (result.status === "rejected") {
console.error(result.reason)

View File

@@ -30,13 +30,11 @@ export class HealthDaemon<Manifest extends SDKManifest> {
private readyPromise: Promise<void>
constructor(
private readonly daemon: Promise<Daemon<Manifest>>,
readonly daemonIndex: number,
private readonly dependencies: HealthDaemon<Manifest>[],
readonly id: string,
readonly ids: string[],
readonly ready: Ready,
readonly effects: Effects,
readonly sigtermTimeout: number = DEFAULT_SIGTERM_TIMEOUT,
) {
this.readyPromise = new Promise((resolve) => (this.resolveReady = resolve))
this.dependencies.forEach((d) => d.addWatcher(() => this.updateStatus()))
@@ -53,7 +51,6 @@ export class HealthDaemon<Manifest extends SDKManifest> {
await this.daemon.then((d) =>
d.term({
timeout: this.sigtermTimeout,
...termOptions,
}),
)

View File

@@ -1,12 +1,12 @@
{
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.11",
"version": "0.4.0-beta.12",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.11",
"version": "0.4.0-beta.12",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^3.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.11",
"version": "0.4.0-beta.12",
"description": "Software development kit to facilitate packaging services for StartOS",
"main": "./package/lib/index.js",
"types": "./package/lib/index.d.ts",