Skip to content
Merged
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
91 changes: 38 additions & 53 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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=<myregistry/image:<tag>> 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
Expand Down Expand Up @@ -389,31 +359,46 @@ 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
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)
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
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)"

# 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
.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)" \
--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

Expand Down
47 changes: 26 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# hyperfleet-operator
# Hyperfleet-Operator

A Kubernetes operator for HyperFleet cluster lifecycle management.

Expand All @@ -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
Expand All @@ -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=<some-registry>/hyperfleet-operator:tag
# set your QUAY_USER to push to personal image regsitry
export QUAY_USER=<YOUR_QUAY_USERNAME>

# Build and push the operator image
make image-dev OPERATOR_IMG=...
# default OPERATOR_IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev-<git-sha>
```

**NOTE:** This image ought to be published in the personal registry you specified.
Expand All @@ -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=<some-registry>/hyperfleet-operator:tag
make deploy OPERATOR_IMG=...
# default OPERATOR_IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev-<git-sha>
```

> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin
Expand All @@ -57,19 +62,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:**

Expand All @@ -89,6 +81,19 @@ make uninstall
make undeploy
```

## Observability

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.
Expand All @@ -103,4 +108,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.
30 changes: 30 additions & 0 deletions catalog.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Building stage
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.18 AS builder

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

RUN /bin/opm alpha render-template basic \
--migrate-level=bundle-object-to-csv-metadata \
-o yaml ./template.yaml > catalog.yaml

# Final serving stage
FROM registry.redhat.io/openshift4/ose-operator-registry-rhel9:v4.18 AS serve

COPY --from=builder /workspace/catalog.yaml /configs/hyperfleet-operator/catalog.yaml

RUN ["/bin/opm", "serve", "/configs/hyperfleet-operator", "--cache-dir=/tmp/cache", "--cache-only"]

ENTRYPOINT ["/bin/opm"]
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ARG APP_VERSION and LABEL version="${APP_VERSION}" the same way the bundle Dockerfile does. The RPA's default tag template is {{ labels.version }}; with the operator-registry base the catalog would inherit version=v4.18.x from the parent and get tagged as an OCP version. Same fix as the bundle needed in 1411.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

14 changes: 14 additions & 0 deletions catalog/base-template.yaml
Original file line number Diff line number Diff line change
@@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, not asking for a change here: the nudge rewrites the digest of the same entry, so every catalog rebuild republishes hyperfleet-operator.v0.0.1 pointing at different content. OLM (both stacks) will not upgrade an installed v0.0.1 to another v0.0.1, so consumers only see new bundles on fresh install, and the N-1 to N upgrade e2e in HYPERFLEET-1413 has no edge to traverse. That is the versioning question HYPERFLEET-1617 owns. Suggest the docs/olm.md TODO says exactly that ("catalog has no upgrade graph until 1617 lands") instead of "assumption is we push all updates to the same tag", so 1413 does not start against this catalog.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

skipRange: "<0.0.1"
# Dockerfile will concatenate the olm.bundle entry depending on the environment
4 changes: 4 additions & 0 deletions catalog/dev-template.yaml
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions catalog/konflux-template.yaml
Original file line number Diff line number Diff line change
@@ -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:f9ba788d8eac7b6a4fadb3043fa72e513aab8dcdd8d1c57725ee84d1e5463acd
Loading