diff --git a/test/bin/ci_phase_iso_build.sh b/test/bin/ci_phase_iso_build.sh index c47f91232f..0edd72a2d7 100755 --- a/test/bin/ci_phase_iso_build.sh +++ b/test/bin/ci_phase_iso_build.sh @@ -137,8 +137,7 @@ run_bootc_image_build() { if [[ "${os}" == "el10" ]]; then # Build el9 images for upgrade tests - $(dry_run) bash -x ./bin/build_bootc_images.sh -l ./image-blueprints-bootc/el9/layer1-base - $(dry_run) bash -x ./bin/build_bootc_images.sh -l ./image-blueprints-bootc/el9/layer2-presubmit + $(dry_run) bash -x ./bin/build_bootc_images.sh -l ./image-blueprints-bootc/el10/layer5-upgrade fi if [[ "${CI_JOB_NAME}" =~ .*periodic.* ]]; then diff --git a/test/bin/pyutils/build_bootc_images.py b/test/bin/pyutils/build_bootc_images.py index 210881eec0..ec105bada7 100644 --- a/test/bin/pyutils/build_bootc_images.py +++ b/test/bin/pyutils/build_bootc_images.py @@ -34,6 +34,7 @@ # Switch to quay.io/centos-bootc/bootc-image-builder:latest if any new upstream # features are required BIB_IMAGE = "registry.redhat.io/rhel9/bootc-image-builder:latest" +IBC_IMAGE = "ghcr.io/osbuild/image-builder-cli:latest" GOMPLATE = common.get_env_var('GOMPLATE') MIRROR_REGISTRY = common.get_env_var('MIRROR_REGISTRY_URL') FORCE_REBUILD = False @@ -46,18 +47,19 @@ def cleanup_atexit(dry_run): common.print_msg(f"Terminating {pid} PID") common.terminate_process(pid) - # Terminate running bootc image builder containers - podman_args = [ - "sudo", "podman", "ps", - "--filter", f"ancestor={BIB_IMAGE}", - "--format", "{{.ID}}" - ] - cids = common.run_command_in_shell(podman_args, dry_run) - if cids: - # Make sure the ids are normalized in a single line - cids = re.sub(r'\s+', ' ', cids) - common.print_msg(f"Terminating '{cids}' container(s)") - common.run_command_in_shell(["sudo", "podman", "stop", cids], dry_run) + # Terminate running image builder containers + for builder_image in [BIB_IMAGE, IBC_IMAGE]: + podman_args = [ + "sudo", "podman", "ps", + "--filter", f"ancestor={builder_image}", + "--format", "{{.ID}}" + ] + cids = common.run_command_in_shell(podman_args, dry_run) + if cids: + # Make sure the ids are normalized in a single line + cids = re.sub(r'\s+', ' ', cids) + common.print_msg(f"Terminating '{cids}' container(s)") + common.run_command_in_shell(["sudo", "podman", "stop", cids], dry_run) def find_latest_rpm(repo_path, version=""): @@ -430,6 +432,76 @@ def should_skip(file): os.rename(f"{bf_outdir}/bootiso/install.iso", bf_targetiso) +def process_image_installer(groupdir, installerfile, dry_run): + ii_path, ii_outname, ii_outdir, ii_logfile = get_process_file_names( + groupdir, installerfile, BOOTC_ISO_DIR) + ii_targetiso = os.path.join(VM_DISK_BASEDIR, f"{ii_outname}.iso") + + def should_skip(file): + if FORCE_REBUILD: + common.print_msg(f"Forcing rebuild of '{file}'") + return False + if not os.path.exists(file): + return False + common.print_msg(f"The '{file}' already exists, skipping") + return True + + if should_skip(ii_targetiso): + common.record_junit(ii_path, "process-image-installer", "SKIPPED") + return + + os.makedirs(ii_outdir, exist_ok=True) + os.makedirs(VM_DISK_BASEDIR, exist_ok=True) + ii_outfile = os.path.join(BOOTC_IMAGE_DIR, installerfile) + run_template_cmd(ii_path, ii_outfile, dry_run) + if not dry_run: + if not common.file_has_valid_lines(ii_outfile): + common.print_msg(f"Skipping an empty {installerfile} file") + return + + common.print_msg(f"Processing {installerfile} with logs in {ii_logfile}") + start_process_image_installer = time.time() + try: + with open(ii_logfile, 'w') as logfile: + ii_distro = common.read_file_valid_lines(ii_outfile).strip() + + build_args = [ + "sudo", "podman", "run", + "--rm", "-i", "--privileged", + "--network", "host", + "--pull=newer", + "--security-opt", "label=type:unconfined_t", + "-v", f"{ii_outdir}:/output", + ] + if os.path.isdir("/etc/pki/entitlement"): + build_args += [ + "-v", "/etc/pki/entitlement:/etc/pki/entitlement:ro", + "-v", "/etc/rhsm:/etc/rhsm:ro", + ] + build_args += [ + IBC_IMAGE, + "build", "--distro", ii_distro, + "image-installer" + ] + start = time.time() + common.retry_on_exception(3, common.run_command_in_shell, build_args, dry_run, logfile, logfile) + common.record_junit(ii_path, "build-installer-image", "OK", start) + except Exception: + common.record_junit(ii_path, "process-image-installer", "FAILED", start_process_image_installer, log_filepath=ii_logfile) + raise + finally: + common.run_command(["sed", f"s/^/{ii_outname}: /", ii_logfile], dry_run) + + if not dry_run: + common.run_command( + ["sudo", "chown", "-R", f"{getpass.getuser()}.", ii_outdir], + dry_run) + iso_candidates = glob.glob(f"{ii_outdir}/**/*.iso", recursive=True) + if not iso_candidates: + raise Exception(f"No ISO found in {ii_outdir}") + os.rename(iso_candidates[0], ii_targetiso) + + def process_container_encapsulate(groupdir, containerfile, dry_run): ce_path, ce_outname, _, ce_logfile = get_process_file_names( groupdir, containerfile, BOOTC_IMAGE_DIR) @@ -546,6 +618,11 @@ def process_group(groupdir, build_type, pattern="*", dry_run=False): common.print_msg(f"Skipping '{file}' due to '{build_type}' filter") continue futures.append(executor.submit(process_image_bootc, groupdir, file, dry_run)) + elif file.endswith(".image-installer"): + if build_type and build_type != "image-installer": + common.print_msg(f"Skipping '{file}' due to '{build_type}' filter") + continue + futures.append(executor.submit(process_image_installer, groupdir, file, dry_run)) elif file.endswith(".container-encapsulate"): if build_type and build_type != "container-encapsulate": common.print_msg(f"Skipping '{file}' due to '{build_type}' filter") @@ -580,7 +657,7 @@ def main(): parser.add_argument("-E", "--no-extract-images", action="store_true", help="Skip container image extraction.") parser.add_argument("-X", "--skip-all-builds", action="store_true", help="Skip all image builds.") parser.add_argument("-b", "--build-type", - choices=["image-bootc", "containerfile", "container-encapsulate"], + choices=["image-bootc", "image-installer", "containerfile", "container-encapsulate"], help="Only build images of the specified type.") dirgroup = parser.add_mutually_exclusive_group(required=False) dirgroup.add_argument("-l", "--layer-dir", action="append", default=[], help="Path to the layer directory to process. Can be specified multiple times.") diff --git a/test/image-blueprints-bootc/el10/layer1-base/group2/rhel102-installer.image-installer b/test/image-blueprints-bootc/el10/layer1-base/group2/rhel102-installer.image-installer new file mode 100644 index 0000000000..2210caeccf --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer1-base/group2/rhel102-installer.image-installer @@ -0,0 +1,4 @@ + +# TODO: Replace this by a RHEL 10.2 image when its RPM repositories are released. +# rhel-10.2 +rhel-10.1 diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-bootc.image-bootc b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-bootc.image-bootc new file mode 120000 index 0000000000..6d4dd553a7 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-bootc.image-bootc @@ -0,0 +1 @@ +../../../el9/layer1-base/group2/rhel96-bootc.image-bootc \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-test-agent.containerfile b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-test-agent.containerfile new file mode 120000 index 0000000000..6f426e19b3 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel96-test-agent.containerfile @@ -0,0 +1 @@ +../../../el9/layer1-base/group1/rhel96-test-agent.containerfile \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-bootc.image-bootc b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-bootc.image-bootc new file mode 120000 index 0000000000..cfefc32ee4 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-bootc.image-bootc @@ -0,0 +1 @@ +../../../el9/layer1-base/group2/rhel98-bootc.image-bootc \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-test-agent.containerfile b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-test-agent.containerfile new file mode 120000 index 0000000000..15bfcb0495 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group1/rhel98-test-agent.containerfile @@ -0,0 +1 @@ +../../../el9/layer1-base/group1/rhel98-test-agent.containerfile \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-prel.containerfile b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-prel.containerfile new file mode 120000 index 0000000000..3f9147cb31 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-prel.containerfile @@ -0,0 +1 @@ +../../../el9/layer1-base/group2/rhel96-bootc-prel.containerfile \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-yminus2.containerfile b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-yminus2.containerfile new file mode 120000 index 0000000000..a6685fa9fd --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel96-bootc-yminus2.containerfile @@ -0,0 +1 @@ +../../../el9/layer1-base/group2/rhel96-bootc-yminus2.containerfile \ No newline at end of file diff --git a/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel98-bootc-source.containerfile b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel98-bootc-source.containerfile new file mode 120000 index 0000000000..2d7bf40b69 --- /dev/null +++ b/test/image-blueprints-bootc/el10/layer5-upgrade/group2/rhel98-bootc-source.containerfile @@ -0,0 +1 @@ +../../../el9/layer2-presubmit/group1/rhel98-bootc-source.containerfile \ No newline at end of file diff --git a/test/image-blueprints-bootc/el9/layer1-base/group2/rhel98-installer.image-installer b/test/image-blueprints-bootc/el9/layer1-base/group2/rhel98-installer.image-installer new file mode 100644 index 0000000000..f19d87fe99 --- /dev/null +++ b/test/image-blueprints-bootc/el9/layer1-base/group2/rhel98-installer.image-installer @@ -0,0 +1,4 @@ + +# TODO: Replace this by a RHEL 9.8 image when its RPM repositories are released. +# rhel-9.8 +rhel-9.7 diff --git a/test/scenarios-bootc/el10/presubmits/el102-src@rpm-install.sh b/test/scenarios-bootc/el10/presubmits/el102-src@rpm-install.sh new file mode 100644 index 0000000000..0951921273 --- /dev/null +++ b/test/scenarios-bootc/el10/presubmits/el102-src@rpm-install.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +# Sourced from scenario.sh and uses functions defined there. + +# The RPM-based image used to create the VM for this test does not +# include MicroShift or greenboot, so tell the framework not to wait +# for greenboot to finish when creating the VM. +export SKIP_GREENBOOT=true + +# NOTE: Unlike most suites, these tests rely on being run IN ORDER to +# ensure the host is in a good state at the start of each test. We +# could have separated them and run them as separate scenarios, but +# did not want to spend the resources on a new VM. +export TEST_RANDOMIZATION=none + +configure_microshift_mirror() { + local -r repo=$1 + + # `repo` might be empty if we install microshift from rhocp + if [[ -z "${repo}" ]] ; then + return + fi + + # `repo` might be an enabled repo from a released version instead + # of a mirror. + if [[ ! "${repo}" =~ ^http ]]; then + return + fi + + local -r tmp_file=$(mktemp) + tee "${tmp_file}" >/dev/null </dev/null </dev/null </dev/null </dev/null <