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
2 changes: 1 addition & 1 deletion .tekton/hyperfleet-operator-bundle-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ metadata:
pipelinesascode.tekton.dev/max-keep-runs: "3"
pipelinesascode.tekton.dev/on-cel-expression: event == "push" && target_branch
== "main" && ( ".tekton/hyperfleet-operator-bundle-push.yaml".pathChanged() || "bundle.konflux.Dockerfile".pathChanged()
|| "bundle-hack/***".pathChanged() || "bundle/***".pathChanged() )
|| "hack/bundle/***".pathChanged() || "bundle/***".pathChanged() )
labels:
appstudio.openshift.io/application: hyperfleet
appstudio.openshift.io/component: hyperfleet-operator-bundle
Expand Down
5 changes: 4 additions & 1 deletion .tekton/hyperfleet-operator-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ metadata:
&& !(files.all.all(x,
x.matches('^bundle\\.konflux\\.Dockerfile$')
|| x.matches('^bundle\\.Dockerfile$')
|| x.matches('^bundle-hack/')
|| x.matches('^hack/bundle/')
|| x.matches('^bundle/')
|| x.matches('^hack/test-disconnected-mirror\\.sh$')
|| x.matches('^\\.tekton/hyperfleet-operator-bundle-push\\.yaml$')
))
labels:
Expand All @@ -38,6 +39,8 @@ spec:
value: .
- name: prefetch-input
value: '{"type": "gomod"}'
- name: hermetic
value: "true"
pipelineSpec:
description: |
This pipeline is ideal for building container images from a Containerfile while maintaining trust after pipeline customization.
Expand Down
40 changes: 34 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,24 @@ cleanup-test-e2e: ## Tear down the Kind cluster used for e2e tests

##@ Lint

LOCALBIN ?= $(shell pwd)/bin

.PHONY: verify-related-images
verify-related-images: ## Verify a final release CSV (CSV_FILE is required).
@test -n "$(CSV_FILE)" || { echo "Set CSV_FILE to the CSV extracted from the release bundle"; exit 1; }
go run ./hack/verify-related-images -csv "$(CSV_FILE)"

.PHONY: lint
lint: ## Run golangci-lint linter
lint: verify-release-images ## Check release image metadata and run golangci-lint.
$(GOLANGCI_LINT) run

.PHONY: verify-release-images
verify-release-images: ## Transform the repository bundle CSV and verify its release images.
yq_path=$$($(call gotool,-n yq)); \
YQ="$$yq_path" bash ./hack/verify-release-images.sh; \
PATH="$$(dirname "$$yq_path"):$$PATH" go test -tags integration ./hack/verify-related-images; \
YQ="$$yq_path" bash ./hack/test-release-images.sh

.PHONY: lint-fix
lint-fix: ## Run golangci-lint linter and perform fixes
$(GOLANGCI_LINT) run --fix
Expand All @@ -134,6 +148,19 @@ lint-config: ## Verify golangci-lint linter configuration

##@ Build

OC_MIRROR_IMAGE ?= hyperfleet-oc-mirror:local

.PHONY: build-oc-mirror-image
build-oc-mirror-image: check-container-tool ## Build the containerized oc-mirror runner.
"$(CONTAINER_TOOL)" build -f hack/oc-mirror.Dockerfile -t "$(OC_MIRROR_IMAGE)" .

.PHONY: test-disconnected-mirror
test-disconnected-mirror: check-container-tool ## Test catalog export and isolated archive import (no cluster install).
CONTAINER_TOOL="$(CONTAINER_TOOL)" OC_MIRROR_IMAGE="$(OC_MIRROR_IMAGE)" \
IMAGE_SET_CONFIG="$(IMAGE_SET_CONFIG)" RELEASE_CSV="$(RELEASE_CSV)" \
BUNDLE_IMAGE="$(BUNDLE_IMAGE)" CONTAINER_DNS="$(CONTAINER_DNS)" \
./hack/test-disconnected-mirror.sh

.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
go build -o bin/manager cmd/main.go
Expand Down Expand Up @@ -178,10 +205,12 @@ GOFLAGS ?= -trimpath

.PHONY: check-container-tool
check-container-tool:
ifndef CONTAINER_TOOL
@echo "Error: No container tool found (docker or podman)"
@exit 1
endif
@case "$(CONTAINER_TOOL)" in \
docker|podman) command -v "$(CONTAINER_TOOL)" >/dev/null 2>&1 || { \
echo "Error: container tool is not installed: $(CONTAINER_TOOL)"; exit 1; \
} ;; \
*) echo "Error: CONTAINER_TOOL must be docker or podman"; exit 1 ;; \
esac

.PHONY: image
image: check-container-tool manifests generate fmt vet ## Build container image with configurable registry/tag
Expand Down Expand Up @@ -388,7 +417,6 @@ catalog-push: ## Push a catalog image.
##@ Dependencies

## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
mkdir -p $(LOCALBIN)

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ A Kubernetes operator for HyperFleet cluster lifecycle management.

hyperfleet-operator packages and delivers HyperFleet as a standard Kubernetes operator, installed and managed through OLM. It exposes a single cluster-scoped custom resource, `HyperFleetConfig`, as the entire partner-facing surface: install, configure, and observe HyperFleet through that one CR and its status conditions, with everything else the operator manages kept internal.

## Installation guides

- [Bundle development](docs/bundle.md)
- [Disconnected OpenShift installation with oc-mirror v2](docs/disconnected-install.md)
- [Release artifact validation](docs/release-validation.md)

## Getting Started

### Prerequisites
Expand Down
24 changes: 0 additions & 24 deletions bundle-hack/update_bundle.sh

This file was deleted.

4 changes: 2 additions & 2 deletions bundle.konflux.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Konflux bundle image build. Unlike the auto-generated bundle.Dockerfile (used
# for local dev with operator-sdk), this runs bundle-hack/update_bundle.sh to
# for local dev with operator-sdk), this runs hack/bundle/update_bundle.sh to
# patch digest-pinned image references into the CSV at build time.
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS builder-runner
RUN microdnf install -y tar gzip && \
Expand All @@ -15,7 +15,7 @@ ENV HYPERFLEET_OPERATOR_IMAGE_PULLSPEC=${HYPERFLEET_OPERATOR_IMAGE_PULLSPEC}
ARG HYPERFLEET_API_IMAGE_PULLSPEC="quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api@sha256:99f8cdda580069de21ba0e13b5b171cf82b81b93dc88b12bcaa8294e72e84fc3"
ENV HYPERFLEET_API_IMAGE_PULLSPEC=${HYPERFLEET_API_IMAGE_PULLSPEC}

COPY bundle-hack .
COPY hack/bundle .
Comment thread
kuudori marked this conversation as resolved.
COPY bundle/manifests /manifests/

RUN ./update_bundle.sh
Expand Down
3 changes: 2 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"

hyperfleetv1alpha1 "github.com/openshift-hyperfleet/hyperfleet-operator/api/v1alpha1"
"github.com/openshift-hyperfleet/hyperfleet-operator/internal/component/api"
"github.com/openshift-hyperfleet/hyperfleet-operator/internal/controller"
// +kubebuilder:scaffold:imports
)
Expand Down Expand Up @@ -235,7 +236,7 @@ func main() {
// it at bundle-build time via the relatedImages convention. Warn — but do not
// fail — when it is unset or uses a mutable tag, so `make run` and tag-based
// deploys keep working while the risk is surfaced in the logs.
apiImage := os.Getenv("RELATED_IMAGE_HYPERFLEET_API")
apiImage := os.Getenv(api.RelatedImageEnv)
switch {
case apiImage == "":
setupLog.Info("RELATED_IMAGE_HYPERFLEET_API not set; falling back to the " +
Expand Down
10 changes: 4 additions & 6 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ kind: Kustomization
resources:
- manager.yaml

# Base image configuration for local development
# For production/Konflux builds, digest-pinned images are set via bundle.konflux.Dockerfile ARG overrides
# Development defaults. Konflux sets release digests in the built bundle CSV.
#
# Local development override:
# make bundle-override-img IMG=quay.io/<quay_repo>/hyperfleet-operator:dev-<git_sha>
Expand All @@ -21,13 +20,12 @@ images:
# RELATED_IMAGE_HYPERFLEET_API environment variable
# Sets the image used for the API operand.
#
# IMPORTANT: Must stay in sync with api.DefaultImage in the operator code
# (v0.4.0+: config schema compatibility plus HYPERFLEET-1603 database *_FILE support)
# This is a static plain-manifest default. The API image must support the
# rendered config schema and HYPERFLEET-1603 database *_FILE variables (v0.4.0+).
# Production Konflux bundle builds override it through bundle.konflux.Dockerfile.
#
# For local development with a custom API image, manually edit the value below
# or use yq to update programmatically, then restore before committing.
#
# Production/Konflux: Digest-pinned via bundle.konflux.Dockerfile ARG overrides
patches:
- patch: |-
- op: add
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ metadata:
}
]
capabilities: Basic Install
# Conforma olm.feature_annotations_format requires all seven as string booleans.
# disconnected is true because relatedImages are digest-pinned. fips-compliant
# flips to "true" only after a verified FIPS build. HYPERFLEET-1614.
features.operators.openshift.io/disconnected: "true"
features.operators.openshift.io/fips-compliant: "false"
features.operators.openshift.io/proxy-aware: "false"
Expand Down
129 changes: 64 additions & 65 deletions docs/bundle.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
## 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
# Bundle development

## CI Installation
This guide covers local bundle-development workflows. It is not an installation
guide.

Once Konflux is in place, the CI pipeline will automatically handle bundling building with operator image updates:
- For an OpenShift air-gapped installation, follow the
[disconnected installation guide](disconnected-install.md).
- For release artifact and catalog-mirror validation, see
[release validation](release-validation.md).

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
## Development installation

### Prerequisite steps
For local development and installation, set your Quay username to automatically configure image paths:

For local development and installation, set your Quay username to automatically
configure image paths:

```bash
# Set your Quay username (required for image-dev)
Expand All @@ -37,13 +32,13 @@ export IMG=quay.io/$QUAY_USER/hyperfleet-operator:dev-<git-sha>
- IMG (hyperfleet-operator image): `quay.io/$QUAY_USER/hyperfleet-operator:dev-<git-sha>` (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

### OLM Installation
Testing hyperfleet-operator installation with OLM
Testing hyperfleet-operator installation with OLM.

**Note:** Ensure `IMG` is properly exported before running these commands
**Note:** Ensure `IMG` is properly exported before running these commands.

1. **Update bundle with operator image:** - WARNING restore changes once done testing!
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
Expand All @@ -59,48 +54,52 @@ Testing hyperfleet-operator installation with OLM
# To override: make bundle-build VERSION=0.0.2 BUNDLE_IMG=<another_repo>
```

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 <NAMESPACE>

# 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 <NAMESPACE>

# 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-<git-sha>"
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.
3. **Quick testing on a Kubernetes 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 <NAMESPACE>

# 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 <NAMESPACE>

# 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 Kubernetes cluster:**
```bash
export IMG="quay.io/$QUAY_USER/hyperfleet-operator:dev-<git-sha>"
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. Before committing, revert those
changes. `bundle-override-img` also regenerates `bundle/` and
`bundle.Dockerfile`; inspect and restore those generated changes as needed.
Loading