pgedge 2.0.1 — workload-list broke replication and backups - #511
Merged
Conversation
…ions lied Two defects in 2.0.0, both found by OTHER templates' rounds in the same batch. 1. `workload-list` did not include this release's own workloads. The internal firewall list governs intra-release traffic too, and pgEdge nodes replicate to each other with Spock ACROSS locations while pgcat connects to every node -- so a list naming only clients denies replication and the mesh silently diverges. Confirmed live in etcd-multi-location (quorum lost cluster-wide) and clickhouse (Raft denied, `Code: 279` on every cross-shard query) on 2026-08-27; both reported every replica `ready=true restarts=0` throughout, and both were reached by following the template's own README. A catalog audit found 74 templates expose `workload-list` and only 6 include their own workloads. pgedge is the one already merged, which is why it goes first. 2. The backup cron sent a PARTIAL `localOptions` (location + suspend). The API backfills a partial block with its OWN platform defaults rather than with the workload's defaultOptions -- measured on cockroach 2026-08-27, where two fields were stored as seven, turning `capacityAI` ON in the one location the cron actually runs and cutting timeoutSeconds to 5. The chart sets `capacityAI: false`, so the stored config contradicted the chart's intent. Every field defaultOptions carries is now repeated. Verified across five render controls: the default render is byte-identical to 2.0.0 apart from version strings; the cron's block is complete; workload-list puts both own workloads ahead of the client on both workloads; no duplicates when the user names them too; and the non-list arm is untouched. Neither fix is live-tested yet -- both need a round with an enforcement control (listed client works, unlisted client does not), since a render cannot show whether peers actually traverse the firewall. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
My own fix was incomplete. It added the pgedge and pgcat workloads to the list and stopped there, but the backup cron connects DIRECTLY to replica-0 of the pgedge workload (PG_HOST), so it is a third own-workload the list must allow. Measured 2026-08-28 while finishing the round by hand: from the moment the release moved to `workload-list`, EVERY scheduled backup failed -- pg_dumpall: error: connection to server at "replica-0.test-pge-pgedge.aws-us-east-1.test-gvc-2.cpln.local" (240.240.1.163), port 5432 failed: server closed the connection unexpectedly -- on all ten runs from 06:25 to 07:10, against zero such errors on the runs before the change. The cron is now added when `backup.enabled`, and left out when it is not, so the list never names a workload that does not exist. Worth recording as a lesson about the fix, not just the bug: I generalised "add the release's own workloads" from two templates whose peers were obvious, and missed a third workload whose traffic is equally intra-release. The audit that found this class should be read as "enumerate every workload in the release that talks to another", not "add the two obvious ones". Separately, and NOT fixed here: the backup image uploaded a 20-byte object -- an empty gzip decompressing to zero bytes -- for each failed run. That is ghcr.io/controlplane-com/backup-images/postgres-backup:17.1.0, not this chart, and it affects every template using it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review diff:
git diff 1930167..HEAD -- pgedge/versions/2.0.1/(
1930167is the verbatimcp -Rof 2.0.0; everything real is in the two commits after it.)A patch to the merged 2.0.0. Both defects were found by other templates' rounds, not by testing pgedge — neither would have surfaced from pgedge alone.
1.
workload-listcut the release off from itself2.0.0 rendered the user's list verbatim on both workloads. That list governs intra-release traffic, and pgEdge nodes replicate to each other with Spock across locations while pgcat connects to every node — so a list naming only clients breaks the mesh. Confirmed live in
etcd-multi-location(quorum lost cluster-wide) andclickhouse(Raft denied,Code: 279on every cross-shard query), both reported every replicaready=truethroughout, and both reached by following the template's own README.A catalog audit found 74 templates expose
workload-listand only 6 include their own workloads. pgedge was the one already merged.The failure mode here is nastier than in the other two. It is not a cluster that goes down — it is nodes that keep accepting writes which silently never propagate. So the test proves replication, not liveness: all-to-all row-level replication with each node holding all 3 rows, all 6 Spock subscriptions
replicating, all 6 slotsactive=true lag=0.2. The backup cron was a third own-workload I initially missed
The first fix added pgedge and pgcat and stopped there. The cron connects directly to
replica-0.{pgedge}.{location}.{gvc}.cpln.local:5432, so from the moment a release moved toworkload-list, every scheduled backup failed:Ten consecutive runs, against zero such errors before the change. Now added when
backup.enabled, and left out when it is not, so the list never names a workload that does not exist.Verified as a real backup, not a job that ran. The failing runs uploaded a 20-byte gzip decompressing to zero bytes, so "completed" and "backed something up" are different claims:
…T14-20-10Z…T14-25-07Z…T14-30-06ZA row written after the firewall change appears only in the post-change dumps — so those are provably fresh reads through the newly-allowed path, and the pre-change dump missing it is the control proving the check discriminates.
3. The backup cron's partial
localOptionscontradicted the chart2.0.0 sent
location+suspendonly. The API backfills a partial block with platform defaults rather than the workload'sdefaultOptions— measured oncockroach, where two fields became seven, turningcapacityAIon in the one location the cron runs and cuttingtimeoutSecondsto 5, both against the chart's explicit settings. Every field is now repeated; the stored spec matches the render in all three locations, and three healthy backups confirm a complete block did not break the schedule.Testing
Two rounds, 0 FAIL. Enforcement control with both arms: listed client → pgcat returns 1 byte and
rows=10over real psql; unlisted client → 0 bytes andserver closed the connection unexpectedly; a dead port returns 0 in every case, so the probe can produce a negative. Log greps were proven to find this workload's own lines before any zero was trusted (36/36 lines correctly labelled).Drift gate: both no-op upgrades reported all 8 resources
Unchangedwith stored specs diffing to 0 lines. The stored list is fully qualified and alphabetically re-sorted versus the render, causing no churn — the fourth template to confirm that.Open question, not introduced here
Turning
backup.enabledoff leaves the stored identity holding itsaws:block (cloudAccountLink,policyRefs) even though the chart renders noaws:key at all. That is the documented catalog-wide platform merge behaviour (CLAUDE.md, 2026-08-21) and affects every backup-capable template — but it is a least-privilege leak invisible from the user's values file, so it may deserve its own issue.Briefing updated in the same PR.
🤖 Generated with Claude Code