From d0ea8cdd181d00086c6e159ee9d57a7b6406490e Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Wed, 9 Sep 2026 13:34:20 -0400 Subject: [PATCH 1/2] HYPERFLEET-1615 - feat: First pass on catalog builds for operator --- Makefile | 23 +++- README.md | 32 +++--- catalog.Dockerfile | 49 ++++++++ catalog/base-template.yaml | 14 +++ catalog/dev-template.yaml | 4 + catalog/konflux-template.yaml | 5 + docs/bundle.md | 106 ----------------- docs/olm.md | 208 ++++++++++++++++++++++++++++++++++ 8 files changed, 314 insertions(+), 127 deletions(-) create mode 100644 catalog.Dockerfile create mode 100644 catalog/base-template.yaml create mode 100644 catalog/dev-template.yaml create mode 100644 catalog/konflux-template.yaml delete mode 100644 docs/bundle.md create mode 100644 docs/olm.md diff --git a/Makefile b/Makefile index 4b7e175..3d4b31a 100644 --- a/Makefile +++ b/Makefile @@ -397,18 +397,29 @@ bundle-override-img: manifests operator-sdk ## Generate bundle with IMG override .PHONY: bundle-build bundle-build: ## Build the bundle image. - $(CONTAINER_TOOL) build -f bundle.Dockerfile -t $(BUNDLE_IMG) . + $(CONTAINER_TOOL) build --platform=$(PLATFORM) -f bundle.Dockerfile -t $(BUNDLE_IMG) . .PHONY: bundle-push bundle-push: ## Push the bundle image. $(MAKE) docker-push IMG=$(BUNDLE_IMG) -# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. -# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: -# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator +TEMPLATEFILE ?= dev-template.yaml +.PHONY: catalog-template-update-bundle-img +catalog-template-update-bundle-img: ## Update the bundle image in the TEMPLATEFILE + @if [ ! -f catalog/$(TEMPLATEFILE) ]; then \ + echo "Error: Template file catalog/$(TEMPLATEFILE) does not exist"; \ + exit 1; \ + fi + @sed -i.bak 's|image: .*|image: $(BUNDLE_IMG)|' catalog/$(TEMPLATEFILE) && rm catalog/$(TEMPLATEFILE).bak + @echo "Updated catalog/$(TEMPLATEFILE) with image: $(BUNDLE_IMG)" + .PHONY: catalog-build -catalog-build: opm ## Build a catalog image. - $(OPM) index add --container-tool $(CONTAINER_TOOL) --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) +catalog-build: ## Build the catalog image with TEMPLATEFILE overrides + $(CONTAINER_TOOL) build \ + -f catalog.Dockerfile \ + --platform $(PLATFORM) \ + --build-arg TEMPLATEFILE=$(TEMPLATEFILE) \ + -t $(CATALOG_IMG) . # Push the catalog image. .PHONY: catalog-push diff --git a/README.md b/README.md index f305ba7..4cafdd3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# hyperfleet-operator +# Hyperfleet-Operator A Kubernetes operator for HyperFleet cluster lifecycle management. @@ -57,19 +57,6 @@ kubectl apply -k config/samples/ >**NOTE**: Ensure that the samples has default values to test it out. -### Observability endpoints - -The manager exposes the standard HyperFleet observability endpoints (defaults): - -- **Liveness probe:** `http://localhost:8080/healthz` -- **Readiness probe:** `http://localhost:8080/readyz` -- **Metrics:** `http://localhost:9090/metrics` - -Metrics are served as plain HTTP under the `hyperfleet_operator_*` namespace. Ports -are configurable via `--health-probe-bind-address` and `--metrics-bind-address`. -See [docs/metrics.md](docs/metrics.md) for the full metric catalogue, labels, and -example PromQL queries. - ### To Uninstall **Delete the instances (CRs) from the cluster:** @@ -89,6 +76,21 @@ make uninstall make undeploy ``` + + +### Observability endpoints + +The manager exposes the standard HyperFleet observability endpoints (defaults): + +- **Liveness probe:** `http://localhost:8080/healthz` +- **Readiness probe:** `http://localhost:8080/readyz` +- **Metrics:** `http://localhost:9090/metrics` + +Metrics are served as plain HTTP under the `hyperfleet_operator_*` namespace. Ports +are configurable via `--health-probe-bind-address` and `--metrics-bind-address`. +See [docs/metrics.md](docs/metrics.md) for the full metric catalogue, labels, and +example PromQL queries. + ## License Copyright 2026. @@ -103,4 +105,4 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and -limitations under the License. +limitations under the License. \ No newline at end of file diff --git a/catalog.Dockerfile b/catalog.Dockerfile new file mode 100644 index 0000000..c400680 --- /dev/null +++ b/catalog.Dockerfile @@ -0,0 +1,49 @@ +# OPM container image version. When invoked via the Makefile, this default is overridden by OPM_CONTAINER_VERSION; bumping only the line below will be ignored by make builds. +ARG OPM_VERSION=v1.69.0 + +# Named stage for OPM so COPY --from can reference it (variable expansion is not supported in --from). +FROM quay.io/operator-framework/opm:${OPM_VERSION} AS opm + +# Use alpine for the build stage with shell support. +FROM alpine:latest AS builder + +# Install OPM from the named stage. +COPY --from=opm /bin/opm /bin/opm + +# Create containers policy configuration. Use standard development policy +# that matches Fedora's default configuration. +RUN mkdir -p /etc/containers && \ + echo '{"default":[{"type":"insecureAcceptAnything"}],"transports":{"docker-daemon":{"":[{"type":"insecureAcceptAnything"}]}}}' > /etc/containers/policy.json + +WORKDIR /workspace + +# COPY template file set as a build-arg +# Supports konflux + dev builds +ARG TEMPLATEFILE +COPY catalog/base-template.yaml ./ +COPY catalog/${TEMPLATEFILE} ./ + +RUN cat base-template.yaml ${TEMPLATEFILE} > ./template.yaml + +# Generate catalog for single template. Use symlink to make +# mount accessible to OPM. This allows OPM to read credentials without +# copying them to the filesystem. +RUN --mount=type=secret,id=dockerconfig,target=/run/secrets/auth.json \ + mkdir -p /root/.docker && \ + ln -s /run/secrets/auth.json /root/.docker/config.json && \ + /bin/opm alpha render-template basic \ + --migrate-level=bundle-object-to-csv-metadata \ + -o yaml ./template.yaml > catalog.yaml && \ + rm -f /root/.docker/config.json + +# Serving stage +FROM opm + +COPY --from=builder /workspace/catalog.yaml /configs/catalog.yaml + +RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"] + +ENTRYPOINT ["/bin/opm"] +CMD ["serve", "/configs", "--cache-dir=/tmp/cache"] + +LABEL operators.operatorframework.io.index.configs.v1=/configs diff --git a/catalog/base-template.yaml b/catalog/base-template.yaml new file mode 100644 index 0000000..4a065c3 --- /dev/null +++ b/catalog/base-template.yaml @@ -0,0 +1,14 @@ +--- +schema: olm.template.basic +entries: + - schema: olm.package + name: hyperfleet-operator + defaultChannel: stable + description: "HyperFleet Operator" + - schema: olm.channel + name: stable + package: hyperfleet-operator + entries: + - name: hyperfleet-operator.v0.0.1 + skipRange: "<0.0.1" +# Dockerfile will concatenate the olm.bundle entry depending on the environment diff --git a/catalog/dev-template.yaml b/catalog/dev-template.yaml new file mode 100644 index 0000000..83ade19 --- /dev/null +++ b/catalog/dev-template.yaml @@ -0,0 +1,4 @@ +# Modify this file to override the operator-bundle image used in your catalog testing +# For dev purposes when testing changes and using catalog installation + - schema: olm.bundle + image: OVERRIDE_BUNDLE_IMAGE diff --git a/catalog/konflux-template.yaml b/catalog/konflux-template.yaml new file mode 100644 index 0000000..f9bbc2d --- /dev/null +++ b/catalog/konflux-template.yaml @@ -0,0 +1,5 @@ +# DO NOT MODIFY THIS FILE -- UPDATED by konflux build-nudges +# Used in KONFLUX builds only +# build-nudges-ref will update this image value + - schema: olm.bundle + image: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle@sha256:70a4f30b45fd221190efcf53ab1ec5395b57f7fa4e6c4ac863db8a3f279daa78 diff --git a/docs/bundle.md b/docs/bundle.md deleted file mode 100644 index 99587ba..0000000 --- a/docs/bundle.md +++ /dev/null @@ -1,106 +0,0 @@ -## Pre-merge checks -1. Updates to bundle.Dockerfile are also reflected in bundle.konflux.Dockerfile -2. bundle/ is correctly updated before merging -3. config/manager/kustomization.yaml is not wrongly updated - -## CI Installation - -Once Konflux is in place, the CI pipeline will automatically handle bundling building with operator image updates: - -1. Konflux builds the operator image and publishes it to quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator -2. The operator-bundle .tekton pipeline will be triggered by any update to the bundle.konflux.Dockerfile -2. `bundle.konflux.Dockerfile` runs `update_bundle.sh` with the new operator image reference -3. `update_bundle.sh` uses yq to update the CSV to ensure the operator deployment has proper values - image, relatedImages, annotations, etc. -4. Publishes the operator-bundle to quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle - -(HYPERFLEET-1411: TODO add more information once the konflux pipelines are in place) - -## Development Installation - -### Prerequisite steps -For local development and installation, set your Quay username to automatically configure image paths: - -```bash -# Set your Quay username (required for image-dev) -export QUAY_USER= -# Checkout dev branch -git checkout -b - -# Build and push dev image -make image-dev -# With default values - pushes to: quay.io/$QUAY_USER/hyperfleet-operator:dev- -export IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- -# export IMG so that it can be properly picked up for bundle generation -``` - -**Image path defaults:** -- IMG (hyperfleet-operator image): `quay.io/$QUAY_USER/hyperfleet-operator:dev-` (defaults `make image-dev`) -- BUNDLE_IMG (hyperfleet-operator-bundle): `quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION)` (default VERSION=0.0.1) - - -### OLM Installation -Testing hyperfleet-operator installation with OLM - -**Note:** Ensure `IMG` is properly exported before running these commands - -1. **Update bundle with operator image:** - WARNING restore changes once done testing! - ```bash - make bundle-override-img - # Updates bundle/ manifests with the operator image from step 2 - # Alternative: manually edit config/manager/kustomization.yaml - # Regenerates bundle.Dockerfile + bundle/ and override config/manager/kustomization.yaml - ``` - -2. **Build and push bundle image:** - ```bash - make bundle-build - make bundle-push - # Pushes to: quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) - # To override: make bundle-build VERSION=0.0.2 BUNDLE_IMG= - ``` - -3. **Quick testing on a k8s cluster:** - ```bash - export BUNDLE_IMG=quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) - # Install Operator Lifecycle Manager in your cluster - operator-sdk olm install - - # Install operator from bundle (note: bundle image uses v prefix) - operator-sdk run bundle $(BUNDLE_IMG) -n - - # Cleanup when done - IMPORTANT: Delete CRs before uninstalling operator - # 1. Export and delete the cluster-scoped HyperFleetConfig CR - kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml - kubectl delete hyperfleetconfig --all - - # 2. Clean up operator (removes CRDs and controller) - operator-sdk cleanup hyperfleet-operator -n - - # 3. Uninstall Operator Lifecycle Manager from your cluster - operator-sdk olm uninstall - ``` - - -### Non-OLM Installation -Testing hyperfleet-operator installation without OLM (kubectl apply) - -**Note:** Ensure `IMG` is properly exported before running these commands -1. **Quick testing on a k8s cluster:** - ```bash - export IMG="quay.io/$QUAY_USER/hyperfleet-operator:dev-" - make deploy - # Generates: dist/install.yaml - # Again, make sure to restore config/manager/kustomization.yaml after testing - # Check status to see that everything installed properly - - # Cleanup - IMPORTANT: Delete CRs before uninstalling operator - # 1. Export and delete the cluster-scoped HyperFleetConfig CR - kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml - kubectl delete hyperfleetconfig --all - - # 2. Undeploy operator (removes CRDs and controller) - make undeploy - # Or manually: kubectl delete -f dist/install.yaml - ``` - -**Note:** `bundle-override-img` and `build-deployer-override-img` modify config/manager/kustomization.yaml in place. So before committing any changes make sure to revert these changes. Additionally when running `bundle-override-img` the bundle/ and bundle.Dockerfile get regenerated in place, so make sure to check these changes before committing them. diff --git a/docs/olm.md b/docs/olm.md new file mode 100644 index 0000000..2b6e04d --- /dev/null +++ b/docs/olm.md @@ -0,0 +1,208 @@ +## Pre-merge checks +1. Updates to bundle.Dockerfile are also reflected in bundle.konflux.Dockerfile +2. bundle/ is correctly updated before merging +3. config/manager/kustomization.yaml is not wrongly updated + +## CI Image Build - Operator Image + Operator Bundle + Operator Catalog + +Konflux Workflow: + +1. Konflux builds the operator image and publishes it to quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator +2. The update of the hyperfleet-operator image will trigger an update to bundle.konflux.Dockerfile. Konflux will create a PR for us and automerge the update. +3. The operator-bundle-push .tekton pipeline will be triggered by any update to the bundle.konflux.Dockerfile in main. So this new operator image update will trigger the build once merged into main. Note - `bundle.konflux.Dockerfile` runs `update_bundle.sh` with the new operator image reference. `update_bundle.sh` uses yq to update the CSV to ensure the operator deployment has proper values - image, relatedImages, annotations, etc. Once completed the pipeline publishes the operator-bundle to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle` +5. Subsequently, the operator-bundle-push pipeline will update the operator-bundle image in the `konflux-template.yaml`. +6. Konflux takes care of auto-merging the update, once merged, it will trigger the operator-catalog-push .tekton pipeline which will build operator-catalog image and push it to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-catalog` + +** TODO - HYPERFLEET-1617 - Update documentation based on release details for the catalog. Assumption right now is we will release the hyperfleet-operator as a catalog that can be installed with olm. + +** Note: Any update to [bundle.konflux.Dockerfile](../bundle.konflux.Dockerfile) operator-bundle-push pipeline and any update to [konflux-template.yaml](../catalog/konflux-template.yaml) will trigger the operator-catalog-push pipeline. + +## Developer Installation + +### Tool Prerequisites +- go version v1.26.0+ +- docker version 17.05+. +- kubectl version v1.11.3+. +- Access to a Kubernetes v1.11.3+ cluster. + +### Prerequisite steps +For local development and installation, set your Quay username to automatically configure image paths: + +```bash +# Set your Quay username (required for image-dev) +export QUAY_USER= +# Checkout dev branch +git checkout -b + +# Build and push dev image +make image-dev +# With default values - pushes to: quay.io/$QUAY_USER/hyperfleet-operator:dev- +export IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- +# export IMG so that it can be properly picked up for bundle generation +``` + +**Image path defaults:** +- IMG (hyperfleet-operator image): `quay.io/$QUAY_USER/hyperfleet-operator:dev-` (defaults `make image-dev`) +- BUNDLE_IMG (hyperfleet-operator-bundle): `quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION)` (default VERSION=0.0.1) +- CATALOG_IMG (hyperfleet-operator-catalog): `quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION)` (defaul VERSION=0.0.1) + +### OLM Installation (Bundle + Catalog) - OLM Classic V0 +Testing hyperfleet-operator installation with OLM using a catalog image. + +The catalog build uses a template system with a base template (`catalog/base-template.yaml`) that defines the package and channel, and environment-specific templates that specify the bundle image: +- `catalog/dev-template.yaml` - for local development (default) +- `catalog/konflux-template.yaml` - for Konflux CI builds + +**Note:** Ensure `IMG`, `BUNDLE_IMG` and `CATALOG_IMG` is properly exported before running these commands + +1. **Update bundle with operator image:** - WARNING restore changes once done testing! + ```bash + make bundle-override-img + # Updates bundle/ manifests with the operator image + # Regenerates bundle.Dockerfile + bundle/ and overrides config/manager/kustomization.yaml + ``` + +2. **Build and push bundle image:** + ```bash + make bundle-build bundle-push PLATFORM=linux/amd64 + # Pushes to: quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) + ``` + +3. **Update the catalog template with the new bundle image:** + ```bash + make catalog-template-update-bundle-img + # Updates catalog/dev-template.yaml with the current BUNDLE_IMG + ``` + +4. **Build and push the catalog image:** + ```bash + make catalog-build catalog-push PLATFORM=linux/amd64 + # Pushes to: quay.io/$QUAY_USER/hyperfleet-operator-catalog:v$(VERSION) + # To use a different template: make catalog-build TEMPLATEFILE=konflux-template.yaml + ``` + +5. **Deploy on a k8s cluster with OLM:** + ```bash + # Install OLM if not already installed + operator-sdk olm install + + # Create a CatalogSource + kubectl apply -f - < + spec: + sourceType: grpc + image: quay.io/$QUAY_USER/hyperfleet-operator-catalog:v$(VERSION) + displayName: HyperFleet Operator + publisher: Red Hat + updateStrategy: + registryPoll: + interval: 5m + EOF + + # Create an OperatorGroup (AllNamespaces mode) + kubectl apply -f - < + spec: {} + EOF + + # Create a Subscription + kubectl apply -f - < + spec: + channel: stable + name: hyperfleet-operator + source: hyperfleet-operator-catalog + sourceNamespace: + installPlanApproval: Automatic + EOF + + # Watch the installation + kubectl get sub,installplan,csv -n -w + ``` + +6. **Cleanup:** + ```bash + # IMPORTANT: Delete CRs before uninstalling operator + kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml + kubectl delete hyperfleetconfig --all + + kubectl delete sub hyperfleet-operator -n + kubectl delete csv hyperfleet-operator.v0.0.1 -n + kubectl delete catalogsource hyperfleet-operator-catalog -n + kubectl delete operatorgroup hyperfleet-operator-group -n + + # Uninstall OLM from your cluster + operator-sdk olm uninstall + ``` + +### OLM Installation (operator-sdk run bundle) +Quick testing with `operator-sdk run bundle` (no catalog needed). + +**Note:** Ensure `IMG` and `BUNDLE_IMG` is properly exported before running these commands + +1. **Update bundle with operator image:** - WARNING restore changes once done testing! + ```bash + make bundle-override-img + ``` + +2. **Build and push bundle image:** + ```bash + make bundle-build bundle-push PLATFORM=linux/amd64 + ``` + +3. **Quick testing on a k8s cluster:** + ```bash + # Install Operator Lifecycle Manager in your cluster + operator-sdk olm install + + # Install operator from bundle + operator-sdk run bundle $BUNDLE_IMG -n + + kubectl apply -k config/samples/ + + # Cleanup when done - IMPORTANT: Delete CRs before uninstalling operator + kubectl delete hyperfleetconfig --all + + operator-sdk cleanup hyperfleet-operator -n + operator-sdk olm uninstall + ``` + + +### Non-OLM Installation +Testing hyperfleet-operator installation without OLM (kubectl apply) + +**Note:** Ensure `IMG` is properly exported before running these commands +1. **Quick testing on a k8s cluster:** + ```bash + export IMG="quay.io/$QUAY_USER/hyperfleet-operator:dev-" + make deploy + # Generates: dist/install.yaml + # Again, make sure to restore config/manager/kustomization.yaml after testing + # Check status to see that everything installed properly + + # Apply an example hyperfleetconfig CR + kubectl apply -k config/samples/ + + # Cleanup - IMPORTANT: Delete CRs before uninstalling operator + # 1. Export and delete the cluster-scoped HyperFleetConfig CR + kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml + kubectl delete hyperfleetconfig --all + + # 2. Undeploy operator (removes CRDs and controller) + make undeploy + # Or manually: kubectl delete -f dist/install.yaml + ``` + +**Note:** `bundle-override-img` and `build-deployer-override-img` modify config/manager/kustomization.yaml in place. So before committing any changes make sure to revert these changes. Additionally when running `bundle-override-img` the bundle/ and bundle.Dockerfile get regenerated in place, so make sure to check these changes before committing them. From 3f395edb04bbb4bd3640195cb4e7b1384c482503 Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Thu, 10 Sep 2026 15:41:34 -0400 Subject: [PATCH 2/2] HYPERFLEET-1615 - feat: Address review comments --- Makefile | 70 +++++---------- README.md | 21 +++-- catalog.Dockerfile | 41 +++------ catalog/dev-template.yaml | 2 +- catalog/konflux-template.yaml | 2 +- docs/olm.md | 158 +++++++++++++++------------------- 6 files changed, 115 insertions(+), 179 deletions(-) diff --git a/Makefile b/Makefile index 3d4b31a..f4b154d 100644 --- a/Makefile +++ b/Makefile @@ -182,11 +182,12 @@ run: manifests generate fmt vet ## Run a controller from your host. # Image configuration PLATFORM ?= linux/amd64 -QUAY_REPO ?= openshift-hyperfleet +QUAY_USER ?= +QUAY_REPO ?= $(if $(QUAY_USER),$(QUAY_USER),openshift-hyperfleet) IMG_REGISTRY ?= quay.io/$(QUAY_REPO) IMG_NAME ?= hyperfleet-operator IMG_TAG ?= $(APP_VERSION) -IMG ?= $(IMG_REGISTRY)/$(IMG_NAME):$(IMG_TAG) +OPERATOR_IMG ?= $(IMG_REGISTRY)/$(IMG_NAME):$(IMG_TAG) # Base image for production builds - matches Dockerfile default # Override with DEV_BASE_IMAGE for dev builds (see image-dev target) BASE_IMAGE ?= registry.access.redhat.com/ubi9-micro:latest @@ -215,21 +216,21 @@ endif .PHONY: image image: check-container-tool manifests generate fmt vet ## Build container image with configurable registry/tag - @echo "Building container image $(IMG)..." + @echo "Building container image $(OPERATOR_IMG)..." $(CONTAINER_TOOL) build \ --platform $(PLATFORM) \ --build-arg BASE_IMAGE=$(BASE_IMAGE) \ --build-arg APP_VERSION=$(APP_VERSION) \ --build-arg GIT_SHA=$(GIT_SHA) \ - -t $(IMG) . - @echo "Image built: $(IMG)" - @echo "$(IMG)" + -t $(OPERATOR_IMG) . + @echo "Image built: $(OPERATOR_IMG)" + @echo "$(OPERATOR_IMG)" .PHONY: image-push image-push: check-container-tool ## Push container image to registry - @echo "Pushing image $(IMG)..." - $(CONTAINER_TOOL) push $(IMG) - @echo "Image pushed: $(IMG)" + @echo "Pushing image $(OPERATOR_IMG)..." + $(CONTAINER_TOOL) push $(OPERATOR_IMG) + @echo "Image pushed: $(OPERATOR_IMG)" .PHONY: image-build-push image-build-push: image image-push ## Build and push container image to registry @@ -246,44 +247,13 @@ endif # Usage: QUAY_USER=myuser make image-dev # Dev image configuration - set QUAY_USER to push to personal registry DEV_TAG ?= dev-$(GIT_SHA) -QUAY_USER ?= DEV_BASE_IMAGE ?= registry.access.redhat.com/ubi9/ubi-minimal:latest .PHONY: image-dev -image-dev: QUAY_REPO = $(QUAY_USER) image-dev: IMG_TAG = $(DEV_TAG) image-dev: BASE_IMAGE = $(DEV_BASE_IMAGE) image-dev: check-quay-user image-build-push ## Build and push dev image to dev Quay registry (requires QUAY_USER) -# If you wish to build the manager image targeting other platforms you can use the --platform flag. -# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. -# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -.PHONY: docker-build -docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG} . - -.PHONY: docker-push -docker-push: ## Push docker image with the manager. - $(CONTAINER_TOOL) push ${IMG} - -# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple -# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: -# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/ -# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/ -# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=> then the export will fail) -# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option. -PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le -.PHONY: docker-buildx -docker-buildx: ## Build and push docker image for the manager for cross-platform support - # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile - sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - - $(CONTAINER_TOOL) buildx create --name hyperfleet-operator-builder - $(CONTAINER_TOOL) buildx use hyperfleet-operator-builder - - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . - - $(CONTAINER_TOOL) buildx rm hyperfleet-operator-builder - rm Dockerfile.cross - - ##@ Deployment ifndef ignore-not-found @@ -389,10 +359,10 @@ bundle: manifests operator-sdk ## Generate bundle manifests and metadata, then v .PHONY: bundle-override-img bundle-override-img: manifests operator-sdk ## Generate bundle with IMG override, then restore kustomization.yaml $(OPERATOR_SDK) generate kustomize manifests -q - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) + cd config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMG) $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) $(OPERATOR_SDK) bundle validate ./bundle - @echo "Bundle generated with IMG=$(IMG)" + @echo "Bundle generated with $(OPERATOR_IMG)" @echo "Note: config/manager/kustomization.yaml has been modified. Commit or reset as needed." .PHONY: bundle-build @@ -400,8 +370,10 @@ bundle-build: ## Build the bundle image. $(CONTAINER_TOOL) build --platform=$(PLATFORM) -f bundle.Dockerfile -t $(BUNDLE_IMG) . .PHONY: bundle-push -bundle-push: ## Push the bundle image. - $(MAKE) docker-push IMG=$(BUNDLE_IMG) +bundle-push: check-container-tool ## Push bundle image to registry + @echo "Pushing image $(BUNDLE_IMG)..." + $(CONTAINER_TOOL) push $(BUNDLE_IMG) + @echo "Image pushed: $(BUNDLE_IMG)" TEMPLATEFILE ?= dev-template.yaml .PHONY: catalog-template-update-bundle-img @@ -418,13 +390,15 @@ catalog-build: ## Build the catalog image with TEMPLATEFILE overrides $(CONTAINER_TOOL) build \ -f catalog.Dockerfile \ --platform $(PLATFORM) \ - --build-arg TEMPLATEFILE=$(TEMPLATEFILE) \ + --build-arg TEMPLATEFILE="$(TEMPLATEFILE)" \ + --build-arg APP_VERSION="$(APP_VERSION)" \ -t $(CATALOG_IMG) . -# Push the catalog image. .PHONY: catalog-push -catalog-push: ## Push a catalog image. - $(MAKE) docker-push IMG=$(CATALOG_IMG) +catalog-push: check-container-tool ## Push catalog image to registry + @echo "Pushing image $(CATALOG_IMG)..." + $(CONTAINER_TOOL) push $(CATALOG_IMG) + @echo "Image pushed: $(CATALOG_IMG)" ##@ Dependencies diff --git a/README.md b/README.md index 4cafdd3..8b9923a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ hyperfleet-operator packages and delivers HyperFleet as a standard Kubernetes op ## Installation guides -- [Developer workflow: operator and bundle images](docs/bundle.md) +- [OLM bundle + catalog workflow + developer installation example](docs/olm.md) - [Disconnected OpenShift installation with oc-mirror v2](docs/disconnected-install.md) The disconnected workflow mirrors the published catalog. The catalog selects @@ -23,10 +23,14 @@ the OLM bundle and its related images. - Access to a Kubernetes v1.11.3+ cluster. ### To Deploy on the cluster -**Build and push your image to the location specified by `IMG`:** - +**Build and push your image to the location specified by `OPERATOR_IMG`:** ```sh -make docker-build docker-push IMG=/hyperfleet-operator:tag +# set your QUAY_USER to push to personal image regsitry +export QUAY_USER= + +# Build and push the operator image +make image-dev OPERATOR_IMG=... +# default OPERATOR_IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- ``` **NOTE:** This image ought to be published in the personal registry you specified. @@ -39,10 +43,11 @@ Make sure you have the proper permission to the registry if the above commands d make install ``` -**Deploy the Manager to the cluster with the image specified by `IMG`:** +**Deploy the Manager to the cluster with the image specified by `OPERATOR_IMG`:** ```sh -make deploy IMG=/hyperfleet-operator:tag +make deploy OPERATOR_IMG=... +# default OPERATOR_IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- ``` > **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin @@ -76,9 +81,7 @@ make uninstall make undeploy ``` - - -### Observability endpoints +## Observability The manager exposes the standard HyperFleet observability endpoints (defaults): diff --git a/catalog.Dockerfile b/catalog.Dockerfile index c400680..8beebc9 100644 --- a/catalog.Dockerfile +++ b/catalog.Dockerfile @@ -1,19 +1,5 @@ -# OPM container image version. When invoked via the Makefile, this default is overridden by OPM_CONTAINER_VERSION; bumping only the line below will be ignored by make builds. -ARG OPM_VERSION=v1.69.0 - -# Named stage for OPM so COPY --from can reference it (variable expansion is not supported in --from). -FROM quay.io/operator-framework/opm:${OPM_VERSION} AS opm - -# Use alpine for the build stage with shell support. -FROM alpine:latest AS builder - -# Install OPM from the named stage. -COPY --from=opm /bin/opm /bin/opm - -# Create containers policy configuration. Use standard development policy -# that matches Fedora's default configuration. -RUN mkdir -p /etc/containers && \ - echo '{"default":[{"type":"insecureAcceptAnything"}],"transports":{"docker-daemon":{"":[{"type":"insecureAcceptAnything"}]}}}' > /etc/containers/policy.json +# Building stage +FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.18 AS builder WORKDIR /workspace @@ -25,25 +11,20 @@ COPY catalog/${TEMPLATEFILE} ./ RUN cat base-template.yaml ${TEMPLATEFILE} > ./template.yaml -# Generate catalog for single template. Use symlink to make -# mount accessible to OPM. This allows OPM to read credentials without -# copying them to the filesystem. -RUN --mount=type=secret,id=dockerconfig,target=/run/secrets/auth.json \ - mkdir -p /root/.docker && \ - ln -s /run/secrets/auth.json /root/.docker/config.json && \ - /bin/opm alpha render-template basic \ +RUN /bin/opm alpha render-template basic \ --migrate-level=bundle-object-to-csv-metadata \ - -o yaml ./template.yaml > catalog.yaml && \ - rm -f /root/.docker/config.json + -o yaml ./template.yaml > catalog.yaml -# Serving stage -FROM opm +# Final serving stage +FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.18 AS serve -COPY --from=builder /workspace/catalog.yaml /configs/catalog.yaml +COPY --from=builder /workspace/catalog.yaml /configs/hyperfleet-operator/catalog.yaml -RUN ["/bin/opm", "serve", "/configs", "--cache-dir=/tmp/cache", "--cache-only"] +RUN ["/bin/opm", "serve", "/configs/hyperfleet-operator", "--cache-dir=/tmp/cache", "--cache-only"] ENTRYPOINT ["/bin/opm"] -CMD ["serve", "/configs", "--cache-dir=/tmp/cache"] +CMD ["serve", "/configs/hyperfleet-operator", "--cache-dir=/tmp/cache"] +ARG APP_VERSION="0.0.0-dev" +LABEL version="${APP_VERSION}" LABEL operators.operatorframework.io.index.configs.v1=/configs diff --git a/catalog/dev-template.yaml b/catalog/dev-template.yaml index 83ade19..9c329c8 100644 --- a/catalog/dev-template.yaml +++ b/catalog/dev-template.yaml @@ -1,4 +1,4 @@ # Modify this file to override the operator-bundle image used in your catalog testing # For dev purposes when testing changes and using catalog installation - schema: olm.bundle - image: OVERRIDE_BUNDLE_IMAGE + image: OVERRIDE_BUNDLE_IMAGE \ No newline at end of file diff --git a/catalog/konflux-template.yaml b/catalog/konflux-template.yaml index f9bbc2d..da2be88 100644 --- a/catalog/konflux-template.yaml +++ b/catalog/konflux-template.yaml @@ -2,4 +2,4 @@ # Used in KONFLUX builds only # build-nudges-ref will update this image value - schema: olm.bundle - image: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle@sha256:70a4f30b45fd221190efcf53ab1ec5395b57f7fa4e6c4ac863db8a3f279daa78 + image: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle@sha256:f9ba788d8eac7b6a4fadb3043fa72e513aab8dcdd8d1c57725ee84d1e5463acd diff --git a/docs/olm.md b/docs/olm.md index 2b6e04d..2cb87d7 100644 --- a/docs/olm.md +++ b/docs/olm.md @@ -1,3 +1,5 @@ +# Hyperfleet-Operator Installation via OLM + ## Pre-merge checks 1. Updates to bundle.Dockerfile are also reflected in bundle.konflux.Dockerfile 2. bundle/ is correctly updated before merging @@ -8,80 +10,89 @@ Konflux Workflow: 1. Konflux builds the operator image and publishes it to quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator -2. The update of the hyperfleet-operator image will trigger an update to bundle.konflux.Dockerfile. Konflux will create a PR for us and automerge the update. -3. The operator-bundle-push .tekton pipeline will be triggered by any update to the bundle.konflux.Dockerfile in main. So this new operator image update will trigger the build once merged into main. Note - `bundle.konflux.Dockerfile` runs `update_bundle.sh` with the new operator image reference. `update_bundle.sh` uses yq to update the CSV to ensure the operator deployment has proper values - image, relatedImages, annotations, etc. Once completed the pipeline publishes the operator-bundle to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle` -5. Subsequently, the operator-bundle-push pipeline will update the operator-bundle image in the `konflux-template.yaml`. -6. Konflux takes care of auto-merging the update, once merged, it will trigger the operator-catalog-push .tekton pipeline which will build operator-catalog image and push it to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-catalog` +2. Konflux automatically updates image references for the operator image in the bundle.konflux.Dockerfile. This will automatically get merged. +3. The operator-bundle-push .tekton pipeline will be triggered by the update to the bundle.konflux.Dockerfile. So this new operator image update will trigger the build once merged into main. Note - `bundle.konflux.Dockerfile` runs `update_bundle.sh` with the new operator image reference. `update_bundle.sh` uses yq to update the CSV to ensure the operator deployment has proper values - image, relatedImages, annotations, etc. Once completed the pipeline publishes the operator-bundle to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle` +5. Konflux will subsequently update the image reference for the operator-bundle image in `konflux-template.yaml`. Auto-merging the update. +6. The operator-catalog-push .tekton pipeline will be triggered by the update to the `konflux-template.yaml`. This pipeline will build operator-catalog image and push it to `quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator-catalog. -** TODO - HYPERFLEET-1617 - Update documentation based on release details for the catalog. Assumption right now is we will release the hyperfleet-operator as a catalog that can be installed with olm. +> **Note**: Any update to [bundle.konflux.Dockerfile](../bundle.konflux.Dockerfile) will trigger the operator-bundle-push pipeline and any update to [konflux-template.yaml](../catalog/konflux-template.yaml) will trigger the operator-catalog-push pipeline. -** Note: Any update to [bundle.konflux.Dockerfile](../bundle.konflux.Dockerfile) operator-bundle-push pipeline and any update to [konflux-template.yaml](../catalog/konflux-template.yaml) will trigger the operator-catalog-push pipeline. +> **TODO** - HYPERFLEET-1617 - Update documentation based on release details for the catalog. Currently no upgrade graph for the hyperfleet-operator. ## Developer Installation -### Tool Prerequisites +### Prerequisites - go version v1.26.0+ -- docker version 17.05+. +- docker version 18.06+ +- operator-sdk v1.42.3+ - kubectl version v1.11.3+. -- Access to a Kubernetes v1.11.3+ cluster. +- Access to a Kubernetes v1.27.0+ cluster. ### Prerequisite steps + For local development and installation, set your Quay username to automatically configure image paths: -```bash -# Set your Quay username (required for image-dev) -export QUAY_USER= -# Checkout dev branch -git checkout -b - -# Build and push dev image -make image-dev -# With default values - pushes to: quay.io/$QUAY_USER/hyperfleet-operator:dev- -export IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- -# export IMG so that it can be properly picked up for bundle generation -``` - -**Image path defaults:** -- IMG (hyperfleet-operator image): `quay.io/$QUAY_USER/hyperfleet-operator:dev-` (defaults `make image-dev`) +1. **Export your quay username:** (Required) + ```bash + export QUAY_USER= + ``` +2. **Build and push the operator image:** + ```bash + make image-dev OPERATOR_IMG=... + # default OPERATOR_IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev- + ``` +3. **Update the bundle with your OPERATOR_IMG:** + ```bash + make bundle-override-img OPERATOR_IMG=... + ``` +**Note** When running `bundle-override-img` the bundle/ and bundle.Dockerfile get regenerated in place, so make sure to check these changes before committing them. +4. **Build the bundle image:** + ```bash + make bundle-build BUNDLE_IMG=... + # default BUNDLE_IMG=quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) + # default VERSION = 0.0.1 + ``` +5. **Push the bundle image:** + ```bash + make bundle-push BUNDLE_IMG=... + ``` + +**Image path defaults with QUAY_USER set:** +- OPERATOR_IMG (hyperfleet-operator): `quay.io/$QUAY_USER/hyperfleet-operator:dev-` - BUNDLE_IMG (hyperfleet-operator-bundle): `quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION)` (default VERSION=0.0.1) -- CATALOG_IMG (hyperfleet-operator-catalog): `quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION)` (defaul VERSION=0.0.1) +- CATALOG_IMG (hyperfleet-operator-catalog): `quay.io/$QUAY_USER/hyperfleet-operator-catalog:v$(VERSION)` (defaul VERSION=0.0.1) -### OLM Installation (Bundle + Catalog) - OLM Classic V0 + +### Bundle + Catalog with OLM Classic V0 Testing hyperfleet-operator installation with OLM using a catalog image. The catalog build uses a template system with a base template (`catalog/base-template.yaml`) that defines the package and channel, and environment-specific templates that specify the bundle image: - `catalog/dev-template.yaml` - for local development (default) - `catalog/konflux-template.yaml` - for Konflux CI builds -**Note:** Ensure `IMG`, `BUNDLE_IMG` and `CATALOG_IMG` is properly exported before running these commands - -1. **Update bundle with operator image:** - WARNING restore changes once done testing! - ```bash - make bundle-override-img - # Updates bundle/ manifests with the operator image - # Regenerates bundle.Dockerfile + bundle/ and overrides config/manager/kustomization.yaml - ``` +**Note:** Ensure `QUAY_USER`, `BUNDLE_IMG` and `CATALOG_IMG` are set before running these commands +**Note:** Make sure you have completed the steps in [Prerequisite Steps](#prerequisite-steps) -2. **Build and push bundle image:** +1. **Update the catalog template with the new bundle image:** ```bash - make bundle-build bundle-push PLATFORM=linux/amd64 - # Pushes to: quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) + make catalog-template-update-bundle-img BUNDLE_IMG=... TEMPLATEFILE=... + # default TEMPLATEFILE=dev-template.yaml + # default BUNDLE_IMG=quay.io/$QUAY_USER/hyperfleet-operator-bundle:v$(VERSION) + # updates catalog/ with the current BUNDLE_IMG ``` -3. **Update the catalog template with the new bundle image:** +2. **Build the catalog image:** ```bash - make catalog-template-update-bundle-img - # Updates catalog/dev-template.yaml with the current BUNDLE_IMG + make catalog-build CATALOG_IMG=... + # default CATALOG_IMG=quay.io/$QUAY_USER/hyperfleet-operator-catalog:v$(VERSION) + # default VERSION = 0.0.1 ``` - -4. **Build and push the catalog image:** +3. **Push the catalog image:** ```bash - make catalog-build catalog-push PLATFORM=linux/amd64 - # Pushes to: quay.io/$QUAY_USER/hyperfleet-operator-catalog:v$(VERSION) - # To use a different template: make catalog-build TEMPLATEFILE=konflux-template.yaml + make catalog-push CATALOG_IMG=... ``` -5. **Deploy on a k8s cluster with OLM:** +4. **Deploy on a k8s cluster with OLM:** ```bash # Install OLM if not already installed operator-sdk olm install @@ -132,7 +143,7 @@ The catalog build uses a template system with a base template (`catalog/base-tem kubectl get sub,installplan,csv -n -w ``` -6. **Cleanup:** +5. **Cleanup:** ```bash # IMPORTANT: Delete CRs before uninstalling operator kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml @@ -147,62 +158,29 @@ The catalog build uses a template system with a base template (`catalog/base-tem operator-sdk olm uninstall ``` -### OLM Installation (operator-sdk run bundle) -Quick testing with `operator-sdk run bundle` (no catalog needed). - -**Note:** Ensure `IMG` and `BUNDLE_IMG` is properly exported before running these commands +> **TODO**: HYPERFLEET-1616: OLM V1 install -1. **Update bundle with operator image:** - WARNING restore changes once done testing! - ```bash - make bundle-override-img - ``` +### Install with operator-sdk and bundle - (operator-sdk run bundle) +Quick testing with `operator-sdk run bundle` (no catalog needed). -2. **Build and push bundle image:** - ```bash - make bundle-build bundle-push PLATFORM=linux/amd64 - ``` +**Note:** Ensure `BUNDLE_IMG` is exported before running these commands 3. **Quick testing on a k8s cluster:** ```bash # Install Operator Lifecycle Manager in your cluster operator-sdk olm install - # Install operator from bundle + # Install hyperfleet-operator from bundle operator-sdk run bundle $BUNDLE_IMG -n - + + # Apply an example hyperfleetconfig cr kubectl apply -k config/samples/ # Cleanup when done - IMPORTANT: Delete CRs before uninstalling operator kubectl delete hyperfleetconfig --all - + + # Uninstall hyperfleet-operator operator-sdk cleanup hyperfleet-operator -n + # Uninstall olm operator-sdk olm uninstall ``` - - -### Non-OLM Installation -Testing hyperfleet-operator installation without OLM (kubectl apply) - -**Note:** Ensure `IMG` is properly exported before running these commands -1. **Quick testing on a k8s cluster:** - ```bash - export IMG="quay.io/$QUAY_USER/hyperfleet-operator:dev-" - make deploy - # Generates: dist/install.yaml - # Again, make sure to restore config/manager/kustomization.yaml after testing - # Check status to see that everything installed properly - - # Apply an example hyperfleetconfig CR - kubectl apply -k config/samples/ - - # Cleanup - IMPORTANT: Delete CRs before uninstalling operator - # 1. Export and delete the cluster-scoped HyperFleetConfig CR - kubectl get hyperfleetconfig -o yaml > hyperfleetconfig-backup.yaml - kubectl delete hyperfleetconfig --all - - # 2. Undeploy operator (removes CRDs and controller) - make undeploy - # Or manually: kubectl delete -f dist/install.yaml - ``` - -**Note:** `bundle-override-img` and `build-deployer-override-img` modify config/manager/kustomization.yaml in place. So before committing any changes make sure to revert these changes. Additionally when running `bundle-override-img` the bundle/ and bundle.Dockerfile get regenerated in place, so make sure to check these changes before committing them.