skill(freebsd): add boot environment rollback + cross-release override

Two improvements from the live OSA upgrade run:

1. Boot environment rollback: step 2 (before any base changes) now creates
   a BE with naming convention MAJOR.MINOR-upgrade-DD.mon.YY. pkgbase does
   NOT auto-snapshot ZFS — this must be done manually. If the upgrade
   misbehaves after reboot, bectl activate + reboot = instant rollback.

2. Cross-release override: pkgbase refuses to fetch 15.1 packages while
   running 15.0 userland. Document the env OSVERSION=1501000 override
   needed to cross the boundary.

Renumbered subsequent steps 2→3, 3→4, ..., 7→8.
This commit is contained in:
Sam & Claude 2026-06-25 11:23:36 +02:00
parent 00cc28e39e
commit aebc225ddc

View file

@ -71,7 +71,22 @@ pkg update -f && pkg upgrade # ports packages (separate from base here)
*Pre-reboot status capture* in the reference (hostname, `freebsd-version -k`
/ `-u`, `uname -r`, services, `jls`, `pfctl -s info`). Record
permission-limited checks as such, not as "down".
2. **Upgrade base** (by the method from step 0):
2. **Create a boot environment rollback point** — before any base changes.
The host is root-on-ZFS, so a boot environment is instant and near-free.
If the upgrade misbehaves after reboot, `bectl activate <name>` + reboot
puts you back exactly where you were.
```sh
bectl create MAJOR.MINOR-upgrade-DD.mon.YY
# example: 15.1-upgrade-25.jun.26
bectl list | grep upgrade
```
Name convention: `<target-release>-upgrade-<EU date>` — operator-facing,
readable at a glance. pkg does NOT auto-create ZFS boot environments;
this must be done manually.
3. **Upgrade base** (by the method from step 0):
- **pkgbase**: a pkgbase host already has a `FreeBSD-base` repo — **inspect
it** (`pkg -vv | grep -A6 -i FreeBSD-base`) and **edit that existing entry
in place**. A pinned `base_release_0` only delivers 15.0 patch levels; point
@ -80,23 +95,29 @@ pkg update -f && pkg upgrade # ports packages (separate from base here)
undefined, last-wins behavior. Then `pkg update`, **dry-run** with
`pkg upgrade -n` to confirm 15.1 base packages are actually offered, then
`pkg upgrade` (base + ports together).
**Cross-release override:** pkgbase refuses to fetch packages for a
newer release while running the old userland. Override with:
`env OSVERSION=1501000 ABI="FreeBSD:15:amd64" pkg update -f` then use
the same env for `pkg upgrade -n` and the real `pkg upgrade`.
(Replace `1501000` with the target release's __FreeBSD_version.)
- **freebsd-update**: `freebsd-update -r <target> upgrade` then
`freebsd-update install`.
Either way the new kernel is staged; the system runs the old one until reboot.
3. **Confirm a reboot is needed**: `freebsd-version -k` newer than `uname -r`
4. **Confirm a reboot is needed**: `freebsd-version -k` newer than `uname -r`
means staged-not-active. State that plainly and **reboot only on explicit
operator go-ahead** — never reboot the always-on board host autonomously.
4. **After reboot**: on freebsd-update hosts, run `freebsd-update install` again
5. **After reboot**: on freebsd-update hosts, run `freebsd-update install` again
to finish userland. Then the *Post-reboot verification* block — `-k`/`-u`/
`uname -r` must all match, and the app-readiness checks (Clawdie control
plane, Forgejo, jails, PF, Tailscale) must pass.
5. **Packages**: same-major ABI (`FreeBSD:15:amd64`) is unchanged, so this is a
freshness refresh, not a rebuild — pkgbase already covered it in step 2;
6. **Packages**: same-major ABI (`FreeBSD:15:amd64`) is unchanged, so this is a
freshness refresh, not a rebuild — pkgbase already covered it in step 3;
freebsd-update hosts do `pkg update -f && pkg upgrade`. A same-major
PostgreSQL bump needs no dump/restore (restart/reboot to load new binaries).
6. **Upgrade the jails** — the host upgrade does NOT touch them. Do this after
7. **Upgrade the jails** — the host upgrade does NOT touch them. Do this after
the host is on the new kernel. See *Jails* below.
7. **Vulnerability audit**: if `pkg audit` still flags packages (host or jails),
8. **Vulnerability audit**: if `pkg audit` still flags packages (host or jails),
do not imply the upgrade failed — the upgrade completed; unrelated packages
remain vulnerable until fixed versions land. (Wording in the reference.)