diff --git a/ci-operator/config/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main__s390x.yaml b/ci-operator/config/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main__s390x.yaml new file mode 100644 index 0000000000000..47b0696c4d252 --- /dev/null +++ b/ci-operator/config/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main__s390x.yaml @@ -0,0 +1,65 @@ +base_images: + cli: + name: "5.0" + namespace: ocp + tag: cli + libvirt-installer: + name: "5.0" + namespace: ocp + tag: libvirt-installer + upi-installer: + name: "5.0" + namespace: ocp + tag: upi-installer +build_root: + image_stream_tag: + name: release + namespace: openshift + tag: rhel-9-release-golang-1.26-openshift-5.0 +releases: + latest: + candidate: + architecture: multi + product: ocp + stream: nightly + version: "5.0" + s390x-latest: + candidate: + architecture: s390x + product: ocp + stream: nightly + version: "5.0" +resources: + '*': + limits: + memory: 8Gi + requests: + cpu: "2" + memory: 2Gi +tests: +- always_run: false + as: e2e + capabilities: + - intranet + optional: true + steps: + cluster_profile: libvirt-s390x-vpn-oz + dependencies: + OPENSHIFT_INSTALL_TARGET: release:s390x-latest + env: + ARCH: s390x + BRANCH: "5.0" + COMPUTE_COUNT: "2" + CONTROL_COUNT: "3" + CRO_ART_IMAGE_SHARE: quay.io/redhat-user-workloads/ocp-art-tenant/art-images-share + CRO_CATALOG_IMAGE: quay.io/redhat-user-workloads/ocp-art-tenant/art-fbc:ocp__5.0__ose-clusterresourceoverride-rhel9-operator + CRO_CATALOG_SOURCE: cro-art-fbc + ETCD_DISK_SPEED: slow + NODE_TUNING: "true" + USE_EXTERNAL_DNS: "true" + workflow: cluster-resource-override-s390x +zz_generated_metadata: + branch: main + org: openshift + repo: cluster-resource-override-admission-operator + variant: s390x diff --git a/ci-operator/jobs/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main-presubmits.yaml b/ci-operator/jobs/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main-presubmits.yaml index 64dde4b8edd91..10db759050301 100644 --- a/ci-operator/jobs/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main-presubmits.yaml +++ b/ci-operator/jobs/openshift/cluster-resource-override-admission-operator/openshift-cluster-resource-override-admission-operator-main-presubmits.yaml @@ -376,6 +376,93 @@ presubmits: secret: secretName: result-aggregator trigger: (?m)^/test( | .* )images,?($|\s.*) + - agent: kubernetes + always_run: false + branches: + - ^main$ + - ^main- + cluster: build12 + context: ci/prow/s390x-e2e + decorate: true + decoration_config: + skip_cloning: true + labels: + capability/intranet: intranet + ci-operator.openshift.io/cloud: libvirt-s390x-vpn-oz + ci-operator.openshift.io/cloud-cluster-profile: libvirt-s390x-vpn-oz + ci-operator.openshift.io/variant: s390x + ci.openshift.io/generator: prowgen + job-release: "5.0" + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: pull-ci-openshift-cluster-resource-override-admission-operator-main-s390x-e2e + optional: true + rerun_command: /test s390x-e2e + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=e2e + - --variant=s390x + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator + trigger: (?m)^/test( | .* )s390x-e2e,?($|\s.*) - agent: kubernetes always_run: false branches: diff --git a/ci-operator/step-registry/cluster-resource-override/OWNERS b/ci-operator/step-registry/cluster-resource-override/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/OWNERS b/ci-operator/step-registry/cluster-resource-override/s390x/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/OWNERS b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-commands.sh b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-commands.sh new file mode 100755 index 0000000000000..0043b00b77ff9 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-commands.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -euo pipefail + +echo "=== Cleaning up ClusterResourceOverride s390x test components (best effort) ===" + +oc delete clusterresourceoverride cluster -n "${CRO_NAMESPACE}" --ignore-not-found --timeout=60s || true +oc delete subscription "${CRO_SUBSCRIPTION_NAME}" -n "${CRO_NAMESPACE}" --ignore-not-found --timeout=60s || true +oc delete csv --all -n "${CRO_NAMESPACE}" --ignore-not-found --timeout=60s || true +oc delete operatorgroup --all -n "${CRO_NAMESPACE}" --ignore-not-found --timeout=60s || true +oc delete imagedigestmirrorset "${CRO_IDMS_NAME}" --ignore-not-found || true +# Only delete custom catalogs we created; never remove stock redhat-operators. +if [[ -n "${CRO_CATALOG_SOURCE:-}" && "${CRO_CATALOG_SOURCE}" != "redhat-operators" && "${CRO_CATALOG_SOURCE}" != "certified-operators" && "${CRO_CATALOG_SOURCE}" != "community-operators" && "${CRO_CATALOG_SOURCE}" != "redhat-marketplace" ]]; then + oc delete catalogsource "${CRO_CATALOG_SOURCE}" -n "${CRO_CATALOG_SOURCE_NAMESPACE:-openshift-marketplace}" --ignore-not-found || true +fi +oc delete ns "${CRO_NAMESPACE}" --ignore-not-found --timeout=180s || true + +echo "=== Component cleanup complete ===" diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.metadata.json b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.metadata.json new file mode 100644 index 0000000000000..b8ca129058121 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.yaml", + "owners": { + "approvers": [ + "multiarch-approvers" + ], + "reviewers": [ + "multiarch-reviewers" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.yaml b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.yaml new file mode 100644 index 0000000000000..a7000d031c760 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cleanup/cluster-resource-override-s390x-cleanup-ref.yaml @@ -0,0 +1,39 @@ +ref: + as: cluster-resource-override-s390x-cleanup + from_image: + namespace: ocp + name: cli-jq + tag: latest + commands: cluster-resource-override-s390x-cleanup-commands.sh + grace_period: 1m0s + resources: + requests: + cpu: 100m + memory: 200Mi + timeout: 15m0s + env: + - name: CRO_NAMESPACE + default: "openshift-cluster-resource-override" + documentation: |- + Namespace where the ClusterResourceOverride operator was installed. + - name: CRO_SUBSCRIPTION_NAME + default: "clusterresourceoverride" + documentation: |- + Subscription name to delete during cleanup. + - name: CRO_IDMS_NAME + default: "cluster-resource-override-idms" + documentation: |- + ImageDigestMirrorSet name to delete during cleanup. + - name: CRO_CATALOG_SOURCE + default: "redhat-operators" + documentation: |- + CatalogSource name. Custom sources (not stock marketplace catalogs) are + deleted during cleanup. + - name: CRO_CATALOG_SOURCE_NAMESPACE + default: "openshift-marketplace" + documentation: |- + Namespace of CRO_CATALOG_SOURCE. + documentation: |- + Best-effort cleanup of ClusterResourceOverride operator resources created by + the s390x install step (CR, Subscription, CSVs, namespace, IDMS, custom + CatalogSource). diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.metadata.json b/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.metadata.json new file mode 100644 index 0000000000000..f037d9d487b7d --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.yaml", + "owners": { + "approvers": [ + "multiarch-approvers" + ], + "reviewers": [ + "multiarch-reviewers" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.yaml b/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.yaml new file mode 100644 index 0000000000000..af72556a6f20d --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/cluster-resource-override-s390x-workflow.yaml @@ -0,0 +1,25 @@ +workflow: + as: cluster-resource-override-s390x + steps: + allow_best_effort_post_steps: true + pre: + - ref: upi-libvirt-cleanup-pre + - chain: upi-conf-libvirt + - ref: ipi-debug-missing-static-pod-controller-degraded + - ref: ipi-conf-etcd-on-ramfs + - chain: upi-install-libvirt + test: + - chain: cluster-resource-override-s390x-test + post: + - ref: cluster-resource-override-s390x-cleanup + - ref: ipi-conf-debug-kdump-gather-logs + - chain: gather + - ref: upi-libvirt-cleanup-post + documentation: |- + End-to-end workflow for the ClusterResourceOverride operator on s390x (IBM Z). + Provisions an OCP cluster on the VPN'd IBM Z CI environment using the same + UPI/libvirt pre and post steps as openshift-e2e-libvirt-vpn, installs the + ClusterResourceOverride operator via OLM (with optional ImageDigestMirrorSet + image source changes), creates the ClusterResourceOverride CR, then runs the + test step. Component cleanup runs first in post, followed by gather and + cluster deprovisioning. diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/OWNERS b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-commands.sh b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-commands.sh new file mode 100755 index 0000000000000..96d9040e203e3 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-commands.sh @@ -0,0 +1,409 @@ +#!/bin/bash + +set -euo pipefail + +wait_for_csv() { + local ns="$1" sub="$2" csv phase + echo "Waiting for CSV of subscription ${sub} in ${ns} ..." + for _ in $(seq 1 90); do + csv="$(oc get subscription "${sub}" -n "${ns}" -o jsonpath='{.status.installedCSV}' 2>/dev/null || true)" + if [[ -n "${csv}" ]]; then + phase="$(oc get csv "${csv}" -n "${ns}" -o jsonpath='{.status.phase}' 2>/dev/null || true)" + echo " ${csv} phase: ${phase:-}" + [[ "${phase}" == "Succeeded" ]] && return 0 + fi + sleep 10 + done + echo "ERROR: CSV for ${sub} did not reach Succeeded" >&2 + oc get subscription "${sub}" -n "${ns}" -o yaml >&2 || true + oc get csv -n "${ns}" -o yaml >&2 || true + oc get events -n "${ns}" --sort-by='.lastTimestamp' | tail -30 >&2 || true + dump_deployment_debug "csv-not-succeeded" + return 1 +} + +dump_deployment_debug() { + local reason="${1:-deployment-failure}" + local out="${ARTIFACT_DIR}/cro-deploy-debug-${reason}" + mkdir -p "${out}" + + echo "=== DEBUG (${reason}): dumping operator deployment state to ${out} ===" >&2 + + { + echo "=== reason: ${reason} ===" + echo "=== namespace: ${CRO_NAMESPACE} ===" + echo "=== CRO_OPERATOR_IMAGE=${CRO_OPERATOR_IMAGE:-} ===" + echo "=== CRO_OPERAND_IMAGE=${CRO_OPERAND_IMAGE:-} ===" + date -u +"=== timestamp: %Y-%m-%dT%H:%M:%SZ ===" + } >"${out}/summary.txt" 2>&1 || true + + oc get all,csv,subscription,installplan,operatorgroup -n "${CRO_NAMESPACE}" -o wide \ + >"${out}/get-all-wide.txt" 2>&1 || true + oc get deployment,rs,pods -n "${CRO_NAMESPACE}" -o yaml \ + >"${out}/workload.yaml" 2>&1 || true + oc describe deployment/clusterresourceoverride-operator -n "${CRO_NAMESPACE}" \ + >"${out}/describe-deployment.txt" 2>&1 || true + oc get pods -n "${CRO_NAMESPACE}" -o wide \ + >"${out}/pods-wide.txt" 2>&1 || true + oc get pods -n "${CRO_NAMESPACE}" -o json \ + >"${out}/pods.json" 2>&1 || true + oc get events -n "${CRO_NAMESPACE}" --sort-by='.lastTimestamp' \ + >"${out}/events.txt" 2>&1 || true + + # Per-pod details (image pull / crashloop) + local pod + for pod in $(oc get pods -n "${CRO_NAMESPACE}" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null || true); do + oc describe pod "${pod}" -n "${CRO_NAMESPACE}" \ + >"${out}/describe-pod-${pod}.txt" 2>&1 || true + oc logs "${pod}" -n "${CRO_NAMESPACE}" --all-containers --tail=200 \ + >"${out}/logs-pod-${pod}.txt" 2>&1 || true + oc get pod "${pod}" -n "${CRO_NAMESPACE}" -o jsonpath='{.spec.containers[*].image}{"\n"}{.status.containerStatuses[*].image}{"\n"}{.status.containerStatuses[*].imageID}{"\n"}{.status.containerStatuses[*].state}{"\n"}' \ + >"${out}/images-pod-${pod}.txt" 2>&1 || true + done + + local csv + csv="$(oc get subscription "${CRO_SUBSCRIPTION_NAME}" -n "${CRO_NAMESPACE}" -o jsonpath='{.status.installedCSV}' 2>/dev/null || true)" + if [[ -n "${csv}" ]]; then + oc get csv "${csv}" -n "${CRO_NAMESPACE}" -o yaml >"${out}/csv.yaml" 2>&1 || true + oc describe csv "${csv}" -n "${CRO_NAMESPACE}" >"${out}/describe-csv.txt" 2>&1 || true + fi + + # Also echo a short digest into the build log for quick triage + echo "=== DEBUG (${reason}): deployments/pods ===" >&2 + oc get deployment,pods -n "${CRO_NAMESPACE}" -o wide >&2 || true + echo "=== DEBUG (${reason}): recent events ===" >&2 + oc get events -n "${CRO_NAMESPACE}" --sort-by='.lastTimestamp' | tail -40 >&2 || true + echo "=== DEBUG (${reason}): pod images/state ===" >&2 + oc get pods -n "${CRO_NAMESPACE}" -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\t"}{range .status.containerStatuses[*]}{.image}{"\t"}{.state}{"\n"}{end}{end}' >&2 || true + echo "=== DEBUG (${reason}): full dump under ${out} ===" >&2 +} + +apply_idms_if_configured() { + if [[ -z "${CRO_MIRROR_OPERATOR_IMAGE}" && -z "${CRO_MIRROR_OPERAND_IMAGE}" ]]; then + echo "=== Skipping ImageDigestMirrorSet (no CRO_MIRROR_* repositories configured) ===" + return 0 + fi + + echo "=== Applying ImageDigestMirrorSet ${CRO_IDMS_NAME} (image source change) ===" + { + echo "apiVersion: config.openshift.io/v1" + echo "kind: ImageDigestMirrorSet" + echo "metadata:" + echo " name: ${CRO_IDMS_NAME}" + echo "spec:" + echo " imageDigestMirrors:" + if [[ -n "${CRO_MIRROR_OPERATOR_IMAGE}" ]]; then + echo " - source: ${CRO_SOURCE_OPERATOR_IMAGE}" + echo " mirrors:" + echo " - ${CRO_MIRROR_OPERATOR_IMAGE}" + fi + if [[ -n "${CRO_MIRROR_OPERAND_IMAGE}" ]]; then + echo " - source: ${CRO_SOURCE_OPERAND_IMAGE}" + echo " mirrors:" + echo " - ${CRO_MIRROR_OPERAND_IMAGE}" + fi + } | oc apply -f - +} + +# Match secrets-store / Konflux ART weekly jobs: pull-secret for art-images-share + +# IDMS so registry.redhat.io/openshift{4,5}/ose-clusterresourceoverride-* digests +# resolve from quay.io/redhat-user-workloads/ocp-art-tenant/art-images-share. +setup_art_image_share_access() { + if [[ -z "${CRO_ART_IMAGE_SHARE}" ]]; then + echo "=== Skipping ART image-share access (CRO_ART_IMAGE_SHARE unset) ===" + return 0 + fi + + local art_pull_secret="${CRO_ART_PULL_SECRET_PATH}" + if [[ ! -f "${art_pull_secret}" ]]; then + echo "ERROR: ART image-share pull secret not found at ${art_pull_secret}" >&2 + echo "Mount credentials secret deploy-konflux-operator-art-image-share (test-credentials)." >&2 + return 1 + fi + + echo "=== Merging ART image-share credentials into cluster pull-secret ===" + # Disable tracing due to pull-secret handling + [[ $- == *x* ]] && WAS_TRACING=true || WAS_TRACING=false + set +x + mkdir -p /tmp/cro-pull-secret + oc extract secret/pull-secret -n openshift-config --confirm --to /tmp/cro-pull-secret + jq -s '.[0].auths += .[1].auths | .[0]' \ + /tmp/cro-pull-secret/.dockerconfigjson \ + "${art_pull_secret}" > /tmp/cro-merged-pullsecret.json + oc set data secret/pull-secret -n openshift-config \ + --from-file=.dockerconfigjson=/tmp/cro-merged-pullsecret.json + rm -rf /tmp/cro-pull-secret /tmp/cro-merged-pullsecret.json + $WAS_TRACING && set -x + + echo "=== Applying ImageDigestMirrorSet ${CRO_IDMS_NAME} -> ${CRO_ART_IMAGE_SHARE} ===" + cat </dev/null || true)" + if [[ "${status}" == "READY" ]]; then + echo "CatalogSource ${CRO_CATALOG_SOURCE} is READY" + return 0 + fi + echo "Waiting for CatalogSource READY... (${i}/60) state=${status:-}" + sleep 10 + done + + echo "ERROR: CatalogSource ${CRO_CATALOG_SOURCE} did not become READY" >&2 + oc -n "${CRO_CATALOG_SOURCE_NAMESPACE}" get catalogsource "${CRO_CATALOG_SOURCE}" -o yaml >&2 || true + oc -n "${CRO_CATALOG_SOURCE_NAMESPACE}" get pods -l "olm.catalogSource=${CRO_CATALOG_SOURCE}" -o wide >&2 || true + oc -n "${CRO_CATALOG_SOURCE_NAMESPACE}" get pods -l "olm.catalogSource=${CRO_CATALOG_SOURCE}" -o yaml >&2 || true + return 1 +} + +package_manifest_ready() { + oc get packagemanifest -n openshift-marketplace -o json \ + | jq -e \ + --arg pkg "${CRO_PACKAGE_NAME}" \ + --arg src "${CRO_CATALOG_SOURCE}" ' + .items[] + | select(.status.catalogSource == $src) + | select( + .metadata.name == $pkg + or (.status.packageName // "") == $pkg + ) + ' >/dev/null 2>&1 +} + +patch_operator_images() { + local csv + if [[ -z "${CRO_OPERATOR_IMAGE}" && -z "${CRO_OPERAND_IMAGE}" ]]; then + echo "=== Skipping image overrides (CRO_OPERATOR_IMAGE / CRO_OPERAND_IMAGE unset) ===" + return 0 + fi + + csv="$(oc get subscription "${CRO_SUBSCRIPTION_NAME}" -n "${CRO_NAMESPACE}" -o jsonpath='{.status.installedCSV}')" + if [[ -z "${csv}" ]]; then + echo "ERROR: no installedCSV for ${CRO_SUBSCRIPTION_NAME}" >&2 + return 1 + fi + + echo "=== Patching CSV ${csv} images ===" + echo " operator: ${CRO_OPERATOR_IMAGE:-}" + echo " operand: ${CRO_OPERAND_IMAGE:-}" + + echo "=== Pre-override deployment images ===" + oc get deployment/clusterresourceoverride-operator -n "${CRO_NAMESPACE}" \ + -o jsonpath='{.spec.template.spec.containers[*].name}{" -> "}{.spec.template.spec.containers[*].image}{"\n"}' || true + + oc get csv "${csv}" -n "${CRO_NAMESPACE}" -o json \ + | jq \ + --arg op_img "${CRO_OPERATOR_IMAGE}" \ + --arg operand_img "${CRO_OPERAND_IMAGE}" ' + def set_container_image: + if $op_img != "" then + (.spec.install.spec.deployments[]? + | select(.name == "clusterresourceoverride-operator") + | .spec.template.spec.containers[]? + | select(.name == "clusterresourceoverride-operator") + | .image) = $op_img + else . end; + def set_operand_env: + if $operand_img != "" then + (.spec.install.spec.deployments[]? + | select(.name == "clusterresourceoverride-operator") + | .spec.template.spec.containers[]? + | select(.name == "clusterresourceoverride-operator") + | .env[]? + | select(.name == "OPERAND_IMAGE") + | .value) = $operand_img + else . end; + def set_related_images: + if (.spec.relatedImages|type) == "array" then + .spec.relatedImages |= map( + if $op_img != "" and (.name|test("operator";"i")) then .image = $op_img + elif $operand_img != "" and (.name|test("operand|clusterresourceoverride";"i")) and (.name|test("operator";"i")|not) then .image = $operand_img + else . end + ) + else . end; + set_container_image | set_operand_env | set_related_images + ' \ + | oc apply -f - + + if [[ -n "${CRO_OPERATOR_IMAGE}" ]]; then + oc set image deployment/clusterresourceoverride-operator \ + -n "${CRO_NAMESPACE}" \ + "clusterresourceoverride-operator=${CRO_OPERATOR_IMAGE}" + fi + if [[ -n "${CRO_OPERAND_IMAGE}" ]]; then + oc set env deployment/clusterresourceoverride-operator \ + -n "${CRO_NAMESPACE}" \ + "OPERAND_IMAGE=${CRO_OPERAND_IMAGE}" + fi + + echo "=== Post-override deployment images ===" + oc get deployment/clusterresourceoverride-operator -n "${CRO_NAMESPACE}" \ + -o jsonpath='{.spec.template.spec.containers[*].name}{" -> "}{.spec.template.spec.containers[*].image}{"\n"}' || true + oc set env deployment/clusterresourceoverride-operator -n "${CRO_NAMESPACE}" --list 2>/dev/null | grep -E 'OPERAND_IMAGE|RELATED' || true + + if ! oc rollout status deployment/clusterresourceoverride-operator \ + -n "${CRO_NAMESPACE}" --timeout=600s; then + dump_deployment_debug "rollout-after-image-patch" + return 1 + fi +} + +echo "=== Ensuring operator namespace ${CRO_NAMESPACE} ===" +oc get ns "${CRO_NAMESPACE}" >/dev/null 2>&1 || oc create ns "${CRO_NAMESPACE}" + +setup_art_image_share_access +apply_idms_if_configured +ensure_catalog_source + +echo "=== Waiting for PackageManifest ${CRO_PACKAGE_NAME} from CatalogSource ${CRO_CATALOG_SOURCE} ===" +for i in $(seq 1 36); do + if package_manifest_ready; then + echo "PackageManifest found from ${CRO_CATALOG_SOURCE}." + break + fi + echo "Waiting for PackageManifest... (${i}/36)" + sleep 10 +done + +if ! package_manifest_ready; then + echo "ERROR: PackageManifest '${CRO_PACKAGE_NAME}' not found from CatalogSource '${CRO_CATALOG_SOURCE}'" >&2 + oc get packagemanifest -n openshift-marketplace -o wide 2>/dev/null | grep -i clusterresource || true + oc get packagemanifest -n openshift-marketplace -o json \ + | jq -r --arg pkg "${CRO_PACKAGE_NAME}" \ + '.items[] | select(.metadata.name == $pkg) | [.metadata.name, .status.catalogSource, .status.catalogSourceNamespace] | @tsv' \ + >&2 || true + oc get catalogsource -n "${CRO_CATALOG_SOURCE_NAMESPACE}" -o wide >&2 || true + exit 1 +fi + +echo "=== Creating OperatorGroup and Subscription ===" +cat < "${ARTIFACT_DIR}/clusterresourceoverride-cr.yaml" || true +fi + +echo "=== ClusterResourceOverride operator install complete ===" diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.metadata.json b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.metadata.json new file mode 100644 index 0000000000000..24eca770cbcd2 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.yaml", + "owners": { + "approvers": [ + "multiarch-approvers" + ], + "reviewers": [ + "multiarch-reviewers" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.yaml b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.yaml new file mode 100644 index 0000000000000..547254869e96e --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/install-operator/cluster-resource-override-s390x-install-operator-ref.yaml @@ -0,0 +1,116 @@ +ref: + as: cluster-resource-override-s390x-install-operator + from_image: + namespace: ocp + name: cli-jq + tag: latest + commands: cluster-resource-override-s390x-install-operator-commands.sh + grace_period: 1m0s + resources: + requests: + cpu: 100m + memory: 200Mi + # Pull-secret/IDMS MCP rollout + OLM subscribe; keep tighter than a padded 90m. + timeout: 60m0s + credentials: + - namespace: test-credentials + name: deploy-konflux-operator-art-image-share + mount_path: /var/run/secrets/pull-secret + env: + - name: CRO_NAMESPACE + default: "openshift-cluster-resource-override" + documentation: |- + Namespace where the ClusterResourceOverride operator is installed. + - name: CRO_PACKAGE_NAME + default: "clusterresourceoverride" + documentation: |- + OLM package name to subscribe to. Product catalogs often use + "clusterresourceoverride"; upstream bundle annotations use + "clusterresourceoverride-operator". + - name: CRO_SUBSCRIPTION_NAME + default: "clusterresourceoverride" + documentation: |- + Name of the Subscription object created in CRO_NAMESPACE. + - name: CRO_CHANNEL + default: "stable" + documentation: |- + Subscription channel for the ClusterResourceOverride operator. + - name: CRO_CATALOG_SOURCE + default: "redhat-operators" + documentation: |- + CatalogSource name used for the Subscription (in openshift-marketplace + unless CRO_CATALOG_SOURCE_NAMESPACE is overridden). When CRO_CATALOG_IMAGE + is set, this CatalogSource is created/replaced before subscribing. + - name: CRO_CATALOG_SOURCE_NAMESPACE + default: "openshift-marketplace" + documentation: |- + Namespace of the CatalogSource referenced by the Subscription. + - name: CRO_CATALOG_IMAGE + default: "" + documentation: |- + Optional index/FBC image for a custom CatalogSource. When set, the step + creates CRO_CATALOG_SOURCE from this image (ART FBC recommended for 5.0 + s390x where redhat-operators may not list clusterresourceoverride yet). + Example: quay.io/redhat-user-workloads/ocp-art-tenant/art-fbc:ocp__5.0__ose-clusterresourceoverride-rhel9-operator + - name: CRO_CREATE_CR + default: "true" + documentation: |- + When "true", create the ClusterResourceOverride CR after the CSV is Ready. + - name: CRO_OPERATOR_IMAGE + default: "" + documentation: |- + Optional override for the clusterresourceoverride-operator container image + (CSV + Deployment). When empty, the image from the OLM catalog CSV is used. + - name: CRO_OPERAND_IMAGE + default: "" + documentation: |- + Optional override for OPERAND_IMAGE on the operator Deployment/CSV. When + empty, the catalog/CSV value is left unchanged. + - name: CRO_ART_IMAGE_SHARE + default: "" + documentation: |- + When set (e.g. quay.io/redhat-user-workloads/ocp-art-tenant/art-images-share), + merge deploy-konflux-operator-art-image-share into the cluster pull-secret + and create an ImageDigestMirrorSet mapping registry.redhat.io openshift4/5 + ClusterResourceOverride repos to this mirror (Konflux ART weekly pattern). + - name: CRO_ART_PULL_SECRET_PATH + default: "/var/run/secrets/pull-secret/.dockerconfigjson" + documentation: |- + Path to the mounted ART image-share dockerconfigjson (from credentials + deploy-konflux-operator-art-image-share). + - name: CRO_IDMS_NAME + default: "cluster-resource-override-idms" + documentation: |- + Name of the ImageDigestMirrorSet created for ART image-share and/or + CRO_MIRROR_* mappings. + - name: CRO_SOURCE_OPERATOR_IMAGE + default: "registry.redhat.io/openshift4/ose-clusterresourceoverride-rhel9-operator" + documentation: |- + Source operator image repository for ImageDigestMirrorSet. Ignored when + CRO_MIRROR_OPERATOR_IMAGE is empty. + - name: CRO_MIRROR_OPERATOR_IMAGE + default: "" + documentation: |- + Mirror repository for the operator image. When non-empty, an + ImageDigestMirrorSet entry is created mapping CRO_SOURCE_OPERATOR_IMAGE + to this mirror (image source change). Prefer CRO_OPERATOR_IMAGE when using + a full pullspec override (tag or digest). + - name: CRO_SOURCE_OPERAND_IMAGE + default: "registry.redhat.io/openshift4/ose-clusterresourceoverride-rhel9" + documentation: |- + Source operand image repository for ImageDigestMirrorSet. Ignored when + CRO_MIRROR_OPERAND_IMAGE is empty. + - name: CRO_MIRROR_OPERAND_IMAGE + default: "" + documentation: |- + Mirror repository for the operand (admission webhook) image. When non-empty, + an ImageDigestMirrorSet entry is created mapping CRO_SOURCE_OPERAND_IMAGE + to this mirror. Prefer CRO_OPERAND_IMAGE when using a full pullspec override. + documentation: |- + Installs the ClusterResourceOverride operator via OLM Subscription on a + provisioned s390x cluster. Optionally merges Konflux ART image-share + credentials + IDMS (CRO_ART_IMAGE_SHARE), creates a CatalogSource from + CRO_CATALOG_IMAGE (ART FBC), and/or patches CSV/Deployment when + CRO_OPERATOR_IMAGE / CRO_OPERAND_IMAGE are set. Waits for the CSV to + Succeed, then optionally creates the ClusterResourceOverride CR. + diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/OWNERS b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-commands.sh b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-commands.sh new file mode 100755 index 0000000000000..a5591a221ff3a --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-commands.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +echo "=== ClusterResourceOverride s390x e2e ===" +echo "Namespace: ${CRO_NAMESPACE}" +echo "E2E_SKIP: ${E2E_SKIP:-}" + +echo "=== Operator status before tests ===" +oc get deployment,pods,csv,subscription -n "${CRO_NAMESPACE}" -o wide || true +oc get clusterresourceoverride -A -o wide || true + +oc wait --for=condition=Available deployment/clusterresourceoverride-operator \ + -n "${CRO_NAMESPACE}" --timeout=600s + +# make e2e expects OPERATOR_NAMESPACE and KUBECONFIG; KUBECONFIG is injected by ci-operator. +export OPERATOR_NAMESPACE="${CRO_NAMESPACE}" +KUBECTL="$(which oc)" +export KUBECTL + +echo "=== Running make e2e ===" +make e2e E2E_SKIP="${E2E_SKIP}" OPERATOR_NAMESPACE="${CRO_NAMESPACE}" KUBECTL="${KUBECTL}" + +echo "=== e2e complete ===" diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.metadata.json b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.metadata.json new file mode 100644 index 0000000000000..3b116b91923c6 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.yaml", + "owners": { + "approvers": [ + "multiarch-approvers" + ], + "reviewers": [ + "multiarch-reviewers" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.yaml b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.yaml new file mode 100644 index 0000000000000..2e41874b90448 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/run-tests/cluster-resource-override-s390x-run-tests-ref.yaml @@ -0,0 +1,28 @@ +ref: + as: cluster-resource-override-s390x-run-tests + from: src + cli: latest + commands: cluster-resource-override-s390x-run-tests-commands.sh + grace_period: 1m0s + resources: + requests: + cpu: 100m + memory: 200Mi + timeout: 60m0s + env: + - name: CRO_NAMESPACE + default: "openshift-cluster-resource-override" + documentation: |- + Namespace where the ClusterResourceOverride operator is installed. Must match + OPERATOR_NAMESPACE expected by make e2e (default openshift-cluster-resource-override). + - name: E2E_SKIP + default: "TestUpgradePre|TestUpgradePost|TestResourceOverrideExemptNamespace" + documentation: |- + Regex passed to go test -skip. Defaults to skipping upgrade-only tests that + require the dedicated pre/post upgrade flow, and TestResourceOverrideExemptNamespace + until ART ships an operator build that creates ValidatingAdmissionPolicy + resourceoverride-exempt-namespace (landed on main after CSV 202608041944). + documentation: |- + Runs the ClusterResourceOverride admission operator Go e2e suite from this + repository (make e2e / ./test/e2e/...) against the operator already installed + on the s390x cluster. Skips upgrade-only tests by default. diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/test/OWNERS b/ci-operator/step-registry/cluster-resource-override/s390x/test/OWNERS new file mode 100644 index 0000000000000..68eeddf0cd187 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/test/OWNERS @@ -0,0 +1,4 @@ +approvers: +- multiarch-approvers +reviewers: +- multiarch-reviewers diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.metadata.json b/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.metadata.json new file mode 100644 index 0000000000000..8f18fe9bbca86 --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.metadata.json @@ -0,0 +1,11 @@ +{ + "path": "cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.yaml", + "owners": { + "approvers": [ + "multiarch-approvers" + ], + "reviewers": [ + "multiarch-reviewers" + ] + } +} \ No newline at end of file diff --git a/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.yaml b/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.yaml new file mode 100644 index 0000000000000..4d03aa84e266c --- /dev/null +++ b/ci-operator/step-registry/cluster-resource-override/s390x/test/cluster-resource-override-s390x-test-chain.yaml @@ -0,0 +1,12 @@ +chain: + as: cluster-resource-override-s390x-test + steps: + - ref: cluster-resource-override-s390x-install-operator + - ref: cluster-resource-override-s390x-run-tests + documentation: |- + Installs the ClusterResourceOverride operator via OLM on a provisioned s390x + OCP cluster (optional ImageDigestMirrorSet + Subscription), creates the + ClusterResourceOverride CR, then runs the repository Go e2e suite + (make e2e / ./test/e2e/...), skipping upgrade-only tests by default. + Component and cluster cleanup are handled by the post phase of the + cluster-resource-override-s390x workflow.