riju/backend/src/util.ts

100 lines
2.3 KiB
TypeScript

import { spawn, SpawnOptions } from "child_process";
import * as process from "process";
import * as appRoot from "app-root-path";
export interface Options extends SpawnOptions {
input?: string;
check?: boolean;
}
export interface Context {
uid: number;
uuid: string;
}
export const rijuSystemPrivileged = appRoot.resolve(
"system/out/riju-system-privileged"
);
export function getEnv(uuid: string) {
const cwd = `/tmp/riju/${uuid}`;
const path = [
`${cwd}/.gem/ruby/2.7.0/bin`,
`${cwd}/.local/bin`,
`${cwd}/node_modules/.bin`,
`/usr/local/sbin`,
`/usr/local/bin`,
`/usr/sbin`,
`/usr/bin`,
`/bin`,
];
return {
HOME: cwd,
HOSTNAME: "riju",
LANG: process.env.LANG || "",
LC_ALL: process.env.LC_ALL || "",
PATH: path.join(":"),
PWD: cwd,
SHELL: "/usr/bin/bash",
TERM: "xterm-color",
};
}
export async function run(
args: string[],
log: (msg: string) => void,
options?: Options
) {
options = options || {};
const input = options.input;
const check = options.check === undefined ? true : options.check;
delete options.input;
delete options.check;
const proc = spawn(args[0], args.slice(1), options);
if (typeof input === "string") {
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 || !check) {
resolve();
} else {
reject(`command ${args[0]} failed with error code ${code}`);
}
});
});
}
export function privilegedUseradd(uid: number) {
return [rijuSystemPrivileged, "useradd", `${uid}`];
}
export function privilegedSetup({ uid, uuid }: Context) {
return [rijuSystemPrivileged, "setup", `${uid}`, uuid];
}
export function privilegedSpawn({ uid, uuid }: Context, args: string[]) {
return [rijuSystemPrivileged, "spawn", `${uid}`, uuid].concat(args);
}
export function privilegedTeardown({ uid, uuid }: Context) {
return [rijuSystemPrivileged, "teardown", `${uid}`, uuid];
}
export function bash(cmdline: string) {
return ["bash", "-c", cmdline];
}