feat(catalog): reload manifest overlay when a refreshed catalog changes

load_manifests() only ran at startup, so a manifest published via the
signed catalog sat dormant until the next service restart (found while
shipping the strfry manifest fixes: package.check-updates refreshed the
cache but the orchestrator kept rendering the old overlay).

- refresh_catalog now reports whether the cached bytes actually changed
  (write_cache skips identical rewrites), so unchanged hourly polls
  don't churn the manifest map.
- New ContainerOrchestrator::reload_manifests (default no-op); prod
  delegates to load_manifests — the rebuild is atomic under the state
  write lock, and the reconciler's durable user-stopped/uninstalled
  marker filters make a mid-session reload equivalent to the restart
  path that already runs on every boot.
- package.check-updates reloads on change and reports catalog_changed +
  manifests_reloaded; the hourly update-scheduler tick (and its startup
  refresh) do the same.

Tests: app_catalog 5/5 (new write_cache changed-detection test),
reconcile 16/16, knows_app 1/1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-07-09 18:54:00 -04:00
co-authored by Claude Fable 5
parent 2c46da387c
commit ceb319c292
6 changed files with 142 additions and 25 deletions
+4 -1
View File
@@ -222,7 +222,10 @@ async fn main() -> Result<()> {
)
.await
{
Ok(Ok(n)) => info!("🛰️ app-catalog refreshed before manifest load ({n} apps)"),
Ok(Ok(r)) => info!(
"🛰️ app-catalog refreshed before manifest load ({} apps)",
r.apps
),
Ok(Err(e)) => tracing::debug!("app-catalog pre-load refresh failed (using cache): {e}"),
Err(_) => tracing::debug!("app-catalog pre-load refresh timed out (using cache)"),
}