Release Controller Documentation¶
Overview¶
The Release controller manages the lifecycle of Release custom resources in SolAr. Its primary responsibility is to validate that a Release's referenced ComponentVersion exists and to reflect the resolution status via status conditions.
Once the ComponentVersion is resolved, the controller also writes status.effectiveUniqueName, the deduplication key the Target controller will use for this Release. This equals spec.uniqueName when set, or the sanitized OCM component name (spec.componentName) of the ComponentVersion otherwise.
The Release controller does not trigger rendering — that is handled by the Target controller once a Release is bound to a Target via a ReleaseBinding.
Architecture¶
flowchart TD
subgraph Kubernetes
Ctrl[Release Controller]
Rel[Release]
CV[ComponentVersion]
end
Ctrl -->|reconciles| Rel
Rel -->|resolves| CV
CV -->|spec.componentName| Ctrl
Ctrl -->|writes status.effectiveUniqueName| Rel
Ctrl -->|adds/removes componentversion-ref| CV
Finalizers¶
The Release controller manages two finalizers:
| Finalizer | On resource | Purpose |
|---|---|---|
solar.opendefense.cloud/release-finalizer |
Release | Allows the controller to observe deletion and run cleanup logic before the object is garbage-collected |
solar.opendefense.cloud/componentversion-ref |
ComponentVersion | Prevents deletion of the referenced ComponentVersion while any Release references it |
On deletion, the controller:
- Checks whether any other active Release still references the same ComponentVersion.
- If none remain, removes
solar.opendefense.cloud/componentversion-reffrom the ComponentVersion. - Removes
solar.opendefense.cloud/release-finalizerfrom the Release, allowing it to be garbage-collected.
Cross-namespace references (resolved via ReferenceGrant) are considered when counting active references.
Status Conditions¶
stateDiagram-v2
[*] --> Unresolved: Release created
Unresolved --> ComponentVersionResolved: ComponentVersion found
Unresolved --> Unresolved: ComponentVersion missing (requeues on CV change)
ComponentVersionResolved --> Unresolved: ReferenceGrant revoked
ComponentVersionResolved --> [*]
| Condition | Status | Reason | Description |
|---|---|---|---|
ComponentVersionResolved |
True |
Resolved |
ComponentVersion exists |
ComponentVersionResolved |
False |
NotFound |
ComponentVersion does not exist |
ComponentVersionResolved |
False |
NotGranted |
Cross-namespace access not permitted by ReferenceGrant |
Renderable |
True/False/Unknown |
mirrored from the ComponentVersion | Status and reason of the referenced ComponentVersion's Available condition, carried over verbatim (e.g. False/DescriptorMissing) |
Renderable |
Unknown |
AvailabilityUnknown |
The ComponentVersion has no Available condition yet |
Renderable |
Unknown |
ComponentVersionUnresolved |
The ComponentVersion is not resolved, so availability cannot be judged |
Renderable currently reflects descriptor availability only. Further preconditions for rendering (a bound Registry, usable credentials, a resolvable entrypoint) are follow-up work and will narrow this condition further without changing its meaning.
The apiserver does not reject a Release whose ComponentVersion is unavailable. It is admitted and shows red instead, via Renderable and the RENDERABLE column of kubectl get releases. Existing Releases are never mutated when their ComponentVersion turns unavailable.
Status Fields¶
| Field | Description |
|---|---|
effectiveUniqueName |
The deduplication key used by the Target controller. Equals spec.uniqueName when set, otherwise the sanitized OCM component name (spec.componentName) of the referenced ComponentVersion. spec.uniqueName itself is not modified. This field exists only for operator visibility. |
Watch Triggers¶
The Release controller is triggered when:
- A
Releaseresource is created, updated, or deleted. - A
ComponentVersionthat is referenced by one or more Releases changes. - A
ReferenceGrantthat covers a cross-namespace ComponentVersion reference changes.
Relationship to Other Controllers¶
The Release controller is intentionally minimal. Rendering logic is delegated to the Target controller:
flowchart LR
Release -->|validated by| ReleaseCtrl[Release Controller]
Release -->|referenced by| ReleaseBinding
ReleaseBinding -->|bound by| Target
Target -->|creates RenderTasks via| TargetCtrl[Target Controller]