Status Detection
Component-operator needs to determine whether each dependent object has reached a ready state before proceeding to the next apply wave or completing the component reconciliation. The readiness check is based on the kstatus library, with additional tuning capabilities.
How kstatus Works
For most resources, vanilla kstatus uses the following algorithm to determine if a Kubernetes object is ready (a special logic applies for some builtin types):
Step 1 — observedGeneration check:
Does the object have status.observedGeneration?
→ Yes: Does status.observedGeneration equal metadata.generation?
→ Yes: proceed to readyCondition check
→ No: object is NOT ready (generation mismatch)
→ No: proceed to readyCondition check
Step 2 — readyCondition check:
Does the object have status.conditions[type == "Ready"]?
→ Yes: Is condition.status == "True"?
→ Yes: object is READY
→ No (False or Unknown): object is NOT ready
→ No: object is READY (absence of a Ready condition means "implicitly ready")
This logic works well for controllers that set status.observedGeneration and status.conditions reliably. In particular it is crucial that
- objects are born with a
status.observedGeneration: -1(or some other impossible value) - on each reconcile iteration,
status.observedGenerationandstatus.conditionsare updated by the responsible controller.
However, some controllers set these fields lazily or not at all, which can cause problems:
- A controller may not immediately set
status.observedGenerationafter an object is created, leaving it absent for a brief period. kstatus would then skip the generation check and might incorrectly conclude the object is ready. - A controller may never set a
Readycondition, even though it uses other condition types to indicate readiness. - A controller may set
status.observedGenerationbut only update it lazily, creating a window where the object appears unready even though the controller has already processed the current generation.
Tuning Status Detection with Annotations
To handle these cases, the annotation component-operator.cs.sap.com/status-hint can be added to any rendered manifest. It accepts a comma-separated list of hints:
has-observed-generation
Tells component-operator to treat the object as having a status.observedGeneration field, even if it is not yet set by the controller. This is useful for controllers that set the field lazily: without this hint, the generation check would be skipped during the window where the field is absent, potentially causing a false-positive ready status.
metadata:
annotations:
component-operator.cs.sap.com/status-hint: has-observed-generation
has-ready-condition
Tells component-operator to require a Ready condition. If the condition is absent, the object is treated as having status: Unknown (i.e., not ready). This is useful for objects where the controller will eventually set a Ready condition but may not have done so yet at time of first check.
metadata:
annotations:
component-operator.cs.sap.com/status-hint: has-ready-condition
conditions
A semicolon-separated list of additional condition types that must all be present and have status: True for the object to be considered ready.
metadata:
annotations:
component-operator.cs.sap.com/status-hint: "conditions=Synced;Healthy"
Combining hints
Multiple hints can be combined as a comma-separated list:
metadata:
annotations:
component-operator.cs.sap.com/status-hint: "has-observed-generation,has-ready-condition"