|
| 1 | +# Waiting for Readiness |
| 2 | + |
| 3 | +In some scenarios, simply creating objects during initialization is not enough. You may need to wait for |
| 4 | +certain resources to become ready before the init-agent marks the workspace as initialized. For example, |
| 5 | +a CRD must be `Established` before custom resources using it can be created by other initializers |
| 6 | +further down the chain. |
| 7 | + |
| 8 | +The `initialization.kcp.io/wait-for-ready` annotation allows you to express this requirement on |
| 9 | +individual manifests. |
| 10 | + |
| 11 | +## How It Works |
| 12 | + |
| 13 | +When the init-agent encounters a manifest (from any of its [init sources](./init-sources/)) with |
| 14 | +the `initialization.kcp.io/wait-for-ready` annotation, it will: |
| 15 | + |
| 16 | +1. Create (or confirm the existence of) the object as usual. |
| 17 | +2. Re-fetch the object's current state from the API server. |
| 18 | +3. Check whether the condition type specified in the annotation's value has `status: "True"` in the |
| 19 | + object's `status.conditions` list. |
| 20 | +4. If the condition is not yet `True`, the agent requeues reconciliation and tries again after a few |
| 21 | + seconds. |
| 22 | +5. Only once **all** annotated objects across **all** sources have their required conditions met will |
| 23 | + the agent remove the initializer from the workspace, completing initialization. |
| 24 | + |
| 25 | +The annotation value must be the **name of a condition type** (e.g. `Established`, `Ready`, |
| 26 | +`Available`). This condition must appear in the standard Kubernetes `status.conditions` array of |
| 27 | +the resource. |
| 28 | + |
| 29 | +!!! warning "Important" |
| 30 | + Waiting for a condition to become `True` inherently means that **some process must set that |
| 31 | + condition**. In some cases this happens automatically (e.g. the Kubernetes API server sets |
| 32 | + `Established` on CRDs), but in other cases you may need a dedicated controller or operator to |
| 33 | + act on the resource and update its status. |
| 34 | + |
| 35 | + Due to the nature of kcp's workspace initialization, the workspace is not accessible through |
| 36 | + the regular API while it still has initializers. Only processes that work through the same |
| 37 | + `initializingworkspaces` virtual workspace – i.e. processes that are registered for the **same |
| 38 | + initializer** as the init-agent – can see and modify objects in the workspace during |
| 39 | + initialization. |
| 40 | + |
| 41 | + This means that if you need an external controller to make a resource "ready", that controller |
| 42 | + must also operate on the same initializer's `initializingworkspaces` view. Without this, the |
| 43 | + controller will not be able to access the workspace and therefore cannot set the condition the |
| 44 | + init-agent is waiting for. The initialization would be stuck indefinitely. |
| 45 | + |
| 46 | + In practice, this is most relevant for custom operators that need to reconcile resources created |
| 47 | + by the init-agent. Make sure these operators have the appropriate kcp permissions and are |
| 48 | + configured to watch the same initializing workspaces. |
| 49 | + |
| 50 | +## Usage |
| 51 | + |
| 52 | +Add the annotation to any manifest inside an `InitTemplate`'s `spec.template`. The following example |
| 53 | +creates a CRD and waits for it to become `Established` before initialization is considered complete: |
| 54 | + |
| 55 | +```yaml |
| 56 | +apiVersion: initialization.kcp.io/v1alpha1 |
| 57 | +kind: InitTemplate |
| 58 | +metadata: |
| 59 | + name: widgets-crd |
| 60 | +spec: |
| 61 | + template: | |
| 62 | + apiVersion: apiextensions.k8s.io/v1 |
| 63 | + kind: CustomResourceDefinition |
| 64 | + metadata: |
| 65 | + name: widgets.example.com |
| 66 | + annotations: |
| 67 | + initialization.kcp.io/wait-for-ready: "Established" |
| 68 | + spec: |
| 69 | + group: example.com |
| 70 | + names: |
| 71 | + kind: Widget |
| 72 | + listKind: WidgetList |
| 73 | + plural: widgets |
| 74 | + singular: widget |
| 75 | + scope: Cluster |
| 76 | + versions: |
| 77 | + - name: v1alpha1 |
| 78 | + served: true |
| 79 | + storage: true |
| 80 | + schema: |
| 81 | + openAPIV3Schema: |
| 82 | + type: object |
| 83 | +``` |
| 84 | +
|
| 85 | +In this example the init-agent will create the CRD and then wait until its `Established` condition |
| 86 | +is `True` before considering this source complete. CRDs are just a nice example of a Kube-native |
| 87 | +resource that on its own becomes ready. |
| 88 | + |
| 89 | +The agent will keep retrying indefinitely. If a condition is never set, the workspace will remain |
| 90 | +in the initializing state. Use kcp's workspace lifecycle management to handle stuck workspaces if |
| 91 | +necessary. |
| 92 | + |
| 93 | +The annotation works with **any Kubernetes resource** that follows the standard conditions pattern |
| 94 | +in its status. Common examples include: |
| 95 | + |
| 96 | +| Resource | Typical Condition | |
| 97 | +| -------- | ----------------- | |
| 98 | +| `CustomResourceDefinition` | `Established` | |
| 99 | +| `Deployment` | `Available` | |
| 100 | +| `APIBinding` (kcp) | `Ready` | |
0 commit comments