Merge pull request 'Install the upgrade tool on the privileged tier, which never got it' (#21) from privileged-upgrade-tool into main

Reviewed-on: #21
Reviewed-by: branderson <brad@branderson.io>
This commit was merged in pull request #21.
This commit is contained in:
2026-08-27 20:13:41 -07:00
5 changed files with 99 additions and 7 deletions
+35
View File
@@ -498,8 +498,43 @@ elif [ "$ROLE" = privileged ]; then
for tpl in "$SRC"/examples/*; do
[ -f "$tpl" ] && install -m 0644 "$tpl" "/usr/local/share/dejima-ci/templates/${tpl##*/}"
done
# dejima-ci-upgrade, for the same reason and a stronger one.
#
# install.sh puts it on a confined host. Without this line a privileged host
# never gets it from anywhere, because nothing else here installs anything -
# so the tier whose ONLY boundary is the node firewall would be the one tier
# with no way to ask which node-side versions it is missing, short of
# cloning the repository every time.
install -m 0755 "$SRC/bin/dejima-ci-upgrade" /usr/local/sbin/dejima-ci-upgrade
install -d -m 0755 /usr/local/share/dejima-ci/upgrades
for note in "$SRC"/upgrades/*.md; do
[ -f "$note" ] && install -m 0644 "$note" "/usr/local/share/dejima-ci/upgrades/${note##*/}"
done
# And the tier, which is definitionally known here and is otherwise the
# operator's to type. dejima-ci-upgrade refuses to guess it, on the grounds
# that an absent config identifies a privileged host and a confined one
# whose install.sh has not run - but this is the branch that IS the
# privileged path, so there is nothing to guess.
#
# guest_version is deliberately NOT written. It tracks what install.sh
# installed, and this tier runs none: the two programs placed above are
# tools rather than controls, and a stale installed copy is a thing
# dejima-ci-upgrade already reports about itself.
install -d -m 0755 /etc/dejima-ci
{
[ -r /etc/dejima-ci/state ] && grep -v '^tier=' /etc/dejima-ci/state || true
printf 'tier=privileged\n'
} > /etc/dejima-ci/state.new
sort -o /etc/dejima-ci/state.new /etc/dejima-ci/state.new
chmod 0640 /etc/dejima-ci/state.new
mv /etc/dejima-ci/state.new /etc/dejima-ci/state
say
say " installed /usr/local/sbin/dejima-ci-runners"
say " installed /usr/local/sbin/dejima-ci-upgrade"
say " recorded /etc/dejima-ci/state (tier=privileged)"
say
/usr/local/sbin/dejima-ci-runners --role privileged || \
say " runner setup did not finish - re-run: sudo dejima-ci-runners --role privileged"
+9 -3
View File
@@ -297,10 +297,16 @@ cmd_status() {
node=$(state_get node_version) || node=""
if [ "$tier" = privileged ]; then
# Not a gap. This tier installs nothing in the guest by design, which is
# the grant it exists for, so an unset guest_version is the correct
# Not a gap. guest_version tracks what install.sh installed - the
# allowlist, the resolver, the job firewall - and this tier runs none of
# it, which is the grant the tier exists for. So unset is the correct
# reading rather than a missing one.
say " guest n/a this tier runs no install.sh"
#
# bootstrap does place two programs here, dejima-ci-runners and this
# one, and they are deliberately not counted: they are tools rather than
# controls, and a stale installed copy is something this program already
# reports about itself.
say " guest n/a no install.sh on this tier; no guest-side controls"
else
say " guest ${guest:+v}${guest:-unrecorded}"
fi
+13 -4
View File
@@ -96,10 +96,19 @@ node_asserted=2026-08-25
node_verified=yes
```
**`guest_version`** is written by `install.sh`. The **privileged tier has no
`install.sh`** and no guest-side install at all — that is the grant the tier
exists for — so there it stays unset, and the tool reports `n/a` rather than
treating it as a gap.
**`guest_version`** is written by `install.sh`. It tracks the guest-side
*controls* — the allowlist, the resolver, the job firewall — and the
**privileged tier runs none of them**, which is the grant that tier exists for.
So there it stays unset, and the tool reports `n/a` rather than treating it as a
gap.
`dejima-ci-bootstrap --role privileged` does install two programs on that tier,
`dejima-ci-runners` and `dejima-ci-upgrade`, and records `tier=privileged` while
it is there — otherwise the one tier whose only boundary is the node firewall
would be the one tier unable to ask which node-side versions it is missing.
Those are tools rather than controls, so they are deliberately not counted in
`guest_version`; a stale installed copy is something `dejima-ci-upgrade` already
reports about itself.
**`node_version`** is written by `dejima-ci-upgrade mark-node`, by you, saying
you did the console work.
+20
View File
@@ -256,6 +256,26 @@ stub_check() {
# --- the notes themselves ---------------------------------------------------
@test "bootstrap installs the upgrade tool on the privileged tier" {
# install.sh puts it on a confined host and does not run on a privileged
# one. Without bootstrap doing it, the single tier whose ONLY boundary is
# the node firewall is the single tier with no way to ask which node-side
# versions it is missing - which is backwards.
branch=$(awk '/elif \[ "\$ROLE" = privileged \]/,/^else$/' "$REPO/bin/dejima-ci-bootstrap")
[ -n "$branch" ]
printf '%s' "$branch" | grep -q 'bin/dejima-ci-upgrade' \
|| { echo "the privileged branch of bootstrap does not install dejima-ci-upgrade"; false; }
}
@test "bootstrap records the tier it has definitionally just built" {
# The tool refuses to guess the tier, correctly. But this branch IS the
# privileged path, so there is nothing to guess and no reason to make an
# operator type it.
branch=$(awk '/elif \[ "\$ROLE" = privileged \]/,/^else$/' "$REPO/bin/dejima-ci-bootstrap")
printf '%s' "$branch" | grep -q 'tier=privileged' \
|| { echo "bootstrap does not record tier=privileged"; false; }
}
@test "every version from 1 to VERSION has an upgrade note" {
newest=$(tr -d '[:space:]' < "$REPO/VERSION")
for v in $(seq 1 "$newest"); do
+22
View File
@@ -147,6 +147,28 @@ v2 The LAN boundary gains IPv6 and the CGNAT range
— which is the true state of a rebuilt runner, and is the reason skipping the
record is a real option rather than a corner cut.
### On a privileged host, nothing is installed and nothing here installs it
Worth calling out because it is the tier where this matters most and the tier
where the tool is least available.
`install.sh` does not run on a privileged host — that is the grant the tier
exists for — so `dejima-ci-upgrade` never arrives there by that route. From this
version, `dejima-ci-bootstrap --role privileged` installs it directly, alongside
`dejima-ci-runners` and for the same reason. But **bootstrap is not part of this
upgrade**, so a privileged host already built at v1 has no copy and will not get
one from anything on this page.
Run it from a checkout there, as below. That is the whole answer for v2, and it
is not a workaround: the node rules are in force regardless, and a checkout is
the recommended way to run this tool on any tier.
If you would rather have it installed, re-running
`sudo ./bin/dejima-ci-bootstrap --role privileged` will do it — but that is a
guest-side change on a machine a rollback rebuilds, so it belongs in a snapshot
cycle rather than done casually. It also records `tier=privileged` for you,
which saves the `set-tier` step below.
### Running the tool at all
On a box where nothing is installed, from a checkout: