diff --git a/Makefile b/Makefile index 08372ea..0ee66a2 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ else ifneq (,$(filter $(I),base lang)) ifeq ($(I),lang) @: $${L} endif - docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src --label riju-install-target=yes $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(LANG_TAG) $(BASH_CMD) + docker run -it --rm --hostname $(LANG_TAG) -v $(VOLUME_MOUNT):/src --label riju-install-target=yes $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(LANG_TAG) $(BASH_CMD) else ifeq ($(I),runtime) docker run -it --rm --hostname $(I) -v $(VOLUME_MOUNT):/src -v /var/run/docker.sock:/var/run/docker.sock $(SHELL_PORTS) $(SHELL_ENV) $(IMAGE_HASH) riju:$(I) $(BASH_CMD) else diff --git a/backend/langs.js b/backend/langs.js index 63716b0..f477050 100644 --- a/backend/langs.js +++ b/backend/langs.js @@ -13,10 +13,9 @@ export let langs = {}; // Map from language aliases and IDs to canonical language IDs. export let aliases = {}; -// Read languages from JSON files in /opt/riju/langs, and update the -// global langs variable in this module. Never throw an error. If -// there is a problem then just leave the languages as they previously -// were. +// Read languages from YAML, and update the global langs variable in +// this module. Never throw an error. If there is a problem then just +// leave the languages as they previously were. async function updateLangsFromDisk() { try { const newLangs = {}; diff --git a/backend/sandbox.bash b/backend/sandbox.bash index a08e84d..8c6f6ec 100644 --- a/backend/sandbox.bash +++ b/backend/sandbox.bash @@ -5,10 +5,13 @@ if [[ -z "$L" ]]; then exit 1 fi -cfg="$(< "/opt/riju/langs/$L.json")" || exit 1 +if [[ -z "$LANG_CONFIG" ]]; then + echo 'environment variable unset: $LANG_CONFIG' >&2 + exit 1 +fi function get { - jq -r ".$1" <<< "${cfg}" + jq -r ".$1" <<< "${LANG_CONFIG}" } function has { diff --git a/backend/sandbox.js b/backend/sandbox.js index a89d79e..19fb2fd 100644 --- a/backend/sandbox.js +++ b/backend/sandbox.js @@ -2,14 +2,17 @@ import { spawn } from "child_process"; import { promises as fs } from "fs"; import process from "process"; +import pty from "node-pty"; import { quote } from "shell-quote"; -import { getUUID } from "./util.js"; - +import { readLangConfig } from "../lib/yaml.js"; import { - privilegedSetup, - privilegedSpawn, - privilegedTeardown, + bash, + getUUID, + privilegedExec, + privilegedPty, + privilegedSession, + privilegedWait, run, } from "./util.js"; @@ -28,22 +31,40 @@ async function main() { if (!lang) { die("environment variable unset: $L"); } + const langConfig = await readLangConfig(lang); const uuid = getUUID(); - await run(privilegedSetup({ uuid }), log); - const args = privilegedSpawn({ uuid }, [ - "bash", - "-c", - `exec env L='${lang}' bash --rcfile <(cat <<< ${quote([sandboxScript])})`, - ]); + console.log(`Starting session with UUID ${uuid}`); + const sessionArgs = privilegedSession({ uuid, lang }); + const session = pty.spawn(sessionArgs[0], sessionArgs.slice(1), { + name: "xterm-color", + }); + await run(privilegedWait({ uuid }), log); + console.log( + bash( + `env L='${lang}' LANG_CONFIG=${quote([ + JSON.stringify(langConfig), + ])} bash --rcfile <(cat <<< ${quote([sandboxScript])})` + )[2] + ); + const args = privilegedPty( + { uuid }, + bash( + `env L='${lang}' LANG_CONFIG=${quote([ + JSON.stringify(langConfig), + ])} bash --rcfile <(cat <<< ${quote([sandboxScript])})` + ) + ); const proc = spawn(args[0], args.slice(1), { stdio: "inherit", }); - await new Promise((resolve, reject) => { - proc.on("error", reject); - proc.on("close", resolve); - }); - await run(privilegedTeardown({ uuid }), log); - await returnUser(); + try { + await new Promise((resolve, reject) => { + proc.on("error", reject); + proc.on("close", resolve); + }); + } finally { + session.kill(); + } } main().catch(die);