Add daemon support, sandbox script

This commit is contained in:
Radon Rosborough 2020-07-10 09:58:16 -06:00
parent a7b1ba67f3
commit bb14a6c9ab
5 changed files with 72 additions and 3 deletions

View File

@ -7,7 +7,6 @@ import { IPty } from "node-pty";
import * as rpc from "vscode-jsonrpc";
import { v4 as getUUID } from "uuid";
import { PRIVILEGED } from "./config";
import { LangConfig, langs } from "./langs";
import { borrowUser } from "./users";
import {
@ -27,6 +26,7 @@ export class Session {
reader: rpc.StreamMessageReader;
writer: rpc.StreamMessageWriter;
} | null;
daemon: ChildProcess | null;
ws: WebSocket;
homedir: string | null;
uid: number | null;
@ -41,6 +41,7 @@ export class Session {
this.config = langs[lang];
this.term = { pty: null, live: false };
this.lsp = null;
this.daemon = null;
this.code = null;
this.homedir = null;
this.uid = null;
@ -118,6 +119,7 @@ export class Session {
}
const {
name,
daemon,
repl,
main,
suffix,
@ -217,6 +219,18 @@ export class Session {
this.send({ event: "terminalOutput", output: data });
}
});
if (daemon && this.daemon === null) {
this.daemon = spawn("bash", ["-c", daemon], { env: getEnv(this.uuid) });
this.daemon.on("exit", (code) =>
this.send({ event: "daemonCrashed", code })
);
this.daemon.stdout!.on("data", (data) =>
this.send({ event: "daemonLog", output: data.toString("utf8") })
);
this.daemon.stderr!.on("data", (data) =>
this.send({ event: "daemonLog", output: data.toString("utf8") })
);
}
if (lsp && this.lsp === null) {
if (lspSetup) {
await spawnPrivileged(

View File

@ -2,6 +2,7 @@ export interface LangConfig {
aliases?: string[];
name: string;
monacoLang: string;
daemon?: string;
repl?: string;
main: string;
prefix?: string;

35
backend/src/sandbox.ts Normal file
View File

@ -0,0 +1,35 @@
import { spawn } from "child_process";
import * as fs from "fs";
import { v4 as getUUID } from "uuid";
import { langs } from "./langs";
import { borrowUser } from "./users";
import { callPrivileged, getEnv, rijuSystemPrivileged } from "./util";
function die(msg: any) {
console.error(msg);
process.exit(1);
}
function log(msg: any) {
console.log(msg);
}
async function main() {
const uuid = getUUID();
const { uid, cleanup } = await borrowUser(log);
await callPrivileged(["setup", `${uid}`, uuid], log);
const args = [rijuSystemPrivileged, "spawn", `${uid}`, `${uuid}`, "bash"];
const proc = spawn(args[0], args.slice(1), {
env: getEnv(uuid),
stdio: "inherit",
});
await new Promise((resolve, reject) => {
proc.on("error", reject);
proc.on("exit", resolve);
});
await cleanup();
}
main().catch(die);

View File

@ -142,6 +142,7 @@ async function main() {
let clientDisposable: Disposable | null = null;
let servicesDisposable: Disposable | null = null;
let lspLogBuffer = "";
let daemonLogBuffer = "";
console.log("Connecting to server...");
socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") +
@ -162,7 +163,8 @@ async function main() {
if (
DEBUG &&
message?.event !== "lspOutput" &&
message?.event !== "lspLog"
message?.event !== "lspLog" &&
message?.event !== "daemonLog"
) {
console.log("RECEIVE:", message);
}
@ -244,7 +246,23 @@ async function main() {
}
}
return;
case "daemonLog":
if (typeof message.output !== "string") {
console.error("Unexpected message from server:", message);
return;
}
if (DEBUG) {
daemonLogBuffer += message.output;
while (daemonLogBuffer.includes("\n")) {
const idx = daemonLogBuffer.indexOf("\n");
const line = daemonLogBuffer.slice(0, idx);
daemonLogBuffer = daemonLogBuffer.slice(idx + 1);
console.log(`DAEMON || ${line}`);
}
}
return;
case "lspCrashed":
case "daemonCrashed":
return;
default:
console.error("Unexpected message from server:", message);

View File

@ -57,6 +57,7 @@
"system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash",
"build": "run-s backend frontend system",
"dev": "run-p backend-dev frontend-dev system-dev server-dev",
"lsp": "node backend/out/lsp-repl.js"
"lsp-repl": "node backend/out/lsp-repl.js",
"sandbox": "node backend/out/sandbox.js"
}
}