Misc fixes for unbuffering (#7404)

- Wrap the executable in `stdbuf` higher up than in `executeDirect`
which means we run `stdbuf` _inside_ the jail instead of outside it when
running. This fixes jail/stdbuf interactions.
- Install `which` types to avoid a `no-ts`
- Ensure `stdbuf` et al is mapped in compilers-and-tools
- As a fly-by also unify the configuration of NVidia devices between
execution and compilation.
This commit is contained in:
Matt Godbolt
2025-02-18 15:17:15 -06:00
committed by GitHub
parent d3ce34dca6
commit 7d4f77d84a
5 changed files with 69 additions and 18 deletions

View File

@@ -148,6 +148,22 @@ mount {
is_bind: true
}
###
# Support for stdbuf
mount {
src: "/usr/bin/stdbuf"
dst: "/usr/bin/stdbuf"
is_bind: true
}
mount {
src: "/usr/libexec/coreutils/libstdbuf.so"
dst: "/usr/libexec/coreutils/libstdbuf.so"
is_bind: true
}
###
###
# NVidia support
mount {
src: "/dev/nvidia0"
dst: "/dev/nvidia0"
@@ -175,6 +191,28 @@ mount {
is_bind: true
mandatory: false
}
mount {
src: "/dev/nvidia-uvm-tools"
dst: "/dev/nvidia-uvm-tools"
is_bind: true
mandatory: false
}
mount {
src: "/sys/module/nvidia"
dst: "/sys/module/nvidia"
is_bind: true
mandatory: false
}
mount {
src: "/sys/module/nvidia_uvm"
dst: "/sys/module/nvidia_uvm"
is_bind: true
mandatory: false
}
# End NVidia support
###
mount {
dst: "/proc"

View File

@@ -26,7 +26,6 @@ import buffer from 'buffer';
import child_process from 'node:child_process';
import os from 'node:os';
import path from 'node:path';
// @ts-ignore
import which from 'which';
import {Stream} from 'node:stream';
@@ -53,7 +52,7 @@ type NsJailOptions = {
const execProps = propsFor('execution');
let stdbufPath = null;
let stdbufPath: null | string = null;
function checkExecOptions(options: ExecutionOptions) {
if (options.env) {
@@ -74,6 +73,25 @@ function setupOnError(stream: Stream, name: string) {
});
}
async function maybeUnbuffer(command: string, args: string[]): Promise<string> {
if (!stdbufPath) {
const unbufferStdoutExe = execProps<string>('unbufferStdoutExe');
if (unbufferStdoutExe) {
stdbufPath = await which(unbufferStdoutExe).catch(() => null);
if (!stdbufPath) logger.error(`Could not find ${unbufferStdoutExe} in PATH`);
else logger.info(`Unbuffering with ${stdbufPath}`);
}
}
if (stdbufPath) {
const stdbufArgs = splitArguments(execProps<string>('unbufferStdoutArgs'));
args.unshift(...stdbufArgs, command);
command = stdbufPath;
}
return command;
}
export async function executeDirect(
command: string,
args: string[],
@@ -97,20 +115,6 @@ export async function executeDirect(
if (command.startsWith('./')) command = path.join(process.cwd(), command);
}
if (stdbufPath == null) {
const unbufferStdoutExe = execProps<string>('unbufferStdoutExe', undefined); // by default 'stdout'
if (unbufferStdoutExe) {
stdbufPath = await which(unbufferStdoutExe);
if (!stdbufPath) logger.error(`Could not find ${unbufferStdoutExe} in PATH`);
}
}
if (stdbufPath) {
const stdbufArgs = splitArguments(execProps<string>('unbufferStdoutArgs', undefined)); // by default ['-o0']
args.unshift(...stdbufArgs, command);
command = stdbufPath;
}
let okToCache = true;
let timedOut = false;
// In WSL; run Windows-volume executables in a temp directory.
@@ -431,6 +435,7 @@ export async function sandbox(
const dispatchEntry = sandboxDispatchTable[type as 'none' | 'nsjail' | 'firejail' | 'cewrapper'];
if (!dispatchEntry) throw new Error(`Bad sandbox type ${type}`);
if (!command) throw new Error('No executable provided');
command = await maybeUnbuffer(command, args);
return await dispatchEntry(command, args, options);
}
@@ -649,5 +654,6 @@ export async function execute(
const dispatchEntry = executeDispatchTable[type];
if (!dispatchEntry) throw new Error(`Bad sandbox type ${type}`);
if (!command) throw new Error('No executable provided');
command = await maybeUnbuffer(command, args);
return await dispatchEntry(command, args, options);
}

View File

@@ -31,8 +31,6 @@ import Server from 'http-proxy';
import PromClient, {Counter} from 'prom-client';
import temp from 'temp';
import _ from 'underscore';
// @ts-ignore
import which from 'which';
import {remove, splitArguments} from '../../shared/common-utils.js';

8
package-lock.json generated
View File

@@ -99,6 +99,7 @@
"@types/underscore": "^1.13.0",
"@types/url-join": "^4.0.3",
"@types/webpack-env": "^1.18.8",
"@types/which": "^3.0.4",
"@types/ws": "^8.5.14",
"@vitest/coverage-v8": "^2.1.9",
"aws-sdk-client-mock": "^4.1.0",
@@ -5036,6 +5037,13 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/which": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.4.tgz",
"integrity": "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.5.14",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",

View File

@@ -108,6 +108,7 @@
"@types/underscore": "^1.13.0",
"@types/url-join": "^4.0.3",
"@types/webpack-env": "^1.18.8",
"@types/which": "^3.0.4",
"@types/ws": "^8.5.14",
"@vitest/coverage-v8": "^2.1.9",
"aws-sdk-client-mock": "^4.1.0",