From 7e58bb4268619cd0db08fcadc6d5505b6bc7f97f Mon Sep 17 00:00:00 2001 From: Enderson Maia Date: Fri, 7 Aug 2026 14:32:08 +0000 Subject: [PATCH] fix: verify QEMU registration instead of trusting the installer's exit code tonistiigi/binfmt exits 0 even when it fails to mount binfmt_misc and register the emulator - it only logs the error. That let 'setup-qemu' report success while riscv64 support was silently never registered, surfacing as a confusing failure two steps later (e.g. 'cartesi doctor' reporting "Your system does not support riscv64 architecture"). Check /proc/sys/fs/binfmt_misc/qemu-riscv64 directly after running the installer and fail the step with an explanatory message if it's missing. Co-Authored-By: Claude Sonnet 5 --- README.md | 8 ++++++++ dist/index.js | 16 ++++++++++++++++ src/qemu.ts | 26 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/README.md b/README.md index ec74295..bd819b1 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,14 @@ The Cartesi CLI drives Docker for most of its commands (`cartesi build`, `cartes registration (`setup-qemu`) also runs through Docker. GitHub-hosted Linux runners already provide Docker, so this action never installs it there. +### QEMU registration is verified, not just run + +The `tonistiigi/binfmt` installer exits `0` even when it fails to register anything — it only logs +the error. Rather than trust that exit code, the action checks +`/proc/sys/fs/binfmt_misc/qemu-riscv64` directly afterwards and fails the step with an explanatory +message if it's missing, instead of reporting success while `docker buildx`/`cartesi build` are +left unable to run RISC-V images. + ## Security - The action only ever downloads from a fixed set of hardcoded sources: the `cartesi/machine-emulator`, diff --git a/dist/index.js b/dist/index.js index 34cb2f3..922701a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -23722,6 +23722,16 @@ function detectPlatform(platform2 = process.platform, arch3 = process.arch) { } // src/qemu.ts +import { access as access2 } from "node:fs/promises"; +var BINFMT_ENTRY = `/proc/sys/fs/binfmt_misc/qemu-${QEMU_ARCH}`; +async function binfmtRegistered() { + try { + await access2(BINFMT_ENTRY); + return true; + } catch { + return false; + } +} async function setupQemu(platform2) { if (platform2.os !== "linux") { info( @@ -23738,6 +23748,12 @@ async function setupQemu(platform2) { "--install", QEMU_ARCH ]); + if (!await binfmtRegistered()) { + throw new Error( + `the ${QEMU_ARCH} QEMU emulator was not registered: ${BINFMT_ENTRY} does not exist after running the installer. This runner's kernel may not support binfmt_misc registration from a container. Set 'setup-qemu: false' to skip this step.` + ); + } + info(`${QEMU_ARCH} QEMU emulator registered`); } // src/main.ts diff --git a/src/qemu.ts b/src/qemu.ts index 87362c7..8a39595 100644 --- a/src/qemu.ts +++ b/src/qemu.ts @@ -1,8 +1,25 @@ +import { access } from "node:fs/promises"; import * as core from "@actions/core"; import * as exec from "@actions/exec"; import { BINFMT_IMAGE, QEMU_ARCH } from "./constants.js"; import type { Platform } from "./platform.js"; +/** + * Where the kernel exposes a registered handler once `--install` succeeds. + * Checked directly after running the installer, because that tool's process + * exits 0 even when it fails to register anything (it only logs the error). + */ +const BINFMT_ENTRY = `/proc/sys/fs/binfmt_misc/qemu-${QEMU_ARCH}`; + +async function binfmtRegistered(): Promise { + try { + await access(BINFMT_ENTRY); + return true; + } catch { + return false; + } +} + /** * Registers the QEMU emulator for `QEMU_ARCH` with the kernel's binfmt_misc * via the same `tonistiigi/binfmt` image `docker/setup-qemu-action` uses, @@ -29,4 +46,13 @@ export async function setupQemu(platform: Platform): Promise { "--install", QEMU_ARCH, ]); + + if (!(await binfmtRegistered())) { + throw new Error( + `the ${QEMU_ARCH} QEMU emulator was not registered: ${BINFMT_ENTRY} does not exist ` + + "after running the installer. This runner's kernel may not support binfmt_misc " + + "registration from a container. Set 'setup-qemu: false' to skip this step.", + ); + } + core.info(`${QEMU_ARCH} QEMU emulator registered`); }