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:
+50
-34
@@ -236,81 +236,93 @@ default `--snapshot-name` is `BaseClean`, so Linux jobs must pass
|
||||
## 4. Manual VM lifecycle
|
||||
|
||||
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
|
||||
|
||||
`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
|
||||
ci vm new \
|
||||
VMX=$(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 \
|
||||
--job-id "dbg-$(date +%s)" \
|
||||
--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,
|
||||
add `--gui` (needs an X display — see [§4.7](#47-open-a-vm-in-the-workstation-gui)):
|
||||
`--gui` opens the clone in the Workstation window so you can watch it while you
|
||||
debug (it needs an X display — see [§4.7](#47-open-a-vm-in-the-workstation-gui)).
|
||||
Drop `--gui` for a headless boot.
|
||||
|
||||
```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, then capture the IP
|
||||
|
||||
### 4.2 Wait until reachable
|
||||
|
||||
Prints the guest IP once ready. Use `--ip-address` to skip polling, or
|
||||
`--credential-target` for WinRM guests.
|
||||
`wait-ready` blocks until SSH is up. The clean guest IP comes from
|
||||
`vmrun getGuestIPAddress`; capture it for the next steps.
|
||||
|
||||
```bash
|
||||
ci wait-ready \
|
||||
--vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx \
|
||||
--vmx "$VMX" \
|
||||
--guest-os linux \
|
||||
--ssh-user ci_build \
|
||||
--ssh-key-path /var/lib/ci/keys/ci_linux \
|
||||
--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
|
||||
|
||||
The guest must already be up — capture its IP first (see
|
||||
[§2](#find-a-running-guests-ip)). 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.
|
||||
Unlike `job`, `ci build run` does **not** inject the Gitea PAT, so an in-guest
|
||||
`--clone-url` only works for a public repo. For a private repo (like
|
||||
`burnin-dummy`), upload a local source directory with `--host-source-dir`
|
||||
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
|
||||
ci build run \
|
||||
--ip-address "$IP" \
|
||||
--guest-os 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" \
|
||||
--guest-artifact-source dist
|
||||
```
|
||||
|
||||
### 4.4 Collect artifacts
|
||||
|
||||
`build run` stages the artifact under `/opt/ci/output`, so collect from there
|
||||
(not from the `dist` source directory).
|
||||
|
||||
```bash
|
||||
ci artifacts collect \
|
||||
--ip-address "$IP" \
|
||||
--guest-os linux \
|
||||
--ssh-user ci_build --ssh-key-path /var/lib/ci/keys/ci_linux \
|
||||
--guest-artifact-path dist \
|
||||
--host-artifact-dir /var/lib/ci/artifacts/dbg-1 \
|
||||
--include-logs --job-id dbg-1
|
||||
--guest-artifact-path /opt/ci/output \
|
||||
--host-artifact-dir /var/lib/ci/artifacts/dbg-manual \
|
||||
--include-logs --job-id dbg-manual
|
||||
```
|
||||
|
||||
### 4.5 Destroy the clone
|
||||
|
||||
```bash
|
||||
ci vm remove --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.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"
|
||||
ci vm remove --vmx "$VMX" --force # skip the soft stop
|
||||
```
|
||||
|
||||
### 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
|
||||
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
|
||||
ci vmware # bare GUI, no VM
|
||||
ci vmware --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.vmx
|
||||
ci vmware --vmx /var/lib/ci/build-vms/Clone_dbg-1_*/Clone_dbg-1_*.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 # bare GUI, no VM
|
||||
ci vmware --vmx "$VMX" # open the VM
|
||||
ci vmware --vmx "$VMX" --power-on # power on (-x)
|
||||
ci vmware --vmx "$VMX" --fullscreen # power on + fullscreen (-X)
|
||||
```
|
||||
|
||||
Other flags: `--new-window` (`-n`), `--display :0` (force a display when
|
||||
|
||||
Reference in New Issue
Block a user