Skip to content

Treat a ClusterConnection without status or with a stale status as not ready - #100

Merged
ThoSap merged 1 commit into
mainfrom
fix-cluster-connection-without-status
Oct 25, 2026
Merged

ThoSap merged 1 commit into
mainfrom
fix-cluster-connection-without-status

Conversation

@ThoSap

@ThoSap ThoSap commented Oct 25, 2026

Copy link
Copy Markdown
Member

Fixes #98

BaseReconciler.getReferencedClusterConnection read the phase of the referenced ClusterConnection without two checks:

  1. No null check for the status. Before the first reconcile of a ClusterConnection, its status is null, and getStatus().getPhase() threw a NullPointerException. All ten callers (reconcile and cleanup of Database, Schema, Role, Grant and DefaultPrivilege) call the method before their try block, so handleError did not run and no status was written.
  2. No generation check. A READY of an older generation also counted. After a change of the ClusterConnection spec, a dependent resource used the new spec before the ClusterConnection reconciler had probed it.

What changed

  1. Two more checks, each with a WARN line. The method returns empty when the status is null ("has not been probed yet"), and when status.observedGeneration differs from metadata.generation ("changed and has not been probed again yet"). The "not ready yet" line now also shows status.phase. This is the same fix as in the Garage Operator (aboutbits/garage-operator@c25e3bb, aboutbits/garage-operator@66ff039).
  2. Javadoc. It names all cases with an empty result: the ClusterConnection does not exist, is not READY, or is READY for an older generation. Callers treat this as "not yet", not "broken", and try again after 60 seconds.
  3. New BaseReconcilerTest. A unit test with the fabric8 mock server covers all five cases: missing, no status, not READY, READY for an older generation, and READY for the current generation.
  4. The test data creator waits for the current generation. ClusterConnectionCreate now waits until status.observedGeneration equals metadata.generation, not only until a status exists. The Grant and DefaultPrivilege creators apply the same ClusterConnection several times with a new spec, so without this wait the new check made them wait for the 60 second retry.

Consequences

  • A resource that is applied together with its ClusterConnection, for example in one Helm release, can now wait 60 seconds for its first successful reconcile. Before, the NullPointerException started the JOSDK retry, which came after 2 seconds, but which stopped after 5 attempts. The retry now has no attempt limit.
  • After a change of the ClusterConnection spec, its dependent resources report PENDING until the ClusterConnection reconciler has probed the new spec. They do not watch the ClusterConnection, so they find out at their next retry, up to 60 seconds later.

Checks that CI cannot do

  • Without the fix, the new unit test fails in two cases: the ClusterConnection without status throws the NullPointerException, and the READY of an older generation is returned.
  • The fabric8 mock server sets metadata.generation to 1 on create and keeps the status, because no CRD with a status subresource is registered. The unit test checks this in each case that creates a ClusterConnection, so it cannot pass for the wrong reason.

Other changes

…t ready

Before, a missing status threw a NullPointerException outside the try
block of each caller, so no status was written. A READY of an older
generation also counted, although it says nothing about the new spec.

Assisted-by: Claude:claude-opus-5-5
@ThoSap ThoSap self-assigned this Oct 25, 2026
@ThoSap
ThoSap merged commit 6b68f09 into main Oct 25, 2026
4 checks passed
@ThoSap
ThoSap deleted the fix-cluster-connection-without-status branch October 25, 2026 17:47
@ThoSap ThoSap added the bug Something isn't working label Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

getReferencedClusterConnection throws a NullPointerException for a ClusterConnection without status and ignores its generation

1 participant