This guide covers bundle management for the OpenShift Lightspeed Operator.
📖 For OLM Fundamentals: See Operator SDK Bundle Documentation
📖 For CSV Field Reference: See ClusterServiceVersion Spec
An OLM bundle packages an operator for distribution and installation. It contains:
- Manifests: ClusterServiceVersion (CSV), CRD, RBAC
- Metadata: OLM annotations (channels, versions, compatibility)
- Dockerfile: Bundle image build instructions
bundle/
├── manifests/
│ ├── lightspeed-operator.clusterserviceversion.yaml # Main metadata and install strategy
│ ├── ols.openshift.io_olsconfigs.yaml # CRD definition
│ └── *_rbac.authorization.k8s.io_*.yaml # RBAC resources
├── metadata/
│ └── annotations.yaml # Bundle metadata (channels, OCP versions)
└── tests/scorecard/
└── config.yaml # Scorecard configuration
bundle.Dockerfile # Bundle image build
Our Configuration:
- CSV install mode:
OwnNamespace(operator deployed inopenshift-lightspeed) - CRD scope:
Cluster(OLSConfig is cluster-scoped, no namespace required)
Why this matters:
The OLSConfig CRD is intentionally cluster-scoped despite OwnNamespace install mode:
- Singleton Pattern: One OLSConfig instance per cluster (name must be
cluster) - Semantic Correctness: Cluster-wide service = cluster-scoped resource
- Cross-Namespace Watching: Can watch Secrets/ConfigMaps in any namespace
- User Convenience:
oc get olsconfig cluster(no namespace flag needed)
Key Distinction:
- CSV install mode: Where operator deployment lives (
openshift-lightspeed) - CRD scope: How users access the custom resource (cluster-wide)
All operand resources (deployments, services) are still created in openshift-lightspeed namespace.
Required:
- RBAC changes (
//+kubebuilder:rbacmarkers orconfig/rbac/) - CRD changes (
api/v1alpha1/olsconfig_types.go) - Image changes (operator or operand images)
- CSV metadata changes (description, keywords, maintainers)
- Any other change in .config directory
Not Required:
- Reconciliation logic changes
- Tests, docs, internal utilities
Generate bundle:
make bundle BUNDLE_TAG=0.1.0
# With custom images
make bundle BUNDLE_TAG=0.1.0 RELATED_IMAGES_FILE=related_images.jsonWhat happens:
- Generates manifests via
operator-sdkandkustomize - Updates image references from
related_images.json - Adds OpenShift compatibility annotations
- Generates bundle Dockerfile
- Validates bundle
Validate:
operator-sdk bundle validate ./bundle
# For OpenShift
operator-sdk bundle validate ./bundle --select-optional name=operatorhubBuild and push:
make bundle-build BUNDLE_IMG=quay.io/myorg/lightspeed-operator-bundle:v0.1.0
make bundle-push BUNDLE_IMG=quay.io/myorg/lightspeed-operator-bundle:v0.1.0- Makefile:
Makefile(lines 329-346) - Script:
hack/update_bundle.sh - Images:
related_images.json - Dockerfile:
bundle.Dockerfile
Purpose: related_images.json is the single source of truth for (component name, image) pairs. It drives CSV spec.relatedImages and deployment args/container image substitution. Placeholder strings used for substitution are defined in hack/image_placeholders.json (and must match config/default/kustomization.yaml).
Format:
{
"name": "lightspeed-operator",
"image": "quay.io/redhat-user-workloads/crt-nshift-lightspeed-tenant/ols/lightspeed-operator@sha256:65b288d147503bd66808eecf69deee8e71ec890752a70f83a9314061fe0d4420",
"revision": "e5e1454f3fa8b19293200868684abcaf18f38097"
}Workflow:
related_images.json → hack/update_bundle.sh → CSV relatedImages → CSV deployment args → Controller → Operand deployments
Best practice:
- Development: Use tags (
:latest,:v1.0.0) - Production: Use digests (
@sha256:abc123...) for reproducibility
Bump version:
# 1. Update version
vim Makefile # Update BUNDLE_TAG
# 2. Generate bundle
make bundle BUNDLE_TAG=0.2.0
# 3. Review and commit
git diff bundle/
git add bundle/ bundle.Dockerfile
git commit -m "chore: bump bundle version to v0.2.0"Semantic Versioning:
- Major (x.0.0): Breaking changes
- Minor (0.x.0): New features, backward-compatible
- Patch (0.0.x): Bug fixes
Ensure version consistency across:
Makefile(BUNDLE_TAG)- CSV metadata name (
lightspeed-operator.v0.2.0) - CSV spec
versionfield - Bundle Dockerfile labels
# Get image references from Konflux snapshot
./hack/snapshot_to_image_list.sh -s <snapshot-ref> -o related_images.json
# Update bundle (uses version from related_images.json or current CSV)
make bundle
# Verify operator image was updated
grep "lightspeed-operator" bundle/manifests/*.clusterserviceversion.yamlvim config/rbac/role.yaml # Update RBAC
make manifests && make bundle BUNDLE_TAG=0.1.0
yq '.spec.install.spec.clusterPermissions[0].rules' \
bundle/manifests/lightspeed-operator.clusterserviceversion.yaml # Verifyvim bundle/metadata/annotations.yaml # Change: com.redhat.openshift.versions
operator-sdk bundle validate ./bundleoperator-sdk bundle validate ./bundle -o text # Verbose outputCommon fixes:
- Check CSV YAML syntax (indentation)
- Ensure required fields present (
minKubeVersion,displayName,version) - Verify image references are valid
- Check RBAC rules format
YQ=$(which yq) JQ=$(which jq) ./hack/update_bundle.sh -v 0.1.0 -i related_images.jsonCommon fixes:
- Verify
related_images.jsonformat - Ensure
yqandjqare installed - Check image names match expected patterns
# Check subscription and install plan
oc get subscription lightspeed-operator -n openshift-lightspeed -o yaml
oc get installplan -n openshift-lightspeedCommon fixes:
- Verify RBAC permissions complete
- Ensure CRD is valid
- Review deployment spec in CSV
- OLM Catalog Management - Next: organize bundles into catalogs
- OLM Integration & Lifecycle - Deploy bundles via OLM
- Operator SDK Bundle Docs
- CSV Field Reference