Skip to content

Commit c67e540

Browse files
committed
Force tcg-compatible QEMU CPU in smoke runner
1 parent 303163e commit c67e540

2 files changed

Lines changed: 81 additions & 5 deletions

File tree

scripts/e2e-smoke.sh

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,18 @@ bun run oci2gondolin -- \
3333
--mode assets \
3434
--out "${OUT_DIR}"
3535

36-
GONDOLIN_BIN="${ROOT_DIR}/node_modules/@earendil-works/gondolin/dist/bin/gondolin.js"
37-
if [[ ! -f "${GONDOLIN_BIN}" ]]; then
38-
echo "gondolin CLI not found at ${GONDOLIN_BIN}"
39-
exit 1
36+
GONDOLIN_SMOKE_ACCEL="${GONDOLIN_SMOKE_ACCEL:-}"
37+
GONDOLIN_SMOKE_CPU="${GONDOLIN_SMOKE_CPU:-}"
38+
39+
if [[ "$(uname -s)" == "Linux" ]] && [[ ! -r /dev/kvm || ! -w /dev/kvm ]]; then
40+
# qemu + tcg on CI does not support -cpu host; force a tcg-compatible model.
41+
GONDOLIN_SMOKE_ACCEL="tcg"
42+
GONDOLIN_SMOKE_CPU="max"
4043
fi
4144

42-
GONDOLIN_GUEST_DIR="${OUT_DIR}" bun "${GONDOLIN_BIN}" exec -- /bin/busybox echo e2e-smoke-ok
45+
GONDOLIN_GUEST_DIR="${OUT_DIR}" \
46+
GONDOLIN_SMOKE_ACCEL="${GONDOLIN_SMOKE_ACCEL}" \
47+
GONDOLIN_SMOKE_CPU="${GONDOLIN_SMOKE_CPU}" \
48+
bun ./scripts/gondolin-smoke-exec.ts /bin/busybox echo e2e-smoke-ok
4349

4450
echo "E2E smoke test passed (image=${IMAGE}, platform=${TARGET_PLATFORM})."

scripts/gondolin-smoke-exec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { VM } from "@earendil-works/gondolin";
2+
3+
type SandboxOptions = {
4+
accel?: "kvm" | "hvf" | "tcg";
5+
cpu?: string;
6+
machineType?: string;
7+
};
8+
9+
function parseCommand(argv: string[]): string[] {
10+
const args = argv.slice(2);
11+
if (args.length === 0) {
12+
throw new Error("missing command to execute");
13+
}
14+
return args;
15+
}
16+
17+
function resolveSandboxOptions(): SandboxOptions | undefined {
18+
const accel = process.env.GONDOLIN_SMOKE_ACCEL?.trim();
19+
const cpu = process.env.GONDOLIN_SMOKE_CPU?.trim();
20+
const machineType = process.env.GONDOLIN_SMOKE_MACHINE?.trim();
21+
22+
const out: SandboxOptions = {};
23+
if (accel === "kvm" || accel === "hvf" || accel === "tcg") {
24+
out.accel = accel;
25+
}
26+
if (cpu) {
27+
out.cpu = cpu;
28+
}
29+
if (machineType) {
30+
out.machineType = machineType;
31+
}
32+
33+
return Object.keys(out).length > 0 ? out : undefined;
34+
}
35+
36+
async function main() {
37+
const command = parseCommand(process.argv);
38+
const sandbox = resolveSandboxOptions();
39+
40+
let vm: VM | null = null;
41+
try {
42+
vm = await VM.create({
43+
sandbox,
44+
});
45+
46+
const result = await vm.exec(command);
47+
48+
process.stdout.write(result.stdout);
49+
process.stderr.write(result.stderr);
50+
51+
if (result.signal !== undefined) {
52+
process.stderr.write(`process exited due to signal ${result.signal}\n`);
53+
process.exit(1);
54+
}
55+
56+
process.exit(result.exitCode);
57+
} finally {
58+
if (vm) {
59+
await vm.close().catch(() => {
60+
// ignore close errors
61+
});
62+
}
63+
}
64+
}
65+
66+
main().catch((error) => {
67+
const message = error instanceof Error ? error.message : String(error);
68+
process.stderr.write(`${message}\n`);
69+
process.exit(1);
70+
});

0 commit comments

Comments
 (0)