rig platform: what is this machine, calculated at run time, stored nowhere #64
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#64
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?
rig platform: what is this machine, calculated at run time, stored nowhereThe gap
rig reads no hardware. At all. The single exception is
uname -minrunner-install.sh:147-150, used to pick a runner tarball and then discarded.So "is this the 32GB one, or the M900?" is a question you answer by logging in
and running
free -h,nproc,df -handuname -rby hand, four commandsdeep, on a machine you are already unsure about. There is no
rig inspectandno machine-wide
rig status; the nearest things arerig runner statusandrig users status, each of which knows exactly one domain.Why this is a command and not a file
It would be easy to write the specs into
/etc/rig/manifestduring bootstrap.That is the wrong shape, and the reason is the whole design:
Specs change without rig doing anything. Someone adds RAM, resizes the
root disk, or the unattended-upgrades bootstrap itself enables
(
bootstrap.sh:198-201) patches the kernel. A stored spec is stale the momentthe machine changes, and refreshing it on every run collides with the contract
at
bootstrap.sh:3— "Convergent: safe to re-run; a second run changesnothing" — enforced by cmp-guards at nine sites.
Computing at run time removes the problem instead of managing it. The answer
is correct by construction because there is nothing to go stale, and the
convergence contract is never touched because nothing is written.
The corollary is a property worth having deliberately:
rig platformworkson a machine rig has never converged. It reads only
/proc,unameand/etc/os-release, so it runs on bare Debian before bootstrap — which makes ituseful for deciding what to converge this into, not just for auditing
afterwards. It needs no root either.
#61 keeps the complementary half: provenance — which rig, and when — which is
decided rather than observed, so it is written once and never changes.
Proposed output
The bottom block is read from
/etc/rig/manifest(#61) and/etc/rig/role—read, never written. On a machine with no manifest those two lines are
omitted or render as
not bootstrapped, which is itself the useful answer.That degradation is why this command must not hard-depend on #61 landing
first; the two are independent and either can go in on its own.
Sources
All coreutils,
/procand systemd — nothing rig would have to add as adependency, and nothing absent on a minimal Debian:
HOSTNAMEhostnameOS. /etc/os-release && printf '%s %s' "$NAME" "$VERSION"KERNELuname -r,uname -mCPU/proc/cpuinfofirstmodel name;nprocMEMORY/proc/meminfoMemTotal/MemAvailableDISKdf -h /VIRTsystemd-detect-virt(systemd is already a hard dependency)One trap, already documented in five places in the tree
(
bootstrap.sh:155-159,runner-install.sh:88-92, and three more):/etc/os-releasemust be sourced in a subshell. It definesVERSION,NAMEandID, and sourcing it in the main shell silently clobberssame-named script variables. The existing sites all use
$(. /etc/os-release && printf ...)— follow that verbatim.systemd-detect-virtexits non-zero on bare metal (printingnone), which isa normal result and not an error — worth stating because
set -ewillotherwise turn a bare-metal machine into a failed command.
The name —
platformoverstatusBoth were on the table. I recommend
rig platform, for two reasons:statusmeans something specific in this tree already.rig users statusandrig runner statusboth cross-check recorded state againstlive state and print
DRIFT(users-status.sh:77-84). That is the housemeaning of the word: is reality still what we recorded? This command
cannot drift — it records nothing and computes everything — so calling it
statusborrows a promise it structurally cannot make.rig statusfree for the aggregate it will eventually want tobe: a machine-wide health roll-up over users, runner, box and tailscale,
each of which already has its own
status. Spending the name now on ahardware description would be hard to walk back.
rig platformsays what it is: a description of the platform, no judgement.Out of scope
property, not an implementation detail.
cheatsheet, not
inxi— the bar is "what would I want to know before I SSHin", and the proposed set fits on one screen.
rig status's job if it ever exists, and it needs thresholds this command has nobusiness owning.
Open questions
--json? Everything else in rig prints for humans, and rig famously hasno
jqon the target. But this is the one output a fleet-wide sweep wouldwant to collect and diff across machines. A flat
key=valuemode (rig platform --raw) is probably the rig-shaped answer, matching the manifest'sown format and parseable with
read.tailscale status --jsonis available on aconverged machine and the hostname/tags are genuinely part of "what is this
machine". Against: it is a network call, it is slow when the tailnet is
unreachable, and it makes the command fail in ways
/procnever will.Probably a separate line item, or behind a flag.
reflect the host's hardware filtered through the instance's limits, and
VIRTwill saylxc. Worth confirming the numbers shown there are thelimits rather than the host's totals — otherwise the output is actively
misleading on exactly the machines rig converges most often.
Complements #61 (provenance: which rig, and when). Neither blocks the other.