fix(runner): install refuses a box registered to another repo #14
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:bootstrap
scope:coolify
scope:db
scope:docs
scope:drill
scope:installer
scope:labels
scope:platform
scope:runner
scope:users
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/rig#14
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/runner-install-repo-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #13.
rig runner install --repo <B>on a box already registered to repo A treated the mere existence of.runneras "already registered": it skippedconfigure, started the service still pointed at A, and reported success.--repowas accepted, validated, and then ignored — leaving B with zero runners and itsruns-onjobs queued against a runner that will never come.The fix
Gate
installon the repo.runneractually names, before anything is prompted for, downloaded, or started:Convergence — the property worth keeping — is untouched. Re-running
installagainst the repo the box is already on still re-uses the binary, skips registration, never asks for a token, and exits 0. Skipping when the repo differs was never convergence, only a silently ignored argument.An
.runnerrig cannot read is refused as well: it is no licence to assume a match.Shape of the change
commands/lib/runner-config.sh(new) — the.runnerreader thatstatusandrepointeach carried a copy of, now in one place, plus theassert_runner_repoguard. Sourced, never executed (mode 644);install.shalready ships the whole tree, so it lands on boxes as-is.runner-install.sh— calls the guard between the root check and the token prompt. TheREG_PENDINGlogic is otherwise unchanged.runner-status.sh/runner-repoint.sh— use the shared reader; no behavior change.installis documented as convergent toward--repo, and therepointsection no longer describesinstallas convergent-by-skipping.One incidental fix that falls out of sharing the reader:
json_fieldno longer dies bare underset -o pipefailwhen a key is missing — which is whatstatus's own${REPO_URL:-unknown}fallback had always assumed but never got.repointis unaffected: it deregisters (removing.runner) before callinginstall, so the guard sees an unregistered box and passes.Tests
test/cli.shgains the guard, exercised against a fixture.runner: refuses another repo naming both, points atrepoint, no-ops on the same repo, passes an unregistered box, refuses an unreadable one — plus an assertion that the guard precedessvc.sh start, since ordering is the whole fix. Reaching it through the CLI would need root and a really-registered runner, which the dependency-free harness cannot fabricate; this is the closest honest thing to the end-to-end case the issue sketched, and it is why the ordering is asserted rather than trusted.Verified by mutation — all three go red, and the suite is green (66/66) unmutated:
svc.sh startshellcheck -xis clean across the tree.Left alone, deliberately
The issue's "skim the other commands for the same shape" turned up two lesser instances in
install, both out of scope here — neither is a trust boundary, and both are currently documented as intended:--versionis ignored when a runner binary is already present (deliberate: the runner self-updates regardless, so the pin is a starting point — the README says so).--name/--labelsare ignored on an already-registered box, sinceconfigureis skipped. This one is a real, if quieter, silently-ignored argument — a--labelsthat does not take is a workflow that stops matching itsruns-on. Happy to file it as a follow-up.🤖 Generated with Claude Code