Skip to content

Own the pre-check failure shape: owner Ready condition plus watched or unwatched requeue #209

Description

@sourcehawk

Problem

ocf has no owner-level failure concept. Prerequisite is per component and only knows DependsOn(ConditionType); Guardable blocks a single resource and reports inside a component condition. Neither can say: the owner's spec does not resolve, report the reason on the owner's Ready condition, and here is whether a watch will wake the reconcile or a timer must.

konsole-is/camunda-operator filled the gap with a shadow package, pkg/conditions: PreCheckFailure, Stage, Failed, Aggregate, BoundMessage, and UnwatchedPreCheckFailure. Nine controllers construct PreCheckFailure. The handling block is copy-pasted near verbatim in at least three (internal/controller/camundacluster/controller.go, internal/controller/elasticsearchcluster/controller.go, internal/controller/databaseserver/controller.go): errors.As for the failure, stage it on Ready, errors.As again for the unwatched variant, then either return bare (a watch will fire) or RequeueAfter a retry interval. The retry interval knob itself is duplicated five times as a default constant, an exported override field and a two-line getter (camundacluster, elasticsearchcluster, logicalbackupelasticsearch, pointintimerestore, database).

The genuinely reusable insight is the watched or unwatched distinction driving the requeue decision. The rest is boilerplate that every new controller re-types.

Approach

A component.PreCheck (or precheck) surface: a Failure{Reason, Message, Watched bool} type, a StageFailure(owner, failure) that writes the owner Ready condition with observedGeneration, and a Result() that yields an empty ctrl.Result for watched failures and RequeueAfter: cfg.RetryInterval for unwatched ones, with the interval configured once on the ReconcileContext instead of once per controller.

The consumer keeps deciding what fails and why; the framework owns the staging, the aggregation with component conditions, and the requeue policy.

Verification

  • pkg/conditions in konsole-is/camunda-operator can be deleted and its nine constructor call sites ported with no behavior change in the staged conditions.
  • The three verbatim handler blocks reduce to one framework call each.
  • The five per-controller retry interval knobs collapse into the ReconcileContext configuration.
  • A test covers: watched failure returns no requeue, unwatched failure returns the configured interval, and a failure staged on Ready carries the owner's current generation.

Context

Found while auditing konsole-is/camunda-operator for repeated hand-rolled patterns. Composes with the detached suspension issue: fail the pre-check through this surface, then suspend the managed workloads through that one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

featureUser-observable capability or surface

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions