# Pi-Kit Updater Plan ## Goals - Add seamless in-dashboard updates for Pi-Kit assets (web UI, api script, helper scripts). - Allow manual check/apply + rollback; optional daily auto-check with a status chip. - Use release tarballs (not git clones) from Gitea; verify hashes; stage before swap; keep one backup. - Keep UX friendly: clear progress, errors, and “update available” indicator. ## Release Format (Gitea) - Release asset: `pikit-.tar.gz` containing: - `pikit-web/` (built assets only, no node_modules) - `pikit-api.py` - helper scripts/configs that should overwrite - `manifest.json` (see below) - `manifest.json` fields: - `version` (string) - `changelog` (url) - `files`: array of { `path`, `sha256`, `mode`? } - `post_install` (optional array of commands or service restarts) - Optional: detached signature in future (ed25519), not in v1. ## On-device Updater (Python helper) - Location: `/usr/local/bin/pikit-updater.py` (invoked by API and timer). - State file: `/var/lib/pikit-update/state.json` (latest, current, last_check, last_result, progress, backup_path). - Steps for apply: 1) Fetch manifest (HTTP GET release URL). 2) Download tarball to `/var/tmp/pikit-update//bundle.tar.gz`. 3) Verify SHA256 against manifest. 4) Unpack to staging dir. 5) Backup current managed files to `/var/backups/pikit//` (keep 1 latest). 6) Rsync staged files to destinations: - `/var/www/pikit-web/` (built assets) - `/usr/local/bin/pikit-api.py` 7) Restart services: `dietpi-dashboard-frontend`, api service (if exists), maybe nginx reload. 8) Update state; mark current version file `/etc/pikit/version`. - Rollback: restore latest backup and restart services. - Concurrency: use lockfile in `/var/run/pikit-update.lock`. ## API additions (pikit-api.py) - `GET /api/update/status` -> returns state.json contents + current version. - `POST /api/update/check` -> fetch manifest only, update state. - `POST /api/update/apply` -> spawn updater apply (can run inline for v1) and stream status. - `POST /api/update/rollback` -> restore last backup. - `POST /api/update/auto` -> enable/disable daily timer. ## Timer - systemd timer: `pikit-update.timer/service` running check daily (e.g., 04:20). - Writes last_check and latest_version to state. ## UI changes (pikit-web) - Top-bar chip: “Updates: Up to date / Update available / Checking…”. - New “Updates” modal (not the OS auto-updates) for Pi-Kit releases: - Show current vs latest version, changelog link. - Buttons: Check, Download & Install, Rollback, View logs. - Progress states + errors. - Hook into existing status refresh: call `/api/update/status`. ## Safety / Edge - Preflight disk space check before download. - Handle offline: clear message. - If apply fails, auto rollback. - Skip overwriting user-edited config? For v1 assume assets/api are managed; nginx site left unchanged. ## Implementation steps 1) Add current version markers (maybe file in repo, read by UI). 2) Implement updater helper script with check/apply/rollback + state. 3) Add systemd service/timer units template (install script TBD, for now keep files in repo). 4) Extend `pikit-api.py` with new endpoints calling updater functions. 5) Extend UI (status chip + modal) and wire to API. 6) Add mock responses for dev (mock-update-status.json). 7) Test locally (mock) and on device (manual apply pointing to a dummy URL or skip download logic for now). ## Open questions / assumptions - Release hosting: use Gitea releases at `https://git.44r0n.cc/44r0n7/pi-kit/releases/latest` (JSON API? or static URLs). For v1, hardcode base URL env var or config. - Services to restart: assume `dietpi-dashboard-frontend` and `pikit-api` (if we add a service file). Need to verify actual service names on device. - Device perms: updater runs as root (via sudo from API). Ensure API endpoint requires auth (existing login).