From e9e23230386ea1193e5e13eccc5c59085875bca0 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Thu, 24 Sep 2026 18:09:14 +0300 Subject: [PATCH 1/3] ci: wait for PR image before deploying Che in CI tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the upcoming switch from IPI to HyperShift hosted clusters, cluster provisioning will complete in ~5-10 minutes instead of ~40. The GitHub Action that builds and pushes the PR image to quay.io takes ~20 minutes, so the cluster may be ready before the image is available. Add waitForPRImage() that polls the Quay API until the tag appears, preventing deployChe from failing on a missing image. This is backward-compatible with the current IPI setup — when the cluster takes longer than the build, the check passes immediately. CRW-13245 Co-Authored-By: Claude Opus 4.6 --- .ci/openshift-ci/common.sh | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.ci/openshift-ci/common.sh b/.ci/openshift-ci/common.sh index 6093c79e75..84efe8be29 100644 --- a/.ci/openshift-ci/common.sh +++ b/.ci/openshift-ci/common.sh @@ -35,6 +35,33 @@ export TEST_FILE_NAME=${TEST_FILE_NAME:-"Date.txt"} export CUSTOM_CONFIG_MAP_NAME=${CUSTOM_CONFIG_MAP_NAME:-"custom-ca-certificates"} export GIT_SSL_CONFIG_MAP_NAME=${GIT_SSL_CONFIG_MAP_NAME:-"che-self-signed-cert"} +waitForPRImage() { + echo "------- [INFO] Waiting for PR image ${CHE_SERVER_IMAGE} to be available on registry -------" + CURRENT_TIME=$(date +%s) + ENDTIME=$((CURRENT_TIME + 1800)) + ELAPSED=0 + + while [ "$(date +%s)" -lt $ENDTIME ]; do + RESPONSE=$(curl -s "https://quay.io/api/v1/repository/eclipse/che-server/tag/?specificTag=${PR_IMAGE_TAG}&onlyActiveTags=true") + if echo "${RESPONSE}" | grep -q "\"name\": \"${PR_IMAGE_TAG}\""; then + echo "" + echo "======= [INFO] PR image ${CHE_SERVER_IMAGE} is available (after ${ELAPSED}s). =======" + return 0 + fi + sleep 30 + ELAPSED=$((ELAPSED + 30)) + if (( ELAPSED % 300 == 0 )); then + echo " $((ELAPSED / 60))m" + else + echo -n "." + fi + done + + echo "" + echo "####### [ERROR] PR image ${CHE_SERVER_IMAGE} is not available after 30 minutes. #######" + exit 1 +} + provisionOpenShiftOAuthUser() { echo "------- [INFO] Start provisioning Openshift OAuth user -------" htpasswd -c -B -b users.htpasswd ${OCP_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD} @@ -564,6 +591,7 @@ setupTestEnvironment() { OCP_USER_NAME=$1 provisionOpenShiftOAuthUser + waitForPRImage createCustomResourcesFile deployChe forwardPortToService @@ -576,6 +604,7 @@ setupTestEnvironmentOAuthFlow() { APPLICATION_SECRET=$3 provisionOpenShiftOAuthUser + waitForPRImage configureGitSelfSignedCertificate createCustomResourcesFile deployChe From 90231f5b5644187c396bf88f1a59182825b29001 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Fri, 25 Sep 2026 17:32:15 +0300 Subject: [PATCH 2/3] ci: add HyperShift OAuth support and image tag fallback - provisionOpenShiftOAuthUser() now detects HyperShift via ${SHARED_DIR}/nested_kubeconfig and configures htpasswd IDP through HostedCluster API on the management cluster instead of directly modifying oauths/cluster (blocked by ValidatingAdmissionPolicy) - Smart image tag: uses pr- for che-server PRs, falls back to "next" tag for ci-operator config rehearsals (REPO_NAME != che-server) - waitForPRImage() skips when not a che-server PR - Added waitForPRImage call in test-che-smoke-test.sh before deployChe - Increased OAuth wait timeout to 10 min (HyperShift rollout is slower) Co-Authored-By: Claude Opus 4.6 --- .ci/openshift-ci/common.sh | 73 ++++++++++++++++++++++--- .ci/openshift-ci/test-che-smoke-test.sh | 1 + 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/.ci/openshift-ci/common.sh b/.ci/openshift-ci/common.sh index 84efe8be29..9ad800dd2e 100644 --- a/.ci/openshift-ci/common.sh +++ b/.ci/openshift-ci/common.sh @@ -15,7 +15,12 @@ set -e # only exit with zero if all commands of the pipeline exit successfully set -o pipefail -PR_IMAGE_TAG="pr-${PULL_NUMBER}" +if [[ "${REPO_NAME:-}" == "che-server" ]]; then + PR_IMAGE_TAG="pr-${PULL_NUMBER}" +else + PR_IMAGE_TAG="next" + echo "[INFO] Not a che-server PR (repo: ${REPO_OWNER:-unknown}/${REPO_NAME:-unknown}), using image tag: ${PR_IMAGE_TAG}" +fi export CHE_NAMESPACE=${CHE_NAMESPACE:-"eclipse-che"} export CHE_SERVER_IMAGE=${CHE_SERVER_IMAGE:-"quay.io/eclipse/che-server:${PR_IMAGE_TAG}"} @@ -36,6 +41,10 @@ export CUSTOM_CONFIG_MAP_NAME=${CUSTOM_CONFIG_MAP_NAME:-"custom-ca-certificates" export GIT_SSL_CONFIG_MAP_NAME=${GIT_SSL_CONFIG_MAP_NAME:-"che-self-signed-cert"} waitForPRImage() { + if [[ "${REPO_NAME:-}" != "che-server" ]]; then + echo "------- [INFO] Skipping PR image wait (not a che-server PR, using ${PR_IMAGE_TAG}) -------" + return 0 + fi echo "------- [INFO] Waiting for PR image ${CHE_SERVER_IMAGE} to be available on registry -------" CURRENT_TIME=$(date +%s) ENDTIME=$((CURRENT_TIME + 1800)) @@ -66,26 +75,76 @@ provisionOpenShiftOAuthUser() { echo "------- [INFO] Start provisioning Openshift OAuth user -------" htpasswd -c -B -b users.htpasswd ${OCP_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD} htpasswd -b users.htpasswd ${OCP_NON_ADMIN_USER_NAME} ${OCP_LOGIN_PASSWORD} - oc create secret generic htpass-secret --from-file=htpasswd="users.htpasswd" -n openshift-config - oc apply -f ".ci/openshift-ci/htpasswdProvider.yaml" + + if [ -f "${SHARED_DIR}/nested_kubeconfig" ]; then + provisionOpenShiftOAuthUserHyperShift + else + provisionOpenShiftOAuthUserIPI + fi + oc adm policy add-cluster-role-to-user cluster-admin ${OCP_ADMIN_USER_NAME} - echo "------- [INFO] Waiting for htpasswd auth to be working up to 5 minutes -------" + echo "------- [INFO] Waiting for htpasswd auth to be working up to 10 minutes -------" CURRENT_TIME=$(date +%s) - ENDTIME=$((CURRENT_TIME + 300)) + ENDTIME=$((CURRENT_TIME + 600)) while [ "$(date +%s)" -lt $ENDTIME ]; do - if oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify=false; then + if oc login -u=${OCP_ADMIN_USER_NAME} -p=${OCP_LOGIN_PASSWORD} --insecure-skip-tls-verify; then echo "======= [INFO] OpenShift OAuth htpasswd is configured. ======= ======= [INFO] Login to OCP cluster with admin user credentials is success.=======" return 0 fi - sleep 5 + sleep 10 done echo "####### [ERROR] Error occurred while waiting OpenShift OAuth htpasswd setup. Try to rerun test. #######" exit 1 } +provisionOpenShiftOAuthUserIPI() { + echo "------- [INFO] IPI environment: configuring OAuth directly -------" + oc create secret generic htpass-secret --from-file=htpasswd="users.htpasswd" -n openshift-config + oc apply -f ".ci/openshift-ci/htpasswdProvider.yaml" +} + +provisionOpenShiftOAuthUserHyperShift() { + echo "------- [INFO] HyperShift environment: configuring OAuth via HostedCluster API -------" + + local CLUSTER_NAME + CLUSTER_NAME=$(cat "${SHARED_DIR}/cluster-name") + + local MGMT_KUBECONFIG + if [ -f "${SHARED_DIR}/mgmt_kubeconfig" ]; then + MGMT_KUBECONFIG="${SHARED_DIR}/mgmt_kubeconfig" + else + echo "####### [ERROR] Management cluster kubeconfig not found #######" + exit 1 + fi + + local HYPERSHIFT_NS + HYPERSHIFT_NS=$(cat "${SHARED_DIR}/hypershift-clusters-namespace" 2>/dev/null || echo "clusters") + + KUBECONFIG="${MGMT_KUBECONFIG}" oc create secret generic htpass-secret \ + --from-file=htpasswd="users.htpasswd" -n "${HYPERSHIFT_NS}" + + KUBECONFIG="${MGMT_KUBECONFIG}" oc patch hostedcluster "${CLUSTER_NAME}" \ + -n "${HYPERSHIFT_NS}" --type=merge -p '{ + "spec": { + "configuration": { + "oauth": { + "identityProviders": [{ + "htpasswd": {"fileData": {"name": "htpass-secret"}}, + "mappingMethod": "claim", + "name": "htpasswd", + "type": "HTPasswd" + }] + } + } + } + }' + + echo "------- [INFO] HostedCluster OAuth patched, waiting for rollout -------" +} + configureGitSelfSignedCertificate() { echo "------- [INFO] Configure self-signed certificate for Git provider -------" oc adm new-project ${CHE_NAMESPACE} diff --git a/.ci/openshift-ci/test-che-smoke-test.sh b/.ci/openshift-ci/test-che-smoke-test.sh index 704c8e895b..5be619690b 100644 --- a/.ci/openshift-ci/test-che-smoke-test.sh +++ b/.ci/openshift-ci/test-che-smoke-test.sh @@ -27,6 +27,7 @@ source "${SCRIPT_DIR}"/common.sh trap "collectLogs" EXIT SIGINT provisionOpenShiftOAuthUser +waitForPRImage createCustomResourcesFile deployChe startSmokeTest From 6a7c7753308e4b0cfc2207c4e82ae6f22b5f4013 Mon Sep 17 00:00:00 2001 From: Aleksandr Shmaraiev Date: Fri, 25 Sep 2026 18:07:01 +0300 Subject: [PATCH 3/3] ci: safely append htpasswd IDP instead of replacing identityProviders list Use python3 to read the HostedCluster JSON, append the htpasswd provider to the existing identityProviders array, and oc replace. This avoids --type=merge which would overwrite any pre-existing IDPs. Co-Authored-By: Claude Opus 4.6 --- .ci/openshift-ci/common.sh | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/.ci/openshift-ci/common.sh b/.ci/openshift-ci/common.sh index 9ad800dd2e..4009b43492 100644 --- a/.ci/openshift-ci/common.sh +++ b/.ci/openshift-ci/common.sh @@ -126,21 +126,26 @@ provisionOpenShiftOAuthUserHyperShift() { KUBECONFIG="${MGMT_KUBECONFIG}" oc create secret generic htpass-secret \ --from-file=htpasswd="users.htpasswd" -n "${HYPERSHIFT_NS}" - KUBECONFIG="${MGMT_KUBECONFIG}" oc patch hostedcluster "${CLUSTER_NAME}" \ - -n "${HYPERSHIFT_NS}" --type=merge -p '{ - "spec": { - "configuration": { - "oauth": { - "identityProviders": [{ - "htpasswd": {"fileData": {"name": "htpass-secret"}}, - "mappingMethod": "claim", - "name": "htpasswd", - "type": "HTPasswd" - }] - } - } - } - }' + KUBECONFIG="${MGMT_KUBECONFIG}" oc get hostedcluster "${CLUSTER_NAME}" \ + -n "${HYPERSHIFT_NS}" -o json > /tmp/hostedcluster.json + + python3 -c " +import json +with open('/tmp/hostedcluster.json') as f: + hc = json.load(f) +cfg = hc.setdefault('spec', {}).setdefault('configuration', {}).setdefault('oauth', {}) +idps = cfg.setdefault('identityProviders', []) +idps.append({ + 'htpasswd': {'fileData': {'name': 'htpass-secret'}}, + 'mappingMethod': 'claim', + 'name': 'htpasswd', + 'type': 'HTPasswd' +}) +with open('/tmp/hostedcluster.json', 'w') as f: + json.dump(hc, f) +" + + KUBECONFIG="${MGMT_KUBECONFIG}" oc replace -f /tmp/hostedcluster.json echo "------- [INFO] HostedCluster OAuth patched, waiting for rollout -------" }