Expand description
Shared install-script builder for a control-plane (yubaba + kamaji) roll.
This is the ONE net-new mechanism of the rolling-upgrade envelope (R608): the atomic fetch→verify→anchor→install→assert→restart of the signed yubaba+kamaji pair. It lives here — in the crate BOTH the CLI orchestrator and yubaba itself depend on — so the two apply transports share a single, trusted script and cannot drift:
- SSH transport (R608-F5,
app/yah/cli/src/rollout/apply.rs::apply_over_ssh) pipes the script tossh <node> bash -sfrom the orchestrator. - Mesh transport (R608-F10, yubaba
POST /self-update) runs the same script locally on the node via asystemd-runtransient unit — no SSH.
The script body is not written here. It lives beside this file as
control_plane_install.sh and is include_str!d,
because a third caller — scripts/roll-node.sh, the one-node operator SSH
job (R755-F3) — has to run the identical bytes from bash with no Rust in the
loop. This function only prepends the four-variable prologue the template
declares (URL / SHA / VER / SUDO); roll-node.sh prepends the same
four. Keeping the body in a format! string would have forced that script to
become a fourth transcription of the most safety-critical code in the fleet
(stand-up-yubaba.sh’s install tail is already the second).
The script is a state-preserving, atomic transcription of the install tail of
stand-up-yubaba.sh: fetch the signed release tarball, sha256 -c it against
the digest the signed manifest already resolved (callers only ever pass
manifest-derived values — there is no path for an AI or a wire request to
fabricate a version/url/digest), extract, leave a dated rollback anchor beside
every file it is about to replace, stage each file next to its target on the
same filesystem, then mv it into place so a half-written
/usr/local/bin/yubaba can never appear. yubaba + kamaji install as one
atomic pair (W275 OQ5).
Success is proved by content, never by --version. After the rename the
script hashes each installed binary against the file it extracted from the
manifest-verified tarball. The version string is the workspace version baked
in at build time and can be right on a binary that predates the code it
claims — us-east-001 reported kamaji 0.8.22 while carrying none of the 0.8.22
tree (R746-T3). The hash chain manifest → tarball → extracted → installed has
no version string in it.
Never touches durable state. The script contains no reference to
/var/lib/yah-cloud/identity.json (the ed25519 host identity — wiping it
forces a re-TOFU and breaks hostkey-drift detection, the R589 gotcha) or the
raft log dir. A roll moves /usr/local/bin bytes + unit files, nothing else.
The [tests::script_never_touches_durable_state] test is the guard.
Constants§
- INSTALL_
SCRIPT_ TEMPLATE - The canonical roll script body, shared verbatim with
scripts/roll-node.sh. Expects the four-variable prologuebuild_install_scriptemits.
Functions§
- build_
install_ script - Build the self-contained install script for the yubaba+kamaji pair.