From 10b84603f620e9da4dbb32b1edd6c6e9c09539d2 Mon Sep 17 00:00:00 2001 From: Richard Su Date: Fri, 19 Dec 2025 15:53:56 -0600 Subject: [PATCH] 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 | 49 ++++++++++---- agent/06_agent_create_cluster.sh | 32 +++------ agent/common.sh | 2 + agent/iso_no_registry.sh | 106 ++++++++++++++++++++++++++++++ config_example.sh | 11 +++- ocp_install_env.sh | 3 +- 6 files changed, 165 insertions(+), 38 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..a8c90a319 100755 --- a/agent/04_agent_prepare_release.sh +++ b/agent/04_agent_prepare_release.sh @@ -13,9 +13,43 @@ 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 +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 + +# Prepare registry directory for appliance if using ISO_NO_REGISTRY +if [[ "${MIRROR_IMAGES}" == "true" && "${AGENT_E2E_TEST_BOOT_MODE}" == "ISO_NO_REGISTRY" ]]; then + 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" fi # To replace an image entry in the openshift release image, set _LOCAL_REPO so that: @@ -34,15 +68,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 diff --git a/agent/06_agent_create_cluster.sh b/agent/06_agent_create_cluster.sh index 5455baf33..f9cf10570 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,30 +83,6 @@ function create_config_image() { cp -r ${config_image_dir}/auth ${asset_dir} } -function create_agent_iso_no_registry() { - local asset_dir=${1} - - 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}" - - # Update release_info.json as its needed by CI tests - save_release_info ${OPENSHIFT_RELEASE_IMAGE} ${OCP_DIR} - - # Create agent ISO without registry a.k.a. OVE ISO - pushd . - cd "${asset_dir}"/src - # Build the ISO in the container image - make build-ove-iso-container PULL_SECRET_FILE="${PULL_SECRET_FILE}" RELEASE_IMAGE_URL="${OPENSHIFT_RELEASE_IMAGE}" ARCH=${ARCH} - # Retrieve ISO from container - ./hack/iso-from-container.sh - local iso_name="agent-ove.${ARCH}.iso" - echo "Moving ${iso_name} to ${asset_dir}" - mv ./output-iso/${iso_name} "${asset_dir}" - rm -rf "${asset_dir}"/src - popd -} - function assert_agent_no_registry_iso_size(){ agent_iso_no_registry=$(get_agent_iso_no_registry) iso_size=$(stat -c%s "$agent_iso_no_registry") @@ -639,6 +616,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 8b7c69083..3214fe596 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:-"container"} export BOND_CONFIG=${BOND_CONFIG:-"none"} diff --git a/agent/iso_no_registry.sh b/agent/iso_no_registry.sh new file mode 100755 index 000000000..de7cc0c73 --- /dev/null +++ b/agent/iso_no_registry.sh @@ -0,0 +1,106 @@ +#!/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" ]]; 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) + if [[ "${MIRROR_IMAGES}" == "true" ]]; then + echo "Using mirrored release image: ${release_image_url}" + else + echo "Using upstream release image: ${release_image_url}" + fi + + # 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 f7eb46948..76cc7cd6f 100755 --- a/config_example.sh +++ b/config_example.sh @@ -870,11 +870,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' (default) - Uses containerized Dockerfile-based build (required for CI/build pipelines) +# 'script' - 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=container + # 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/ocp_install_env.sh b/ocp_install_env.sh index 31dbf2cc0..f94a6a957 100644 --- a/ocp_install_env.sh +++ b/ocp_install_env.sh @@ -51,7 +51,8 @@ function extract_command() { cmd="oc" fi - 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.