fix(btcpay): declare btcpay-db-password; stop reconcile failing on absent apps #166

Closed
ssmithx wants to merge 0 commits from fix/btcpay-db-password into main
Collaborator

Problem

On a node where btcpay is not installed, every ~50s reconcile pass logged:

reconcile failed app_id=archy-btcpay-db error=resolving secret_env ...: required secret 'btcpay-db-password' is missing

(and the same for archy-nbxplorer and btcpay-server). reconcile pass completed with failures ok=67 failed=3.

There are two causes:

  1. Nothing declares the secret. All three btcpay manifests read btcpay-db-password via secret_env, but none lists it in generated_secrets. Only the legacy stacks.rs installer (read_or_generate_secret) creates it.
  2. Boot reconcile resolves env for catalog-only apps. ensure_running_with_mode ran resolve_dynamic_env before checking whether the app has a container, so an uninstalled app's missing secret counted as a reconcile failure. Each failing pass also holds the app-lifecycle lock longer, which makes the user-click refusals fixed in #165 more likely.

Fix

  • fix(reconcile): in ExistingOnly mode, if env resolution fails for a non-baseline app that has no container and no quadlet unit, report Left("absent"), which is what the container check returns anyway. Installed apps still fail loudly.
  • fix(btcpay): declare btcpay-db-password (hex32) in generated_secrets on all three members. Generation is idempotent, so a node with an existing readable password keeps it and running btcpay databases are unaffected.

Catalog

The signed catalog overrides disk manifests, so the manifest commit takes effect for catalog-covered nodes only after the catalog is regenerated and re-signed (offline signing). The reconcile commit fixes the log noise on its own.

Tests

  • New: reconcile_existing_leaves_absent_app_with_unresolvable_secret_alone.
  • all_shipped_manifests_parse and catalog_overlay_accepts_all_real_image_manifests pass.
  • prod_orchestrator: 108 pass. The 6 failures also fail on unmodified main (7 there); they need scripts/test-backend-isolated.sh.

Verified on a real node without btcpay installed: before, every pass logged failed=3; after the deploy, passes ran with no failures, and installed apps were unaffected.

🤖 Generated with Claude Code

## Problem On a node where btcpay is **not installed**, every ~50s reconcile pass logged: ``` reconcile failed app_id=archy-btcpay-db error=resolving secret_env ...: required secret 'btcpay-db-password' is missing ``` (and the same for `archy-nbxplorer` and `btcpay-server`). `reconcile pass completed with failures ok=67 failed=3`. There are two causes: 1. **Nothing declares the secret.** All three btcpay manifests read `btcpay-db-password` via `secret_env`, but none lists it in `generated_secrets`. Only the legacy `stacks.rs` installer (`read_or_generate_secret`) creates it. 2. **Boot reconcile resolves env for catalog-only apps.** `ensure_running_with_mode` ran `resolve_dynamic_env` before checking whether the app has a container, so an uninstalled app's missing secret counted as a reconcile failure. Each failing pass also holds the app-lifecycle lock longer, which makes the user-click refusals fixed in #165 more likely. ## Fix - `fix(reconcile)`: in `ExistingOnly` mode, if env resolution fails for a non-baseline app that has no container and no quadlet unit, report `Left("absent")`, which is what the container check returns anyway. Installed apps still fail loudly. - `fix(btcpay)`: declare `btcpay-db-password` (`hex32`) in `generated_secrets` on all three members. Generation is idempotent, so a node with an existing readable password keeps it and running btcpay databases are unaffected. ## Catalog The signed catalog overrides disk manifests, so the manifest commit takes effect for catalog-covered nodes only after the catalog is regenerated and re-signed (offline signing). The reconcile commit fixes the log noise on its own. ## Tests - New: `reconcile_existing_leaves_absent_app_with_unresolvable_secret_alone`. - `all_shipped_manifests_parse` and `catalog_overlay_accepts_all_real_image_manifests` pass. - prod_orchestrator: 108 pass. The 6 failures also fail on unmodified `main` (7 there); they need `scripts/test-backend-isolated.sh`. Verified on a real node without btcpay installed: before, every pass logged `failed=3`; after the deploy, passes ran with no failures, and installed apps were unaffected. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ssmithx added 2 commits 2026-10-24 12:21:30 +00:00
Boot reconcile resolved every catalog manifest's env, secrets included,
before checking whether the app had a container. An uninstalled app
whose secret is only created at install time (btcpay's
btcpay-db-password) therefore failed every ~50s pass, logging three
errors and lengthening the lifecycle-lock hold that blocks user clicks.

In ExistingOnly mode, a resolve failure for a non-baseline app with no
container and no quadlet unit is now reported as Left("absent"), which
is what the container check would have returned anyway. Installed apps
still fail loudly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All three btcpay members read btcpay-db-password via secret_env, but no
manifest declared it, so only the legacy stacks.rs installer ever
created it. An orchestrator install or reconcile on a node that never
ran that path failed with "required secret 'btcpay-db-password' is
missing".

Declare it (hex32) on each member. Generation is idempotent: a node with
an existing readable password keeps it, so running btcpay databases are
unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator

Reconciled against canonical ngit review: fix(btcpay): declare btcpay-db-password; stop reconcile failing on absent apps is applied.

This PR's exact head b7a20c4ed85124e4b18847a990b775c88f337e85 is already an ancestor of accepted main 1a4ea15df9c8800b6d288277d2839c7b93662ff7, which matches on ngit and Gitea. The existing review fixes and commit history are preserved.

Closing the redundant Gitea PR record because its contribution has already been integrated through ngit. No second merge or history rewrite is being performed. Artifact publication and installed-device acceptance remain separate from this source-review disposition.

Reconciled against canonical ngit review: [fix(btcpay): declare btcpay-db-password; stop reconcile failing on absent apps](https://gitworkshop.dev/nevent1qqs20cv9fn579scahnclqetrhppt5gz6v8ah2mm60vxc5ucw3tj0gncpz3mhxue69uhhyetvv9ujumn8d96zuer9wc0h68nq) is **applied**. This PR's exact head `b7a20c4ed85124e4b18847a990b775c88f337e85` is already an ancestor of accepted main `1a4ea15df9c8800b6d288277d2839c7b93662ff7`, which matches on ngit and Gitea. The existing review fixes and commit history are preserved. Closing the redundant Gitea PR record because its contribution has already been integrated through ngit. No second merge or history rewrite is being performed. Artifact publication and installed-device acceptance remain separate from this source-review disposition.
chaum closed this pull request 2026-11-09 12:31:29 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.