Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ controllers, and tooling that support the packaging, distribution, and lifecycli
- provide secure, high-quality, and predictable user experiences centered around declarative GitOps concepts
- give cluster admins the minimal necessary controls to build their desired cluster architectures and to have ultimate control

OLM v1 consists of two different components:
OLM v1 consists of the following components:

* operator-controller
* catalogd
* object-controller (experimental): manages `ClusterObjectSet` resources independently of `ClusterExtension`

For a more complete overview of OLM v1 and how it differs from OLM v0, see our [overview](docs/project/olmv1_design_decisions.md).

Expand Down
15 changes: 15 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,19 @@ olmv1 = {
'yaml': 'helm/tilt.yaml',
}

values = read_yaml(olmv1['yaml'])
options = values.get('options', {})
features = options.get('operatorController', {}).get('features', {})
object_controller_enabled = options.get('objectController', {}).get('enabled')
if object_controller_enabled == None:
object_controller_enabled = options.get('operatorController', {}).get('enabled', True) and 'BoxcutterRuntime' in features.get('enabled', []) and 'BoxcutterRuntime' not in features.get('disabled', ['BoxcutterRuntime'])
if object_controller_enabled:
olmv1['repos']['object-controller'] = {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
'image': 'quay.io/operator-framework/object-controller',
'binary': './cmd/object-controller',
'deployment': 'object-controller-controller-manager',
'deps': ['api', 'cmd/object-controller', 'internal/object-controller', 'internal/shared', 'go.mod', 'go.sum'],
'starting_debug_port': 40000,
}

deploy_repo(olmv1, '-tags containers_image_openpgp')
46 changes: 46 additions & 0 deletions docs/draft/concepts/clusterobjectsets.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,49 @@ Each ClusterObjectSet has:

ClusterObjectSets can be used by any controller or system that needs to manage the rollout of a set of Kubernetes resources in a controlled, phased manner. Within OLM, the operator-controller uses ClusterObjectSets as the mechanism to deploy and upgrade ClusterExtensions.

### Controller deployment

The experimental `object-controller` runs in its own Deployment with its own service
account and leader-election lease. It watches ClusterObjectSets and the objects they
manage; it does not require ClusterExtension or ClusterCatalog resources or controllers.
The operator-controller continues to resolve and unpack bundles, create ClusterObjectSets,
and observe their status when `BoxcutterRuntime` is enabled.

The Helm chart automatically enables object-controller alongside operator-controller
when `BoxcutterRuntime` is enabled. To deploy it independently, first build an image
and make it available to your cluster (push it to a registry, or load it into your
local cluster). Set the image reference below, then render and apply the manifests:

```sh
helm template object-controller helm/olmv1 \
--set options.featureSet=experimental \
--set options.objectController.enabled=true \
--set options.operatorController.enabled=false \
--set options.catalogd.enabled=false \
--set-string options.objectController.deployment.image='<your-built-image>' \
> object-controller.yaml
kubectl apply -f object-controller.yaml
kubectl -n olmv1-system rollout status deployment/object-controller-controller-manager --timeout=180s
```

Set `options.objectController.deployment.image` to the built image when using a local
or downstream image. `make go-build-local` builds `bin/object-controller`;
`make docker-build` builds its image alongside the existing controller images.
`OBJECT_CONTROLLER_IMAGE_REPO` controls its build and release repository.

Object-controller reads immutable referenced Secrets directly from the API server in
the namespace specified by each reference. Metrics require a TLS certificate and key;
the chart configures these through cert-manager or the OpenShift service CA when enabled.
The minimal standalone example above enables neither certificate provider, so metrics
are disabled. Health and readiness probes remain enabled.
The default service account has cluster-admin privileges because ClusterObjectSets can
manage arbitrary Kubernetes resources, matching the existing experimental runtime.

For downstream builds enabling `BoxcutterRuntime`, package the new binary and configure
its image in addition to the operator-controller image. It is possible to package both
binaries in one image while running them in separate Deployments. Standard installations
and default Helm installations without `BoxcutterRuntime` do not enable object-controller.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
## Why ClusterObjectSets?

ClusterObjectSets solve several problems that arise when managing sets of related Kubernetes resources:
Expand Down Expand Up @@ -382,6 +425,9 @@ kubectl get clusterobjectsets -l olm.operatorframework.io/owner-name=my-extensio

# View full details for a specific revision
kubectl get clusterobjectset <name> -o yaml

# Inspect reconciliation in the independent controller
kubectl -n olmv1-system logs deployment/object-controller-controller-manager
```

Example output:
Expand Down
13 changes: 13 additions & 0 deletions hack/test/e2e-coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ OPERATOR_CONTROLLER_MANAGER_DEPLOYMENT_NAME="operator-controller-controller-mana
CATALOGD_NAMESPACE="olmv1-system"
CATALOGD_MANAGER_DEPLOYMENT_NAME="catalogd-controller-manager"

OBJECT_CONTROLLER_MANAGER_DEPLOYMENT_NAME="object-controller-controller-manager"

COPY_POD_NAME="e2e-coverage-copy-pod"

# Create a temporary directory for coverage
Expand All @@ -26,6 +28,17 @@ kubectl -n "$CATALOGD_NAMESPACE" scale deployment/"$CATALOGD_MANAGER_DEPLOYMENT_
kubectl -n "$OPERATOR_CONTROLLER_NAMESPACE" wait --for=delete pods -l control-plane="$OPERATOR_CONTROLLER_MANAGER_DEPLOYMENT_NAME" --timeout=60s
kubectl -n "$CATALOGD_NAMESPACE" wait --for=delete pods -l control-plane="$CATALOGD_MANAGER_DEPLOYMENT_NAME" --timeout=60s

if object_controller_lookup=$(kubectl -n "$OPERATOR_CONTROLLER_NAMESPACE" get deployment/"$OBJECT_CONTROLLER_MANAGER_DEPLOYMENT_NAME" -o name 2>&1); then
kubectl -n "$OPERATOR_CONTROLLER_NAMESPACE" scale deployment/"$OBJECT_CONTROLLER_MANAGER_DEPLOYMENT_NAME" --replicas=0
kubectl -n "$OPERATOR_CONTROLLER_NAMESPACE" wait --for=delete pods -l control-plane="$OBJECT_CONTROLLER_MANAGER_DEPLOYMENT_NAME" --timeout=60s
else
object_controller_lookup_status=$?
if [[ "$object_controller_lookup" != *"Error from server (NotFound): deployments.apps \"$OBJECT_CONTROLLER_MANAGER_DEPLOYMENT_NAME\" not found"* ]]; then
printf '%s\n' "$object_controller_lookup" >&2
exit "$object_controller_lookup_status"
fi
fi

# Copy the coverage data from the temporary pod
kubectl -n "$OPERATOR_CONTROLLER_NAMESPACE" cp "$COPY_POD_NAME":/e2e-coverage/ "$COVERAGE_DIR"

Expand Down
10 changes: 10 additions & 0 deletions scripts/install.tpl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,16 @@ curl -L -s "${olmv1_manifest}" | sed "s/olmv1-system/${olmv1_namespace}/g" | kub
kubectl_wait_rollout "${olmv1_namespace}" "deployment/catalogd-controller-manager" "60s"
kubectl_wait "${olmv1_namespace}" "deployment/catalogd-controller-manager" "60s"
kubectl_wait "${olmv1_namespace}" "deployment/operator-controller-controller-manager" "60s"
if object_controller_lookup=$(kubectl get deployment/object-controller-controller-manager --namespace="${olmv1_namespace}" -o name 2>&1); then
kubectl_wait_rollout "${olmv1_namespace}" "deployment/object-controller-controller-manager" "60s"
kubectl_wait "${olmv1_namespace}" "deployment/object-controller-controller-manager" "60s"
else
object_controller_lookup_status=$?
if [[ "${object_controller_lookup}" != *'Error from server (NotFound): deployments.apps "object-controller-controller-manager" not found'* ]]; then
printf '%s\n' "${object_controller_lookup}" >&2
exit "${object_controller_lookup_status}"
fi
fi

if [[ "${install_default_catalogs}" != "false" ]]; then
kubectl apply -f "${default_catalogs_manifest}"
Expand Down
Loading