fix(woodpecker): set database/owner on the wp-pg recovery bootstrap
Addresses the second blocking review finding on #504. bootstrap.recovery set only `source`. The live CRD documents the defaults: `database` defaults to `app`, and `owner` defaults to whatever `database` is. Neither name exists in the physically restored data, which carries woodpecker/woodpecker from the backup. So CNPG would have restored the real data, then provisioned a separate empty `app` database and pointed the generated wp-pg-app Secret and the -app Service at that instead — a cluster reporting healthy, holding the right bytes, with the credentials aimed at the wrong database. The runbook's own verification (psql -U woodpecker -d woodpecker using the wp-pg-app password) would not have authenticated, so the failure would have surfaced as a confusing auth error rather than as what it was. kubernetes/RECOVERY.md sets both fields on all three recovery examples it documents (ak-pg, im-pg, pprl-pg) for exactly this reason; this one did not follow the pattern. Added a runbook step to read dbname/username back out of the wp-pg-app Secret before the row-count checks, so the mismatch is caught directly rather than inferred from a psql failure. Co-Authored-By: Claude Bot <claude-bot@renner.uno>
This commit is contained in:
@@ -98,8 +98,19 @@ logs carry the reason:
|
||||
kubectl -n woodpecker logs -l cnpg.io/jobRole=full-recovery --tail=100
|
||||
```
|
||||
|
||||
**Confirm the restore actually holds Woodpecker's data** — a cluster that comes
|
||||
up healthy but empty is the failure mode worth catching:
|
||||
**First check the generated app credentials target the right database.** CNPG
|
||||
defaults `bootstrap.recovery.database` to `app`; the restored data uses
|
||||
`woodpecker`. If this reads anything but `woodpecker`, the cluster has
|
||||
provisioned an empty `app` database and the real data is unreachable through
|
||||
the `-app` Secret and Service:
|
||||
|
||||
```sh
|
||||
kubectl -n woodpecker get secret wp-pg-app -o jsonpath='{.data.dbname}' | base64 -d; echo
|
||||
kubectl -n woodpecker get secret wp-pg-app -o jsonpath='{.data.username}' | base64 -d; echo
|
||||
```
|
||||
|
||||
**Then confirm the restore actually holds Woodpecker's data** — a cluster that
|
||||
comes up healthy but empty is the failure mode worth catching:
|
||||
|
||||
```sh
|
||||
PGPASS=$(kubectl -n woodpecker get secret wp-pg-app -o jsonpath='{.data.password}' | base64 -d)
|
||||
|
||||
@@ -33,6 +33,15 @@ spec:
|
||||
bootstrap:
|
||||
recovery:
|
||||
source: wp-pg-apps
|
||||
# Must mirror the initdb values of the cluster this restores from
|
||||
# (apps/wp-pg: database woodpecker, owner woodpecker). CNPG defaults
|
||||
# `database` to `app` and `owner` to whatever `database` is, and those
|
||||
# names do not exist in the physically restored data — it would provision
|
||||
# an empty `app` database, point the generated wp-pg-app Secret and the
|
||||
# -app Service at it, and leave the real data unreachable through them.
|
||||
# Same pattern as every recovery example in kubernetes/RECOVERY.md.
|
||||
database: woodpecker
|
||||
owner: woodpecker
|
||||
externalClusters:
|
||||
- name: wp-pg-apps
|
||||
plugin:
|
||||
|
||||
Reference in New Issue
Block a user