fix(lifecycle): resurrect fully-stopped stacks member-by-member (quadlet)

Second instance of the stop→start destruction class from tonight's gate
runs (.228): package.stop of a multi-container stack marks every member
user-stopped and quadlet-removes their containers; package.start's fallback
then resurrected only the bare package id, leaving the other members absent
AND user-stopped — indeedhub lost all 7 containers this way (mempool needed
its umbrella alias for the same reason).

- New stack_member_app_ids map (real manifest app ids, dependency order) —
  used by the start fallback when a stack has no live containers, and by
  package.restart instead of hard-failing "No containers found".
- orchestrator_uninstall_app_ids grows the missing indeedhub arm (same
  reconciler-ghost rationale as the immich arm).
- do_orchestrator_package_start no longer aborts the whole sequence when one
  member's unknown-app-id fallback fails (the #73/#74 wish) — collects and
  continues.

NOTE: extends the known §G per-app-map debt (tracker updated) — the proper
home for stack membership is a manifest field; parked post-tag by design.

Tests: package:: 48/48 incl. new fallback + indeedhub-uninstall coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-07-08 21:22:40 -04:00
co-authored by Claude Fable 5
parent e719c55fea
commit 922b79bf95
3 changed files with 123 additions and 11 deletions
+3 -1
View File
@@ -306,7 +306,9 @@ media (latest artifact only one minor behind).
`prod_orchestrator.rs:54-83` baseline/restart-sensitive lists). Move `baseline`,
`restart_sensitive`, `stack_members`, `multi_container` into the manifest schema; collapse
the five near-identical `install_*_stack()` wrappers into one generic call. **Biggest
maintainability win.**
maintainability win.** (Grew again 2026-07-09: `stack_member_app_ids` in
`package/dependencies.rs` — the quadlet stack-resurrection fallback — is a fifth
per-app map that must fold into the same manifest field.)
- [ ] 🟢 **Route all podman/systemctl through `podman_client`.** 113 raw `Command::new("podman")`
+ 32 `systemctl` calls bypass the existing 952-LOC wrapper → untestable + the blocking-call
risk (§C). Consolidating also unlocks unit tests for the thinly-tested `package/` handlers