Updates & patching¶
What this is¶
PiHerder’s update system has two layers:
| Layer | Meaning |
|---|---|
| Check | Safe detection — count packages / HA components / compare images; no upgrade |
| Apply | Real change — apt upgrade, ha … update on HAOS, or compose pull + up |
You can run either manually or on a schedule. Silent auto-upgrade is never the default.
HAOS hosts
On Home Assistant OS, “OS patch” is labelled HA updates and uses the ha CLI (Core / OS / Supervisor), not apt. See HAOS hosts.
Why it exists¶
Keeping a fleet patched without a shared process leads to “I forgot that Pi for six months.” Checks fill the dashboard need attention view; apply is deliberate so you choose the maintenance window. Live logs and exclusive jobs stop double-clicks from stacking conflicting upgrades.
Feature flags¶
| Feature | Edit → Features | Why gated |
|---|---|---|
| OS packages / HA updates | OS patch | Debian: apt. HAOS: ha CLI (same flag; UI says HA updates) |
| Container images | Docker / containers | No Docker → no image checks; leave off on HAOS |
End-to-end: one host, check then apply¶
- Enable OS patch and/or Docker on the server.
- Run Check OS / Check containers (manual).
- Open Jobs and confirm success; dashboard counts move.
- Read package/image results on the host.
- When ready, run Upgrade / Patch containers (or full-upgrade if you understand the extra packages).
- If reboot is required, use Reboot after apply finishes.
- Only after a few manual cycles, enable check schedules; enable apply schedules later with “only when last check found updates.”
Full journey: Operator scenarios — Journey C.
Update checks (safe)¶
Configured under Edit → Schedules.
| Schedule | Does | Does not |
|---|---|---|
| OS packages (apt) | Count ready packages, phased count, reboot-pending | Run upgrade |
HA updates (os_type=haos) | Count Core / OS / Supervisor with update_available | Run ha … update |
| Container images | Pull/compare image IDs per compose project | compose up -d |
Results feed the dashboard, badges, and notifications.
Patch apply (opt-in)¶
Off by default. Requires the matching feature flag.
| Option | Behaviour | Why |
|---|---|---|
| Enable scheduled apply | Registers APScheduler job | Automate after you trust checks |
| Only when last check found updates | Skips if last check count is 0 | Avoid empty upgrade noise |
| OS: full-upgrade | Uses full-upgrade instead of upgrade (+ update + autoremove) | Opt-in broader package moves |
| Cron | e.g. weekly Sunday 30 3 * * 0 | Quiet maintenance window |
Also skipped when a job of the same type is already pending/running on that server.
Scheduled work is audited as system / scheduler.
Manual apply¶
- Debian/Ubuntu: update / upgrade XOR full-upgrade / autoremove; live apt log; Ubuntu phased packages counted separately.
- HAOS: refresh versions + apply available components (supervisor → core → OS); live CLI log; no apt / no full-upgrade.
- Container patch:
compose pull+ conditionalup -dwith live logs (not for HAOS fleet).
One active job per host (no double-run)¶
For a given server, PiHerder allows at most one active job of each exclusive type:
| Type | Meaning |
|---|---|
os_patch / container_patch | Apply |
os_update_check / container_update_check | Check-only |
A second trigger (double-click, concurrent bulk, scheduler overlap) does not start a second run. The UI attaches to the existing job; the API returns HTTP 409 with the existing job_id.
Celery workers vs container jobs
Celery multi-slot concurrency (CELERY_CONCURRENCY, default 2) applies to backups only. OS/container patch and update checks run on the web process (BackgroundTasks / thread pools). Scaling Celery workers does not re-execute a container job twice. See Multi-worker.
Docker: Check updates vs Deploy¶
| UI action | Meaning |
|---|---|
| Check updates | Pull / compare only |
| Deploy | Pull + up -d — surfaces pull/up results (not silent success) |
Successful Deploy clears pending stack badges and resolves container_updates when none remain.
Bulk actions (Servers list)¶
Why bulk: patching ten hosts one-by-one is how fleets drift. Bulk queues the same job type across eligible hosts; feature flags and exclusive-job rules still apply.
On Servers (/servers):
- Tick one or more host checkboxes (or Select all visible).
- Use the bulk bar (appears when something is selected):
| Action | Requires feature on host |
|---|---|
| Check OS | OS patch enabled |
| Upgrade OS | OS patch enabled |
| Check containers | Docker / containers enabled |
| Patch containers | Docker / containers enabled |
| Backup | Backups enabled |
Per-host ⋯ menu: open host, backups, OS/container patch, Docker, settings (feature-gated). Status pills (OS packages, images, reboot, backup, optional Kuma/LAN chips) come from the last stored check results — the list does not open live SSH on every paint.
Hosts without the matching feature flag are skipped (not failed). Confirm dialog shows which hosts will run. Progress is on Jobs; a banner summarises started / skipped / failed.
Bulk Upgrade OS / Patch containers enqueue each host on the apply pool (up to six concurrent SSH sessions). They must not wait for the first host’s apt to finish. After a web recreate, leftover pending/running os_patch rows are failed so the per-host exclusive lock does not stick.
Bulk does not bypass exclusive-job rules: if a host already has that job type running, it is skipped as already active.
Reboot¶
Least-priv sudoers may allow /usr/sbin/reboot (and common alternate paths). PiHerder:
- Schedules reboot in the background (
sleep 1then reboot) so the SSH command returns quickly. - Closes SSH with a short timeout (hosts dying mid-session no longer hang the request).
- Clears local
reboot_pendingafter a successful send so the UI does not stick.
Why this design: rebooting the same host that runs PiHerder takes the stack down moments later; the HTTP response and audit row should already be finished.
Related¶
- Jobs, audit & notifications
- Reports — OS patch applies and container image patches over time
- Docker overview
- Troubleshooting