Skip to content

feat: fail-fast preflight for extension update paths (+ e2e for >1-minor jumps and migration failure) #448

Description

@WentingWu666666

Context

Follow-up to #439, which tracked the schema-upgrade e2e gaps left open by #426.

#443 landed the test-only gaps that needed no operator change (schemaVersion: "auto", rollback within the safe window, multi-instance/HA rollout ordering, unpullable documentDBVersion). The remaining gaps from #439 were explicitly deferred because they all depend on one unmade decision: the operator has no update-path validation at all today. It runs a blanket ALTER EXTENSION documentdb UPDATE and relies entirely on PostgreSQL to resolve the path. Writing e2e tests for the failure modes first would just pin in whatever behavior falls out of that, so the contract needs to be ratified before the tests are meaningful.

This issue carries the design decision plus the work and tests that follow from it. Full write-up in this comment on #439.

Decision needed from maintainers

  1. Confirm multi-minor jumps are a supported path, not rejected. The documentdb extension ships minors roughly monthly, at times bi-weekly. A user upgrading quarterly is already 3+ minors behind; twice-a-year is 6+. Adjacent-only (N → N+1) upgrades would mean 3–12 sequential rolling restarts to catch up, which in practice pushes users to never upgrade.
  2. Confirm the fail-fast contract: block + surface a status condition when no update path exists, rather than firing ALTER EXTENSION and surfacing the raw PG error.
  3. Confirm placement: controller only, or also a static check in the validating webhook. The path check needs DB connectivity, so the controller (which already holds a SQL executor and cluster handle) is the pragmatic home; only cheap static parts could move to the webhook.

The risk being managed

A jump only works if the extension ships a continuous chain of documentdb--A--B.sql update scripts. If any release omits its script, ALTER EXTENSION UPDATE fails at execution time with a raw PG error (extension has no update path from X to Y), re-fires every reconcile, and the user gets a cryptic failure with no actionable status.

Proposed implementation

PostgreSQL exposes the update-path graph read-only:

SELECT path FROM pg_extension_update_paths('documentdb')
WHERE source = '0.109-0' AND target = '0.113-0';
  • Path resolvable → non-NULL arrow-joined sequence.
  • No path → path IS NULL → fail-fast signal.

Hook this into documentdb_controller.go immediately before the SQLExecutor(... updateSQL) call. If no path exists: skip ALTER EXTENSION, emit a Warning event plus a SchemaUpgradeBlocked status condition (reason NoUpdatePath) naming the exact gap, and return cleanly without a crash-loop.

Today With preflight
When failure is learned After firing ALTER EXTENSION Before touching schema
Error quality Raw PG error in logs Actionable status condition + event
Visibility Operator logs only status.conditions on the CR
Loop behavior Errors every reconcile Clean stop

Scope

Acceptance

The preflight is implemented and the three deferred e2e gaps from #439 are covered with appropriate labels/levels, or re-deferred with a documented rationale.

Follow-up to #439. Original coverage work in #426 and #443.

Metadata

Metadata

Labels

enhancementNew feature or requestgoPull requests that update go codetest

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions