Compare commits

...
Author SHA1 Message Date
branderson 58162126f0 Install the upgrade tool on the privileged tier, which never got it
Reported: dejima-ci-upgrade never reaches a privileged box. install.sh puts
it on a confined host and does not run on a privileged one - that is the
grant the tier exists for - and nothing else installed it. So the one tier
whose ONLY boundary is the node firewall was the one tier unable to ask which
node-side versions it was missing.

bootstrap now installs it there, alongside dejima-ci-runners and for the same
reason that already justifies that line: on this role install.sh is not there
to do it, and the host should end up with the same "re-run it to change
something" story as a confined one.

It also records tier=privileged. The tool refuses to guess the tier, which is
right - an absent config identifies a privileged host and equally a confined
one whose install.sh has not run - but this branch IS the privileged path, so
there is nothing to guess and no reason to make an operator type it.

guest_version is deliberately still not written there. It tracks the
guest-side controls, and this tier runs none; the two programs bootstrap
places are tools, and a stale installed copy is something the tool already
reports about itself. The comment claiming the tier "installs nothing in the
guest" was true when written and is not any more, so it says what it means
now.

WHAT THIS DOES NOT FIX is a privileged host already built at v1. Bootstrap is
not part of the v2 upgrade, so those hosts still have no copy and will not
get one from anything on that page. The note now says so where a privileged
operator will be looking, points at the checkout as the answer for v2, and
notes that re-running bootstrap is the alternative and is a guest-side change
with a rollback cycle behind it.

`bats test/` 135 passing, 2 new.
2026-08-27 17:56:59 -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: