Fresh-install + upgrade-path hardening bundle

Six independent fixes surfaced during the v2.9.1 → v2.9.2 admin-UI
upgrade validation today. Together they make a clean install on a new
box work end-to-end without in-session patching.

- Fix 1: scripts/validate-compose-parity.sh + build-release.sh hook —
  fail release builds when api/admin/media-api/nginx healthcheck
  blocks drift between docker-compose.yml and docker-compose.prod.yml.
  Previous boot-race fix had to be applied to both files manually.

- Fix 2: scripts/systemd/install.sh chowns logs/ to the install user
  (the API container creates subdirs there as root, locking the
  host-side watcher out), pre-creates logs/upgrade-watcher.log, and
  changemaker-upgrade.service adds StartLimitIntervalSec=0 so a
  single transient failure can't wedge the .path unit permanently.

- Fix 3: /api/upgrade/status now returns a `watcher` sub-object that
  flags the host systemd watcher as stalled when trigger.json has
  been pending >30s. Admin SettingsPage SystemUpgradeTab renders a
  warning Alert with the systemctl recovery command when unhealthy.

- Fix 4: scripts/upgrade.sh write_result() — prefer head -1 VERSION
  over `git rev-parse HEAD` so release-mode upgrades report the new
  tag in result.json instead of "unknown".

- Fix 5: admin container healthcheck start_period 20s → 60s in both
  compose files, same class as the earlier api fix. Matches Gancio
  convention.

- Fix 7: /api/pangolin/sync now detects resources bound to a stale
  siteId (common after --pangolin-site new rotations), deletes and
  recreates them against the current site, and reports them under
  a new `reassigned` response field.

Bunker Admin
This commit is contained in:
2026-04-15 11:57:50 -06:00
parent 5115c65691
commit 23df6a8b52
12 changed files with 223 additions and 39 deletions

View File

@@ -1,6 +1,7 @@
[Unit]
Description=Changemaker Lite upgrade dispatcher
Documentation=https://docs.cmlite.org/docs/admin/services/
StartLimitIntervalSec=0
[Service]
Type=oneshot

View File

@@ -28,6 +28,14 @@ for unit in "${SCRIPT_DIR}"/changemaker-upgrade.*; do
echo " Installed ${filename}"
done
# Ensure logs/ is writable by the install user. The API container creates
# subdirs here as root, which locks out the host-side upgrade-watcher service.
mkdir -p "${PROJECT_DIR}/logs"
chown "${INSTALL_USER}:${INSTALL_USER}" "${PROJECT_DIR}/logs"
touch "${PROJECT_DIR}/logs/upgrade-watcher.log"
chown "${INSTALL_USER}:${INSTALL_USER}" "${PROJECT_DIR}/logs/upgrade-watcher.log"
echo " Prepared ${PROJECT_DIR}/logs (owned by ${INSTALL_USER})"
systemctl daemon-reload
systemctl enable --now changemaker-upgrade.path