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/current names the last up on the machine, whichever session ran it. A command without SIM_INSTANCE or --instance now 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 concurrent up cannot move a long command partway through.
  • The dev base on the default branch. Gitaly's Makefile exports GOTOOLCHAIN=local, so once its go.mod outgrew the build image's Go every full-stack spec reported 0 examples. dev-gitaly-go.sh reads go.mod at the clone's GITALY_SERVER_VERSION, installs that Go from go.dev against its published sha256 when the image's is older, and run.sh puts it first on PATH, re-checking whenever the Gitaly pin moves. No Go version is named.
  • Testing a merge request on dev. gce.md applies the merge request's diff from the API with git apply. Copying the branch's files whole reverted every line the default branch had changed in them since the branch point.
  • GCP_ZONE and GCP_PROJECT. An exported value now wins over ~/.config/env/secrets.zsh, which still wins over gcloud config.
  • drift-check. A transfer that fails after its 200 is retried and reported as unreachable with curl's exit code, never checked as served.
  • real-model status says 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 status ran 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.

Merge request reports

Loading
Loading