diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index df52c7003..c3f8e50bb 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -69,5 +69,6 @@ jobs: run: | docker run -d -p 5000:5000 --name registry registry:2 make bundle-build bundle-push catalog-build catalog-deps-build + sed -i 's|localhost:5000|quay.io|g' catalog/odf-dependencies.yaml msg='Uncommitted catalog changes. run `make catalog` and commit results.' git diff --exit-code catalog || (echo -e '\e[31m'"$msg"; exit 1) diff --git a/Makefile b/Makefile index cf0ba63a6..66af80fbb 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,12 @@ e2e-test: ginkgo ## Run end to end functional tests. ./hack/e2e-test.sh define MANAGER_ENV_VARS +ODF_DEPS_SUBSCRIPTION_NAME=$(ODF_DEPS_SUBSCRIPTION_NAME) +ODF_DEPS_SUBSCRIPTION_PACKAGE=$(ODF_DEPS_SUBSCRIPTION_PACKAGE) +ODF_DEPS_SUBSCRIPTION_CHANNEL=$(ODF_DEPS_SUBSCRIPTION_CHANNEL) +ODF_DEPS_SUBSCRIPTION_STARTINGCSV=$(ODF_DEPS_SUBSCRIPTION_STARTINGCSV) +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE=$(ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE) +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE=$(ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE) NOOBAA_SUBSCRIPTION_NAME=$(NOOBAA_SUBSCRIPTION_NAME) NOOBAA_SUBSCRIPTION_PACKAGE=$(NOOBAA_SUBSCRIPTION_PACKAGE) NOOBAA_SUBSCRIPTION_CHANNEL=$(NOOBAA_SUBSCRIPTION_CHANNEL) @@ -170,10 +176,18 @@ undeploy-with-olm: ## Undeploy controller from the K8s cluster # Make target to ignore (git checkout) changes if there are only timestamp changes in the bundle checkout-bundle-timestamp: - (git diff --quiet --ignore-matching-lines createdAt bundle && git checkout --quiet bundle) || true + (git diff --quiet --ignore-matching-lines createdAt bundle/odf-operator && git checkout --quiet bundle/odf-operator) || true + (git diff --quiet --ignore-matching-lines createdAt bundle/odf-dependencies && git checkout --quiet bundle/odf-dependencies) || true .PHONY: bundle bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. + # Dependencies bundle + $(KUSTOMIZE) build config/bundle | $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) \ + --output-dir bundle/odf-dependencies --package odf-dependencies + $(OPERATOR_SDK) bundle validate bundle/odf-dependencies + @mv bundle.Dockerfile bundle.deps.Dockerfile + + # Main odf-operator bundle $(OPERATOR_SDK) generate kustomize manifests -q cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) cd config/default && $(KUSTOMIZE) edit set image rbac-proxy=$(RBAC_PROXY_IMG) @@ -184,17 +198,20 @@ bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metada 'olm.properties':'[{"type": "olm.maxOpenShiftVersion", "value": "$(MAX_OCP_VERSION)"}]' && \ $(KUSTOMIZE) edit add patch --name odf-operator.v0.0.0 --kind ClusterServiceVersion \ --patch '[{"op": "replace", "path": "/spec/replaces", "value": "$(REPLACES)"}]' - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) - $(OPERATOR_SDK) bundle validate ./bundle + $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) \ + --output-dir bundle/odf-operator + $(OPERATOR_SDK) bundle validate bundle/odf-operator @$(MAKE) --no-print-directory checkout-bundle-timestamp .PHONY: bundle-build bundle-build: bundle ## Build the bundle image. docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . + docker build -f bundle.deps.Dockerfile -t $(ODF_DEPS_BUNDLE_IMG) . .PHONY: bundle-push bundle-push: ## Push the bundle image. $(MAKE) docker-push IMG=$(BUNDLE_IMG) + $(MAKE) docker-push IMG=$(ODF_DEPS_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: @@ -202,6 +219,7 @@ bundle-push: ## Push the bundle image. .PHONY: catalog catalog: opm ## Generate catalog manifests and then validate generated files. $(OPM) render --output=yaml $(BUNDLE_IMG) $(OPM_RENDER_OPTS) > catalog/odf.yaml + $(OPM) render --output=yaml $(ODF_DEPS_BUNDLE_IMG) $(OPM_RENDER_OPTS) > catalog/odf-dependencies.yaml $(OPM) render --output=yaml $(OCS_BUNDLE_IMG) $(OPM_RENDER_OPTS) > catalog/ocs.yaml $(OPM) render --output=yaml $(OCS_CLIENT_BUNDLE_IMG) $(OPM_RENDER_OPTS) > catalog/ocs-client.yaml $(OPM) render --output=yaml $(IBM_BUNDLE_IMG) $(OPM_RENDER_OPTS) > catalog/ibm.yaml diff --git a/bundle.Dockerfile b/bundle.Dockerfile index f384a2c00..2c31a3609 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -16,6 +16,6 @@ LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ # Copy files to locations specified by labels. -COPY bundle/manifests /manifests/ -COPY bundle/metadata /metadata/ -COPY bundle/tests/scorecard /tests/scorecard/ +COPY bundle/odf-operator/manifests /manifests/ +COPY bundle/odf-operator/metadata /metadata/ +COPY bundle/odf-operator/tests/scorecard /tests/scorecard/ diff --git a/bundle.deps.Dockerfile b/bundle.deps.Dockerfile new file mode 100644 index 000000000..039aed7c5 --- /dev/null +++ b/bundle.deps.Dockerfile @@ -0,0 +1,16 @@ +FROM scratch + +# Core bundle labels. +LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 +LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ +LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ +LABEL operators.operatorframework.io.bundle.package.v1=odf-dependencies +LABEL operators.operatorframework.io.bundle.channels.v1=alpha +LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.31.0 +LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 + +# Copy files to locations specified by labels. +COPY bundle/odf-dependencies/manifests /manifests/ +COPY bundle/odf-dependencies/metadata /metadata/ diff --git a/bundle/odf-dependencies/manifests/odf-dependencies.clusterserviceversion.yaml b/bundle/odf-dependencies/manifests/odf-dependencies.clusterserviceversion.yaml new file mode 100644 index 000000000..761479bd3 --- /dev/null +++ b/bundle/odf-dependencies/manifests/odf-dependencies.clusterserviceversion.yaml @@ -0,0 +1,49 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: '[]' + createdAt: "2024-11-14T03:00:40Z" + operatorframework.io/suggested-namespace: openshift-storage + operators.operatorframework.io/builder: operator-sdk-v1.31.0 + operators.operatorframework.io/operator-type: non-standalone + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + labels: + operatorframework.io/arch.amd64: supported + operatorframework.io/arch.ppc64le: supported + operatorframework.io/arch.s390x: supported + name: odf-dependencies.v4.18.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: {} + description: | + deploys dependencies. + displayName: Data Foundation Dependencies + icon: + - base64data: PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxOTIgMTQ1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwMDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlJlZEhhdC1Mb2dvLUhhdC1Db2xvcjwvdGl0bGU+PHBhdGggZD0iTTE1Ny43Nyw2Mi42MWExNCwxNCwwLDAsMSwuMzEsMy40MmMwLDE0Ljg4LTE4LjEsMTcuNDYtMzAuNjEsMTcuNDZDNzguODMsODMuNDksNDIuNTMsNTMuMjYsNDIuNTMsNDRhNi40Myw2LjQzLDAsMCwxLC4yMi0xLjk0bC0zLjY2LDkuMDZhMTguNDUsMTguNDUsMCwwLDAtMS41MSw3LjMzYzAsMTguMTEsNDEsNDUuNDgsODcuNzQsNDUuNDgsMjAuNjksMCwzNi40My03Ljc2LDM2LjQzLTIxLjc3LDAtMS4wOCwwLTEuOTQtMS43My0xMC4xM1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjcuNDcsODMuNDljMTIuNTEsMCwzMC42MS0yLjU4LDMwLjYxLTE3LjQ2YTE0LDE0LDAsMCwwLS4zMS0zLjQybC03LjQ1LTMyLjM2Yy0xLjcyLTcuMTItMy4yMy0xMC4zNS0xNS43My0xNi42QzEyNC44OSw4LjY5LDEwMy43Ni41LDk3LjUxLjUsOTEuNjkuNSw5MCw4LDgzLjA2LDhjLTYuNjgsMC0xMS42NC01LjYtMTcuODktNS42LTYsMC05LjkxLDQuMDktMTIuOTMsMTIuNSwwLDAtOC40MSwyMy43Mi05LjQ5LDI3LjE2QTYuNDMsNi40MywwLDAsMCw0Mi41Myw0NGMwLDkuMjIsMzYuMywzOS40NSw4NC45NCwzOS40NU0xNjAsNzIuMDdjMS43Myw4LjE5LDEuNzMsOS4wNSwxLjczLDEwLjEzLDAsMTQtMTUuNzQsMjEuNzctMzYuNDMsMjEuNzdDNzguNTQsMTA0LDM3LjU4LDc2LjYsMzcuNTgsNTguNDlhMTguNDUsMTguNDUsMCwwLDEsMS41MS03LjMzQzIyLjI3LDUyLC41LDU1LC41LDc0LjIyYzAsMzEuNDgsNzQuNTksNzAuMjgsMTMzLjY1LDcwLjI4LDQ1LjI4LDAsNTYuNy0yMC40OCw1Ni43LTM2LjY1LDAtMTIuNzItMTEtMjcuMTYtMzAuODMtMzUuNzgiLz48L3N2Zz4= + mediatype: image/svg+xml + install: + spec: + deployments: [] + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: false + type: AllNamespaces + links: + - name: Source Code + url: https://github.com/red-hat-storage/odf-operator + maintainers: + - email: ocs-support@redhat.com + name: Red Hat Support + maturity: alpha + minKubeVersion: 1.16.0 + provider: + name: Red Hat + version: 4.18.0 diff --git a/bundle/odf-dependencies/metadata/annotations.yaml b/bundle/odf-dependencies/metadata/annotations.yaml new file mode 100644 index 000000000..4c2cd6dbe --- /dev/null +++ b/bundle/odf-dependencies/metadata/annotations.yaml @@ -0,0 +1,11 @@ +annotations: + # Core bundle annotations. + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: odf-dependencies + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.bundle.channel.default.v1: alpha + operators.operatorframework.io.metrics.builder: operator-sdk-v1.31.0 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 diff --git a/bundle/metadata/dependencies.yaml b/bundle/odf-dependencies/metadata/dependencies.yaml similarity index 100% rename from bundle/metadata/dependencies.yaml rename to bundle/odf-dependencies/metadata/dependencies.yaml diff --git a/bundle/manifests/odf-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml b/bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml similarity index 100% rename from bundle/manifests/odf-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml rename to bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-monitor_monitoring.coreos.com_v1_servicemonitor.yaml diff --git a/bundle/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_role.yaml b/bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_role.yaml similarity index 100% rename from bundle/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_role.yaml rename to bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_role.yaml diff --git a/bundle/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_rolebinding.yaml b/bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_rolebinding.yaml similarity index 100% rename from bundle/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_rolebinding.yaml rename to bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_rbac.authorization.k8s.io_v1_rolebinding.yaml diff --git a/bundle/manifests/odf-operator-controller-manager-metrics-service_v1_service.yaml b/bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_v1_service.yaml similarity index 100% rename from bundle/manifests/odf-operator-controller-manager-metrics-service_v1_service.yaml rename to bundle/odf-operator/manifests/odf-operator-controller-manager-metrics-service_v1_service.yaml diff --git a/bundle/manifests/odf-operator-manager-config_v1_configmap.yaml b/bundle/odf-operator/manifests/odf-operator-manager-config_v1_configmap.yaml similarity index 90% rename from bundle/manifests/odf-operator-manager-config_v1_configmap.yaml rename to bundle/odf-operator/manifests/odf-operator-manager-config_v1_configmap.yaml index b1458b1ee..ff21d5ee7 100644 --- a/bundle/manifests/odf-operator-manager-config_v1_configmap.yaml +++ b/bundle/odf-operator/manifests/odf-operator-manager-config_v1_configmap.yaml @@ -36,6 +36,12 @@ data: OCS_SUBSCRIPTION_NAME: ocs-operator OCS_SUBSCRIPTION_PACKAGE: ocs-operator OCS_SUBSCRIPTION_STARTINGCSV: ocs-operator.v4.18.0 + ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE: odf-catalogsource + ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE: openshift-marketplace + ODF_DEPS_SUBSCRIPTION_CHANNEL: alpha + ODF_DEPS_SUBSCRIPTION_NAME: odf-dependencies + ODF_DEPS_SUBSCRIPTION_PACKAGE: odf-dependencies + ODF_DEPS_SUBSCRIPTION_STARTINGCSV: odf-dependencies.v4.18.0 PROMETHEUS_SUBSCRIPTION_CATALOGSOURCE: odf-catalogsource PROMETHEUS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE: openshift-marketplace PROMETHEUS_SUBSCRIPTION_CHANNEL: beta diff --git a/bundle/manifests/odf-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/odf-operator/manifests/odf-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml similarity index 100% rename from bundle/manifests/odf-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml rename to bundle/odf-operator/manifests/odf-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml diff --git a/bundle/manifests/odf-operator.clusterserviceversion.yaml b/bundle/odf-operator/manifests/odf-operator.clusterserviceversion.yaml similarity index 99% rename from bundle/manifests/odf-operator.clusterserviceversion.yaml rename to bundle/odf-operator/manifests/odf-operator.clusterserviceversion.yaml index 552610530..8020acfbf 100644 --- a/bundle/manifests/odf-operator.clusterserviceversion.yaml +++ b/bundle/odf-operator/manifests/odf-operator.clusterserviceversion.yaml @@ -35,7 +35,7 @@ metadata: categories: Storage console.openshift.io/plugins: '["odf-console"]' containerImage: quay.io/ocs-dev/odf-operator:latest - createdAt: "2024-11-13T13:01:04Z" + createdAt: "2024-11-14T03:00:40Z" description: OpenShift Data Foundation provides a common control plane for storage solutions on OpenShift Container Platform. features.operators.openshift.io/token-auth-aws: "true" @@ -418,6 +418,7 @@ spec: port: 8081 initialDelaySeconds: 5 periodSeconds: 10 + timeoutSeconds: 90 resources: limits: cpu: 200m diff --git a/bundle/manifests/odf.openshift.io_storagesystems.yaml b/bundle/odf-operator/manifests/odf.openshift.io_storagesystems.yaml similarity index 100% rename from bundle/manifests/odf.openshift.io_storagesystems.yaml rename to bundle/odf-operator/manifests/odf.openshift.io_storagesystems.yaml diff --git a/bundle/metadata/annotations.yaml b/bundle/odf-operator/metadata/annotations.yaml similarity index 100% rename from bundle/metadata/annotations.yaml rename to bundle/odf-operator/metadata/annotations.yaml diff --git a/bundle/tests/scorecard/config.yaml b/bundle/odf-operator/tests/scorecard/config.yaml similarity index 100% rename from bundle/tests/scorecard/config.yaml rename to bundle/odf-operator/tests/scorecard/config.yaml diff --git a/catalog/index.yaml b/catalog/index.yaml index eeafc6fb1..2b670f8ab 100644 --- a/catalog/index.yaml +++ b/catalog/index.yaml @@ -9,6 +9,17 @@ name: alpha entries: - name: odf-operator.v4.18.0 +--- +defaultChannel: alpha +name: odf-dependencies +schema: olm.package +--- +schema: olm.channel +package: odf-dependencies +name: alpha +entries: + - name: odf-dependencies.v4.18.0 + --- defaultChannel: alpha name: ocs-operator diff --git a/catalog/odf-dependencies.yaml b/catalog/odf-dependencies.yaml new file mode 100644 index 000000000..a000bc08f --- /dev/null +++ b/catalog/odf-dependencies.yaml @@ -0,0 +1,48 @@ +--- +image: quay.io/ocs-dev/odf-dependencies-bundle:latest +name: odf-dependencies.v4.18.0 +package: odf-dependencies +properties: +- type: olm.package + value: + packageName: odf-dependencies + version: 4.18.0 +- type: olm.package.required + value: + packageName: cephcsi-operator + versionRange: '>=4.17.0 <=4.18.0' +- type: olm.package.required + value: + packageName: csi-addons + versionRange: '>=0.9.1 <=0.10.0' +- type: olm.package.required + value: + packageName: noobaa-operator + versionRange: '>=5.17.0 <=5.18.0' +- type: olm.package.required + value: + packageName: ocs-client-operator + versionRange: '>=4.17.0 <=4.18.0' +- type: olm.package.required + value: + packageName: ocs-operator + versionRange: '>=4.17.0 <=4.18.0' +- type: olm.package.required + value: + packageName: odf-prometheus-operator + versionRange: '>=4.17.0 <=4.18.0' +- type: olm.package.required + value: + packageName: recipe + versionRange: 0.0.1 +- type: olm.package.required + value: + packageName: rook-ceph-operator + versionRange: '>=4.17.0 <=4.18.0' +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsiYWxtLWV4YW1wbGVzIjoiW10iLCJjcmVhdGVkQXQiOiIyMDI0LTExLTE0VDAzOjAwOjQwWiIsIm9wZXJhdG9yZnJhbWV3b3JrLmlvL3N1Z2dlc3RlZC1uYW1lc3BhY2UiOiJvcGVuc2hpZnQtc3RvcmFnZSIsIm9wZXJhdG9ycy5vcGVyYXRvcmZyYW1ld29yay5pby9idWlsZGVyIjoib3BlcmF0b3Itc2RrLXYxLjMxLjAiLCJvcGVyYXRvcnMub3BlcmF0b3JmcmFtZXdvcmsuaW8vb3BlcmF0b3ItdHlwZSI6Im5vbi1zdGFuZGFsb25lIiwib3BlcmF0b3JzLm9wZXJhdG9yZnJhbWV3b3JrLmlvL3Byb2plY3RfbGF5b3V0IjoiZ28ua3ViZWJ1aWxkZXIuaW8vdjMifSwibGFiZWxzIjp7Im9wZXJhdG9yZnJhbWV3b3JrLmlvL2FyY2guYW1kNjQiOiJzdXBwb3J0ZWQiLCJvcGVyYXRvcmZyYW1ld29yay5pby9hcmNoLnBwYzY0bGUiOiJzdXBwb3J0ZWQiLCJvcGVyYXRvcmZyYW1ld29yay5pby9hcmNoLnMzOTB4Ijoic3VwcG9ydGVkIn0sIm5hbWUiOiJvZGYtZGVwZW5kZW5jaWVzLnY0LjE4LjAiLCJuYW1lc3BhY2UiOiJwbGFjZWhvbGRlciJ9LCJzcGVjIjp7ImFwaXNlcnZpY2VkZWZpbml0aW9ucyI6e30sImN1c3RvbXJlc291cmNlZGVmaW5pdGlvbnMiOnt9LCJkZXNjcmlwdGlvbiI6ImRlcGxveXMgZGVwZW5kZW5jaWVzLlxuIiwiZGlzcGxheU5hbWUiOiJEYXRhIEZvdW5kYXRpb24gRGVwZW5kZW5jaWVzIiwiaWNvbiI6W3siYmFzZTY0ZGF0YSI6IlBITjJaeUJwWkQwaVRHRjVaWEpmTVNJZ1pHRjBZUzF1WVcxbFBTSk1ZWGxsY2lBeElpQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIWnBaWGRDYjNnOUlqQWdNQ0F4T1RJZ01UUTFJajQ4WkdWbWN6NDhjM1I1YkdVK0xtTnNjeTB4ZTJacGJHdzZJMlV3TUR0OVBDOXpkSGxzWlQ0OEwyUmxabk0rUEhScGRHeGxQbEpsWkVoaGRDMU1iMmR2TFVoaGRDMURiMnh2Y2p3dmRHbDBiR1UrUEhCaGRHZ2daRDBpVFRFMU55NDNOeXcyTWk0Mk1XRXhOQ3d4TkN3d0xEQXNNU3d1TXpFc015NDBNbU13TERFMExqZzRMVEU0TGpFc01UY3VORFl0TXpBdU5qRXNNVGN1TkRaRE56Z3VPRE1zT0RNdU5Ea3NOREl1TlRNc05UTXVNallzTkRJdU5UTXNORFJoTmk0ME15dzJMalF6TERBc01Dd3hMQzR5TWkweExqazBiQzB6TGpZMkxEa3VNRFpoTVRndU5EVXNNVGd1TkRVc01Dd3dMREF0TVM0MU1TdzNMak16WXpBc01UZ3VNVEVzTkRFc05EVXVORGdzT0RjdU56UXNORFV1TkRnc01qQXVOamtzTUN3ek5pNDBNeTAzTGpjMkxETTJMalF6TFRJeExqYzNMREF0TVM0d09Dd3dMVEV1T1RRdE1TNDNNeTB4TUM0eE0xb2lMejQ4Y0dGMGFDQmpiR0Z6Y3owaVkyeHpMVEVpSUdROUlrMHhNamN1TkRjc09ETXVORGxqTVRJdU5URXNNQ3d6TUM0Mk1TMHlMalU0TERNd0xqWXhMVEUzTGpRMllURTBMREUwTERBc01Dd3dMUzR6TVMwekxqUXliQzAzTGpRMUxUTXlMak0yWXkweExqY3lMVGN1TVRJdE15NHlNeTB4TUM0ek5TMHhOUzQzTXkweE5pNDJRekV5TkM0NE9TdzRMalk1TERFd015NDNOaTQxTERrM0xqVXhMalVzT1RFdU5qa3VOU3c1TUN3NExEZ3pMakEyTERoakxUWXVOamdzTUMweE1TNDJOQzAxTGpZdE1UY3VPRGt0TlM0MkxUWXNNQzA1TGpreExEUXVNRGt0TVRJdU9UTXNNVEl1TlN3d0xEQXRPQzQwTVN3eU15NDNNaTA1TGpRNUxESTNMakUyUVRZdU5ETXNOaTQwTXl3d0xEQXNNQ3cwTWk0MU15dzBOR013TERrdU1qSXNNell1TXl3ek9TNDBOU3c0TkM0NU5Dd3pPUzQwTlUweE5qQXNOekl1TURkak1TNDNNeXc0TGpFNUxERXVOek1zT1M0d05Td3hMamN6TERFd0xqRXpMREFzTVRRdE1UVXVOelFzTWpFdU56Y3RNell1TkRNc01qRXVOemRETnpndU5UUXNNVEEwTERNM0xqVTRMRGMyTGpZc016Y3VOVGdzTlRndU5EbGhNVGd1TkRVc01UZ3VORFVzTUN3d0xERXNNUzQxTVMwM0xqTXpRekl5TGpJM0xEVXlMQzQxTERVMUxDNDFMRGMwTGpJeVl6QXNNekV1TkRnc056UXVOVGtzTnpBdU1qZ3NNVE16TGpZMUxEY3dMakk0TERRMUxqSTRMREFzTlRZdU55MHlNQzQwT0N3MU5pNDNMVE0yTGpZMUxEQXRNVEl1TnpJdE1URXRNamN1TVRZdE16QXVPRE10TXpVdU56Z2lMejQ4TDNOMlp6ND0iLCJtZWRpYXR5cGUiOiJpbWFnZS9zdmcreG1sIn1dLCJpbnN0YWxsIjp7InNwZWMiOnsiZGVwbG95bWVudHMiOltdfSwic3RyYXRlZ3kiOiJkZXBsb3ltZW50In0sImluc3RhbGxNb2RlcyI6W3sic3VwcG9ydGVkIjp0cnVlLCJ0eXBlIjoiT3duTmFtZXNwYWNlIn0seyJzdXBwb3J0ZWQiOnRydWUsInR5cGUiOiJTaW5nbGVOYW1lc3BhY2UifSx7InN1cHBvcnRlZCI6ZmFsc2UsInR5cGUiOiJNdWx0aU5hbWVzcGFjZSJ9LHsic3VwcG9ydGVkIjpmYWxzZSwidHlwZSI6IkFsbE5hbWVzcGFjZXMifV0sImxpbmtzIjpbeyJuYW1lIjoiU291cmNlIENvZGUiLCJ1cmwiOiJodHRwczovL2dpdGh1Yi5jb20vcmVkLWhhdC1zdG9yYWdlL29kZi1vcGVyYXRvciJ9XSwibWFpbnRhaW5lcnMiOlt7ImVtYWlsIjoib2NzLXN1cHBvcnRAcmVkaGF0LmNvbSIsIm5hbWUiOiJSZWQgSGF0IFN1cHBvcnQifV0sIm1hdHVyaXR5IjoiYWxwaGEiLCJtaW5LdWJlVmVyc2lvbiI6IjEuMTYuMCIsInByb3ZpZGVyIjp7Im5hbWUiOiJSZWQgSGF0In0sInZlcnNpb24iOiI0LjE4LjAifX0= +relatedImages: +- image: quay.io/ocs-dev/odf-dependencies-bundle:latest + name: "" +schema: olm.bundle diff --git a/config/bundle/csv.yaml b/config/bundle/csv.yaml new file mode 100644 index 000000000..98babe703 --- /dev/null +++ b/config/bundle/csv.yaml @@ -0,0 +1,40 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + operatorframework.io/suggested-namespace: openshift-storage + operators.operatorframework.io/operator-type: non-standalone + labels: + operatorframework.io/arch.amd64: supported + operatorframework.io/arch.ppc64le: supported + operatorframework.io/arch.s390x: supported + name: odf-dependencies.v0.0.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + description: | + deploys dependencies. + displayName: Data Foundation Dependencies + icon: + - base64data: PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxOTIgMTQ1Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwMDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlJlZEhhdC1Mb2dvLUhhdC1Db2xvcjwvdGl0bGU+PHBhdGggZD0iTTE1Ny43Nyw2Mi42MWExNCwxNCwwLDAsMSwuMzEsMy40MmMwLDE0Ljg4LTE4LjEsMTcuNDYtMzAuNjEsMTcuNDZDNzguODMsODMuNDksNDIuNTMsNTMuMjYsNDIuNTMsNDRhNi40Myw2LjQzLDAsMCwxLC4yMi0xLjk0bC0zLjY2LDkuMDZhMTguNDUsMTguNDUsMCwwLDAtMS41MSw3LjMzYzAsMTguMTEsNDEsNDUuNDgsODcuNzQsNDUuNDgsMjAuNjksMCwzNi40My03Ljc2LDM2LjQzLTIxLjc3LDAtMS4wOCwwLTEuOTQtMS43My0xMC4xM1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjcuNDcsODMuNDljMTIuNTEsMCwzMC42MS0yLjU4LDMwLjYxLTE3LjQ2YTE0LDE0LDAsMCwwLS4zMS0zLjQybC03LjQ1LTMyLjM2Yy0xLjcyLTcuMTItMy4yMy0xMC4zNS0xNS43My0xNi42QzEyNC44OSw4LjY5LDEwMy43Ni41LDk3LjUxLjUsOTEuNjkuNSw5MCw4LDgzLjA2LDhjLTYuNjgsMC0xMS42NC01LjYtMTcuODktNS42LTYsMC05LjkxLDQuMDktMTIuOTMsMTIuNSwwLDAtOC40MSwyMy43Mi05LjQ5LDI3LjE2QTYuNDMsNi40MywwLDAsMCw0Mi41Myw0NGMwLDkuMjIsMzYuMywzOS40NSw4NC45NCwzOS40NU0xNjAsNzIuMDdjMS43Myw4LjE5LDEuNzMsOS4wNSwxLjczLDEwLjEzLDAsMTQtMTUuNzQsMjEuNzctMzYuNDMsMjEuNzdDNzguNTQsMTA0LDM3LjU4LDc2LjYsMzcuNTgsNTguNDlhMTguNDUsMTguNDUsMCwwLDEsMS41MS03LjMzQzIyLjI3LDUyLC41LDU1LC41LDc0LjIyYzAsMzEuNDgsNzQuNTksNzAuMjgsMTMzLjY1LDcwLjI4LDQ1LjI4LDAsNTYuNy0yMC40OCw1Ni43LTM2LjY1LDAtMTIuNzItMTEtMjcuMTYtMzAuODMtMzUuNzgiLz48L3N2Zz4= + mediatype: image/svg+xml + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: false + type: AllNamespaces + links: + - name: Source Code + url: https://github.com/red-hat-storage/odf-operator + maintainers: + - email: ocs-support@redhat.com + name: Red Hat Support + maturity: alpha + minKubeVersion: 1.16.0 + provider: + name: Red Hat + version: 0.0.0 diff --git a/config/bundle/kustomization.yaml b/config/bundle/kustomization.yaml new file mode 100644 index 000000000..34990d776 --- /dev/null +++ b/config/bundle/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- csv.yaml diff --git a/config/manager/manager.env b/config/manager/manager.env index fc61fbdad..061e14e5f 100644 --- a/config/manager/manager.env +++ b/config/manager/manager.env @@ -1,3 +1,9 @@ +ODF_DEPS_SUBSCRIPTION_NAME=odf-dependencies +ODF_DEPS_SUBSCRIPTION_PACKAGE=odf-dependencies +ODF_DEPS_SUBSCRIPTION_CHANNEL=alpha +ODF_DEPS_SUBSCRIPTION_STARTINGCSV=odf-dependencies.v4.18.0 +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE=odf-catalogsource +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE=openshift-marketplace NOOBAA_SUBSCRIPTION_NAME=noobaa-operator NOOBAA_SUBSCRIPTION_PACKAGE=noobaa-operator NOOBAA_SUBSCRIPTION_CHANNEL=alpha diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index d4d689ace..9a79ac9f9 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -50,6 +50,7 @@ spec: drop: - ALL readOnlyRootFilesystem: true + # ref https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes livenessProbe: httpGet: path: /healthz @@ -62,6 +63,7 @@ spec: port: 8081 initialDelaySeconds: 5 periodSeconds: 10 + timeoutSeconds: 90 resources: limits: cpu: 200m diff --git a/controllers/defaults.go b/controllers/defaults.go index f36d5fa3b..b8d837b21 100644 --- a/controllers/defaults.go +++ b/controllers/defaults.go @@ -24,6 +24,13 @@ var ( DefaultValMap = map[string]string{ "OPERATOR_NAMESPACE": "openshift-storage", + "ODF_DEPS_SUBSCRIPTION_NAME": "odf-dependencies", + "ODF_DEPS_SUBSCRIPTION_PACKAGE": "odf-dependencies", + "ODF_DEPS_SUBSCRIPTION_CHANNEL": "alpha", + "ODF_DEPS_SUBSCRIPTION_STARTINGCSV": "odf-dependencies.v4.18.0", + "ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE": "odf-catalogsource", + "ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE": "openshift-marketplace", + "NOOBAA_SUBSCRIPTION_NAME": "noobaa-operator", "NOOBAA_SUBSCRIPTION_PACKAGE": "noobaa-operator", "NOOBAA_SUBSCRIPTION_CHANNEL": "alpha", @@ -90,6 +97,13 @@ var ( OperatorNamespace = GetEnvOrDefault("OPERATOR_NAMESPACE") + OdfDepsSubscriptionName = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_NAME") + OdfDepsSubscriptionPackage = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_PACKAGE") + OdfDepsSubscriptionChannel = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_CHANNEL") + OdfDepsSubscriptionStartingCSV = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_STARTINGCSV") + OdfDepsSubscriptionCatalogSource = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE") + OdfDepsSubscriptionCatalogSourceNamespace = GetEnvOrDefault("ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE") + OcsSubscriptionName = GetEnvOrDefault("OCS_SUBSCRIPTION_NAME") OcsSubscriptionPackage = GetEnvOrDefault("OCS_SUBSCRIPTION_PACKAGE") OcsSubscriptionChannel = GetEnvOrDefault("OCS_SUBSCRIPTION_CHANNEL") diff --git a/controllers/subscriptions.go b/controllers/subscriptions.go index da5dc6144..9bd42ec14 100644 --- a/controllers/subscriptions.go +++ b/controllers/subscriptions.go @@ -28,6 +28,7 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -110,6 +111,14 @@ func CheckExistingSubscriptions(cli client.Client, desiredSubscription *operator } if !subExsist { + // Set the catalog source for the odf-dependencies subscription to match that of the odf-operator subscription + // This ensures that the odf-dependencies subscription uses the same catalog source across all environments, + // including offline and test environments where the catalog name may vary. + if desiredSubscription.Spec.Package == OdfDepsSubscriptionPackage { + desiredSubscription.Spec.CatalogSource = odfSub.Spec.CatalogSource + desiredSubscription.Spec.CatalogSourceNamespace = odfSub.Spec.CatalogSourceNamespace + } + if desiredSubscription.Spec.Config == nil { desiredSubscription.Spec.Config = &operatorv1alpha1.SubscriptionConfig{ Tolerations: odfSub.Spec.Config.Tolerations, @@ -127,6 +136,9 @@ func isProviderMode(cli client.Client) (bool, error) { storageclusters := &ocsv1.StorageClusterList{} err := cli.List(context.TODO(), storageclusters) if err != nil { + if meta.IsNoMatchError(err) { + return false, nil + } return false, err } @@ -206,6 +218,12 @@ func EnsureDesiredSubscription(cli client.Client, desiredSubscription *operatorv return err } + // Skip creating (only update) subscriptions other than odf-dependencies + // It will allow OLM to manage their creation via dependency resolution + if desiredSubscription.Spec.Package != OdfDepsSubscriptionPackage && desiredSubscription.CreationTimestamp.IsZero() { + return nil + } + // create/update subscription sub := &operatorv1alpha1.Subscription{} sub.ObjectMeta = desiredSubscription.ObjectMeta @@ -262,7 +280,7 @@ func GetVendorCsvNames(cli client.Client, kind odfv1alpha1.StorageKind) ([]strin if kind == VendorFlashSystemCluster() { csvNames = []string{IbmSubscriptionStartingCSV} } else if kind == VendorStorageCluster() { - csvNames = []string{OcsSubscriptionStartingCSV, RookSubscriptionStartingCSV, NoobaaSubscriptionStartingCSV, + csvNames = []string{OdfDepsSubscriptionStartingCSV, OcsSubscriptionStartingCSV, RookSubscriptionStartingCSV, NoobaaSubscriptionStartingCSV, PrometheusSubscriptionStartingCSV, RecipeSubscriptionStartingCSV} isProvider, err = isProviderMode(cli) @@ -432,6 +450,22 @@ func GetSubscriptions(k odfv1alpha1.StorageKind) []*operatorv1alpha1.Subscriptio // GetStorageClusterSubscription return subscription for StorageCluster func GetStorageClusterSubscriptions() []*operatorv1alpha1.Subscription { + + odfDepsSubscription := &operatorv1alpha1.Subscription{ + ObjectMeta: metav1.ObjectMeta{ + Name: OdfDepsSubscriptionName, + Namespace: OperatorNamespace, + }, + Spec: &operatorv1alpha1.SubscriptionSpec{ + CatalogSource: OdfDepsSubscriptionCatalogSource, + CatalogSourceNamespace: OdfDepsSubscriptionCatalogSourceNamespace, + Package: OdfDepsSubscriptionPackage, + Channel: OdfDepsSubscriptionChannel, + StartingCSV: OdfDepsSubscriptionStartingCSV, + InstallPlanApproval: operatorv1alpha1.ApprovalAutomatic, + }, + } + noobaaSubscription := &operatorv1alpha1.Subscription{ ObjectMeta: metav1.ObjectMeta{ Name: NoobaaSubscriptionName, @@ -584,7 +618,7 @@ func GetStorageClusterSubscriptions() []*operatorv1alpha1.Subscription { }, } - return []*operatorv1alpha1.Subscription{ocsSubscription, rookSubscription, noobaaSubscription, + return []*operatorv1alpha1.Subscription{odfDepsSubscription, ocsSubscription, rookSubscription, noobaaSubscription, csiAddonsSubscription, cephCsiSubscription, ocsClientSubscription, prometheusSubscription, recipeSubscription} } diff --git a/controllers/subscriptions_test.go b/controllers/subscriptions_test.go index 9a0975323..54ec512be 100644 --- a/controllers/subscriptions_test.go +++ b/controllers/subscriptions_test.go @@ -22,6 +22,7 @@ import ( "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -60,6 +61,9 @@ func TestEnsureSubscription(t *testing.T) { for _, subscription := range subs { sub := subscription.DeepCopy() sub.Spec.Channel = "fake-channel" + // Set the creation timestamp to a non-zero value to simulate that the subscription already exists + // This is required because the fake client does not set the creation timestamp + sub.CreationTimestamp = metav1.Now() err = fakeReconciler.Client.Create(context.TODO(), sub) assert.NoError(t, err) } @@ -101,10 +105,27 @@ func TestEnsureSubscription(t *testing.T) { } actualSubscription := &operatorv1alpha1.Subscription{} - err = fakeReconciler.Client.Get(context.TODO(), types.NamespacedName{Name: expectedSubscription.Name, Namespace: expectedSubscription.Namespace}, actualSubscription) - assert.NoError(t, err) - - assert.Equal(t, expectedSubscription.Spec, actualSubscription.Spec) + err = fakeReconciler.Client.Get(context.TODO(), + types.NamespacedName{Name: expectedSubscription.Name, Namespace: expectedSubscription.Namespace}, actualSubscription) + + // create case + if !tc.subscriptionAlreadyExist { + if expectedSubscription.Spec.Package == OdfDepsSubscriptionPackage { + assert.NoError(t, err) + // Set odf-dependencies catalog and catalog namespace same as odf-operator in expected subscription + // That is what being set by controller and verify the same + expectedSubscription.Spec.CatalogSource = odfSub.Spec.CatalogSource + expectedSubscription.Spec.CatalogSourceNamespace = odfSub.Spec.CatalogSourceNamespace + assert.Equal(t, expectedSubscription.Spec, actualSubscription.Spec) + } else { + assert.Error(t, err) + assert.True(t, errors.IsNotFound(err)) + } + // update case + } else if tc.subscriptionAlreadyExist { + assert.NoError(t, err) + assert.Equal(t, expectedSubscription.Spec, actualSubscription.Spec) + } } } } diff --git a/e2e/config.go b/e2e/config.go index 544a1b30b..2066c6924 100644 --- a/e2e/config.go +++ b/e2e/config.go @@ -18,6 +18,8 @@ var ( OdfClusterUninstall bool // OdfClusterServiceVersion is the name of odf csv OdfClusterServiceVersion string + // OdfDepsClusterServiceVersion is the name of the odf-dependency csv + OdfDepsClusterServiceVersion string // OcsClusterServiceVersion is the name of ocs csv OcsClusterServiceVersion string // OcsClientClusterServiceVersion is the name of ocs-client csv @@ -53,6 +55,7 @@ func init() { flag.BoolVar(&OdfOperatorInstall, "odf-operator-install", true, "Install the ODF operator before starting tests") flag.BoolVar(&OdfClusterUninstall, "odf-operator-uninstall", true, "Uninstall the ODF operator after test completion") flag.StringVar(&OdfClusterServiceVersion, "odf-cluster-service-version", "", "The ODF CSV name which needs to verified") + flag.StringVar(&OdfDepsClusterServiceVersion, "odf-deps-cluster-service-version", "", "The ODF deps CSV name which needs to verified") flag.StringVar(&OcsClusterServiceVersion, "ocs-cluster-service-version", "", "The OCS CSV name which needs to verified") flag.StringVar(&OcsClientClusterServiceVersion, "ocs-client-cluster-service-version", "", "The OCS CSV name which needs to verified") flag.StringVar(&NoobaClusterServiceVersion, "nooba-cluster-service-version", "", "The Nooba CSV name which needs to verified") @@ -93,6 +96,10 @@ func verifyFlags() { panic("odf-cluster-service-version is not provided") } + if OdfDepsClusterServiceVersion == "" { + panic("odf-deps-cluster-service-version is not provided") + } + if OcsClusterServiceVersion == "" { panic("ocs-cluster-service-version is not provided") } diff --git a/hack/e2e-test.sh b/hack/e2e-test.sh index c7780d0c0..e01e07f4f 100755 --- a/hack/e2e-test.sh +++ b/hack/e2e-test.sh @@ -8,6 +8,7 @@ cd e2e/odf && ${GINKGO} build && ./odf.test \ --odf-operator-install=${ODF_OPERATOR_INSTALL} \ --odf-operator-uninstall=${ODF_OPERATOR_UNINSTALL} \ --odf-cluster-service-version=odf-operator.v${VERSION} \ + --odf-deps-cluster-service-version=odf-dependencies.v${VERSION} \ --ocs-cluster-service-version=${OCS_SUBSCRIPTION_STARTINGCSV} \ --ocs-client-cluster-service-version=${OCS_CLIENT_SUBSCRIPTION_STARTINGCSV} \ --nooba-cluster-service-version=${NOOBAA_SUBSCRIPTION_STARTINGCSV} \ diff --git a/hack/install-odf.sh b/hack/install-odf.sh index 7158d0561..0da0e2daf 100755 --- a/hack/install-odf.sh +++ b/hack/install-odf.sh @@ -20,6 +20,15 @@ fi "$OPERATOR_SDK" run bundle "$BUNDLE_IMG" --timeout=10m --security-context-config restricted -n "$INSTALL_NAMESPACE" --index-image "$CATALOG_DEPS_IMG" +# Check for the presence of the CSVs in the cluster for up to 5 minutes, +# Since 'oc wait' exits immediately if the resource is not found. +for i in {1..30}; do + if oc get -n "$INSTALL_NAMESPACE" csv $CSV_NAMES &> /dev/null; then + break + fi + sleep 10 +done + oc wait --timeout=5m --for jsonpath='{.status.phase}'=Succeeded -n "$INSTALL_NAMESPACE" csv $CSV_NAMES || { echo "CSV $CSV_NAMES did not succeed, describing CSV" diff --git a/hack/make-bundle-vars.mk b/hack/make-bundle-vars.mk index 14d00c998..eb2f03dfa 100644 --- a/hack/make-bundle-vars.mk +++ b/hack/make-bundle-vars.mk @@ -53,6 +53,8 @@ REGISTRY_NAMESPACE ?= ocs-dev IMAGE_TAG ?= latest IMAGE_NAME ?= odf-operator BUNDLE_IMAGE_NAME ?= $(IMAGE_NAME)-bundle +ODF_DEPS_BUNDLE_NAME ?= odf-dependencies +ODF_DEPS_BUNDLE_IMAGE_NAME ?= $(ODF_DEPS_BUNDLE_NAME)-bundle CATALOG_IMAGE_NAME ?= $(IMAGE_NAME)-catalog CATALOG_DEPS_IMAGE_NAME ?= $(IMAGE_NAME)-catalog-deps @@ -62,6 +64,9 @@ IMG ?= $(IMAGE_REGISTRY)/$(REGISTRY_NAMESPACE)/$(IMAGE_NAME):$(IMAGE_TAG) # BUNDLE_IMG defines the image used for the bundle. BUNDLE_IMG ?= $(IMAGE_REGISTRY)/$(REGISTRY_NAMESPACE)/$(BUNDLE_IMAGE_NAME):$(IMAGE_TAG) +# ODF_DEPS_BUNDLE_IMG defines the image used for the odf-dependencies bundle. +ODF_DEPS_BUNDLE_IMG ?= $(IMAGE_REGISTRY)/$(REGISTRY_NAMESPACE)/$(ODF_DEPS_BUNDLE_IMAGE_NAME):$(IMAGE_TAG) + # CATALOG_IMG defines the image used for the catalog. CATALOG_IMG ?= $(IMAGE_REGISTRY)/$(REGISTRY_NAMESPACE)/$(CATALOG_IMAGE_NAME):$(IMAGE_TAG) @@ -142,7 +147,7 @@ RECIPE_BUNDLE_IMG ?= $(RECIPE_BUNDLE_IMG_LOCATION)/$(RECIPE_BUNDLE_IMG_NAME):$(R # A space-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0 example.com/operator-bundle:v0.2.0). # These images MUST exist in a registry and be pull-able. -BUNDLE_IMGS ?= $(BUNDLE_IMG) $(OCS_BUNDLE_IMG) $(OCS_CLIENT_BUNDLE_IMG) $(IBM_BUNDLE_IMG) $(NOOBAA_BUNDLE_IMG) \ +BUNDLE_IMGS ?= $(BUNDLE_IMG) $(ODF_DEPS_BUNDLE_IMG) $(OCS_BUNDLE_IMG) $(OCS_CLIENT_BUNDLE_IMG) $(IBM_BUNDLE_IMG) $(NOOBAA_BUNDLE_IMG) \ $(CSIADDONS_BUNDLE_IMG) $(CEPHCSI_BUNDLE_IMG) $(ROOK_BUNDLE_IMG) $(PROMETHEUS_BUNDLE_IMG) $(RECIPE_BUNDLE_IMG_TAG) # Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. @@ -155,6 +160,13 @@ OPERATOR_NAMESPACE ?= openshift-storage OPERATOR_CATALOGSOURCE ?= odf-catalogsource OPERATOR_CATALOGSOURCE_NAMESPACE ?= openshift-marketplace +ODF_DEPS_SUBSCRIPTION_NAME ?= $(ODF_DEPS_BUNDLE_NAME) +ODF_DEPS_SUBSCRIPTION_PACKAGE ?= $(ODF_DEPS_BUNDLE_NAME) +ODF_DEPS_SUBSCRIPTION_CHANNEL ?= $(DEFAULT_CHANNEL) +ODF_DEPS_SUBSCRIPTION_STARTINGCSV ?= $(ODF_DEPS_BUNDLE_NAME).v$(VERSION) +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE ?= $(OPERATOR_CATALOGSOURCE) +ODF_DEPS_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE ?= $(OPERATOR_CATALOGSOURCE_NAMESPACE) + NOOBAA_SUBSCRIPTION_NAME ?= $(NOOBAA_BUNDLE_NAME) NOOBAA_SUBSCRIPTION_PACKAGE ?= $(NOOBAA_BUNDLE_NAME) NOOBAA_SUBSCRIPTION_CHANNEL ?= $(DEFAULT_CHANNEL) @@ -218,9 +230,9 @@ RECIPE_SUBSCRIPTION_STARTINGCSV ?= $(RECIPE_BUNDLE_NAME).$(RECIPE_BUNDLE_VERSION RECIPE_SUBSCRIPTION_CATALOGSOURCE ?= $(OPERATOR_CATALOGSOURCE) RECIPE_SUBSCRIPTION_CATALOGSOURCE_NAMESPACE ?= $(OPERATOR_CATALOGSOURCE_NAMESPACE) -STARTING_CSVS ?= "$(IMAGE_NAME).v$(VERSION) $(OCS_SUBSCRIPTION_STARTINGCSV) $(ROOK_SUBSCRIPTION_STARTINGCSV) $(NOOBAA_SUBSCRIPTION_STARTINGCSV) \ - $(CSIADDONS_SUBSCRIPTION_STARTINGCSV) $(CEPHCSI_SUBSCRIPTION_STARTINGCSV) $(OCS_CLIENT_SUBSCRIPTION_STARTINGCSV) \ - $(PROMETHEUS_SUBSCRIPTION_STARTINGCSV) $(RECIPE_SUBSCRIPTION_STARTINGCSV)" +STARTING_CSVS ?= "$(IMAGE_NAME).v$(VERSION) $(ODF_DEPS_SUBSCRIPTION_STARTINGCSV) $(OCS_SUBSCRIPTION_STARTINGCSV) $(ROOK_SUBSCRIPTION_STARTINGCSV) \ + $(NOOBAA_SUBSCRIPTION_STARTINGCSV) $(CSIADDONS_SUBSCRIPTION_STARTINGCSV) $(CEPHCSI_SUBSCRIPTION_STARTINGCSV) \ + $(OCS_CLIENT_SUBSCRIPTION_STARTINGCSV) $(PROMETHEUS_SUBSCRIPTION_STARTINGCSV) $(RECIPE_SUBSCRIPTION_STARTINGCSV)" # kube rbac proxy image variables CLUSTER_ENV ?= openshift diff --git a/main.go b/main.go index dcaa3f2e0..7079ffe60 100644 --- a/main.go +++ b/main.go @@ -171,7 +171,24 @@ func main() { setupLog.Error(err, "unable to set up health check") os.Exit(1) } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + + // console plugin is dependent on CRDs that are part of these CSVs and we + // can't check for only odf-dependencies CSV as OLM doesn't guarantee + // (based on observations) existence of all CRDs brought by OLM dependency + // mechanism. + csvsToBeSuceeded := []string{ + controllers.OcsSubscriptionStartingCSV, + controllers.RookSubscriptionStartingCSV, + controllers.NoobaaSubscriptionStartingCSV, + } + if err := mgr.AddReadyzCheck( + "readyz", + util.CheckCSVPhase( + mgr.GetClient(), + operatorNamespace, + csvsToBeSuceeded..., + ), + ); err != nil { setupLog.Error(err, "unable to set up ready check") os.Exit(1) } diff --git a/pkg/util/readiness.go b/pkg/util/readiness.go new file mode 100644 index 000000000..fe5e5a8f8 --- /dev/null +++ b/pkg/util/readiness.go @@ -0,0 +1,79 @@ +/* +Copyright 2024 Red Hat OpenShift Data Foundation. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. +*/ + +package util + +import ( + "fmt" + "net/http" + "strings" + + opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/healthz" +) + +func CheckCSVPhase(c client.Client, namespace string, csvNames ...string) healthz.Checker { + + csvMap := map[string]struct{}{} + for _, name := range csvNames { + csvMap[name] = struct{}{} + } + return func(r *http.Request) error { + csvList := &opv1a1.ClusterServiceVersionList{} + if err := c.List(r.Context(), csvList, client.InNamespace(namespace)); err != nil { + return err + } + + // Check if it is upgrade from 4.17 to 4.18 + // The new CSVs won't exists while upgrading + // They will exists only after new operator has created a new subscription + if AreMultipleOdfOperatorCsvsPresent(csvList) { + return nil + } + + for idx := range csvList.Items { + csv := &csvList.Items[idx] + _, exists := csvMap[csv.Name] + if exists { + if csv.Status.Phase != opv1a1.CSVPhaseSucceeded { + return fmt.Errorf("CSV %s is not in Succeeded phase", csv.Name) + } else if csv.Status.Phase == opv1a1.CSVPhaseSucceeded { + delete(csvMap, csv.Name) + } + } + } + if len(csvMap) != 0 { + for csvName := range csvMap { + return fmt.Errorf("CSV %s is not found", csvName) + } + } + return nil + } +} + +func AreMultipleOdfOperatorCsvsPresent(csvs *opv1a1.ClusterServiceVersionList) bool { + + count := 0 + + for _, csv := range csvs.Items { + if strings.HasPrefix(csv.Name, "odf-operator") { + count += 1 + } + } + + return count > 1 +}