From 57b45aadb438c41fc1dab4a9512c997949f297ca Mon Sep 17 00:00:00 2001 From: Richard Su Date: Fri, 19 Dec 2025 15:53:56 -0600 Subject: [PATCH 1/3] AGENT-1193: Add mirror-path and registry-cert support for OVE ISO builds Add support for using pre-mirrored images (--mirror-path) and custom registry certificates (--registry-cert) when building OVE ISOs. This allows building ISOs in disconnected environments without requiring oc-mirror to run during the build process. Note: mirror-path and registry-cert options are only available when using the script build method (AGENT_ISO_NO_REGISTRY_BUILD_METHOD=script). The container build method does not support these options. Changes: - Refactor create_agent_iso_no_registry() for better readability - Extract helper functions into agent/iso_no_registry.sh - Add mirror-path and registry-cert support to script build method - Pass mirror-path to skip oc-mirror execution in appliance - Pass registry certificate for custom registries with self-signed certs Assisted-by: Claude Sonnet 4.5 --- agent/04_agent_prepare_release.sh | 89 ++++++++++++++++++++------ agent/06_agent_create_cluster.sh | 44 +++---------- agent/common.sh | 6 ++ agent/iso_no_registry.sh | 102 ++++++++++++++++++++++++++++++ config_example.sh | 11 +++- oc_mirror.sh | 4 +- ocp_install_env.sh | 3 +- 7 files changed, 199 insertions(+), 60 deletions(-) create mode 100755 agent/iso_no_registry.sh diff --git a/agent/04_agent_prepare_release.sh b/agent/04_agent_prepare_release.sh index 413666e8b..ae5a84853 100755 --- a/agent/04_agent_prepare_release.sh +++ b/agent/04_agent_prepare_release.sh @@ -13,13 +13,55 @@ source $SCRIPTDIR/agent/common.sh source $SCRIPTDIR/ocp_install_env.sh source $SCRIPTDIR/oc_mirror.sh -# Temporarily skip preparing the custom local release in case of OVE ISO -if [[ "${AGENT_E2E_TEST_BOOT_MODE}" == "ISO_NO_REGISTRY" ]]; then - exit 0 -fi +# Function definitions + +# Prepares the registry directory structure for the OpenShift appliance builder. +# +# When building OVE ISOs with mirror-path support, the appliance expects a specific +# directory layout with pre-mirrored registry data and oc-mirror output files. This +# function organizes the registry directory created by setup_release_mirror() into +# the format expected by the appliance builder. +# +# Directory structure created: +# REGISTRY_DIR/ +# ├── cache/-/ # Where appliance will write the ISO +# ├── data/ # Pre-mirrored registry data (from oc-mirror) +# ├── working-dir/ # oc-mirror YAML files (IDMS, CatalogSources) +# └── results-*/ # oc-mirror mapping.txt +# +# The appliance uses this directory via the --mirror-path flag to skip running +# oc-mirror during the build and instead use the pre-mirrored images directly. +function prepare_registry_dir_for_appliance() { + echo "Preparing registry directory structure for appliance..." + + # Create the cache directory structure expected by appliance + # Appliance expects: mirror-path/cache/ (ISO output) + # Appliance will read registry data directly from mirror-path/data + + # Extract version from release image to create cache subdirectory + # Appliance creates cache dir in format: cache/- + VERSION=$(skopeo inspect --authfile ${PULL_SECRET_FILE} docker://${OPENSHIFT_RELEASE_IMAGE} | jq -r '.Labels["io.openshift.release"]') + ARCH=$(uname -m) + CACHE_SUBDIR="${VERSION}-${ARCH}" + mkdir -p ${REGISTRY_DIR}/cache/${CACHE_SUBDIR} + + # Copy YAML files and mapping.txt to registry directory so appliance can find them + if [[ -d ${WORKING_DIR}/working-dir ]]; then + cp -r ${WORKING_DIR}/working-dir ${REGISTRY_DIR}/ + fi + + # Copy results directory containing mapping.txt + for results_dir in ${WORKING_DIR}/results-*; do + if [[ -d "$results_dir" ]]; then + cp -r "$results_dir" ${REGISTRY_DIR}/ + fi + done + + echo "Registry directory prepared for appliance" +} # To replace an image entry in the openshift release image, set _LOCAL_REPO so that: -# - ENTRYNAME matches an uppercase version of the name in the release image with "-" converted to "_" +# - ENTRYNAME matches an uppercase version of the name in the release image with "-" converted to "_" # - The var value must point to an already locally cloned repo # # To specify a custom Dockerfile set _DOCKERFILE, as a relative path of the Dockerfile @@ -34,15 +76,6 @@ fi # export ASSISTED_SERVICE_DOCKERFILE=Dockerfile.assisted-service.ocp # export ASSISTED_SERVICE_IMAGE=agent-installer-api-server -early_deploy_validation -write_pull_secret - -# Release mirroring could be required by the subsequent steps -# even if the current one will be skipped -if [[ ! -z "${MIRROR_IMAGES}" && "${MIRROR_IMAGES,,}" != "false" ]]; then - setup_release_mirror -fi - function build_local_release() { # Sanity checks if [[ -z "${MIRROR_IMAGES}" || "${MIRROR_IMAGES,,}" == "false" ]]; then @@ -62,13 +95,13 @@ function build_local_release() { # Build new images for IMAGE_VAR in $REPO_OVERRIDES ; do - + if [[ ! -d ${!IMAGE_VAR} ]]; then echo "The specified local repo ${IMAGE_VAR}=${!IMAGE_VAR} does not exist" exit 1 fi cd ${!IMAGE_VAR} - + export $IMAGE_VAR=${!IMAGE_VAR##*/}:latest export $IMAGE_VAR=$LOCAL_REGISTRY_DNS_NAME:$LOCAL_REGISTRY_PORT/localimages/${!IMAGE_VAR} @@ -90,13 +123,13 @@ function build_local_release() { sudo podman build --network host --authfile $PULL_SECRET_FILE -t ${!IMAGE_VAR} -f $IMAGE_DOCKERFILE --build-arg "${IMAGE_BUILD_ARG}" . cd - sudo podman push --tls-verify=false --authfile $PULL_SECRET_FILE ${!IMAGE_VAR} ${!IMAGE_VAR} - + FINAL_IMAGE_NAME=${IMAGE_VAR/_LOCAL_REPO}_IMAGE FINAL_IMAGE=${!FINAL_IMAGE_NAME:-} if [[ -z "$FINAL_IMAGE" ]]; then FINAL_IMAGE=$(echo ${IMAGE_VAR/_LOCAL_REPO} | tr '[:upper:]_' '[:lower:]-') fi - + OLDIMAGE=$(sudo podman run --rm --authfile $PULL_SECRET_FILE $OPENSHIFT_RELEASE_IMAGE image $FINAL_IMAGE) echo "RUN sed -i 's%$OLDIMAGE%${!IMAGE_VAR}%g' /release-manifests/*" >> $DOCKERFILE done @@ -108,12 +141,28 @@ function build_local_release() { fi } -export REPO_OVERRIDES=$(env | grep '_LOCAL_REPO=' | grep -o '^[^=]*') +# Main execution + +early_deploy_validation +write_pull_secret + +# Release mirroring could be required by the subsequent steps +# even if the current one will be skipped +if [[ "${MIRROR_IMAGES}" == "true" ]]; then + setup_release_mirror +fi + +export REPO_OVERRIDES=$(get_repo_overrides) # Skip the step in case of no overrides -if [[ ! -z "${REPO_OVERRIDES}" ]] ; then +if [[ ! -z "${REPO_OVERRIDES}" ]] ; then build_local_release # Extract openshift-install from the newly built release image, in case it was updated extract_command "${OPENSHIFT_INSTALLER_CMD}" "${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE}" "${OCP_DIR}" fi + +# Prepare registry directory for appliance if using ISO_NO_REGISTRY +if [[ "${MIRROR_IMAGES}" == "true" && "${AGENT_E2E_TEST_BOOT_MODE}" == "ISO_NO_REGISTRY" ]]; then + prepare_registry_dir_for_appliance +fi \ No newline at end of file diff --git a/agent/06_agent_create_cluster.sh b/agent/06_agent_create_cluster.sh index 1ec527071..734750870 100755 --- a/agent/06_agent_create_cluster.sh +++ b/agent/06_agent_create_cluster.sh @@ -14,6 +14,7 @@ source $SCRIPTDIR/validation.sh source $SCRIPTDIR/release_info.sh source $SCRIPTDIR/agent/common.sh source $SCRIPTDIR/agent/iscsi_utils.sh +source $SCRIPTDIR/agent/iso_no_registry.sh early_deploy_validation @@ -82,42 +83,6 @@ function create_config_image() { cp -r ${config_image_dir}/auth ${asset_dir} } -# Build OVE ISO using script method -function build_ove_iso_script() { - local asset_dir=$1 - local release_image_url=$2 - - echo "Start building Agent OVE ISO" - ./hack/build-ove-image.sh \ - --pull-secret-file "${PULL_SECRET_FILE}" \ - --release-image-url "${release_image_url}" \ - --ssh-key-file "${SSH_KEY_FILE}" \ - ${APPLIANCE_IMAGE:+--appliance-image "${APPLIANCE_IMAGE}"} \ - --dir "${asset_dir}" >/dev/null - echo "Agent OVE ISO completed" - - # Move the agent-ove iso in the default folder - agent_iso_no_registry=$(get_agent_iso_no_registry) - mv ${agent_iso_no_registry} "$SCRIPTDIR/$OCP_DIR" -} - -function create_agent_iso_no_registry() { - local asset_dir=${1} - - # Update release_info.json as its needed by CI tests - save_release_info ${OPENSHIFT_RELEASE_IMAGE} ${OCP_DIR} - - AGENT_ISO_BUILDER_IMAGE=$(getAgentISOBuilderImage) - - id=$(podman create --pull always --authfile "${PULL_SECRET_FILE}" "${AGENT_ISO_BUILDER_IMAGE}") && \ - podman cp "${id}":/src "${asset_dir}" && \ - podman rm "${id}" - - pushd . - cd "${asset_dir}"/src - build_ove_iso_script "${asset_dir}" "${OPENSHIFT_RELEASE_IMAGE}" - popd -} function assert_agent_no_registry_iso_size(){ agent_iso_no_registry=$(get_agent_iso_no_registry) @@ -652,6 +617,13 @@ case "${AGENT_E2E_TEST_BOOT_MODE}" in cleanup_diskspace_agent_iso_noregistry ${asset_dir} fi + # Clean up registry data to save disk space after ISO is created + if [[ "${MIRROR_IMAGES}" == "true" ]]; then + echo "Cleaning up registry data at ${REGISTRY_DIR} to save disk space" + sudo rm -rf ${REGISTRY_DIR}/data + echo "Registry data cleanup complete" + fi + attach_agent_iso_no_registry master $NUM_MASTERS attach_agent_iso_no_registry worker $NUM_WORKERS attach_agent_iso_no_registry arbiter $NUM_ARBITERS diff --git a/agent/common.sh b/agent/common.sh index 82fe1a2aa..39d828508 100644 --- a/agent/common.sh +++ b/agent/common.sh @@ -15,6 +15,8 @@ export AGENT_ROOT_DEVICE_HINTS=${AGENT_ROOT_DEVICE_HINTS:-""} export AGENT_BM_HOSTS_IN_INSTALL_CONFIG=${AGENT_BM_HOSTS_IN_INSTALL_CONFIG:-"false"} export AGENT_MINIMAL_ISO=${AGENT_MINIMAL_ISO:-"false"} +# OVE ISO build method: "script" uses build-ove-image.sh, "container" uses Dockerfile-based build +export AGENT_ISO_NO_REGISTRY_BUILD_METHOD=${AGENT_ISO_NO_REGISTRY_BUILD_METHOD:-"script"} export BOND_CONFIG=${BOND_CONFIG:-"none"} @@ -105,3 +107,7 @@ function getAgentISOBuilderImage() { agent_iso_builder_image="registry.ci.openshift.org/ocp/${major_minor_version}:agent-iso-builder" echo ${agent_iso_builder_image} } + +function get_repo_overrides() { + env | grep '_LOCAL_REPO=' | grep -o '^[^=]*' +} diff --git a/agent/iso_no_registry.sh b/agent/iso_no_registry.sh new file mode 100755 index 000000000..e8983707d --- /dev/null +++ b/agent/iso_no_registry.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +set -euo pipefail + +# OVE (OpenShift Virtualization Edition) ISO building utilities +# Functions for creating agent ISOs without embedded registry + +# Check if using a custom registry (not upstream quay.io or CI registry) +function is_custom_registry() { + [[ ! "${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE}" =~ quay\.io ]] && \ + [[ ! "${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE}" =~ registry\.ci\.openshift\.org ]] +} + +# Determine release image URL based on mirror configuration +function get_release_image_url() { + if [[ "${MIRROR_IMAGES}" == "true" ]] && [[ -n "$(get_repo_overrides)" ]]; then + echo "${OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE}" + else + echo "${OPENSHIFT_RELEASE_IMAGE}" + fi +} + +# Build OVE ISO using script method +function build_ove_iso_script() { + local asset_dir=$1 + local release_image_url=$2 + local mirror_path_arg=$3 + local registry_cert_arg=$4 + + ./hack/build-ove-image.sh \ + --pull-secret-file "${PULL_SECRET_FILE}" \ + --release-image-url "${release_image_url}" \ + --ssh-key-file "${SSH_KEY_FILE}" \ + --dir "${asset_dir}" \ + ${mirror_path_arg} \ + ${registry_cert_arg} +} + +# Build OVE ISO using container method +function build_ove_iso_container() { + local asset_dir=$1 + local release_image_url=$2 + + # Build ISO in container + make build-ove-iso-container \ + PULL_SECRET_FILE="${PULL_SECRET_FILE}" \ + RELEASE_IMAGE_URL="${release_image_url}" \ + ARCH=${ARCH} + + # Extract ISO from container + ./hack/iso-from-container.sh + + # Move to asset directory + local iso_name="agent-ove.${ARCH}.iso" + echo "Moving ${iso_name} to ${asset_dir}" + mv ./output-iso/${iso_name} "${asset_dir}" +} + +# Create agent ISO without registry (OVE ISO) +function create_agent_iso_no_registry() { + local asset_dir=${1} + + # Update release_info.json as its needed by CI tests + save_release_info ${OPENSHIFT_RELEASE_IMAGE} ${OCP_DIR} + + AGENT_ISO_BUILDER_IMAGE=$(getAgentISOBuilderImage) + + # Extract agent-iso-builder source from container + id=$(podman create --pull always --authfile "${PULL_SECRET_FILE}" "${AGENT_ISO_BUILDER_IMAGE}") && \ + podman cp "${id}":/src "${asset_dir}" && \ + podman rm "${id}" + + pushd . + cd "${asset_dir}"/src + + # Determine release image URL + local release_image_url=$(get_release_image_url) + echo "build_ove_iso will use release image ${release_image_url}" + + # Prepare mirror and certificate arguments for script build method + local mirror_path_arg="" + local registry_cert_arg="" + + if [[ "${MIRROR_IMAGES}" == "true" ]]; then + echo "Using pre-mirrored images from ${REGISTRY_DIR}" + mirror_path_arg="--mirror-path ${REGISTRY_DIR}" + + # Add registry certificate if using custom registry + if is_custom_registry && [[ -f "${REGISTRY_DIR}/certs/${REGISTRY_CRT}" ]]; then + registry_cert_arg="--registry-cert ${REGISTRY_DIR}/certs/${REGISTRY_CRT}" + fi + fi + + # Build OVE ISO using selected method + if [[ "${AGENT_ISO_NO_REGISTRY_BUILD_METHOD}" == "script" ]]; then + build_ove_iso_script "${asset_dir}" "${release_image_url}" "${mirror_path_arg}" "${registry_cert_arg}" + else + build_ove_iso_container "${asset_dir}" "${release_image_url}" + fi + + rm -rf "${asset_dir}"/src + popd +} diff --git a/config_example.sh b/config_example.sh index f595240a3..302ec38d4 100755 --- a/config_example.sh +++ b/config_example.sh @@ -898,11 +898,20 @@ set -x # AGENT_E2E_TEST_BOOT_MODE is set to ISO_NO_REGISTRY. # AGENT_CLEANUP_ISO_BUILDER_CACHE_LOCAL_DEV is useful for reclaiming disk space when building agent OVE ISO locally # by deleting all the files from the working directory, example ocp/ostest/iso_builder except the generated OVE ISO. -# Set to 'true' to enable the cleanup. +# Set to 'true' to enable the cleanup. # Default behavior (unset or any value other than 'yes') is to skip cleanup. # Recommended to set to true for local dev/test purposes and unset in CI. # export AGENT_CLEANUP_ISO_BUILDER_CACHE_LOCAL_DEV=false +# AGENT_ISO_NO_REGISTRY_BUILD_METHOD controls which method is used to build the OVE ISO when +# AGENT_E2E_TEST_BOOT_MODE is set to ISO_NO_REGISTRY. +# Options: +# 'container' - Uses containerized Dockerfile-based build (required for CI/build pipelines) +# 'script' (default) - Uses build-ove-image.sh script directly (faster for local development/debugging) +# The container method is required in CI/build pipeline environments where nested podman is not supported. +# The script method is recommended for local development as it allows faster iteration and easier debugging. +# export AGENT_ISO_NO_REGISTRY_BUILD_METHOD=script + # Specifies the hostname of the node that should be identified and set as the rendezvous node # during the OVE cluster installation process. This node acts as the bootstrap node in the cluster. # Accepts only master nodes. diff --git a/oc_mirror.sh b/oc_mirror.sh index 6f5698447..2fb74790a 100755 --- a/oc_mirror.sh +++ b/oc_mirror.sh @@ -72,7 +72,7 @@ function mirror_to_file() { config=${1} pushd ${WORKING_DIR} - oc-mirror --v2 -c ${config} file://${WORKING_DIR} --ignore-release-signature + oc-mirror --v2 -c ${config} file://${WORKING_DIR} --ignore-release-signature --remove-signatures popd } @@ -81,7 +81,7 @@ function publish_image() { config=${1} pushd ${WORKING_DIR} - oc-mirror --v2 --config ${config} --from file://${WORKING_DIR} docker://${LOCAL_REGISTRY_DNS_NAME}:${LOCAL_REGISTRY_PORT} --ignore-release-signature + oc-mirror --v2 --config ${config} --from file://${WORKING_DIR} docker://${LOCAL_REGISTRY_DNS_NAME}:${LOCAL_REGISTRY_PORT} --ignore-release-signature --remove-signatures popd } diff --git a/ocp_install_env.sh b/ocp_install_env.sh index b18cb3ab2..5f905a300 100644 --- a/ocp_install_env.sh +++ b/ocp_install_env.sh @@ -47,7 +47,8 @@ function extract_command() { _tmpfiles="$_tmpfiles $extract_dir" - mv "${extract_dir}/${cmd}" "${outdir}" + mkdir -p "${outdir}" + mv "${extract_dir}/${cmd}" "${outdir}/" } # Let's always grab the `oc` from the release we're using. From cbffa6eb3d65e473994e595ec7f1ac003ef43aef Mon Sep 17 00:00:00 2001 From: Richard Su Date: Wed, 11 Feb 2026 11:18:56 -0600 Subject: [PATCH 2/3] AGENT-1193: Add IDMS entry for local registry in mirror preparation When preparing the registry directory for appliance builds, append an IDMS entry for the local dev-scripts registry to the existing idms-oc-mirror.yaml file. This mapping is needed when dev-scripts builds custom images and pushes them to a custom release image with URIs that reference the dev-scripts registry (e.g., virthost.ostest.test.metalkube.org:5000). The IDMS entry allows the appliance to create the proper registry mappings for these custom images. This change is part of the mirror-path support for OVE ISO builds in disconnected environments. Assisted-by: Claude Sonnet 4.5 --- agent/04_agent_prepare_release.sh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/agent/04_agent_prepare_release.sh b/agent/04_agent_prepare_release.sh index ae5a84853..3ee95bb5b 100755 --- a/agent/04_agent_prepare_release.sh +++ b/agent/04_agent_prepare_release.sh @@ -57,6 +57,24 @@ function prepare_registry_dir_for_appliance() { fi done + # Append IDMS entry for local dev-scripts registry to existing idms-oc-mirror.yaml + # This ensures the local registry can be accessed from the installed cluster + echo "Appending IDMS entry for local registry" + + # Local dev-scripts registry + local local_registry="${LOCAL_REGISTRY_DNS_NAME}:${LOCAL_REGISTRY_PORT}" + + echo "Creating IDMS mapping: ${local_registry} -> ${local_registry}" + + # Append mirror entry to existing IDMS file + cat >> ${REGISTRY_DIR}/working-dir/cluster-resources/idms-oc-mirror.yaml << EOF + - mirrors: + - ${local_registry} + source: ${local_registry} +EOF + + echo "Custom registry IDMS entry appended to ${REGISTRY_DIR}/working-dir/cluster-resources/idms-oc-mirror.yaml" + echo "Registry directory prepared for appliance" } From 25eac17538f883f7ddfcb0526e16412ab7c20153 Mon Sep 17 00:00:00 2001 From: Richard Su Date: Sat, 4 Apr 2026 08:23:46 -0500 Subject: [PATCH 3/3] AGENT-1193: Fix OVE ISO build issues with mirror-path - oc_mirror.sh: Remove graph:true from imageset config to prevent oc-mirror from generating updateService.yaml, which references the UpdateService CRD that does not exist during cluster bootstrap. When --mirror-path is used with the appliance build, this manifest gets embedded in the appliance ISO and causes bootkube to loop indefinitely trying to apply it, timing out and failing the rendezvous node installation. - oc_mirror.sh: Add registry.redhat.io/rhel9/support-tools:latest to additionalImages so it is included in the local mirror when building the appliance ISO with --mirror-path. Without this, the image is missing from the data partition and the cluster cannot pull it. - agent/04_agent_prepare_release.sh: Use digest reference instead of tag when substituting local images into the release manifest. IDMS (ImageDigestMirrorSet) only redirects digest-based references; tag references bypass IDMS and go directly to the source registry, causing TLS failures when the source registry cert is not trusted inside the appliance's assisted-service container. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- agent/04_agent_prepare_release.sh | 11 ++++++++++- oc_mirror.sh | 23 ++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/agent/04_agent_prepare_release.sh b/agent/04_agent_prepare_release.sh index 3ee95bb5b..a2b9393cf 100755 --- a/agent/04_agent_prepare_release.sh +++ b/agent/04_agent_prepare_release.sh @@ -142,6 +142,15 @@ function build_local_release() { cd - sudo podman push --tls-verify=false --authfile $PULL_SECRET_FILE ${!IMAGE_VAR} ${!IMAGE_VAR} + # Use a digest reference instead of a tag so that IDMS mirror rules apply. + # IDMS (ImageDigestMirrorSet) only redirects digest-based image references; + # tag-based references are ignored (oc warns: "--idms-file only applies to + # images referenced by digest"). Without a digest, oc bypasses the IDMS and + # tries to pull directly from the source registry (virthost:5000) instead of + # the appliance's embedded local registry (registry.appliance.openshift.com:22625). + NEWIMAGE_DIGEST=$(sudo skopeo inspect --format '{{.Digest}}' --tls-verify=false --authfile $PULL_SECRET_FILE docker://${!IMAGE_VAR}) + NEWIMAGE_WITH_DIGEST="${!IMAGE_VAR%:*}@${NEWIMAGE_DIGEST}" + FINAL_IMAGE_NAME=${IMAGE_VAR/_LOCAL_REPO}_IMAGE FINAL_IMAGE=${!FINAL_IMAGE_NAME:-} if [[ -z "$FINAL_IMAGE" ]]; then @@ -149,7 +158,7 @@ function build_local_release() { fi OLDIMAGE=$(sudo podman run --rm --authfile $PULL_SECRET_FILE $OPENSHIFT_RELEASE_IMAGE image $FINAL_IMAGE) - echo "RUN sed -i 's%$OLDIMAGE%${!IMAGE_VAR}%g' /release-manifests/*" >> $DOCKERFILE + echo "RUN sed -i 's%$OLDIMAGE%${NEWIMAGE_WITH_DIGEST}%g' /release-manifests/*" >> $DOCKERFILE done # Publish the new release in the local registry diff --git a/oc_mirror.sh b/oc_mirror.sh index 2fb74790a..d2540c359 100755 --- a/oc_mirror.sh +++ b/oc_mirror.sh @@ -30,6 +30,14 @@ function update_docker_config() { cp ${DOCKER_CONFIG_FILE} ${DOCKER_CONFIG_FILE}.old fi cp ${PULL_SECRET_FILE} ${DOCKER_CONFIG_FILE} + + # oc-mirror --v2 uses the podman auth store as its primary credential source, + # ignoring --authfile for source registry auth. Explicitly refresh the CI registry + # login so the podman auth store has fresh credentials. + local ci_token=$(jq -r '.auths["registry.ci.openshift.org"].auth' ${PULL_SECRET_FILE} | base64 -d) + local ci_user=$(echo "$ci_token" | cut -d: -f1) + local ci_password=$(echo "$ci_token" | cut -d: -f2-) + podman login registry.ci.openshift.org --username "$ci_user" --password "$ci_password" 2>/dev/null || true } function setup_quay_mirror_registry() { @@ -58,10 +66,19 @@ kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v2alpha1 mirror: platform: - graph: true + # graph: true is intentionally omitted. When enabled, oc-mirror generates + # an updateService.yaml manifest referencing the UpdateService CRD, which + # does not exist during cluster bootstrap. This causes bootkube to loop + # indefinitely trying to apply it, eventually timing out and failing the + # rendezvous node installation. This is particularly an issue when + # --mirror-path is used with the appliance build, since the updateService.yaml + # generated here gets picked up via mirrorPath and embedded in the appliance ISO. release: $OPENSHIFT_RELEASE_IMAGE additionalImages: - name: registry.redhat.io/ubi8/ubi:latest + # Required by the OVE ISO appliance config (additionalImages) so it is available + # in the local mirror when building the appliance ISO with --mirror-path. + - name: registry.redhat.io/rhel9/support-tools:latest EOF } @@ -72,7 +89,7 @@ function mirror_to_file() { config=${1} pushd ${WORKING_DIR} - oc-mirror --v2 -c ${config} file://${WORKING_DIR} --ignore-release-signature --remove-signatures + oc-mirror --v2 -c ${config} --authfile ${PULL_SECRET_FILE} file://${WORKING_DIR} --ignore-release-signature --remove-signatures popd } @@ -81,7 +98,7 @@ function publish_image() { config=${1} pushd ${WORKING_DIR} - oc-mirror --v2 --config ${config} --from file://${WORKING_DIR} docker://${LOCAL_REGISTRY_DNS_NAME}:${LOCAL_REGISTRY_PORT} --ignore-release-signature --remove-signatures + oc-mirror --v2 --config ${config} --authfile ${PULL_SECRET_FILE} --from file://${WORKING_DIR} docker://${LOCAL_REGISTRY_DNS_NAME}:${LOCAL_REGISTRY_PORT} --ignore-release-signature --remove-signatures popd }