mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 04:01:58 +00:00
add error status (#2746)
* add error status * update types * ṗ̶̰̙̓͒̈́ͅü̵̢̙̫̣ŗ̷̪̺̺͛g̴̲͉͎̬̒̇e̵̪̎̅͌ ̶̡̜̘͐͛t̶͎͍̣̿̍̐h̴͕̩͗̈́̎̑e̵͚͒̂͝ ̸̛͙̦͈͝v̶̱͙̬̽̔ọ̶̧̡̒̓i̸̬̲͍̋̈́d̴͉̀ * fix some extra voids * add `package.rebuild` * introduce error status and pkg rebuild and fix mocks * minor fixes * fix build --------- Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
@@ -563,7 +563,7 @@ export class StartSdk<Manifest extends T.Manifest, Store> {
|
||||
setupMain: (
|
||||
fn: (o: {
|
||||
effects: Effects
|
||||
started(onTerm: () => PromiseLike<void>): PromiseLike<void>
|
||||
started(onTerm: () => PromiseLike<void>): PromiseLike<null>
|
||||
}) => Promise<Daemons<Manifest, any>>,
|
||||
) => setupMain<Manifest, Store>(fn),
|
||||
/**
|
||||
@@ -657,12 +657,12 @@ export class StartSdk<Manifest extends T.Manifest, Store> {
|
||||
) => InputSpec.of<Spec, Store>(spec),
|
||||
},
|
||||
Daemons: {
|
||||
of(inputSpec: {
|
||||
of(options: {
|
||||
effects: Effects
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<void>
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>
|
||||
healthReceipts: HealthReceipt[]
|
||||
}) {
|
||||
return Daemons.of<Manifest>(inputSpec)
|
||||
return Daemons.of<Manifest>(options)
|
||||
},
|
||||
},
|
||||
List: {
|
||||
|
||||
@@ -12,7 +12,7 @@ export function setupInit<Manifest extends T.Manifest, Store>(
|
||||
install: Install<Manifest, Store>,
|
||||
uninstall: Uninstall<Manifest, Store>,
|
||||
setServiceInterfaces: UpdateServiceInterfaces<any>,
|
||||
setDependencies: (options: { effects: T.Effects }) => Promise<void>,
|
||||
setDependencies: (options: { effects: T.Effects }) => Promise<null>,
|
||||
actions: Actions<Store, any>,
|
||||
exposedStore: ExposedStorePaths,
|
||||
): {
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as T from "../../../base/lib/types"
|
||||
|
||||
export type InstallFn<Manifest extends T.Manifest, Store> = (opts: {
|
||||
effects: T.Effects
|
||||
}) => Promise<void>
|
||||
}) => Promise<null>
|
||||
export class Install<Manifest extends T.Manifest, Store> {
|
||||
private constructor(readonly fn: InstallFn<Manifest, Store>) {}
|
||||
static of<Manifest extends T.Manifest, Store>(
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as T from "../../../base/lib/types"
|
||||
|
||||
export type UninstallFn<Manifest extends T.Manifest, Store> = (opts: {
|
||||
effects: T.Effects
|
||||
}) => Promise<void>
|
||||
}) => Promise<null>
|
||||
export class Uninstall<Manifest extends T.Manifest, Store> {
|
||||
private constructor(readonly fn: UninstallFn<Manifest, Store>) {}
|
||||
static of<Manifest extends T.Manifest, Store>(
|
||||
|
||||
@@ -43,8 +43,8 @@ export class CommandController {
|
||||
| undefined
|
||||
cwd?: string | undefined
|
||||
user?: string | undefined
|
||||
onStdout?: (x: Buffer) => void
|
||||
onStderr?: (x: Buffer) => void
|
||||
onStdout?: (x: Buffer) => null
|
||||
onStderr?: (x: Buffer) => null
|
||||
},
|
||||
) => {
|
||||
const commands = splitCommand(command)
|
||||
|
||||
@@ -37,8 +37,8 @@ export class Daemon {
|
||||
| undefined
|
||||
cwd?: string | undefined
|
||||
user?: string | undefined
|
||||
onStdout?: (x: Buffer) => void
|
||||
onStderr?: (x: Buffer) => void
|
||||
onStdout?: (x: Buffer) => null
|
||||
onStderr?: (x: Buffer) => null
|
||||
sigtermTimeout?: number
|
||||
},
|
||||
) => {
|
||||
|
||||
@@ -74,7 +74,7 @@ export class Daemons<Manifest extends T.Manifest, Ids extends string>
|
||||
{
|
||||
private constructor(
|
||||
readonly effects: T.Effects,
|
||||
readonly started: (onTerm: () => PromiseLike<void>) => PromiseLike<void>,
|
||||
readonly started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>,
|
||||
readonly daemons: Promise<Daemon>[],
|
||||
readonly ids: Ids[],
|
||||
readonly healthDaemons: HealthDaemon[],
|
||||
@@ -86,17 +86,17 @@ export class Daemons<Manifest extends T.Manifest, Ids extends string>
|
||||
*
|
||||
* Daemons run in the order they are defined, with latter daemons being capable of
|
||||
* depending on prior daemons
|
||||
* @param inputSpec
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
static of<Manifest extends T.Manifest>(inputSpec: {
|
||||
static of<Manifest extends T.Manifest>(options: {
|
||||
effects: T.Effects
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<void>
|
||||
started: (onTerm: () => PromiseLike<void>) => PromiseLike<null>
|
||||
healthReceipts: HealthReceipt[]
|
||||
}) {
|
||||
return new Daemons<Manifest, never>(
|
||||
inputSpec.effects,
|
||||
inputSpec.started,
|
||||
options.effects,
|
||||
options.started,
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
|
||||
@@ -81,7 +81,7 @@ export class HealthDaemon {
|
||||
}
|
||||
}
|
||||
|
||||
private healthCheckCleanup: (() => void) | null = null
|
||||
private healthCheckCleanup: (() => null) | null = null
|
||||
private turnOffHealthCheck() {
|
||||
this.healthCheckCleanup?.()
|
||||
}
|
||||
@@ -125,6 +125,7 @@ export class HealthDaemon {
|
||||
this.healthCheckCleanup = () => {
|
||||
setStatus({ done: true })
|
||||
this.healthCheckCleanup = null
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export const DEFAULT_SIGTERM_TIMEOUT = 30_000
|
||||
export const setupMain = <Manifest extends T.Manifest, Store>(
|
||||
fn: (o: {
|
||||
effects: T.Effects
|
||||
started(onTerm: () => PromiseLike<void>): PromiseLike<void>
|
||||
started(onTerm: () => PromiseLike<void>): PromiseLike<null>
|
||||
}) => Promise<Daemons<Manifest, any>>,
|
||||
): T.ExpectedExports.main => {
|
||||
return async (options) => {
|
||||
|
||||
@@ -27,7 +27,7 @@ const TIMES_TO_WAIT_FOR_PROC = 100
|
||||
* case where the subcontainer isn't owned by the process, the subcontainer shouldn't be destroyed.
|
||||
*/
|
||||
export interface ExecSpawnable {
|
||||
get destroy(): undefined | (() => Promise<void>)
|
||||
get destroy(): undefined | (() => Promise<null>)
|
||||
exec(
|
||||
command: string[],
|
||||
options?: CommandOptions & ExecOptions,
|
||||
@@ -47,7 +47,7 @@ export interface ExecSpawnable {
|
||||
export class SubContainer implements ExecSpawnable {
|
||||
private leader: cp.ChildProcess
|
||||
private leaderExited: boolean = false
|
||||
private waitProc: () => Promise<void>
|
||||
private waitProc: () => Promise<null>
|
||||
private constructor(
|
||||
readonly effects: T.Effects,
|
||||
readonly imageId: T.ImageId,
|
||||
@@ -79,7 +79,7 @@ export class SubContainer implements ExecSpawnable {
|
||||
}
|
||||
await wait(1)
|
||||
}
|
||||
resolve()
|
||||
resolve(null)
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -180,12 +180,12 @@ export class SubContainer implements ExecSpawnable {
|
||||
if (this.leaderExited) {
|
||||
return
|
||||
}
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
return new Promise<null>((resolve, reject) => {
|
||||
try {
|
||||
let timeout = setTimeout(() => this.leader.kill("SIGKILL"), 30000)
|
||||
this.leader.on("exit", () => {
|
||||
clearTimeout(timeout)
|
||||
resolve()
|
||||
resolve(null)
|
||||
})
|
||||
if (!this.leader.kill("SIGTERM")) {
|
||||
reject(new Error("kill(2) failed"))
|
||||
@@ -201,6 +201,7 @@ export class SubContainer implements ExecSpawnable {
|
||||
const guid = this.guid
|
||||
await this.killLeader()
|
||||
await this.effects.subcontainer.destroyFs({ guid })
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,16 +246,16 @@ export class SubContainer implements ExecSpawnable {
|
||||
options || {},
|
||||
)
|
||||
if (options?.input) {
|
||||
await new Promise<void>((resolve, reject) =>
|
||||
await new Promise<null>((resolve, reject) =>
|
||||
child.stdin.write(options.input, (e) => {
|
||||
if (e) {
|
||||
reject(e)
|
||||
} else {
|
||||
resolve()
|
||||
resolve(null)
|
||||
}
|
||||
}),
|
||||
)
|
||||
await new Promise<void>((resolve) => child.stdin.end(resolve))
|
||||
await new Promise<null>((resolve) => child.stdin.end(resolve))
|
||||
}
|
||||
const pid = child.pid
|
||||
const stdout = { data: "" as string | Buffer }
|
||||
|
||||
Reference in New Issue
Block a user