Skip to content

fix: postgres pitr hardening — HA restore guard, pure JSON stdout, testable watch timeout - #1058

Merged
paulocsanz merged 3 commits into
masterfrom
pcs/pg-mgmt-e2e-hardening
Aug 8, 2026
Merged

fix: postgres pitr hardening — HA restore guard, pure JSON stdout, testable watch timeout#1058
paulocsanz merged 3 commits into
masterfrom
pcs/pg-mgmt-e2e-hardening

Conversation

@paulocsanz

Copy link
Copy Markdown
Collaborator

Follow-ups from the adversarial review + e2e coverage audit of the railway postgres stack (#1052#1055).

What

  • pitr backup restore refuses HA clusters. An in-place restore replaces only the root's volume; replicas would rejoin with newer, diverged timelines. The CLI cannot reseed replicas (that path is dashboard-only for now), so it bails with a pointer to the dashboard.
  • pitr enable --json keeps stdout pure JSON when the service is already enabled — the human-readable note goes to stderr, so --json | jq works on every path.
  • Debug-only env overrides RAILWAY_POSTGRES_WATCH_TIMEOUT_SECS / RAILWAY_POSTGRES_POLL_INTERVAL_SECS (compiled out of release builds, same pattern as RAILWAY_BACKBOARD_URL) so the e2e harness can exercise the progress --watch timeout branch in seconds instead of 10 minutes.
  • schema.json regenerated from the Public subgraph after railwayapp/mono#34881 exposed replicaServiceIds/wipeServiceIds on volumeInstanceBackupRestore. Semantic diff verified: those two args are the only structural change (the rest of the 36k-line diff is generated-file reflow).

Tests

  • 926/926 unit tests pass, cargo fmt --check clean.
  • Hermetic mock e2e flows covering the new guard/branches land in the harness alongside this PR.

…estable watch timeout

- `pitr backup restore` now refuses HA clusters: an in-place restore only
  replaces the root volume, leaving replicas diverged; the dashboard
  reseeds replicas as part of the same operation.
- `pitr enable --json` on an already-enabled service kept stdout pure
  JSON (the human note moves to stderr).
- Debug-build-only RAILWAY_POSTGRES_{WATCH_TIMEOUT,POLL_INTERVAL}_SECS
  env overrides so the e2e harness can exercise the progress --watch
  timeout branch in seconds (same pattern as RAILWAY_BACKBOARD_URL).
- schema.json regenerated from the Public subgraph post-mono exposure of
  volumeInstanceBackupRestore's replicaServiceIds/wipeServiceIds; the
  only structural change is those two args (rest is generated-file
  reflow).
…it the staged swap, deploy

The server-side createVolumeFromSnapshot workflow copies the backup into a
fresh volume and then only STAGES the volume swap; the dashboard has the
user apply staged changes as a second step. The CLI previously reported
"running in the background" and returned, leaving the service on the old
volume indefinitely (caught by the new in-place-restore e2e step: the
post-backup marker never disappeared).

Now: warn about pre-existing staged changes up front, wait for the copy
(30-min budget via wait_for_workflow_up_to -- the copy scales with volume
size), then commit + deploy, reporting "Restored ... and deployed".
@paulocsanz

Copy link
Copy Markdown
Collaborator Author

Added a third fix the new e2e step caught live: pitr backup restore only started the server-side copy — the volume swap stays as staged changes (dashboard flow applies them manually), so the CLI restore never actually took effect. The verb now waits for the copy, commits the staged swap (with the pre-existing-staged-changes warning), and deploys — "Restored … and deployed", consistent with the other verbs.

An auth refusal on workflowStatus is deterministic (e.g. a workflow type
that doesn't register the queries the resolver authorizes against) --
retrying can't heal it. Previously the poll silently retried its whole
budget (30 min for backup restore). Surface it immediately with a note
that the workflow keeps running server-side.

Companion to railwayapp/mono#34897, which registers the auth query
handlers on createVolumeFromSnapshot itself.
@paulocsanz paulocsanz added the release/minor Author minor release label Aug 8, 2026
@paulocsanz
paulocsanz merged commit fc0331d into master Aug 8, 2026
7 of 8 checks passed
@paulocsanz
paulocsanz deleted the pcs/pg-mgmt-e2e-hardening branch August 8, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release/minor Author minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant