84 lines
1.8 KiB
TypeScript
84 lines
1.8 KiB
TypeScript
import { spawn, SpawnOptions } from "child_process";
|
|
import * as process from "process";
|
|
|
|
interface Options extends SpawnOptions {
|
|
input?: string;
|
|
}
|
|
|
|
export function getEnv(uuid: string) {
|
|
const cwd = `/tmp/riju/${uuid}`;
|
|
return {
|
|
HOME: cwd,
|
|
HOSTNAME: "riju",
|
|
LANG: "C.UTF-8",
|
|
LC_ALL: "C.UTF-8",
|
|
PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin",
|
|
PWD: cwd,
|
|
SHELL: "/usr/bin/bash",
|
|
TERM: "xterm-color",
|
|
};
|
|
}
|
|
|
|
export async function call(
|
|
args: string[],
|
|
log: (msg: string) => void,
|
|
options?: Options
|
|
) {
|
|
options = options || {};
|
|
const input = options.input;
|
|
delete options.input;
|
|
const proc = spawn(args[0], args.slice(1), options);
|
|
if (input) {
|
|
proc.stdin!.end(input);
|
|
}
|
|
let output = "";
|
|
proc.stdout!.on("data", (data: Buffer) => {
|
|
output += `${data}`;
|
|
});
|
|
proc.stderr!.on("data", (data: Buffer) => {
|
|
output += `${data}`;
|
|
});
|
|
await new Promise((resolve, reject) => {
|
|
proc.on("error", reject);
|
|
proc.on("close", (code: number) => {
|
|
output = output.trim();
|
|
if (output) {
|
|
log(`Output from ${args[0]}:\n` + output);
|
|
}
|
|
if (code === 0) {
|
|
resolve();
|
|
} else {
|
|
reject(`command ${args[0]} failed with error code ${code}`);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
export async function callPrivileged(
|
|
args: string[],
|
|
log: (msg: string) => void,
|
|
options?: Options
|
|
) {
|
|
await call(
|
|
["/home/docker/src/system/out/riju-system-privileged"].concat(args),
|
|
log,
|
|
options
|
|
);
|
|
}
|
|
|
|
export async function spawnPrivileged(
|
|
uid: number,
|
|
uuid: string,
|
|
args: string[],
|
|
log: (msg: string) => void,
|
|
options?: Options
|
|
) {
|
|
options = options || {};
|
|
options.env = getEnv(uuid);
|
|
await callPrivileged(
|
|
["spawn", `${uid}`, `${uuid}`].concat(args),
|
|
log,
|
|
options
|
|
);
|
|
}
|