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

View File

@ -2,6 +2,7 @@ export interface LangConfig {
aliases?: string[]; aliases?: string[];
name: string; name: string;
monacoLang: string; monacoLang: string;
daemon?: string;
repl?: string; repl?: string;
main: string; main: string;
prefix?: 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 clientDisposable: Disposable | null = null;
let servicesDisposable: Disposable | null = null; let servicesDisposable: Disposable | null = null;
let lspLogBuffer = ""; let lspLogBuffer = "";
let daemonLogBuffer = "";
console.log("Connecting to server..."); console.log("Connecting to server...");
socket = new WebSocket( socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") + (document.location.protocol === "http:" ? "ws://" : "wss://") +
@ -162,7 +163,8 @@ async function main() {
if ( if (
DEBUG && DEBUG &&
message?.event !== "lspOutput" && message?.event !== "lspOutput" &&
message?.event !== "lspLog" message?.event !== "lspLog" &&
message?.event !== "daemonLog"
) { ) {
console.log("RECEIVE:", message); console.log("RECEIVE:", message);
} }
@ -244,7 +246,23 @@ async function main() {
} }
} }
return; 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 "lspCrashed":
case "daemonCrashed":
return; return;
default: default:
console.error("Unexpected message from server:", message); 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", "system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash",
"build": "run-s backend frontend system", "build": "run-s backend frontend system",
"dev": "run-p backend-dev frontend-dev system-dev server-dev", "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"
} }
} }