skill(freebsd): add freebsd-os-upgrade — minor point-release runbook
Ports the verified freebsd-update-reboot.md (reboot-needed detection, pre/post status capture, package/service notes, vuln-audit wording) from clawdie-ai into a layered-soul skill, alongside the existing freebsd-* operational skills. SKILL.md wraps it as the same-major upgrade procedure (15.0 -> 15.1): ABI FreeBSD:15:amd64 unchanged so no package rebuild / no PG dump-restore; reboot only on operator go-ahead; build-host-first sequence; and the clawdie-iso side (bump/override FREEBSD_VERSION, version-agnostic docs). Escalation is host-agnostic (mdo on the operator image, sudo/doas elsewhere). Validation-evidence slot left for the real OSA 15.0->15.1 run to fold in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
9872e1d4cf
commit
080d18fab8
2 changed files with 194 additions and 0 deletions
98
skills/freebsd-os-upgrade/SKILL.md
Normal file
98
skills/freebsd-os-upgrade/SKILL.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
---
|
||||||
|
name: freebsd-os-upgrade
|
||||||
|
description: Minor (same-major) FreeBSD upgrade runbook for hive nodes — freebsd-update, reboot-needed detection, pre/post verification, and the clawdie-iso FREEBSD_VERSION bump.
|
||||||
|
---
|
||||||
|
|
||||||
|
# FreeBSD OS Upgrade (minor / point release)
|
||||||
|
|
||||||
|
How we move a hive node across a FreeBSD point release within the same major
|
||||||
|
(e.g. `15.0-RELEASE` → `15.1-RELEASE`). Same-major upgrades are low-risk: the
|
||||||
|
package ABI is unchanged, so no package rebuild and no PostgreSQL dump/restore
|
||||||
|
are required. The detailed reboot rules and verification live in
|
||||||
|
[`references/freebsd-update-reboot.md`](references/freebsd-update-reboot.md);
|
||||||
|
this is the procedure that wraps them.
|
||||||
|
|
||||||
|
## Quick reference
|
||||||
|
|
||||||
|
Run the privileged steps as root, or via the host's escalation — `mdo` on the
|
||||||
|
operator image, `sudo`/`doas` elsewhere.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 1. Detect current state (installed vs running)
|
||||||
|
freebsd-version -k # installed kernel
|
||||||
|
freebsd-version -u # installed userland
|
||||||
|
uname -r # running kernel
|
||||||
|
|
||||||
|
# 2. Upgrade base to the target point release (as root)
|
||||||
|
freebsd-update -r 15.1-RELEASE upgrade
|
||||||
|
freebsd-update install # installs new kernel; repeat after reboot
|
||||||
|
|
||||||
|
# 3. Reboot ONLY on operator go-ahead, then (as root):
|
||||||
|
freebsd-update install # finish userland after the new kernel boots
|
||||||
|
|
||||||
|
# 4. Refresh packages (same major — ABI FreeBSD:15:amd64 is unchanged)
|
||||||
|
pkg update -f
|
||||||
|
pkg upgrade
|
||||||
|
```
|
||||||
|
|
||||||
|
## When to use
|
||||||
|
|
||||||
|
- A new FreeBSD point release in the current major is available and a node
|
||||||
|
should track it (OSA / mother, build host, deployed hosts).
|
||||||
|
- Before building a clawdie-iso image for the new point release (build the
|
||||||
|
image on a host at the same series).
|
||||||
|
|
||||||
|
## Runbook
|
||||||
|
|
||||||
|
1. **Capture pre-status** for after-the-fact comparison — see
|
||||||
|
*Pre-reboot status capture* in the reference (hostname, `freebsd-version
|
||||||
|
-kru`, services, `jls`, `pfctl -s info`). Record permission-limited checks as
|
||||||
|
such, not as "down".
|
||||||
|
2. **Upgrade base**: `freebsd-update -r <target> upgrade` then
|
||||||
|
`freebsd-update install`. The new kernel is staged; the system still runs the
|
||||||
|
old one until reboot.
|
||||||
|
3. **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**: 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**: `pkg update -f && pkg upgrade`. Same-major ABI is unchanged, so
|
||||||
|
this is a freshness refresh, not a rebuild. A same-major PostgreSQL bump needs
|
||||||
|
no dump/restore (restart/reboot to load new binaries).
|
||||||
|
6. **Vulnerability audit**: if `pkg audit` still flags packages, do not imply the
|
||||||
|
upgrade failed — the upgrade completed; unrelated packages remain vulnerable
|
||||||
|
until fixed versions land. (Wording in the reference.)
|
||||||
|
|
||||||
|
## clawdie-iso image side
|
||||||
|
|
||||||
|
The operator image tracks the series through a single variable. To build for the
|
||||||
|
new point release:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# build.cfg derives the memstick URL, checksum URL, cache path, and
|
||||||
|
# build-manifest from FREEBSD_VERSION:
|
||||||
|
FREEBSD_VERSION="${FREEBSD_VERSION:-15.1-RELEASE}"
|
||||||
|
|
||||||
|
# or override per-build without editing git:
|
||||||
|
FREEBSD_VERSION=15.1-RELEASE ./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Docs are kept version-agnostic (`FreeBSD 15.x`) so they don't drift on point
|
||||||
|
bumps. `build-vps.sh` (mfsbsd) and `scripts/poudriere/poudriere-setup.sh` carry
|
||||||
|
their own version knobs — bump those separately if that path is in use.
|
||||||
|
|
||||||
|
## Sequence for a release
|
||||||
|
|
||||||
|
Upgrade the build host (OSA) first → refresh its package cache → then build the
|
||||||
|
image for the new point release, so the image is assembled on a host at the same
|
||||||
|
series.
|
||||||
|
|
||||||
|
## Validation evidence
|
||||||
|
|
||||||
|
<!-- Filled from a real run. Fold in the captured freebsd-version output,
|
||||||
|
service/jail/PF status, and any deviations. -->
|
||||||
|
|
||||||
|
- _Pending: OSA `15.0-RELEASE` → `15.1-RELEASE`, <DD.mon.YYYY> — pre/post
|
||||||
|
`freebsd-version -kru`, services, jails, PF captured and matched._
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
# FreeBSD Base Update Reboot Handoff
|
||||||
|
|
||||||
|
Use this reference after FreeBSD base or package updates, and whenever the
|
||||||
|
operator asks whether a reboot is required.
|
||||||
|
|
||||||
|
## Reboot-needed rule
|
||||||
|
|
||||||
|
A reboot is required when the installed kernel/userland version is newer than
|
||||||
|
the running kernel:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
freebsd-version -k # installed kernel
|
||||||
|
freebsd-version -u # installed userland
|
||||||
|
uname -r # running kernel
|
||||||
|
```
|
||||||
|
|
||||||
|
If `freebsd-version -k` or `freebsd-version -u` reports a newer patch level than
|
||||||
|
`uname -r`, the update is staged but not fully active. Report that plainly and
|
||||||
|
ask the operator for an explicit reboot go-ahead. Reboot only on operator
|
||||||
|
go-ahead.
|
||||||
|
|
||||||
|
Example interpretation:
|
||||||
|
|
||||||
|
```text
|
||||||
|
freebsd-version -k: 15.0-RELEASE-p9
|
||||||
|
freebsd-version -u: 15.0-RELEASE-p9
|
||||||
|
uname -r: 15.0-RELEASE-p8
|
||||||
|
```
|
||||||
|
|
||||||
|
This means the system has p9 installed but is still running a p8 kernel. A reboot
|
||||||
|
is required to complete the update.
|
||||||
|
|
||||||
|
## Pre-reboot status capture
|
||||||
|
|
||||||
|
Before recommending or handing off a reboot, capture enough state for the next
|
||||||
|
agent/operator to compare after boot:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
hostname
|
||||||
|
freebsd-version -k
|
||||||
|
freebsd-version -u
|
||||||
|
uname -r
|
||||||
|
/usr/sbin/service clawdie status
|
||||||
|
/usr/sbin/service nginx status
|
||||||
|
/usr/sbin/service postgresql status
|
||||||
|
/usr/sbin/jls
|
||||||
|
/sbin/pfctl -s info
|
||||||
|
```
|
||||||
|
|
||||||
|
Use absolute paths for base-system tools when the agent shell has a narrow PATH.
|
||||||
|
Unprivileged agents may see permission errors for service internals, PostgreSQL,
|
||||||
|
or PF. Record those as permission-limited checks rather than claiming the service
|
||||||
|
is down.
|
||||||
|
|
||||||
|
## Package/service considerations
|
||||||
|
|
||||||
|
A same-major PostgreSQL package upgrade, such as `postgresql18-server` 18.3 →
|
||||||
|
18.4, does not require dump/restore. It still benefits from a reboot or service
|
||||||
|
restart so the new binaries are loaded.
|
||||||
|
|
||||||
|
If `nginx`, `tailscale`, PostgreSQL, or other long-running daemons were upgraded,
|
||||||
|
prefer a controlled reboot over piecemeal restarts unless the operator asks for a
|
||||||
|
minimal-disruption restart plan.
|
||||||
|
|
||||||
|
## Post-reboot verification
|
||||||
|
|
||||||
|
After the operator confirms the host is back, verify:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
freebsd-version -k
|
||||||
|
freebsd-version -u
|
||||||
|
uname -r
|
||||||
|
/usr/sbin/service clawdie status
|
||||||
|
/usr/sbin/service nginx status
|
||||||
|
/usr/sbin/service postgresql status
|
||||||
|
/usr/sbin/jls
|
||||||
|
/sbin/pfctl -s info
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected after a successful reboot: `freebsd-version -k`, `freebsd-version -u`,
|
||||||
|
and `uname -r` all report the same patch level.
|
||||||
|
|
||||||
|
Also verify application-specific readiness that matters for the current work:
|
||||||
|
|
||||||
|
- Clawdie control plane reachable/running
|
||||||
|
- Forgejo reachable if git work is active
|
||||||
|
- jails are running (`cms`, `worker`, or whatever the host normally owns)
|
||||||
|
- PF enabled and rules loaded
|
||||||
|
- Tailscale reachable if remote agents depend on it
|
||||||
|
|
||||||
|
## Vulnerability audit wording
|
||||||
|
|
||||||
|
If `pkg audit` still reports vulnerable packages after an upgrade, do not imply
|
||||||
|
the upgrade failed. Say that the applied upgrade completed, but unrelated
|
||||||
|
packages remain vulnerable until fixed packages are available or the operator
|
||||||
|
chooses a ports/package remediation path.
|
||||||
Loading…
Add table
Reference in a new issue