fix: install pinned drill inputs by commit

This commit is contained in:
codex-bot-andresmgsl 2026-08-18 07:14:26 +00:00
parent 45c29d6dbc
commit e1e4fc77db
10 changed files with 83 additions and 47 deletions

View file

@ -49,13 +49,15 @@ By default that installs the **latest release** — the installer resolves the
release tag off GitHub's `releases/latest` redirect (no API, no token) and
downloads exactly that tree, so two operators running it get the same box.
If the resolution fails it says so and stops — it never silently hands out
`main`. `BOX_REF` picks another channel (a set ref is tried as a tag first,
then as a branch — [#83](https://github.com/heavy-duty/box/issues/83)):
`main`. `BOX_REF` picks another channel: a named ref is tried as a tag first,
then as a branch ([#83](https://github.com/heavy-duty/box/issues/83)), while a
full 40-hex commit SHA selects GitHub's immutable commit archive:
```sh
curl -fsSL .../install.sh | bash # the latest release (default)
curl -fsSL .../install.sh | BOX_REF=0.6.0 bash # pin a release
curl -fsSL .../install.sh | BOX_REF=main bash # the development tip
curl -fsSL .../install.sh | BOX_REF=<full-commit-sha> bash # exact tree
```
(A dev tree's `VERSION` carries a `-dev` suffix, so it lands beside your

32
bin/box
View file

@ -1096,36 +1096,48 @@ load_template() {
T_DISK="${disk:-${BOX_DISK:-${T_DISK:-60GiB}}}"
}
# The ONE substitution a template gets — user-data.yaml is otherwise passed to
# Incus verbatim. The tenant seeds preinstall rig, which inverts the rig→box
# install edge (rig#28: rig installs box on hosts; now box guests install rig),
# and that edge needs a pin point (#81): the seed carries @RIG_REPO@ /
# @RIG_REF@ tokens, resolved here from the mint environment — RIG_REPO
# (default heavy-duty/rig) and RIG_REF (default main). Both directions track
# main unpinned today, said honestly (the same treatment rig#29 gave box's own
# unpinned install) until a release flow exists (rig#32 / #83). The values are
# The ONE substitution a template gets — @RIG_INSTALL@ — while user-data.yaml
# is otherwise passed to Incus verbatim. The tenant seeds preinstall rig, which
# inverts the rig→box install edge (rig#28: rig installs box on hosts; now box
# guests install rig), and that edge needs a pin point (#81). The renderer
# resolves the mint environment's RIG_REPO (default heavy-duty/rig) and RIG_REF
# (default main) into the whole installer command. Named refs keep the normal
# tag/branch channel; a drill-pinned commit carries its immutable archive as
# RIG_INSTALL_SOURCE (#152). Both values are
# allowlist-validated BEFORE touching the YAML: they land inside a runcmd
# shell line, so a quote, a space or a newline smuggled through the
# environment must die on the host, never execute in the guest. bash's =~
# anchors to the whole string — a multi-line value cannot sneak one clean
# line past it the way a line-oriented grep would.
# The rig pin, resolved from the mint environment, in ONE place: render_userdata
# substitutes it into the seed, and the mint stamp (#103) records it onto the
# builds it into the seed, and the mint stamp (#103) records it onto the
# instance. Two spellings of the same default would eventually disagree, and a
# stamp that disagrees with the seed is worse than no stamp at all.
rig_repo() { printf '%s\n' "${RIG_REPO:-heavy-duty/rig}"; }
rig_ref() { printf '%s\n' "${RIG_REF:-main}"; }
render_userdata() {
local f="$1" repo data ref
local f="$1" repo data ref install
repo="$(rig_repo)"; ref="$(rig_ref)"
[[ "$repo" =~ ^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ ]] \
|| die "RIG_REPO must look like owner/repo: $repo"
[[ "$ref" =~ ^[A-Za-z0-9._/-]+$ ]] \
|| die "RIG_REF must be a plain ref name (letters, digits, . _ / -): $ref"
if [[ "$ref" =~ ^[0-9a-f]{40}$ ]]; then
# rig's installer currently resolves named tags/branches. A release drill
# pins the moving ref before mint, so hand that installer the immutable
# commit archive as a local source instead of asking it to resolve again
# inside the guest (#152).
printf -v install '%s' \
"rig_source=/tmp/rig-$ref.tar.gz; rig_installer=/tmp/rig-install-$ref.sh; curl -fsSL https://github.com/$repo/archive/$ref.tar.gz -o \"\$rig_source\" && curl -fsSL https://raw.githubusercontent.com/$repo/$ref/install.sh -o \"\$rig_installer\" && HOME=/root RIG_REPO=\"$repo\" RIG_REF=\"$ref\" RIG_INSTALL_SOURCE=\"\$rig_source\" bash \"\$rig_installer\"; rig_rc=\$?; rm -f \"\$rig_source\" \"\$rig_installer\"; exit \"\$rig_rc\""
else
printf -v install 'curl -fsSL https://raw.githubusercontent.com/%s/%s/install.sh | HOME=/root RIG_REPO="%s" RIG_REF="%s" bash' \
"$repo" "$ref" "$repo" "$ref"
fi
data="$(cat "$f")"
data="${data//@RIG_REPO@/$repo}"
data="${data//@RIG_REF@/$ref}"
data="${data//@RIG_INSTALL@/$install}"
printf '%s\n' "$data"
}

View file

@ -24,10 +24,11 @@ set -euo pipefail
# downloading — for CI and the drill, so what lands is the code under review.
REPO="${BOX_REPO:-heavy-duty/box}"
# Three install channels, one knob (#83): BOX_REF unset installs the LATEST
# Four install channels, one knob (#83, #152): BOX_REF unset installs the LATEST
# RELEASE (the tag resolved from GitHub's releases/latest redirect, below);
# BOX_REF=<tag> pins a release; BOX_REF=<branch> (say, main) is the dev
# channel. A set ref is tried as a tag first, then as a branch.
# channel; and a full 40-hex commit SHA is fetched immutably. A named ref is
# tried as a tag first, then as a branch.
REF="${BOX_REF:-}"
# Root installs GLOBALLY, non-root installs per-user. box's install tree is
# EXECUTED by other users (the multi-user host path: rig installs box once, every
@ -232,8 +233,17 @@ else
fi
INSTALLED_FROM="$REPO@$REF"
log "installing box from $REPO@$REF"
# A ref is a TAG first (the pinned-release channel), a branch second (the
# dev channel, BOX_REF=main) — and the fallback only exists for a ref the
if [[ "$REF" =~ ^[0-9a-f]{40}$ ]]; then
# The drill resolves moving candidate refs before it mutates a host, then
# installs the exact object it measured (#152). GitHub's commit archive is
# outside refs/{tags,heads}; guessing either namespace makes every SHA 404.
URL="https://github.com/$REPO/archive/$REF.tar.gz"
log "downloading immutable commit $URL"
curl -fsSL "$URL" -o "$TMPDIR/box.tar.gz" \
|| die "failed to download commit $REF from $REPO"
else
# A named ref is a TAG first (the pinned-release channel), a branch second
# (the dev channel, BOX_REF=main). The fallback only exists for a ref the
# OPERATOR named: a resolved latest tag has no branch to fall through to.
URL="https://github.com/$REPO/archive/refs/tags/$REF.tar.gz"
log "downloading $URL"
@ -244,6 +254,7 @@ else
curl -fsSL "$URL" -o "$TMPDIR/box.tar.gz" \
|| die "failed to download it as either — '$REF' is neither a tag nor a branch of $REPO"
fi
fi
log "extracting archive"
tar -xzf "$TMPDIR/box.tar.gz" -C "$TMPDIR" \

View file

@ -30,4 +30,4 @@ runcmd:
# HOME=/root: cloud-init runs runcmd as root but with NO $HOME in the
# environment, and the rig installer (set -u) reads $HOME for its DEST —
# measured live: the mint died with "HOME: unbound variable" without it.
- curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | HOME=/root RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash
- '@RIG_INSTALL@'

View file

@ -30,4 +30,4 @@ runcmd:
# HOME=/root: cloud-init runs runcmd as root but with NO $HOME in the
# environment, and the rig installer (set -u) reads $HOME for its DEST —
# measured live: the mint died with "HOME: unbound variable" without it.
- curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | HOME=/root RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash
- '@RIG_INSTALL@'

View file

@ -30,4 +30,4 @@ runcmd:
# HOME=/root: cloud-init runs runcmd as root but with NO $HOME in the
# environment, and the rig installer (set -u) reads $HOME for its DEST —
# measured live: the mint died with "HOME: unbound variable" without it.
- curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | HOME=/root RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash
- '@RIG_INSTALL@'

View file

@ -30,4 +30,4 @@ runcmd:
# HOME=/root: cloud-init runs runcmd as root but with NO $HOME in the
# environment, and the rig installer (set -u) reads $HOME for its DEST —
# measured live: the mint died with "HOME: unbound variable" without it.
- curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | HOME=/root RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash
- '@RIG_INSTALL@'

View file

@ -31,4 +31,4 @@ runcmd:
# HOME=/root: cloud-init runs runcmd as root but with NO $HOME in the
# environment, and the rig installer (set -u) reads $HOME for its DEST —
# measured live: the mint died with "HOME: unbound variable" without it.
- curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | HOME=/root RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash
- '@RIG_INSTALL@'

View file

@ -266,15 +266,28 @@ check "render_userdata: the pin's defaults came with it (guards the grep)" 0 "he
check "render_userdata: the extracted function is valid bash" 0 "" bash -n "$RUFN"
SEED="$(mktemp)"
printf '#cloud-config\nruncmd:\n - curl -fsSL https://raw.githubusercontent.com/@RIG_REPO@/@RIG_REF@/install.sh | RIG_REPO="@RIG_REPO@" RIG_REF="@RIG_REF@" bash\n' > "$SEED"
printf "#cloud-config\nruncmd:\n - '@RIG_INSTALL@'\n" > "$SEED"
# shellcheck disable=SC2016 # $0/$1 expand in the child shell, by design
rud() { # rud [VAR=val ...] — render the fixture seed through the real function
env "$@" bash -c 'die() { echo "box: $*" >&2; exit 1; }; . "$0"; render_userdata "$1"' "$RUFN" "$SEED"
}
check "render_userdata: defaults pin heavy-duty/rig" 0 "githubusercontent.com/heavy-duty/rig/main/install.sh" rud
check "render_userdata: defaults feed the installer's own env too" 0 'RIG_REPO="heavy-duty/rig" RIG_REF="main"' rud
check "render_userdata: the rig install pins HOME=/root (runcmd has no \$HOME)" 0 "HOME=/root " rud
check "render_userdata: RIG_REPO/RIG_REF override at mint" 0 "dan-claude-bot/rig/feat/bootstrap-roles/install.sh" \
rud RIG_REPO=dan-claude-bot/rig RIG_REF=feat/bootstrap-roles
RIG_COMMIT=89abcdef0123456789abcdef0123456789abcdef
check "render_userdata: a rig commit downloads its immutable archive" 0 "archive/$RIG_COMMIT.tar.gz" \
rud RIG_REPO=heavy-duty/rig RIG_REF="$RIG_COMMIT"
# $rig_source belongs to the rendered guest shell.
# shellcheck disable=SC2016
check "render_userdata: a rig commit feeds the archive to the installer" 0 'RIG_INSTALL_SOURCE="$rig_source"' \
rud RIG_REPO=heavy-duty/rig RIG_REF="$RIG_COMMIT"
# Expansion belongs to the bash -c fixture.
# shellcheck disable=SC2016
check "render_userdata: a named rig ref keeps the normal channel" 1 "" \
bash -c 'die() { exit 1; }; RIG_REPO=heavy-duty/rig RIG_REF=main; . "$1"; render_userdata "$2" | grep -q RIG_INSTALL_SOURCE' \
_ "$RUFN" "$SEED"
# shellcheck disable=SC2016 # $0/$1 expand in the child shells, by design
check "render_userdata: no token survives the render" 1 "" \
bash -c 'env bash -c "die() { echo box: \$*; exit 1; }; . \"\$0\"; render_userdata \"\$1\"" "$1" "$2" | grep -q @RIG_' _ "$RUFN" "$SEED"
@ -326,26 +339,13 @@ for d in "$ROOT"/templates/*/; do
# The thin-template contract (#81), both halves per template:
#
# THE SEED — a template that names a tenant role (BOX_BOOTSTRAP_ROLE) must
# preinstall rig carrying BOTH pin tokens, on the installer URL and on the
# installer's own env, or the pin is a half-truth: a mint would fetch one
# ref's installer and install another ref's tree.
# delegate its rig install to render_userdata. That one renderer owns both
# the named-ref channel and the immutable-commit archive channel.
# ------------------------------------------------------------------------
trole="$(tpl "$ROOT" "$t" | sed -n 's/.*ROLE=\([^ ]*\).*/\1/p')"
if [ -n "$trole" ]; then
check "template '$t': the seed installs rig (role '$trole')" 0 "" \
grep -q 'install.sh' "$d/user-data.yaml"
# shellcheck disable=SC2016 # $1 expands in the child shell, by design
check "template '$t': the rig install carries the @RIG_REPO@ pin token" 0 "" \
bash -c 'grep "install.sh" "$1" | grep -q "@RIG_REPO@/@RIG_REF@"' _ "$d/user-data.yaml"
# shellcheck disable=SC2016
check "template '$t': the pin reaches the installer's env too" 0 "" \
bash -c 'grep "install.sh" "$1" | grep -q "RIG_REPO=\"@RIG_REPO@\" RIG_REF=\"@RIG_REF@\""' _ "$d/user-data.yaml"
# HOME=/root: a scar found live — cloud-init's runcmd has no $HOME and
# rig's installer (set -u) dies on it (rig#39). The pin must survive
# every seed rewrite.
# shellcheck disable=SC2016
check "template '$t': the rig install pins HOME=/root (runcmd has no \$HOME)" 0 "" \
bash -c 'grep "install.sh" "$1" | grep -q "HOME=/root "' _ "$d/user-data.yaml"
check "template '$t': the seed installs rig through the renderer (role '$trole')" 0 "" \
grep -q "^[[:space:]]*- '@RIG_INSTALL@'\$" "$d/user-data.yaml"
fi
# ------------------------------------------------------------------------
# THE ABSENCE — no tenant content in ANY template, ever again. Everything a

View file

@ -109,6 +109,16 @@ check "dev channel: tries the tag first" 0 "refs/tags/main.tar.gz" head -1 "$L3"
check "dev channel: then downloads the branch" 0 "" \
grep -qF "archive/refs/heads/main.tar.gz" "$L3"
COMMIT_REF=0123456789abcdef0123456789abcdef01234567
H5="$WORK/h5"; B5="$WORK/b5"; L5="$WORK/c5.log"
check "commit channel: installs an immutable full SHA" 0 "installing box from heavy-duty/box@$COMMIT_REF" \
ninst "$H5" "$B5" BOX_REF="$COMMIT_REF" FAKE_CURL_LOG="$L5" \
FAKE_SERVE_URL="https://github.com/heavy-duty/box/archive/$COMMIT_REF.tar.gz"
check "commit channel: downloads the commit archive directly" 0 "archive/$COMMIT_REF.tar.gz" cat "$L5"
check "commit channel: never guesses tag or branch namespaces" 1 "" grep -Eq 'refs/(tags|heads)' "$L5"
check "commit channel: records the immutable source" 0 "heavy-duty/box@$COMMIT_REF" \
cat "$H5/versions/9.9.9/INSTALLED_FROM"
H4="$WORK/h4"; B4="$WORK/b4"; L4="$WORK/c4.log"
check "resolution failure: names the latest-release probe" 1 "could not resolve the latest release" \
ninst "$H4" "$B4" FAKE_CURL_RC=6 FAKE_CURL_LOG="$L4"
@ -122,6 +132,7 @@ check "unknown ref names both attempted channels" 1 "neither a tag nor a branch"
check "README documents the latest-release channel" 0 "" grep -qF 'latest release' "$ROOT/README.md"
check "README documents the pinned channel" 0 "" grep -qF 'BOX_REF=0.6.0' "$ROOT/README.md"
check "README documents the dev channel" 0 "" grep -qF 'BOX_REF=main' "$ROOT/README.md"
check "README documents the immutable commit channel" 0 "" grep -qF 'BOX_REF=<full-commit-sha>' "$ROOT/README.md"
echo "---"
echo "$PASS passed, $FAIL failed"