Skip to content

feat: add VNC port exposure and settings UI#1

Open
pgk83 wants to merge 1 commit into
chicohaager:mainfrom
pgk83:feature/vnc-port-exposure
Open

feat: add VNC port exposure and settings UI#1
pgk83 wants to merge 1 commit into
chicohaager:mainfrom
pgk83:feature/vnc-port-exposure

Conversation

@pgk83

@pgk83 pgk83 commented Jul 2, 2026

Copy link
Copy Markdown

No description provided.

chicohaager added a commit that referenced this pull request Jul 23, 2026
Adopts the idea behind #1 — making the console's listen address and port
settable — into the existing VNC tab rather than alongside it. #1 adds its own
internal/vnc package and /api/vnc/ handler, paths that the VNC work in v0.5.1
already occupies, so it cannot merge as it stands.

Four things are different from that PR, all of them following from what this
tab is for.

No console goes onto all interfaces without a password. #1 validates only that
listen_address is one of two strings. Here every path that sets 0.0.0.0 ends
with a password on the console; asking for it without one is refused with "a
console on all interfaces needs a password". The reverse is deliberately
allowed: restricting a console to 127.0.0.1 is protective in itself and needs
no password, so tightening is never gated behind remembering one.

The <listen> child element is rewritten, not just the attribute. libvirt keeps
the address in both places and honours the child; editing only the attribute
would have reported success and changed nothing. A child of type='network' is
replaced wholesale rather than patched, since it would otherwise keep
overriding the address. This is the same class of trap as the --security-info
masking documented at the top of virsh/vnc.go.

The address is pinned and reconciled like the password. ZVM regenerates
<graphics> with listen='::' on every re-save, which would quietly put a
restricted console back on the LAN.

The card has three states, not two. `virsh define` writes the persistent
config and the running qemu keeps the socket it started with, so a changed
address shows "restart required" with both the configured and the live address
instead of a green "local only" over a console still on the LAN.

One bug caught while building: an entry that pins only an address has no
password, and the reconciler would have called SetVNCPassword(vm, "") — after
which the config still has no password, so the next pass would repair it
again, once a minute, forever. The password repair is now skipped for such
entries, with a test.

Verified on 192.168.1.147 by measuring the socket rather than the config, and
from the LAN rather than from the host. After restricting one VM and starting
it: qemu gets `-vnc 127.0.0.1:0` where the untouched VMs have `[::]:1` and
`[::]:2`; `ss` shows 127.0.0.1:5900 against *:5901 and *:5902; and a TCP probe
from another machine reaches 5901 and 5902 but not 5900. libvirt applies the
address to ZVM's websocket port as well — 127.0.0.1:5700 against *:5701 and
*:5702 — so both surfaces close together, which was worth checking before
calling anything "local only". The guard was exercised through the button and
again straight at the API, bypassing the button, and refused both times.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant