Machine classes: server-class vs host-class as bootstrap's organizing axis #25
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#25
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Context
Working through the sudo/root "dance" surfaced that the fleet has two coherent identity models, not one inconsistent one — and that the distinction explains every privilege question we've hit. This issue makes that distinction a first-class rig concept: the machine class, the axis the bootstrap roles were implicitly organized around all along.
The model
control-plane,workload,runnerstaging,dev(dev added by this issue)rig users, companion issue below)rig users, scoped by roletag:server(workload/control-plane),tag:ci(runner)tag:local— nevertag:server: hosts are not control-plane-managed, their guests areSetting up multiple users in the control plane or on a prod box makes no sense — only admins belong there and root already is that; adding users/sudo/profiles would be surface without payoff. Hosts are the opposite: humans live there, mint boxes, and need scoped, non-colliding access.
The recursive part that makes it clean: a staging box (guest VM on a staging host) is itself server-class — root-only, no human users, managed by the control plane over the tailnet. The staging host may in practice run a single VM, but the principle is unchanged: host-class shell, server-class guests. (Consequence tracked in heavy-duty/box#69's follow-up: the staging template should be root-only — drop the
opsuser — with the smallbin/boxspecial-case for a root template user.)What changes
commands/bootstrap.sh): a role→class map next to the role case. Class drives the per-class behavior that today is ad-hoc per role: thetag:serverpost-join refusal (host-class-wide, not staging-specific), the/dev/kvmadvisory (host-class), and the closing next-steps log (host-class points at box install +rig users; server-class points at its existing runbooks).devrole — the host-class twin ofstaging, per the precedent that near-identical roles stay distinct for name honesty (control-planevsworkload). Same plumbing; hostname defaultdev; same host-class guards./etc/rig/role(e.g.role=staging class=host), convergent like the hostname. This is rig's first deliberate state on a box — justified because the no-state posture is about credentials, and a role marker is not a secret; precedent exists (.rig-labelson runners). Consumers:rig users' class gate (refuse on server-class),rig <cmd>sanity warnings later (e.g.coolify installon a non-control-plane box). If we reject the marker, the fallback is advisory-only gating — decide in the plan.Non-goals
rig usersimplementation (companion issue).Open questions (settle in the plan doc)
/etc/rig/roleas proposed, or advisory-only gating with no state?Acceptance
rig bootstrap devexists and behaves as host-class (tag:server refusal post-join, kvm advisory, next-steps log);test/cli.shcovers it exactly asstagingis covered.bash test/cli.shgreen.Companion users issue: https://github.com/heavy-duty/rig/issues/24
Prior related: heavy-duty/rig#22 (staging role, PR #23), heavy-duty/box#68 (staging template, PR #69)
Superseded by #26. Working staging and workstations through the class binary showed it bundled three independent questions (who lives there / does it host VMs / how it joins the tailnet) that only correlated across the first four roles — the staging host is unattended (class=server) despite hosting VMs, and a workstation joins user-owned via interactive login, which the authkey model refuses by design. #26 replaces the binary with orthogonal traits and keeps roles as presets over them.