From a0272c2c101282ed5dfd98a62fa8eaa00a39ec3f Mon Sep 17 00:00:00 2001 From: padriano Date: Thu, 4 Jun 2026 14:24:34 +0100 Subject: [PATCH] =?UTF-8?q?add=20Home=20Assistant=202024.5.4=20=E2=86=92?= =?UTF-8?q?=202026.5.0=20upgrade=20plan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- plans/Plan-HA-upgrade.md | 233 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 plans/Plan-HA-upgrade.md diff --git a/plans/Plan-HA-upgrade.md b/plans/Plan-HA-upgrade.md new file mode 100644 index 0000000..2ec163b --- /dev/null +++ b/plans/Plan-HA-upgrade.md @@ -0,0 +1,233 @@ +# Home Assistant Upgrade Plan: 2024.5.4 → 2026.5.0 (revised) + +Direct jump (no intermediate version stops). Two structural compose changes are folded into this upgrade: bump the `image:` tag, and swap the healthcheck endpoint to one that doesn't require auth on modern HA. + +## Current versions + +- Core: `2024.5.4` +- Frontend: `20240501.1` + +## Target versions (as of May 2026) + +- Core: `2026.5.0` (released May 6, 2026) +- Frontend: `20260325.6` (stable) — bundled inside the core image, no separate action needed + +## Scope + +The Home Assistant instance runs as a Docker container defined in `docker-compose.yml`, pinned to `homeassistant/home-assistant:2024.5.4`. The config is volume-mounted at `/home/padriano/projects/ha/config`. + +## 1. Pre-flight checks (read-only) + +Before touching anything, gather facts and confirm assumptions: + +- **Architecture**: `uname -m` — confirm `x86_64` (the official HA image supports it; `armhf` was dropped in 2025). +- **Custom components / HACS**: `ls /home/padriano/projects/ha/config/custom_components 2>/dev/null` — currently empty, good. If anything appears, abort and check each integration's HA 2026.5 compatibility first. +- **USB device passthrough**: confirm no `devices:` mapping in `docker-compose.yml` (none today — no Z-Wave/Zigbee radios at risk). +- **Recorder DB size**: `du -sh /home/padriano/projects/ha/config/home-assistant_v2.db*` — record this. The bigger it is, the longer the first-boot schema migration will take. +- **Free disk**: `df -h /home/padriano/projects/ha` — already 405 GB free, plenty for backup + image pull. +- **Current version (auth-free)**: + + ```bash + docker exec homeassistant python -c "from homeassistant.const import __version__; print(__version__)" + # expected: 2024.5.4 + ``` + + (The old `curl /api/ | grep version` is unreliable and won't work post-upgrade because `/api/` requires auth on modern HA.) +- **Current container health**: + + ```bash + docker inspect --format '{{.State.Health.Status}}' homeassistant + # expected: healthy + ``` +- **Reverse-proxy reachability**: + + ```bash + curl -fsS -o /dev/null -w "%{http_code}\n" https://ha-padriano.duckdns.org + # record current status code so we can compare post-upgrade + ``` + +## 2. Backups + +### 2a. Record image digest and pin a local rollback tag + +```bash +docker inspect --format '{{.Image}}' homeassistant > /home/padriano/projects/ha/image-digest-2024.5.4.txt +docker tag "$(cat /home/padriano/projects/ha/image-digest-2024.5.4.txt)" homeassistant/home-assistant:2024.5.4-rollback +``` + +The local `:2024.5.4-rollback` tag guarantees the exact previous image stays resolvable even if the upstream `:2024.5.4` tag is ever repushed or GC'd. + +### 2b. Create a HA backup from within Home Assistant + +Open Home Assistant UI → **Settings → System → Backups → Create backup** (full backup). This captures integrations state, `.storage/`, and all config managed by HA. Download the `.tar` file. + +### 2c. Off-host copy of the HA backup + +The backup from 2b lands in `/home/padriano/projects/ha/config/backups/` (HA writes it inside `/config`, same disk). Copy it off to `/home/padriano/share/` so we don't only rely on a same-disk copy: + +```bash +cp /home/padriano/projects/ha/config/backups/*.tar /home/padriano/share/ha-backup-2024.5.4.tar +``` + +### 2d. Filesystem backup of the config directory + +Stop the container first to get a consistent SQLite snapshot — otherwise `home-assistant_v2.db-wal` may be mid-write and the copy may be inconsistent. + +```bash +docker compose stop homeassistant +cp -a /home/padriano/projects/ha/config /home/padriano/projects/ha/config.bak-2024.5.4 +diff -rq /home/padriano/projects/ha/config /home/padriano/projects/ha/config.bak-2024.5.4 && echo "Backup OK" || echo "Backup MISMATCH" +``` + +(The container will be restarted in step 5; you can also `docker compose up -d homeassistant` here briefly if you want HA running while you do step 3.) + +## 3. Review breaking changes + +Read the "Backward-incompatible changes" section for each monthly release between 2024.6 and 2026.5: + +- https://www.home-assistant.io/changelogs/core-2024.6/ +- https://www.home-assistant.io/changelogs/core-2024.7/ +- https://www.home-assistant.io/changelogs/core-2024.8/ +- https://www.home-assistant.io/changelogs/core-2024.9/ +- https://www.home-assistant.io/changelogs/core-2024.10/ +- https://www.home-assistant.io/changelogs/core-2024.11/ +- https://www.home-assistant.io/changelogs/core-2024.12/ +- https://www.home-assistant.io/changelogs/core-2025.1/ +- https://www.home-assistant.io/changelogs/core-2025.2/ +- https://www.home-assistant.io/changelogs/core-2025.3/ +- https://www.home-assistant.io/changelogs/core-2025.4/ +- https://www.home-assistant.io/changelogs/core-2025.5/ +- https://www.home-assistant.io/changelogs/core-2025.6/ +- https://www.home-assistant.io/changelogs/core-2025.7/ +- https://www.home-assistant.io/changelogs/core-2025.8/ +- https://www.home-assistant.io/changelogs/core-2025.9/ +- https://www.home-assistant.io/changelogs/core-2025.10/ +- https://www.home-assistant.io/changelogs/core-2025.11/ +- https://www.home-assistant.io/changelogs/core-2025.12/ +- https://www.home-assistant.io/changelogs/core-2026.1/ +- https://www.home-assistant.io/changelogs/core-2026.2/ +- https://www.home-assistant.io/changelogs/core-2026.3/ +- https://www.home-assistant.io/changelogs/core-2026.4/ +- https://www.home-assistant.io/changelogs/core-2026.5/ + +High-impact themes across this window: + +- **2024.6**: AlarmDecoder entities renamed with `alarmdecoder_` prefix; Ping integration `disconnected` → `unavailable`. +- **2024.7–2024.12**: many YAML-only integration configs removed in favor of UI config flow. +- **2025.x**: SQLAlchemy / recorder schema bumps (long first-boot migration expected); `legacy_templates` removal; tightened `http:` / `trusted_proxies` validation. +- **2026.x**: skim release notes the day of upgrade for any last-minute regressions/hotfixes. + +Grep `/home/padriano/projects/ha/config` for any deprecated YAML keys flagged by the changelogs before proceeding. + +## 4. Edit `docker-compose.yml` + +Two changes to the `homeassistant` service: + +```yaml +homeassistant: + image: homeassistant/home-assistant:2026.5.0 # was 2024.5.4 + ... + healthcheck: + test: ["CMD", "curl", "-fsSL", "http://localhost:8123/manifest.json"] # was /api/ (now requires auth) + interval: 30s + timeout: 10s + retries: 5 + start_period: 30m # was 60s — first-boot recorder schema migration can take a long time +``` + +Rationale for `start_period: 30m`: during `start_period`, failing health checks don't mark the container `unhealthy`. The first-boot recorder schema migration can run for many minutes, and a stock 60s `start_period` would flip the container to `unhealthy` mid-migration. Note this is cosmetic/observability — plain Docker does **not** kill or restart an `unhealthy`-but-running container (`restart: unless-stopped` only acts on container *exit*), and nothing here gates on HA's health (`caddy`'s `depends_on` has no `condition: service_healthy`). So the only real risk of a too-short `start_period` is a misleading `unhealthy` status and noisy monitoring during migration. 30 min gives headroom; revert to a shorter value in a follow-up once we've measured the real first-boot time. + +Validate before applying: + +```bash +cd /home/padriano/projects/composer +docker compose config +``` + +## 5. Pull and start + +```bash +cd /home/padriano/projects/composer +docker compose pull homeassistant +docker compose up -d homeassistant +``` + +`pull` only fetches the `homeassistant` image; `duckdns`, `caddy`, `forgejo`, `samba`, `timemachine` are untouched (intended). + +## 6. Verify + +- **Watch the HA log** (where migration detail actually goes — `docker compose logs` only shows stdout): + + ```bash + tail -F /home/padriano/projects/ha/config/home-assistant.log + ``` + + Look for `Database upgrade in progress`, then `Setup of domain X took …`, finally `Home Assistant initialized in …`. +- **Container health**: + + ```bash + docker inspect --format '{{.State.Health.Status}}' homeassistant + # wait until: healthy + ``` +- **Version (auth-free)**: + + ```bash + docker exec homeassistant python -c "from homeassistant.const import __version__; print(__version__)" + # expected: 2026.5.0 + ``` +- **Local HTTP**: + + ```bash + curl -fsS -o /dev/null -w "%{http_code}\n" http://localhost:8123/manifest.json + # expected: 200 + ``` +- **Reverse proxy** (validates `trusted_proxies` still works against modern HA `http:` validation): + + ```bash + curl -fsS -o /dev/null -w "%{http_code}\n" https://ha-padriano.duckdns.org + # expected: same status code as recorded in step 1 + ``` +- **UI**: open Home Assistant → **Settings → Repairs** and address any flagged migration items. + +## 7. Rollback + +**Decide which option by where the upgrade failed.** Once 2026.5.0 has booted successfully it migrates the recorder DB schema *and* `.storage/` to the new format, and HA does **not** support schema downgrade. So whether reverting the image tag alone is safe depends entirely on whether migration started — check the HA log (step 6) for `Database upgrade in progress`: + +- **Migration never started** (new container crashed/failed early, you never saw that line) → the on-disk config is untouched. Use **Option A** (revert tag only). +- **Migration started or completed** (you saw that line, or HA reached the UI) → the DB/`.storage/` are now on the new schema. **Option A will fail** — old core will refuse the newer recorder schema. Use **Option B** (restore the config backup). + +### Option A — revert image tag only (safe ONLY if migration never started) + +Edit `docker-compose.yml`: +- set `image:` back to `homeassistant/home-assistant:2024.5.4` +- revert the healthcheck `test` line to `http://localhost:8123/api/` +- revert `start_period: 60s` + +Then: + +```bash +cd /home/padriano/projects/composer +docker compose up -d homeassistant +``` + +The local `homeassistant/home-assistant:2024.5.4-rollback` tag from step 2a guarantees the exact previous image is still resolvable even if the upstream tag was repushed. + +### Option B — restore config backup (default once migration has run) + +Revert the image tag and healthcheck per Option A, then restore the pre-upgrade config so the DB/`.storage/` schema matches 2024.5.4: + +```bash +docker compose stop homeassistant +mv /home/padriano/projects/ha/config /home/padriano/projects/ha/config.failed-2026.5.0 # keep the failed state for diagnosis instead of rm -rf +cp -a /home/padriano/projects/ha/config.bak-2024.5.4 /home/padriano/projects/ha/config +docker compose up -d homeassistant +``` + +### Option C — last resort + +Restore the HA `.tar` backup (from step 2b/2c) via the HA UI recovery mode on a fresh `2024.5.4` container. + +## 8. Post-upgrade follow-up + +- Measure the actual first-boot migration time from the HA log and lower `healthcheck.start_period` back to a sensible steady-state value (e.g. `2m`) in a follow-up commit. +- Once stable for a few days, delete `/home/padriano/projects/ha/config.bak-2024.5.4` and the local `:2024.5.4-rollback` image tag (`docker rmi homeassistant/home-assistant:2024.5.4-rollback`) to reclaim disk.