fix: guard the x86_64-only binder: vm path on non-x86_64 hosts (#190) - #279
Merged
Conversation
`beetroot modes`/`doctor`/`build --vm-kernel` had no host-arch check, so on a
non-x86_64 host (Apple-Silicon Linux VM, AWS Graviton, ARM CI runner) `modes`
reported `binder: vm, KVM accel: supported` and `doctor` reported
`vm.accel: pass — KVM-accelerated (near-native)` even though KVM can never
accelerate the x86_64 guest cross-arch, and the redroid host path was advertised
despite the x86_64-only redroid+Houdini image.
- vm/qemu.py: new `GUEST_ARCH_MACHINES` + `host_is_guest_arch()` (single
`platform.machine()` probe, no beetroot imports → reused by capabilities and
builder with no cycle). `detect_accel` is now arch-aware: on a non-x86_64 host
`detect_accel("kvm")` raises (cross-arch, checked BEFORE the /dev/kvm probe so
a stray foreign-native /dev/kvm can't fool it) and `detect_accel("auto")`
resolves to "tcg" regardless of /dev/kvm. This one change also fixes the
`_accel_check` doctor row (routes through detect_accel).
- capabilities.py: `classify_modes` gains a pure `host_is_x86_64` (probed in
survey via `qemu.host_is_guest_arch()`). Non-x86_64 → MODE_VM_KVM and
MODE_REDROID_HOST are `unsupported` (cross-arch / native-image mismatch);
MODE_VM_TCG stays reachable (qemu-system-x86_64 TCG boots the x86_64 guest
cross-arch) but its reason flags the extra cross-arch cost.
- builder.py: `vm_bake_preflight` emits a non-x86_64 `PreflightProblem` (the
local bake stages x86_64-linux-gnu libs / arch/x86 bzImage — genuinely
x86_64-only); the prebuilt-fetch path is untouched so a non-x86_64 host can
still fetch + boot under TCG.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmChW67jv2BaPk1a8HreHU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #190. Adds a host-architecture guard so
beetroot modes/doctor/build --vm-kernelstop advertising the x86_64-onlybinder: vmKVM path (and the native redroid path) as usable on non-x86_64 hosts (Apple-Silicon Linux VM, AWS Graviton, ARM CI runners), while keeping the cross-arch TCG fetch path reachable.The bug
On a non-x86_64 host, KVM can never accelerate the x86_64 micro-VM guest (KVM only virtualizes the host's native arch), yet
detect_accel's/dev/kvmprobe was arch-blind — somodesshowedbinder: vm, KVM accel: supportedanddoctorshowedvm.accel: pass — KVM-accelerated (near-native)for a config that fails at launch. The redroid host path was likewise advertised despite Beetroot's x86_64-only redroid+Houdini image.Fix (single
platform.machine()probe, threaded)vm/qemu.py— newGUEST_ARCH_MACHINES+host_is_guest_arch()(no beetroot imports → reused by capabilities/builder, no cycle).detect_accelis now arch-aware: on a non-x86_64 hostdetect_accel("kvm")raises a clear cross-arch error before the/dev/kvmprobe (so a stray foreign-native/dev/kvmcan't fool it) anddetect_accel("auto")resolves to"tcg"regardless of/dev/kvm. This single change also fixes thebackends/vm.py_accel_checkdoctor row (which routes throughdetect_accel). x86_64 behavior unchanged.capabilities.py—classify_modesgains a purehost_is_x86_64(probed insurvey()viaqemu.host_is_guest_arch()). Non-x86_64 →MODE_VM_KVMandMODE_REDROID_HOSTareunsupportedwith cross-arch reasons;MODE_VM_TCGstays reachable (qemu-system-x86_64 under TCG boots the x86_64 guest cross-arch) but its reason honestly flags the extra cross-arch cost instead of promising ~5-20x.builder.py—vm_bake_preflightemits a non-x86_64PreflightProblem(the local bake stagesx86_64-linux-gnulibs, pins/lib64/ld-linux-x86-64.so.2, andcpsarch/x86/boot/bzImage— genuinely x86_64-only). The prebuilt-fetch path is deliberately untouched, so a non-x86_64 host can still fetch prebuilt artifacts and boot under TCG.Design note
The prebuilt-fetch + TCG path is not hard-failed on non-x86_64:
qemu-system-x86_64under TCG can boot the x86_64 guest cross-arch (just slower). Only the physically-impossible KVM path and the genuinely x86_64-only local bake are gated. This supersedes the "Docker static bundle URL hardcodes x86_64" concern from the discovery sweep — the bake now fails its preflight on non-x86_64 before ever reaching that URL.Tests
New/updated in
test_vm_qemu.py(detect_accel foreign-arch:kvmraises,auto→tcg even with/dev/kvm; x86_64 unchanged),test_capabilities.py(classify_modes + survey foreign-arch verdicts, x86_64 unchanged),test_vm_backend.py(_accel_checkcross-arch row is not near-native pass),test_builder.py(vm_bake_preflightemits the arch problem on foreign arch;vm_fetch_preflightdoes not). Full gate green locally: ruff,mypy --strict(src+tests), pytest 2001 passed at 100% line+branch coverage.🤖 Generated with Claude Code
https://claude.ai/code/session_01WmChW67jv2BaPk1a8HreHU
Generated by Claude Code