From a9b119583ef17fc7fddd7a5f2e6c828a83e070ef Mon Sep 17 00:00:00 2001 From: Gregory Giguashvili Date: Sun, 7 Jul 2024 20:25:49 +0300 Subject: [PATCH 1/4] Use docker-dir format when saving bootc images --- test/bin/pyutils/build_bootc_images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bin/pyutils/build_bootc_images.py b/test/bin/pyutils/build_bootc_images.py index 52817e15bd..22151c9efa 100644 --- a/test/bin/pyutils/build_bootc_images.py +++ b/test/bin/pyutils/build_bootc_images.py @@ -293,7 +293,7 @@ def process_containerfile(groupdir, containerfile, dry_run): shutil.rmtree(cf_outdir) save_args = [ "sudo", "podman", "save", - "--format", "oci-dir", + "--format", "docker-dir", "-o", cf_outdir, cf_outname ] common.run_command_in_shell(save_args, dry_run, logfile, logfile) From 5425d7306016af8afaad3cc6b84612640db564c4 Mon Sep 17 00:00:00 2001 From: Gregory Giguashvili Date: Sun, 7 Jul 2024 20:26:25 +0300 Subject: [PATCH 2/4] Implement bootc image mirroring and latest tagging --- scripts/image-builder/mirror-images.sh | 17 ++++++++-- test/bin/mirror_registry.sh | 44 +++++++++++++++++++------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/scripts/image-builder/mirror-images.sh b/scripts/image-builder/mirror-images.sh index 57978c45d8..c0b4a47fb8 100755 --- a/scripts/image-builder/mirror-images.sh +++ b/scripts/image-builder/mirror-images.sh @@ -50,12 +50,19 @@ function mirror_registry() { # Add the target registry prefix dst_img="${dest_registry}/${dst_img}" - # Run the image copy command + # Run the image mirror and tag command echo "Mirroring '${src_img}' to '${dst_img}'" skopeo_retry copy --all --quiet \ --preserve-digests \ + --additional-tag "${dst_img}:latest" \ --authfile "${img_pull_file}" \ docker://"${src_img}" docker://"${dst_img}:${image_tag}-${image_cnt}" + + echo "Tagging '${dst_img}' as 'latest'" + skopeo_retry copy --all --quiet \ + --preserve-digests \ + --authfile "${img_pull_file}" \ + docker://"${dst_img}:${image_tag}-${image_cnt}" docker://"${dst_img}:latest" } # Use timestamp as a tag on the target images to avoid @@ -112,12 +119,18 @@ function dir_to_registry() { dst_img="${dest_registry}/${src_img}" dst_img=$(echo "${dst_img}" | awk -F'@' '{print $1}') - # Run the image upload command + # Run the image upload and tag commands echo "Uploading '${src_img}' to '${dst_img}'" skopeo_retry copy --all --quiet \ --preserve-digests \ --authfile "${img_pull_file}" \ dir://"${local_dir}/${src_img}" docker://"${dst_img}:${image_tag}-${image_cnt}" + + echo "Tagging '${dst_img}' as 'latest'" + skopeo_retry copy --all --quiet \ + --preserve-digests \ + --authfile "${img_pull_file}" \ + docker://"${dst_img}:${image_tag}-${image_cnt}" docker://"${dst_img}:latest" # Increment the counter (( image_cnt += 1 )) diff --git a/test/bin/mirror_registry.sh b/test/bin/mirror_registry.sh index 00d3b29e9b..b9a74629e3 100755 --- a/test/bin/mirror_registry.sh +++ b/test/bin/mirror_registry.sh @@ -53,20 +53,36 @@ mirror_images() { rm -f "${ofile}" } +mirror_bootc_images() { + local -r idir=$1 + "${ROOTDIR}/scripts/image-builder/mirror-images.sh" --dir-to-reg "${PULL_SECRET}" "${idir}" "${REGISTRY_HOST}" +} + usage() { echo "" - echo "Usage: ${0} [-f PATH]" - echo " -f PATH File containing the containers to mirror. Defaults to ${CONTAINER_LIST}" + echo "Usage: ${0} [-cf FILE] [-bd DIR]" + echo " -cf FILE File containing the container image references to mirror." + echo " Defaults to '${CONTAINER_LIST}', skipped if does not exist." + echo " -bd DIR Directory containing the bootc containers data to mirror." + echo " Defaults to '${BOOTC_IMAGE_DIR}', skipped if does not exist." exit 1 } -LIST_FILE="${CONTAINER_LIST}" +# +# Main +# +image_list_file="${CONTAINER_LIST}" +bootc_image_dir="${BOOTC_IMAGE_DIR}" while [ $# -gt 0 ]; do case $1 in - -f) + -cf) + shift + image_list_file=$1 + ;; + -bd) shift - LIST_FILE=$1 + bootc_image_dir=$1 ;; *) usage @@ -75,11 +91,17 @@ while [ $# -gt 0 ]; do shift done -if [ ! -f "${LIST_FILE}" ]; then - echo "File ${LIST_FILE} does not exist" - exit 1 -fi - prereqs setup_registry -mirror_images "${LIST_FILE}" + +if [ -f "${image_list_file}" ]; then + mirror_images "${image_list_file}" +else + echo "WARNING: File '${image_list_file}' does not exist, skipping" +fi + +if [ -d "${bootc_image_dir}" ] ; then + mirror_bootc_images "${bootc_image_dir}" +else + echo "WARNING: Directory '${bootc_image_dir}' does not exist, skipping" +fi From 758e233c5760470f7a31783f2cade65a64e1ebe1 Mon Sep 17 00:00:00 2001 From: Gregory Giguashvili Date: Sun, 7 Jul 2024 20:27:35 +0300 Subject: [PATCH 3/4] Implement ostreecontainer image usage from an insecure registry --- test/bin/scenario.sh | 10 +++------- .../includes/main-ostreecontainer.cfg | 20 +++++++++++++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/test/bin/scenario.sh b/test/bin/scenario.sh index 8502ae7b29..aedc235676 100755 --- a/test/bin/scenario.sh +++ b/test/bin/scenario.sh @@ -17,6 +17,7 @@ source "${SCRIPTDIR}/common.sh" DEFAULT_BOOT_BLUEPRINT="rhel-9.2" LVM_SYSROOT_SIZE="10240" WEB_SERVER_URL="http://${VM_BRIDGE_IP}:${WEB_SERVER_PORT}" +BOOTC_REGISTRY_URL="${VM_BRIDGE_IP}:5000" PULL_SECRET="${PULL_SECRET:-${HOME}/.pull-secret.json}" PULL_SECRET_CONTENT="$(jq -c . "${PULL_SECRET}")" PUBLIC_IP=${PUBLIC_IP:-""} # may be overridden in global settings file @@ -226,6 +227,7 @@ prepare_kickstart() { sed -e "s|REPLACE_LVM_SYSROOT_SIZE|${LVM_SYSROOT_SIZE}|g" \ -e "s|REPLACE_OSTREE_SERVER_URL|${WEB_SERVER_URL}/repo|g" \ + -e "s|REPLACE_BOOTC_REGISTRY_URL|${BOOTC_REGISTRY_URL}|g" \ -e "s|REPLACE_RPM_SERVER_URL|${WEB_SERVER_URL}/rpm-repos|g" \ -e "s|REPLACE_MINOR_VERSION|$(current_minor_version)|g" \ -e "s|REPLACE_BOOT_COMMIT_REF|${boot_commit_ref}|g" \ @@ -430,24 +432,19 @@ launch_vm() { sudo virsh pool-autostart "${vm_pool_name}" fi - # Prepare file system, network and extra arguments for the VM creation + # Prepare network and extra arguments for the VM creation # depending on the number of requested NICs and other parameters local vm_loc_args - local vm_fs_args local vm_network_args local vm_extra_args local vm_initrd_inject vm_loc_args="--location ${VM_DISK_BASEDIR}/${boot_blueprint}.iso" - vm_fs_args="" vm_network_args="" vm_extra_args="fips=${fips_mode}" vm_initrd_inject="" # Add support of bootc image directory sharing with virtual machines if [ "${bootc_mode}" -ne 0 ] ; then - vm_fs_args+=" --filesystem=${BOOTC_IMAGE_DIR},bootc-images,driver.type=virtiofs" - vm_fs_args+=" --memorybacking=source.type=memfd,access.mode=shared" - # The ISO files generated by bootc-image-builder is not recognized by virt-install. # Work around the problem by specifying kernel and initrd paths. if [[ "${boot_blueprint}.iso" == *-bootc.iso ]] ; then @@ -527,7 +524,6 @@ launch_vm() { --events on_reboot=restart \ --noreboot \ ${vm_loc_args} \ - ${vm_fs_args} \ --extra-args "${vm_extra_args}" \ ${vm_initrd_inject} \ --wait ; then diff --git a/test/kickstart-templates/includes/main-ostreecontainer.cfg b/test/kickstart-templates/includes/main-ostreecontainer.cfg index aed7518cbd..a5011ee060 100644 --- a/test/kickstart-templates/includes/main-ostreecontainer.cfg +++ b/test/kickstart-templates/includes/main-ostreecontainer.cfg @@ -1,10 +1,22 @@ -# Mount the bootc image directory from the hypervisor +# Enable insecure registry access from the hypervisor to allow bootc image pull. +# See https://github.com/containers/bootc/blob/main/docs/src/registries-and-offline.md#insecure-registries %pre-install --log=/dev/console --erroronfail -mkdir -p /mnt/bootc-images -mount -v -t virtiofs bootc-images /mnt/bootc-images +mkdir -p /etc/containers/registries.conf.d +cat > /etc/containers/registries.conf.d/998-microshift-bootc-registry.conf < Date: Sun, 7 Jul 2024 21:03:46 +0300 Subject: [PATCH 4/4] Implement parallel skopeo run when copying images to and from local directories --- scripts/image-builder/mirror-images.sh | 47 +++++++++++++++++++------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/scripts/image-builder/mirror-images.sh b/scripts/image-builder/mirror-images.sh index c0b4a47fb8..01db005d90 100755 --- a/scripts/image-builder/mirror-images.sh +++ b/scripts/image-builder/mirror-images.sh @@ -54,7 +54,6 @@ function mirror_registry() { echo "Mirroring '${src_img}' to '${dst_img}'" skopeo_retry copy --all --quiet \ --preserve-digests \ - --additional-tag "${dst_img}:latest" \ --authfile "${img_pull_file}" \ docker://"${src_img}" docker://"${dst_img}:${image_tag}-${image_cnt}" @@ -83,7 +82,11 @@ function registry_to_dir() { local img_file_list=$2 local local_dir=$3 - while read -r src_img ; do + process_image_copy() { + local -r img_pull_file=$1 + local -r local_dir=$2 + local -r src_img=$3 + # Remove the source registry prefix local dst_img dst_img=$(echo "${src_img}" | cut -d '/' -f 2-) @@ -95,8 +98,15 @@ function registry_to_dir() { --preserve-digests \ --authfile "${img_pull_file}" \ docker://"${src_img}" dir://"${local_dir}/${dst_img}" + } - done < "${img_file_list}" + # Export functions for xargs to use + export -f process_image_copy + export -f skopeo_retry + # Generate a list for each image and run copy in parallel. + # Note that the image is passed by replacing "{}" in xarg input. + xargs -P 8 -I {} -a "${img_file_list}" \ + bash -c 'process_image_copy "$@"' _ "${img_pull_file}" "${local_dir}" "{}" } function dir_to_registry() { @@ -104,13 +114,14 @@ function dir_to_registry() { local local_dir=$2 local dest_registry=$3 - # Use timestamp and counter as a tag on the target images to avoid - # their overwrite by the 'latest' automatic tagging - local -r image_tag=mirror-$(date +%y%m%d%H%M%S) - local image_cnt=1 + process_image_copy() { + local -r img_pull_file=$1 + local -r local_dir=$2 + local -r dest_registry=$3 + local -r image_tag=$4 + local -r image_cnt=$(cut -d' ' -f1 <<< "$5") + local -r src_manifest=$(cut -d' ' -f2 <<< "$5") - pushd "${local_dir}" >/dev/null - while read -r src_manifest ; do # Remove the manifest.json file name local src_img src_img=$(dirname "${src_manifest}") @@ -131,10 +142,22 @@ function dir_to_registry() { --preserve-digests \ --authfile "${img_pull_file}" \ docker://"${dst_img}:${image_tag}-${image_cnt}" docker://"${dst_img}:latest" - # Increment the counter - (( image_cnt += 1 )) + } + + # Use timestamp and counter as a tag on the target images to avoid + # their overwrite by the 'latest' automatic tagging + local -r image_tag=mirror-$(date +%y%m%d%H%M%S) + # Export functions for xargs to use + export -f process_image_copy + export -f skopeo_retry - done < <(find . -type f -name manifest.json -printf '%P\n') + # Generate a list with an incremental counter for each image and run copy in parallel. + # Note that the counter and image pairs are passed as one argument by replacing "{}" in xarg input. + pushd "${local_dir}" >/dev/null + find . -type f -name manifest.json -printf '%P\n' | \ + awk '{print NR, $0}' | \ + xargs -P 8 -I {} \ + bash -c 'process_image_copy "$@"' _ "${img_pull_file}" "${local_dir}" "${dest_registry}" "${image_tag}" "{}" popd >/dev/null }