diff --git a/backend/src/api.ts b/backend/src/api.ts index 922998c..aad5e61 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -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( diff --git a/backend/src/langs.ts b/backend/src/langs.ts index a684572..d4f8b2d 100644 --- a/backend/src/langs.ts +++ b/backend/src/langs.ts @@ -2,6 +2,7 @@ export interface LangConfig { aliases?: string[]; name: string; monacoLang: string; + daemon?: string; repl?: string; main: string; prefix?: string; diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts new file mode 100644 index 0000000..f9fd273 --- /dev/null +++ b/backend/src/sandbox.ts @@ -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); diff --git a/frontend/src/app.ts b/frontend/src/app.ts index 8337c3c..bdbe5a0 100644 --- a/frontend/src/app.ts +++ b/frontend/src/app.ts @@ -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); diff --git a/package.json b/package.json index 02bd9dc..db50a61 100644 --- a/package.json +++ b/package.json @@ -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" } }