feat(vm): add --gui/--nogui to vm new --start, default headless

Mirror the `job` flag on the manual lifecycle: `vm new --start` was
hardcoded headless; add --gui/--nogui (default --nogui) so a clone can be
booted into the Workstation GUI window for interactive debugging. The
start banner reflects the mode.

Also update the runbook: §4.1 shows the --gui variant, and §3 notes that
the burnin-dummy build.sh is a ~30s fake build writing dist/build-info.txt
so the examples exercise the full pipeline.
This commit is contained in:
2026-06-08 21:54:47 +02:00
parent 0a8398aebf
commit d10973c467
2 changed files with 30 additions and 3 deletions
+17
View File
@@ -179,6 +179,10 @@ waits for the guest, runs the build, collects artifacts, and destroys the
clone. It is exactly what the runner invokes on each push, and you can run it
by hand too.
The examples use `Simone/burnin-dummy`, whose `build.sh` simulates a real build
(sleeps ~30 s, then writes `dist/build-info.txt`) — so the run exercises the
full clone → build → artifact-collect → destroy path end to end.
```bash
ci job \
--job-id manual-$(date +%s) \
@@ -246,6 +250,19 @@ ci vm new \
--start # prints the clone's VMX path on stdout
```
`--start` boots the clone headless. To watch it in the Workstation GUI instead,
add `--gui` (needs an X display — see [§4.7](#47-open-a-vm-in-the-workstation-gui)):
```bash
ci vm new \
--template /var/lib/ci/templates/LinuxBuild2404/LinuxBuild2404.vmx \
--snapshot BaseClean-Linux \
--clone-base-dir /var/lib/ci/build-vms \
--job-id dbg-1 \
--guest-os linux \
--start --gui
```
### 4.2 Wait until reachable
Prints the guest IP once ready. Use `--ip-address` to skip polling, or
+13 -3
View File
@@ -406,7 +406,15 @@ def vm_cleanup(
"start_vm",
is_flag=True,
default=False,
help="Start the clone headless immediately after creation.",
help="Start the clone immediately after creation.",
)
@click.option(
"--gui/--nogui",
"gui",
default=False,
show_default=True,
help="With --start, open the Workstation GUI window (--gui, needs an X "
"display) or start headless (--nogui, the default).",
)
def vm_new(
template: str,
@@ -416,6 +424,7 @@ def vm_new(
vmrun_path: str | None,
guest_os: str,
start_vm: bool,
gui: bool,
) -> None:
"""Create a linked clone of the template VM for an ephemeral CI build.
@@ -475,9 +484,10 @@ def vm_new(
click.echo(f"[vm new] clone created in {elapsed:.1f}s", err=True)
if start_vm:
click.echo("[vm new] starting VM headless...", err=True)
mode = "GUI" if gui else "headless"
click.echo(f"[vm new] starting VM ({mode})...", err=True)
try:
backend.start(handle, headless=True)
backend.start(handle, headless=not gui)
except BackendError as exc:
raise click.ClickException(f"vmrun start failed: {exc}") from exc
click.echo("[vm new] VM started.", err=True)