Fix things, get stdout working seemingly

This commit is contained in:
Radon Rosborough 2023-01-04 19:44:55 -07:00
parent 1ef298aac6
commit 976adad108
3 changed files with 30 additions and 17 deletions

View File

@ -289,20 +289,20 @@ export async function initUserSession({ watcher, podName, proxyInfo }) {
if (pty) { if (pty) {
cmdline = ["/riju-bin/ptyify", ...cmdline]; cmdline = ["/riju-bin/ptyify", ...cmdline];
} }
const params = new URLSearchParams();
for (const arg of cmdline) {
params.append("cmdline", arg);
}
let conn; let conn;
if (!proxyInfo) { if (!proxyInfo) {
conn = new WebSocket( conn = new WebSocket(
`ws://${podIP}:869/exec?${new URLSearchParams({ `ws://${podIP}:869/exec?${params.toString()}`
cmdline,
}).toString()}`
); );
} else { } else {
conn = new WebSocket( conn = new WebSocket(
`${proxyInfo.wsProtocol}://${proxyInfo.host}:${ `${proxyInfo.wsProtocol}://${proxyInfo.host}:${
proxyInfo.port proxyInfo.port
}/${podIP}/exec?${new URLSearchParams({ }/${podIP}/exec?${params.toString()}`,
cmdline,
}).toString()}`,
{ {
headers: { headers: {
Authorization: `Basic ${Buffer.from( Authorization: `Basic ${Buffer.from(
@ -329,10 +329,10 @@ export async function initUserSession({ watcher, podName, proxyInfo }) {
} }
switch (event) { switch (event) {
case "stdout": case "stdout":
on.stdout(data); on.stdout(Buffer.from(data, "base64"));
break; break;
case "stderr": case "stderr":
on.stderr(data); on.stderr(Buffer.from(data, "base64"));
break; break;
case "exit": case "exit":
on.exit(exitStatus); on.exit(exitStatus);
@ -355,8 +355,14 @@ export async function initUserSession({ watcher, podName, proxyInfo }) {
}); });
return { return {
stdin: { stdin: {
// data should be of type Buffer
write: (data) => write: (data) =>
conn.send(JSON.stringify({ event: "stdin", data })), conn.send(
JSON.stringify({
event: "stdin",
data: data.toString("base64"),
})
),
}, },
}; };
}, },

View File

@ -2,6 +2,9 @@ import { spawn } from "child_process";
import { promises as fs } from "fs"; import { promises as fs } from "fs";
import process from "process"; import process from "process";
import pQueue from "p-queue";
const PQueue = pQueue.default;
import { readLangConfig } from "../lib/yaml.js"; import { readLangConfig } from "../lib/yaml.js";
import * as k8s from "./k8s.js"; import * as k8s from "./k8s.js";
import { deptyify, getUUID } from "./util.js"; import { deptyify, getUUID } from "./util.js";
@ -52,23 +55,27 @@ async function main() {
proxyInfo, proxyInfo,
}); });
console.log(`Initializing sandbox`); console.log(`Initializing sandbox`);
let handlePtyInput;
const pty = await deptyify({
handlePtyInput: (data) => handlePtyInput(data),
handlePtyExit: (_status) => {},
});
await new Promise(async (resolve) => { await new Promise(async (resolve) => {
// Use a queue to resolve the circular dependency between exec and
// pty.
const outputQueue = new PQueue({ concurrency: 1, autoStart: false });
let handlePtyOutput;
const exec = await session.exec(["bash"], { const exec = await session.exec(["bash"], {
pty: true, pty: true,
on: { on: {
stdout: (data) => pty.handlePtyOutput(data), stdout: (data) => outputQueue.add(() => handlePtyOutput(data)),
stderr: (data) => process.stderr.write(data), stderr: (data) => process.stderr.write(data),
exit: (status) => process.exit(status), exit: (status) => process.exit(status),
error: (err) => process.stderr.write(`riju: error: ${err}\n`), error: (err) => process.stderr.write(`riju: error: ${err}\n`),
close: () => resolve(), close: () => resolve(),
}, },
}); });
handlePtyInput = (data) => exec.stdin.write(data); const pty = await deptyify({
handlePtyInput: (data) => exec.stdin.write(data),
handlePtyExit: (_status) => {},
});
handlePtyOutput = pty.handlePtyOutput;
outputQueue.start();
}); });
} }

View File

@ -215,7 +215,7 @@ export function deptyify({ handlePtyInput, handlePtyExit }) {
setTimeout(async () => { setTimeout(async () => {
try { try {
while (true) { while (true) {
handlePtyInput(await input.read({ encoding: "utf-8" })); handlePtyInput((await input.read()).buffer);
} }
} catch (err) { } catch (err) {
logError(err); logError(err);