feat: reachable VNC for --net cni, headless picker fix, parallel image pull#15
Conversation
QEMU runs inside the CNI netns, so its -vnc 127.0.0.1 bind is unreachable off-box. Bind it to a unix socket instead and front that on a host TCP port with a small detached proxy, torn down with the VM. Also always pass -display none: without --vnc, qemu fell back to GTK and aborted headless.
Timeout alone isn't enough: OpenCanopy cancels its countdown on the stray input from USB device enumeration and then waits forever. ShowPicker=false boots the default entry immediately with no picker UI.
ghcr throttles and resets a single HTTP/2 stream on multi-GB blobs. Fetch the qcow2 layer in 8 concurrent Range chunks to a temp file (single-stream fallback when Range is unsupported), verify the sha256 against the layer digest, then import.
A persistent VNC port widens the host's exposure for the VM's whole lifetime. Make it launch-scoped: vm start only enables VNC when --vnc is given, and stop clears the recorded display/password with the qemu they belonged to.
|
Added in 0d9608f — VNC is now decided per start, off by default:
Verified on the testbed: start without |
…ch-scoped --vnc TerminateProcess verifies the pidfile's PID still runs our _vnc-proxy before signaling (a reused PID must not be killed) and waits for death; zero grace escalates straight to SIGKILL since the proxy traps SIGTERM. Also note on create/run/clone --vnc that the setting is cleared on stop.
…lure Review follow-ups: the CNI proxy listens on all host interfaces, so --vnc there now requires --vnc-password; the parent binds the proxy's TCP port and passes the listener fd to the detached child, so a taken port fails the launch (and kills qemu) instead of silently reporting a VNC entry point that doesn't exist. Also stop tearing down the persisted TAP/netns when a restart fails — only the create path cleans up its own fresh network. README documents the per-mode exposure.
|
Both review findings addressed in c948fa9. P1 — off-box exposure contract. P2 — no silent VNC gaps. The detached child's bind error was invisible to the parent, so the launch reported a VNC entry point that didn't exist. The parent now binds the TCP port itself and passes the listener fd to the child ( Testing P2 also exposed a pre-existing bug this PR now fixes: the failed-qemu-launch path unconditionally tore down the VM's TAP/netns, which is correct for |
… scaffolding A failed set_password leaves qemu at password=on with no password, so every VNC auth fails — kill qemu and error instead of warning. The cni --vnc-password check now also runs before create scaffolds anything, and a failed run removes the VM dir it just made: a leftover record pointing at a torn-down netns bricked same-name retries and vm start.
|
Both round-3 findings fixed in the latest commit. Password-set failure now fails the launch. setVNCPassword's own failure mode is qemu left at cni Verified on the testbed: no-password run → immediate error, no dir, no netns; occupied port + valid run → bind error, no dir/netns/qemu left, same-name retry then succeeds with RFB served; existing VM untouched. |
|
Clone now runs the same pre-scaffold check as create: |
Three independent improvements, each its own commit.
--net cniVNC reachable off-boxQEMU runs inside the CNI netns, so
-vnc 127.0.0.1:590nonly listens there. Bind VNC to a unix socket (visible across namespaces on the host FS) and front it with a small detached proxy (vm _vnc-proxy) that listens on0.0.0.0:590nin the host netns; the proxy is started alongside qemu and torn down instop/rm/launch-failure. Also always pass-display none— without--vnc, qemu fell back to GTK and aborted headless.Verified:
10.5.17.79:5901→RFB 003.008from the internal network (no socat, no macOS Screen Sharing / TCC involved).Headless OpenCore boots without the picker
Timeoutalone doesn't prevent a stall: OpenCanopy cancels its countdown on the stray input from USB device enumeration and then waits at the picker forever. SetShowPicker=falseso OpenCore boots the default entry immediately with no picker UI.Verified: guest boots and DHCPs in ~12s with no keypress nudge.
Parallel Range image pull
ghcr throttles and resets a single HTTP/2 stream on multi-GB blobs. Download the qcow2 layer in 8 concurrent Range chunks to a temp file (single-stream fallback when the registry doesn't support Range), verify sha256 against the layer digest, then import.
Checks
make lintclean onGOOS=darwinandGOOS=linuxgo test -racepasses/simplifyreuse/simplification/efficiency/altitude review applied (adoptedutils.WritePIDFile/ReadPIDFile,io.NewOffsetWriter; the altitude finding is what turned the picker fix from a timed keypress intoShowPicker=false)