Repository navigation
firmware-update: reports success on a no-op flash (start POST not verified) #94
Description
Summary
GLKVMDriver.apply_firmware_update reports a flash succeeded whenever POST /api/upgrade/start returns without an HTTP error — it never verifies a flash actually started. This produced a misleading "Firmware flash started" on the first-ever real-hardware run, where nothing was flashed.
Follow-up finding against #92 (gated remote-flash capability).
Evidence (live, 2026-07-03, homelab2 / GL RM1PE @ 10.0.1.20, firmware V1.5.1 release2)
kvm-pilot firmware-update --profile homelab2 --execute --i-have-physical-access --yes printed:
INFO kvm_pilot.safety: Executing destructive op 'firmware.flash' ...
WARNING kvm_pilot.glkvm: Starting firmware flash on 10.0.1.20 ...
Firmware flash started. The device will reboot and may be unreachable for several minutes ...
Observed reality:
- Device never rebooted — healthcheck polled every 20s for ~5 min,
firmware=V1.5.1 release2on every sample, API reachable throughout. - Operator confirmed device LEDs solid (no flash activity).
- Fresh
firmware-checkafterward: stillinstalled V1.5.1 release2.
So POST /api/upgrade/start returned a non-error response and the CLI declared success, but no flash occurred.
Root cause
src/kvm_pilot/drivers/pikvm.py:249-250:
result = self._http.post("/api/upgrade/start", long_timeout=1800, retry=False)
return {"sent": True, "dry_run": False, "plan": plan, "result": result}sent: True is returned on any non-raising POST. A 2xx (or any body the transport doesn't treat as an error) is taken as "flashing," with no confirmation that the device actually entered an upgrade state. Compounded by the fact that the /api/upgrade/* request bodies are provisional/undocumented (see companion issue) — the call can be accepted and no-op.
Proposed fix
After issuing start, verify the flash actually began before returning success. Options, cheapest first:
- Poll
GET /api/upgrade/statusfor a state transition into an in-progress/flashing state within a short window; if it never transitions, returnsent: Falsewith a clear "device did not enter upgrade state" error. - Fall back to detecting the expected control-channel drop / reboot (the driver already documents that the channel drops mid-flash) as corroboration.
- Surface the actual
startresponse body in the result so operators can see what the device returned.
Tie into the harness work (epic under #1): "firmware-update passes" must require an observed effect (version actually changed), not merely a returned call.
Acceptance
- A
startthat does not put the device into an upgrade state returnssent: Falseand a descriptive error, not "flash started." - Unit test with a mocked transport where
start200s butstatusnever flips →apply_firmware_updatereports failure.
Activity
feat(wiki): community hardware-compatibility page from run ledger (#105…
docs(analysis): V1.9.1 follow-up — snapshot fixed by firmware, encode…
RM1PE field report: firmware flash declined + native-res encoder wedge (
release: 0.1.0a2
docs: correct the stale "never run on real hardware" claim (#103)
docs(readme): bring the PyPI long description current for 0.1.0a2
docs: record 2026-07-07 fleet sweep evidence in the ledger + driver-f…
feat(mcp): power tool verifies effect per driver signal + bumps frame…
feat(glkvm,docs): firmware-flash-webui-only quirk + upgrade-path docs (…
feat(cli): kvm-pilot test-report — capability evidence harness append…
feat(wiki): community hardware-compatibility page from run ledger (#105…
RM1PE field report: firmware flash declined + native-res encoder wedge (
release: 0.1.0a2
docs: correct the stale "never run on real hardware" claim (#103)
docs(readme): bring the PyPI long description current for 0.1.0a2
firmware-update: verify the device entered an upgrade state after sta…
MCP support_matrix tool + support-evidence healthcheck from the shipp…
docs: record 2026-07-07 fleet sweep evidence in the ledger + driver-f…
feat(mcp): power tool verifies effect per driver signal + bumps frame…
feat(glkvm,docs): firmware-flash-webui-only quirk + upgrade-path docs (…
feat(cli): kvm-pilot test-report — capability evidence harness append…