Fix seven traps in instance targeting, the dev base and status output
A command that names no instance no longer reaches another session's VM, a dev base cut from the current default branch runs full-stack specs again, and five smaller traps close: a merge request tested by copying its files, a caller's zone lost to the secrets file, a cut-off drift-check transfer read as served, an empty token refresher section, and a default root password printed by the omnibus bootstrap. Each fix is its own commit.
Closes #11 (closed)
flowchart LR
C["a command other than up"] --> N{"instance named?"}
N -->|"yes"| U["that instance"]
N -->|"no"| P{"another simulation from this machine running?<br/>its state file, and its VM in the inventory"}
P -->|"no"| Q["the current pointer"]
P -->|"yes, or inventory unreadable"| R["refused, with the list<br/>status shows the pointer and lists them"]
U --> F["printed, exported,<br/>kept for the whole run"]
Q --> F- Instance targeting.
~/.gitlab-simulation/currentnames the lastupon the machine, whichever session ran it. A command withoutSIM_INSTANCEor--instancenow uses it only while no other simulation from this machine is running, and otherwise refuses with the list. The engine cannot tell which session a command comes from, so the refusal keys on the ambiguity itself. Every command that acts on an existing VM prints its instance and exports it, so a concurrentupcannot move a long command partway through. - The dev base on the default branch. Gitaly's Makefile exports
GOTOOLCHAIN=local, so once itsgo.modoutgrew the build image's Go every full-stack spec reported0 examples.dev-gitaly-go.shreadsgo.modat the clone'sGITALY_SERVER_VERSION, installs that Go from go.dev against its published sha256 when the image's is older, andrun.shputs it first onPATH, re-checking whenever the Gitaly pin moves. No Go version is named. - Testing a merge request on dev.
gce.mdapplies the merge request's diff from the API withgit apply. Copying the branch's files whole reverted every line the default branch had changed in them since the branch point. GCP_ZONEandGCP_PROJECT. An exported value now wins over~/.config/env/secrets.zsh, which still wins overgcloud config.- drift-check. A transfer that fails after its
200is retried and reported as unreachable with curl's exit code, never checked as served. real-model statussays the token refresher is not installed instead of printing an empty section.- The omnibus bootstrap reports whether root has a password, read from the instance in the call that mints the PAT, and never the value.
What the lab showed
Two VMs in one zone, both torn down afterwards: a dev base cloned from the default branch on the day, and an omnibus instance on 19.4.1-ee, unlicensed.
The checks
| behaviour | result |
|---|---|
dev base, ee/spec/lib/gitlab/subscription_portal/clients/rest_spec.rb with the run.sh the default branch writes |
go: go.mod requires go >= 1.26.0 (running go 1.25.11; GOTOOLCHAIN=local), then 0 examples, 0 failures, 1 error occurred outside of examples |
| dev base, this branch's bootstrap | Gitaly at 69e2c557... needs Go 1.26.0; the build image ships 1.25.11; installed go1.26.0 |
the same spec next, with this branch's run.sh |
0 examples again, The gitaly binary does not exist: the failed build had left its clone at the pinned ref, so TestEnv skipped the build. gce.md now says to remove tmp/tests/gitaly once |
the same spec after removing tmp/tests/gitaly and tmp/run/gitaly-* |
303 examples, 0 failures; go version reads go1.26.0 for the gitaly binary TestEnv built |
| an open merge request whose file the default branch changed after it branched | its diff changes 2 lines in that file, while copying the file whole changes +14 -36; git apply --check refuses, naming the file |
| a merge request opened that day | git apply takes all 8 files, git apply -R leaves a clean tree |
GCP_ZONE exported, a different zone in the secrets file |
without the zone change up used the secrets file's zone and failed there on a c2d-standard-8 stockout; with it the VM landed in the exported zone |
a bare ssh or down with the pointer on one simulation while another runs |
refused, naming the running one; nothing reached a VM |
a bare ssh when the only other state file's VM is gone |
the pointer used, instance: <name> (current pointer) printed |
SIM_INSTANCE=<name> just ssh-cmd ... |
instance: <name> (named) printed on every call |
status, and the end of up |
lists the other running simulations and the SIM_INSTANCE that names this one |
omnibus up |
Root login: root, password set (SIM_ROOT_PASSWORD; ...) on both bootstrap passes, the default password nowhere in the output; Rails reads root's password as present |
just drift-check |
92 passed, 0 failed (ref master) |
Known limits
- The pointer check counts the simulations whose state files are on this machine. A VM another machine created in the same project is not counted.
real-model statusran only in the engine self-test; no real-model arm ran.- The dev build image still ships an older Go than Gitaly asks for, so each dev base downloads that Go release from go.dev during its bootstrap.
Testing
just ci passes, the engine self-test included at 388 checks (344 on the
default branch). Of the 44 checks this branch adds, 31 fail against the default
branch's engine, and all pass on the branch. Lab evidence is above.
Claude Code assisted with the change, its tests and this description, and ran
the lab checks above. Each commit carries the AI-Assisted: yes and
AI-Tools: Claude Code trailers that CONTRIBUTING.md asks for.