mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-04 22:39:46 +00:00
fix: Making the daemons keep up the status. (#2617)
* complete get_primary_url fn * complete clear_network_interfaces fn * formatting * complete remove_address fn * get_system_smtp wip * complete get_system_smtp and set_system_smtp * add SetSystemSmtpParams struct * add set_system_smtp subcommand * Remove 'Copy' implementation from `HostAddress` Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> * Refactor `get_host_primary` fn and clone resulting `HostAddress` Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> * misc fixes and debug info * seed hosts with a tor address * fix: Making the daemons keep up the status. * wipFix: Making a service start * fix: Both the start + stop of the service. * fix: Weird edge case of failure and kids --------- Co-authored-by: Shadowy Super Coder <musashidisciple@proton.me> Co-authored-by: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
108
sdk/lib/mainFn/CommandController.ts
Normal file
108
sdk/lib/mainFn/CommandController.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { NO_TIMEOUT, SIGTERM } from "../StartSdk"
|
||||
import { SDKManifest } from "../manifest/ManifestTypes"
|
||||
import { Effects, ValidIfNoStupidEscape } from "../types"
|
||||
import { MountOptions, Overlay } from "../util/Overlay"
|
||||
import { splitCommand } from "../util/splitCommand"
|
||||
import { cpExecFile } from "./Daemons"
|
||||
|
||||
export class CommandController {
|
||||
private constructor(
|
||||
readonly runningAnswer: Promise<unknown>,
|
||||
readonly overlay: Overlay,
|
||||
readonly pid: number | undefined,
|
||||
) {}
|
||||
static of<Manifest extends SDKManifest>() {
|
||||
return async <A extends string>(
|
||||
effects: Effects,
|
||||
imageId: {
|
||||
id: Manifest["images"][number]
|
||||
sharedRun?: boolean
|
||||
},
|
||||
command: ValidIfNoStupidEscape<A> | [string, ...string[]],
|
||||
options: {
|
||||
mounts?: { path: string; options: MountOptions }[]
|
||||
overlay?: Overlay
|
||||
env?:
|
||||
| {
|
||||
[variable: string]: string
|
||||
}
|
||||
| undefined
|
||||
cwd?: string | undefined
|
||||
user?: string | undefined
|
||||
onStdout?: (x: Buffer) => void
|
||||
onStderr?: (x: Buffer) => void
|
||||
},
|
||||
) => {
|
||||
const commands = splitCommand(command)
|
||||
const overlay = options.overlay || (await Overlay.of(effects, imageId))
|
||||
for (let mount of options.mounts || []) {
|
||||
await overlay.mount(mount.options, mount.path)
|
||||
}
|
||||
const childProcess = await overlay.spawn(commands, {
|
||||
env: options.env,
|
||||
})
|
||||
const answer = new Promise<null>((resolve, reject) => {
|
||||
childProcess.stdout.on(
|
||||
"data",
|
||||
options.onStdout ??
|
||||
((data: any) => {
|
||||
console.log(data.toString())
|
||||
}),
|
||||
)
|
||||
childProcess.stderr.on(
|
||||
"data",
|
||||
options.onStderr ??
|
||||
((data: any) => {
|
||||
console.error(data.toString())
|
||||
}),
|
||||
)
|
||||
|
||||
childProcess.on("exit", (code: any) => {
|
||||
if (code === 0) {
|
||||
return resolve(null)
|
||||
}
|
||||
return reject(new Error(`${commands[0]} exited with code ${code}`))
|
||||
})
|
||||
})
|
||||
|
||||
const pid = childProcess.pid
|
||||
|
||||
return new CommandController(answer, overlay, pid)
|
||||
}
|
||||
}
|
||||
async wait() {
|
||||
try {
|
||||
return await this.runningAnswer
|
||||
} finally {
|
||||
await cpExecFile("pkill", ["-9", "-s", String(this.pid)]).catch((_) => {})
|
||||
await this.overlay.destroy().catch((_) => {})
|
||||
}
|
||||
}
|
||||
async term({ signal = SIGTERM, timeout = NO_TIMEOUT } = {}) {
|
||||
try {
|
||||
await cpExecFile("pkill", [
|
||||
`-${signal.replace("SIG", "")}`,
|
||||
"-s",
|
||||
String(this.pid),
|
||||
])
|
||||
|
||||
if (timeout > NO_TIMEOUT) {
|
||||
const didTimeout = await Promise.race([
|
||||
new Promise((resolve) => setTimeout(resolve, timeout)).then(
|
||||
() => true,
|
||||
),
|
||||
this.runningAnswer.then(() => false),
|
||||
])
|
||||
if (didTimeout) {
|
||||
await cpExecFile("pkill", [`-9`, "-s", String(this.pid)]).catch(
|
||||
(_: any) => {},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
await this.runningAnswer
|
||||
}
|
||||
} finally {
|
||||
await this.overlay.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user