-
Notifications
You must be signed in to change notification settings - Fork 0
feat(qemu): default a VM to a window on a graphical host #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,8 +85,7 @@ ssh port: 2222 | |
| ssh user: root | ||
| recipes: xfce | ||
| forwards: 8080:80 | ||
| display: no qemu window; the screen is on /home/user/.stoat/work/vnc.sock | ||
| attach with: gvncviewer /home/user/.stoat/work/vnc.sock | ||
| display: a qemu window | ||
| ``` | ||
|
|
||
| `display` is the only line here that is not a `vm.toml` field. See [`stoat up`](#stoat-up-name) for what it means and why the answer changes. It is omitted entirely for a broken VM, whose `vm.toml` supplies neither of the facts the answer depends on. | ||
|
|
@@ -153,34 +152,32 @@ display: no qemu window; the screen is on /home/user/.stoat/work/vnc.sock | |
|
|
||
| ### Where the screen is | ||
|
|
||
| Exactly one kind of VM gets a real QEMU window: a **disk-mode VM that is not yet installed**, on a host with a graphical session. Its OS installer draws to VGA and a human has to drive it, so `up` says so: | ||
| A VM gets a real QEMU window by default, on a host with a graphical session. Set `display = "vnc"` in `vm.toml` (or cycle it with the `d` key in the TUI) to keep a VM headless instead. QEMU then starts with `-display none` and a VNC server bound to a unix socket in the VM's directory; `-display none` cannot be undone on a running QEMU, so binding VNC at launch keeps a misbehaving guest recoverable. | ||
|
|
||
| ``` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Add language identifiers to the shell examples.
Also applies to: 175-175 🧰 Tools🪛 markdownlint-cli2 (0.23.2)[warning] 157-157: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| display: a qemu window, for the OS installer's console | ||
| $ stoat up work | ||
| starting work... | ||
| work started (ssh :2222) | ||
| display: no qemu window; the screen is on /home/user/.stoat/work/vnc.sock | ||
| attach with: gvncviewer /home/user/.stoat/work/vnc.sock | ||
| ``` | ||
|
|
||
| Every other VM is headless. QEMU is started with `-display none` and a VNC server bound to a unix socket in the VM's directory, because `-display none` cannot be undone on a running QEMU and binding VNC at launch keeps a misbehaving guest recoverable. | ||
|
|
||
| **This includes a disk VM the moment its install finishes.** `setup-alpine` completes, stoat records `installed = true`, and the next start has no window. That is not a failure; the screen moved to the socket. It surprises people who provisioned a desktop onto a disk VM and expected the window to keep coming back. | ||
|
|
||
| The attach command names a viewer that is actually installed on your machine: | ||
|
|
||
| - `gvncviewer <socket>` opens the socket directly, when `gvncviewer` is present. | ||
| - Otherwise `socat TCP-LISTEN:5900,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:<socket>` republishes it on loopback, and any VNC client connects to `127.0.0.1:5900`. | ||
| - If neither is installed, `up` says so and names them rather than printing a command that would fail. | ||
|
|
||
| There is currently no way to ask for a QEMU window on an installed disk VM. `-display gtk` needs a graphical session on the host, so granting one by default would make `stoat up` fail outright over SSH or from a script rather than merely come up headless. | ||
|
|
||
| ### On a host with no graphical session | ||
|
|
||
| `-display gtk` does not degrade when there is no display server: QEMU exits 1. So the install console goes to VNC there too, and `up` says why before it says where: | ||
| `-display gtk` does not degrade when there is no display server: QEMU exits 1. So every VM's screen goes to VNC there instead, and `up` says why before it says where: | ||
|
|
||
| ``` | ||
| $ stoat up alpinedisk | ||
| starting alpinedisk... | ||
| alpinedisk started (ssh :2200) | ||
| display: no usable graphical session on this host, so the OS installer's | ||
| console is on VNC instead; drive it from a machine with a screen | ||
| display: no usable graphical session on this host, so the screen | ||
| is on VNC instead; attach to watch it | ||
| display: no qemu window; the screen is on /home/user/.stoat/alpinedisk/vnc.sock | ||
| attach with: gvncviewer /home/user/.stoat/alpinedisk/vnc.sock | ||
| ``` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,10 +46,13 @@ type VM struct { | |
| Recipes []string `toml:"recipes"` | ||
|
|
||
| // Display is the user's screen preference: "" or "auto" (default), | ||
| // "window", or "vnc". core.validateDisplay is the single place that | ||
| // checks the value; empty means an old vm.toml predates this field, so | ||
| // it must read the same as "auto". qemu.DisplayKind is the rule that | ||
| // turns this into DisplayWindow or DisplayVNC. | ||
| // "window", or "vnc". "auto" opens a real qemu window on a graphical | ||
| // host, and falls back to VNC only when the host has no display server; | ||
| // set "vnc" to opt out of a window on a graphical host. core.validateDisplay | ||
| // is the single place that checks the value; empty means an old vm.toml | ||
| // predates this field, so it must read the same as "auto". | ||
|
Comment on lines
48
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Include the host override in the The comment says 🤖 Prompt for AI Agents |
||
| // qemu.DisplayKind is the rule that turns this into DisplayWindow or | ||
| // DisplayVNC. | ||
| Display string `toml:"display"` | ||
|
|
||
| // Forwards are user-declared TCP ports forwarded from host to guest, in | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Document both VNC routes for console access.
The text limits VNC to the headless fallback, but
display = "vnc"also selects VNC on graphical hosts. Keep both copies aligned.docs/concepts/access-and-auth.md#L133-L133: mention VNC when the host is headless ordisplay = "vnc".internal/core/core.go#L250-L251: apply the same condition to the cloud-console comment.📍 Affects 2 files
docs/concepts/access-and-auth.md#L133-L133(this comment)internal/core/core.go#L250-L251🤖 Prompt for AI Agents