docs(runbook): make §4 manual lifecycle copy-paste-correct

Verified the whole §4 chain end-to-end on the live host and fixed every
break:

- Capture the clone VMX from `vm new` stdout into $VMX and the guest IP
  via `vmrun getGuestIPAddress` into $IP, then reuse both downstream.
  Removes the fragile `Clone_dbg-1_*` globs that broke when more than one
  clone shared a job-id ("unexpected extra argument").
- §4.3: `build run` does not inject the Gitea PAT (only `job` does), so the
  private burnin-dummy repo can't be cloned in-guest. Use --host-source-dir
  against the local copy instead.
- §4.4: collect from /opt/ci/output (where build run stages the artifact),
  not the `dist` source dir — the old path failed with "tar: dist: Cannot
  open".
- §4.1 now boots with --gui (manual debugging); §4.7 reuses $VMX.

Confirmed green: vm new → wait-ready → build → collect (build-info.txt +
manifest.json) → vm remove, and the §3 `job` pipeline (SUCCESS in 66s).
This commit is contained in:
2026-06-08 22:10:18 +02:00
parent d10973c467
commit 11daad8a91
+50 -34
View File
@@ -236,81 +236,93 @@ default `--snapshot-name` is `BaseClean`, so Linux jobs must pass
## 4. Manual VM lifecycle ## 4. Manual VM lifecycle
These are the stages that `job` runs internally. Drive them individually when These are the stages that `job` runs internally. Drive them individually when
debugging a single phase. debugging a single phase. **Run the blocks below in the same shell session** —
each one reuses the `$VMX` and `$IP` variables captured by an earlier step, so
there are no fragile path globs to expand.
### 4.1 Clone a VM ### 4.1 Clone a VM
`ci vm new` prints the clone's VMX path (and nothing else) on stdout, so capture
it straight into a variable. A timestamped job-id keeps repeated runs from
colliding.
```bash ```bash
ci vm new \ VMX=$(ci vm new \
--template /var/lib/ci/templates/LinuxBuild2404/LinuxBuild2404.vmx \ --template /var/lib/ci/templates/LinuxBuild2404/LinuxBuild2404.vmx \
--snapshot BaseClean-Linux \ --snapshot BaseClean-Linux \
--clone-base-dir /var/lib/ci/build-vms \ --clone-base-dir /var/lib/ci/build-vms \
--job-id dbg-1 \ --job-id "dbg-$(date +%s)" \
--guest-os linux \ --guest-os linux \
--start # prints the clone's VMX path on stdout --start --gui)
echo "clone VMX: $VMX"
``` ```
`--start` boots the clone headless. To watch it in the Workstation GUI instead, `--gui` opens the clone in the Workstation window so you can watch it while you
add `--gui` (needs an X display — see [§4.7](#47-open-a-vm-in-the-workstation-gui)): debug (it needs an X display — see [§4.7](#47-open-a-vm-in-the-workstation-gui)).
Drop `--gui` for a headless boot.
```bash ### 4.2 Wait until reachable, then capture the IP
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 `wait-ready` blocks until SSH is up. The clean guest IP comes from
`vmrun getGuestIPAddress`; capture it for the next steps.
Prints the guest IP once ready. Use `--ip-address` to skip polling, or
`--credential-target` for WinRM guests.
```bash ```bash
ci wait-ready \ ci wait-ready \
--vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx \ --vmx "$VMX" \
--guest-os linux \ --guest-os linux \
--ssh-user ci_build \ --ssh-user ci_build \
--ssh-key-path /var/lib/ci/keys/ci_linux \ --ssh-key-path /var/lib/ci/keys/ci_linux \
--timeout 180 --timeout 180
IP=$(sudo -u ci-runner vmrun getGuestIPAddress "$VMX")
echo "guest IP: $IP"
``` ```
For WinRM guests, add `--credential-target BuildVMGuest` to `wait-ready`.
### 4.3 Run the build ### 4.3 Run the build
The guest must already be up — capture its IP first (see Unlike `job`, `ci build run` does **not** inject the Gitea PAT, so an in-guest
[§2](#find-a-running-guests-ip)). Windows guests use `--credential-target `--clone-url` only works for a public repo. For a private repo (like
BuildVMGuest` in place of the SSH flags. Repeatable `--extra-env KEY=VALUE`; `burnin-dummy`), upload a local source directory with `--host-source-dir`
add `--xvfb` for Linux GUI builds or `--use-shared-cache` for the shared cache. instead — here the checked-out copy of `burnin-dummy` that ships in this repo.
The build stages its `--guest-artifact-source` (`dist`) into `/opt/ci/output`,
which is where step 4.4 collects from.
Windows guests use `--credential-target BuildVMGuest` in place of the SSH flags.
Repeatable `--extra-env KEY=VALUE`; add `--xvfb` for Linux GUI builds or
`--use-shared-cache` for the shared cache.
```bash ```bash
ci build run \ ci build run \
--ip-address "$IP" \ --ip-address "$IP" \
--guest-os linux \ --guest-os linux \
--ssh-user ci_build --ssh-key-path /var/lib/ci/keys/ci_linux \ --ssh-user ci_build --ssh-key-path /var/lib/ci/keys/ci_linux \
--clone-url https://gitea.emulab.it/Simone/burnin-dummy.git --clone-branch main \ --host-source-dir /opt/ci/local-ci-cd-system/gitea/burnin-dummy \
--build-command "bash build.sh" \ --build-command "bash build.sh" \
--guest-artifact-source dist --guest-artifact-source dist
``` ```
### 4.4 Collect artifacts ### 4.4 Collect artifacts
`build run` stages the artifact under `/opt/ci/output`, so collect from there
(not from the `dist` source directory).
```bash ```bash
ci artifacts collect \ ci artifacts collect \
--ip-address "$IP" \ --ip-address "$IP" \
--guest-os linux \ --guest-os linux \
--ssh-user ci_build --ssh-key-path /var/lib/ci/keys/ci_linux \ --ssh-user ci_build --ssh-key-path /var/lib/ci/keys/ci_linux \
--guest-artifact-path dist \ --guest-artifact-path /opt/ci/output \
--host-artifact-dir /var/lib/ci/artifacts/dbg-1 \ --host-artifact-dir /var/lib/ci/artifacts/dbg-manual \
--include-logs --job-id dbg-1 --include-logs --job-id dbg-manual
``` ```
### 4.5 Destroy the clone ### 4.5 Destroy the clone
```bash ```bash
ci vm remove --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx ci vm remove --vmx "$VMX"
ci vm remove --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx --force # skip the soft stop ci vm remove --vmx "$VMX" --force # skip the soft stop
``` ```
### 4.6 Sweep orphans ### 4.6 Sweep orphans
@@ -328,11 +340,15 @@ Launches the **interactive** VMware Workstation GUI (not the headless vmrun
path) so you can watch or poke a clone by hand. On a normal desktop session it path) so you can watch or poke a clone by hand. On a normal desktop session it
just works — `ci vmware` behaves exactly like `sudo -u ci-runner vmware`: just works — `ci vmware` behaves exactly like `sudo -u ci-runner vmware`:
Reuse the `$VMX` captured in [§4.1](#41-clone-a-vm), or set it to a clone's VMX
path (`VMX=$(ls /var/lib/ci/build-vms/Clone_*/*.vmx | head -1)` picks the first
existing clone):
```bash ```bash
ci vmware # bare GUI, no VM ci vmware # bare GUI, no VM
ci vmware --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx ci vmware --vmx "$VMX" # open the VM
ci vmware --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx --power-on # power on (-x) ci vmware --vmx "$VMX" --power-on # power on (-x)
ci vmware --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx --fullscreen # power on + fullscreen (-X) ci vmware --vmx "$VMX" --fullscreen # power on + fullscreen (-X)
``` ```
Other flags: `--new-window` (`-n`), `--display :0` (force a display when Other flags: `--new-window` (`-n`), `--display :0` (force a display when