kill process by session, and add timeout (#2608)

This commit is contained in:
Aiden McClelland
2024-04-23 14:01:40 -06:00
committed by GitHub
parent 7b8a0114f5
commit 3a5ee4a296
6 changed files with 191 additions and 85 deletions

View File

@@ -70,7 +70,13 @@ export class Overlay {
async exec(
command: string[],
options?: CommandOptions,
): Promise<{ stdout: string | Buffer; stderr: string | Buffer }> {
timeoutMs: number | null = 30000,
): Promise<{
exitCode: number | null
exitSignal: NodeJS.Signals | null
stdout: string | Buffer
stderr: string | Buffer
}> {
const imageMeta = await fs
.readFile(`/media/startos/images/${this.imageId}.json`, {
encoding: "utf8",
@@ -87,7 +93,7 @@ export class Overlay {
workdir = options.cwd
delete options.cwd
}
return await execFile(
const child = cp.spawn(
"start-cli",
[
"chroot",
@@ -97,8 +103,44 @@ export class Overlay {
this.rootfs,
...command,
],
options,
options || {},
)
const pid = child.pid
const stdout = { data: "" as string | Buffer }
const stderr = { data: "" as string | Buffer }
const appendData =
(appendTo: { data: string | Buffer }) =>
(chunk: string | Buffer | any) => {
if (typeof appendTo.data === "string" && typeof chunk === "string") {
appendTo.data += chunk
} else if (typeof chunk === "string" || chunk instanceof Buffer) {
appendTo.data = Buffer.concat([
Buffer.from(appendTo.data),
Buffer.from(chunk),
])
} else {
console.error("received unexpected chunk", chunk)
}
}
return new Promise((resolve, reject) => {
child.on("error", reject)
if (timeoutMs !== null && pid) {
setTimeout(
() => execFile("pkill", ["-9", "-s", String(pid)]).catch((_) => {}),
timeoutMs,
)
}
child.stdout.on("data", appendData(stdout))
child.stderr.on("data", appendData(stderr))
child.on("exit", (code, signal) =>
resolve({
exitCode: code,
exitSignal: signal,
stdout: stdout.data,
stderr: stderr.data,
}),
)
})
}
async spawn(