Updates & rollback
hal0 updates itself in one atomic symlink swap, backed by cosign-verified release tarballs. If an update goes wrong, one command rolls back to the previous version.
The model
Section titled “The model”The filesystem layout (PLAN §2) is FHS-aligned and deliberately separates the code from the data:
/usr/lib/hal0/current/ # symlink → /usr/lib/hal0-<version>//usr/lib/hal0-0.9.7/ # versioned install/usr/lib/hal0-0.9.8/ # versioned install (next)/etc/hal0/ # config, preserved across updates/var/lib/hal0/ # models, registry, OpenWebUI statehal0 update unpacks the new version next to the current one, then
swaps the current symlink in a single rename(2) call. The systemd
units point at /usr/lib/hal0/current/, so a restart picks up the
new version atomically — no partial state on disk, ever.
Check for an update
Section titled “Check for an update”hal0 update --checkReturns the latest version on the configured channel without applying it.
Apply an update
Section titled “Apply an update”hal0 update # stable channelhal0 update --channel stable # explicithal0 update --channel nightly # bleeding edgeThe flow:
- Fetch the release manifest from
hal0.dev. - Verify the manifest signature.
- Download the version tarball.
- Verify the tarball against
signer_identity+signer_issuer(GitHub OIDC, cosign). - Unpack to
/usr/lib/hal0-<new-version>/. - Swap
/usr/lib/hal0/current/to the new version (atomic). - Restart
hal0-api.service. - Slot units survive the restart — they keep serving traffic throughout.
Rollback
Section titled “Rollback”hal0 update --rollbackPoints current back at the previous versioned directory and
restarts. The data dirs (/etc/hal0, /var/lib/hal0) are untouched,
so your config, models, and registry are preserved.
Channels
Section titled “Channels”| Channel | What you get |
|---|---|
stable | Cut releases. The default; recommended. |
nightly | Every green main build. For testing only. |
Channels are configured in hal0.toml. Switch with
hal0 config edit or via the dashboard’s Settings view.
Why atomic
Section titled “Why atomic”The naive approach — tar xf … && systemctl restart — has two
failure modes that bite at 2am:
- Partial unpack. Disk fills mid-tar; you have half a new version overlaid on the old one. Nothing works.
- Restart loop. New binary crashes on start; systemd retries; no
obvious way back without a second SSH session and a working
mv.
Atomic symlink swap solves both: the new version is fully unpacked
before the swap, and the previous version is still on disk for
--rollback to point back at.