Repository navigation
feat(microvm): make the in-guest tool path usable and assert it - #204
Conversation
Correction to earlier notes: the in-guest tool runner was never missing. The
whole chain already existed — the manager sends a `__lantern_tool_call__`
envelope, the guest exec server routes it to `tool_runner::dispatch`, and the
typed result comes back. `exec_tool` returned UNAVAILABLE because it needs a
heartbeat-derived guest address to dial back on, and the harness could not open
a heartbeat stream until the networking and mTLS fixes landed. Verified end to
end now:
ExecTool shell_exec -> TOOL_STATUS_OK
result.stdout = "hello-from-inside-the-microvm\\naarch64\\n0\\n"
Two things were still missing to make that path exercisable.
The test image had no shell. `shell_exec` spawns `/bin/sh -c`, so every tool
call in this image failed with "spawn failed: No such file or directory" — the
in-guest tool path could not be exercised at all. build-image.sh now installs a
STATIC busybox as /bin/sh (the rootfs has no libc, so it must be static). It
prefers FC_BUSYBOX_BIN, falls back to a host /bin/busybox that `file` confirms
is statically linked, and when neither is present builds exactly as before and
says so — only shell_exec is unavailable.
And nothing asserted it. The integration test now invokes a tool through
ExecTool and requires the tool's own output back. That covers the
workflow-engine's tool_call path end to end, and because ExecTool can only
reach the guest via the heartbeat-derived address, it also proves the harness
is REACHABLE rather than merely started. The assertion degrades to a skip (not
a pass) when the image has no shell, so it can never report success for a path
it did not run.
Verified on real KVM — 5/5 assertions:
Firecracker available · guest live · secret vended over mTLS ·
tool invoked in-guest · all assertions passed
🔎 Codex cross-audit (agent:audit)Blocking: None found. Findings:
|
🔷 Gemini cross-audit (agent:audit-gemini)1. Executive SummaryThe proposed unified diff in No correctness regressions or security vulnerabilities were introduced. However, there are a few important, non-blocking edge cases and missed improvements regarding CI coverage, host binary detection, and in-guest command capabilities. 2. Blocking Issues
3. Important Edge Cases & Recommendations (Non-Blocking)A. Missing CI Dependency (
|
Correction first
The in-guest tool runner was never missing. I listed it as unimplemented in my earlier status — that was wrong. The whole chain already existed: the manager sends a
__lantern_tool_call__envelope, the guest exec server routes it totool_runner::dispatch, and the typed result comes back.exec_toolreturnedUNAVAILABLEbecause it needs a heartbeat-derived guest address to dial back on — and the harness couldn't open a heartbeat stream until the networking and mTLS fixes landed. Verified end to end now:Two things were still missing to make that path exercisable.
1. The test image had no shell
shell_execspawns/bin/sh -c, so every tool call in this image failed withspawn failed: No such file or directory— the in-guest tool path couldn't be exercised at all.build-image.shnow installs a static busybox as/bin/sh(the rootfs has no libc, so it must be static). It prefersFC_BUSYBOX_BIN, falls back to a host/bin/busyboxthatfileconfirms is statically linked, and when neither exists builds exactly as before and says so.2. Nothing asserted it
The integration test now invokes a tool through
ExecTooland requires the tool's own output back. That covers the workflow-engine'stool_callpath end to end — and sinceExecToolcan only reach the guest via the heartbeat-derived address, it also proves the harness is reachable, not merely started.The assertion degrades to a skip, not a pass, when the image has no shell — so it can never report success for a path it didn't run. That's the same failure mode as the boot assertion this session already fixed.
Verified on real KVM — 5/5
Shell/infra only — no Rust or Go changes.