From cb383eb18506b64232af2deef6bf17a8a8f1407e Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Mon, 15 Jun 2026 13:34:43 +0200 Subject: [PATCH 1/8] feat: add RHEL 10.2 RPM standard test scenarios Add el102@rpm-standard1.sh and el102@rpm-standard2.sh under test/scenarios-bootc/el10/releases/ to test MicroShift RPM install/remove on bare RHEL 10.2 VMs with standard test suites. Key adaptations from el98@rpm-standard scenarios: - Use rhel102-installer VM image - Use CDN repo files with entitlement certs for rhocp and fast-datapath (subscription-manager doesn't support these on RHEL 10) - Set subscription-manager release to 10.2 JIRA: USHIFT-7169 Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- .../el10/releases/el102@rpm-standard1.sh | 131 ++++++++++++++++++ .../el10/releases/el102@rpm-standard2.sh | 130 +++++++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 test/scenarios-bootc/el10/releases/el102@rpm-standard1.sh create mode 100644 test/scenarios-bootc/el10/releases/el102@rpm-standard2.sh diff --git a/test/scenarios-bootc/el10/releases/el102@rpm-standard1.sh b/test/scenarios-bootc/el10/releases/el102@rpm-standard1.sh new file mode 100644 index 0000000000..253136bcfd --- /dev/null +++ b/test/scenarios-bootc/el10/releases/el102@rpm-standard1.sh @@ -0,0 +1,131 @@ +#!/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 + +# On RHEL 10, rhocp and fast-datapath repos are not available via +# subscription-manager. Create repo files pointing to the RHEL 9 CDN +# using entitlement certificates as a workaround. +configure_cdn_repo() { + local -r repo_id=$1 + local -r repo_name=$2 + local -r baseurl=$3 + + local -r cert=$(run_command_on_vm host1 "ls /etc/pki/entitlement/[0-9]*.pem | grep -v '\-key.pem' | head -n1") + local -r key=$(run_command_on_vm host1 "ls /etc/pki/entitlement/[0-9]*-key.pem | head -n1") + local -r tmp_file=$(mktemp) + + tee "${tmp_file}" >/dev/null </dev/null </dev/null </dev/null < Date: Mon, 15 Jun 2026 15:56:16 +0200 Subject: [PATCH 2/8] fix: update installer image to RHEL 10.2 Replaced the placeholder for the RHEL 10.2 image in the installer configuration with the actual version. This change ensures that the correct image is used for testing scenarios. pre-commit.check-secrets: ENABLED --- .../el10/layer1-base/group2/rhel102-installer.image-installer | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 index 2210caeccf..c5271c9e1d 100644 --- 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 @@ -1,4 +1,2 @@ -# TODO: Replace this by a RHEL 10.2 image when its RPM repositories are released. -# rhel-10.2 -rhel-10.1 +rhel-10.2 From 755e8c4dad6b795eb189082c410e44fcee55256c Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Tue, 16 Jun 2026 09:55:14 +0200 Subject: [PATCH 3/8] fix: handle RHEL 10 removed packages in configure-composer.sh RHEL 10 removed several packages that configure-composer.sh installed unconditionally, causing the e2e-aws-tests-bootc-el10 ISO build job to fail with: Error: Unable to find a match: genisoimage containernetworking-plugins Changes per RHEL 10 "Considerations in adopting RHEL 10" docs: - genisoimage: removed, replaced by xorriso (provides genisoimage- compatible CLI via symlink) - containernetworking-plugins: removed (CNI replaced by Netavark); MicroShift ships its own containernetworking-plugins-microshift RPM, so the host package is not needed - runc: removed, replaced by crun (the default OCI runtime on RHEL 10) The fix gates these packages on the RHEL major version so RHEL 9 hosts continue to install the original packages while RHEL 10+ hosts install their replacements. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- scripts/devenv-builder/configure-composer.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/devenv-builder/configure-composer.sh b/scripts/devenv-builder/configure-composer.sh index 4de872e592..18f4185d58 100755 --- a/scripts/devenv-builder/configure-composer.sh +++ b/scripts/devenv-builder/configure-composer.sh @@ -9,11 +9,22 @@ install_and_configure_composer() { local -r version_id_major="$(awk -F. '{print $1}' <<< "${version_id}")" "${DNF_RETRY}" "install" "osbuild osbuild-composer" - "${DNF_RETRY}" "install" \ - "git composer-cli ostree rpm-ostree \ - cockpit-composer bash-completion podman runc genisoimage \ + local packages="git composer-cli ostree rpm-ostree \ + cockpit-composer bash-completion podman \ createrepo yum-utils selinux-policy-devel jq wget lorax rpm-build \ - containernetworking-plugins expect httpd-tools vim-common" + expect httpd-tools vim-common" + + # genisoimage and containernetworking-plugins were removed in RHEL 10. + # Use xorriso (provides a genisoimage-compatible CLI) instead. + # containernetworking-plugins (CNI) has no replacement — Podman uses + # Netavark on RHEL 10, and MicroShift ships its own CNI plugins RPM. + if [[ "${version_id_major}" -ge 10 ]]; then + packages+=" crun xorriso" + else + packages+=" runc genisoimage containernetworking-plugins" + fi + + "${DNF_RETRY}" "install" "${packages}" # The mock utility comes from the EPEL repository "${DNF_RETRY}" "install" "https://dl.fedoraproject.org/pub/epel/epel-release-latest-${version_id_major}.noarch.rpm" From 172e6c0e705fafc83fa39000cda96b4badac4b8c Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Tue, 16 Jun 2026 10:36:29 +0200 Subject: [PATCH 4/8] fix: add explicit python3-psutil dependency for RHEL 10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test/bin/pyutils/common.py module imports psutil, but python3-psutil was never explicitly installed — it was pulled in as a transitive dependency on RHEL 9. On RHEL 10, this transitive dependency no longer holds, causing all bootc el10 ISO build jobs to fail with: ModuleNotFoundError: No module named 'psutil' Add python3-psutil to the explicit package list so it is installed regardless of the dependency chain. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- scripts/devenv-builder/configure-composer.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/devenv-builder/configure-composer.sh b/scripts/devenv-builder/configure-composer.sh index 18f4185d58..d6e0f22f6a 100755 --- a/scripts/devenv-builder/configure-composer.sh +++ b/scripts/devenv-builder/configure-composer.sh @@ -10,7 +10,7 @@ install_and_configure_composer() { "${DNF_RETRY}" "install" "osbuild osbuild-composer" local packages="git composer-cli ostree rpm-ostree \ - cockpit-composer bash-completion podman \ + cockpit-composer bash-completion podman python3-psutil \ createrepo yum-utils selinux-policy-devel jq wget lorax rpm-build \ expect httpd-tools vim-common" From 70fcec75b0f67fee2e4a4eda7bd2430a3e01c655 Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Tue, 16 Jun 2026 12:43:35 +0200 Subject: [PATCH 5/8] fix: parameterize hardcoded rhel-9/el9 across CI infrastructure RHEL 10 bootc CI jobs fail because repo names and mirror URLs are hardcoded with `rhel-9`/`el9` throughout the build infrastructure. On RHEL 10 build hosts, `rhocp-*-for-rhel-9-*` subscription repos don't exist, causing dnf failures during ISO builds. Replace all hardcoded `rhel-9`/`el9` references with runtime OS version detection from /etc/os-release: - Shell scripts: `source /etc/os-release; RHEL_MAJOR="${VERSION_ID%%.*}"` - Python scripts: `platform.freedesktop_os_release()['VERSION_ID']` Files changed: - scripts/get-latest-rhocp-repo.sh: repo names and beta mirror URLs - scripts/devenv-builder/configure-vm.sh: subscription-manager repos, mirror URLs (moved OS detection to top-level for all functions) - test/bin/pyutils/build_bootc_images.py: RHOCP availability checks, beta URL construction, and added empty-version guards for PREVIOUS_RELEASE and YMINUS2 (matching existing brew pattern) - test/bin/pyutils/generate_common_versions.py: all repo name and URL construction functions - test/bin/scenario.sh: exit_if_zprel_not_exist() repo name For Y-1/Y-2 versions (4.22/4.21) that only have RHEL 9 repos, the empty-version guards in build_bootc_images.py prevent failures when the subscription repo doesn't exist on the RHEL 10 host. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- scripts/devenv-builder/configure-vm.sh | 22 +++++++++++--------- scripts/get-latest-rhocp-repo.sh | 8 +++++-- test/bin/pyutils/build_bootc_images.py | 15 +++++++------ test/bin/pyutils/generate_common_versions.py | 14 +++++++------ test/bin/scenario.sh | 4 +++- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/scripts/devenv-builder/configure-vm.sh b/scripts/devenv-builder/configure-vm.sh index 0a5b6c68e6..2828d8d87b 100755 --- a/scripts/devenv-builder/configure-vm.sh +++ b/scripts/devenv-builder/configure-vm.sh @@ -152,10 +152,7 @@ function configure_rhel_subscription() { fi sudo subscription-manager config --rhsm.manage_repos=1 - # Parse the OS versions and determine if EUS - source /etc/os-release - VERSION_ID_MAJOR="$(awk -F. '{print $1}' <<< "${VERSION_ID}")" - VERSION_ID_MINOR="$(awk -F. '{print $2}' <<< "${VERSION_ID}")" + # Determine if EUS VERSION_ID_EUS="" if (( "${VERSION_ID_MINOR}" % 2 == 0 )) ; then VERSION_ID_EUS="-eus" @@ -215,15 +212,15 @@ function configure_rhel_repositories() { RHOCP=$("${RHOCP_REPO}") if [[ "${RHOCP}" =~ ^[0-9]{1,2}$ ]]; then - sudo subscription-manager repos --enable "rhocp-${ocp_major}.${RHOCP}-for-rhel-9-$(uname -m)-rpms" + sudo subscription-manager repos --enable "rhocp-${ocp_major}.${RHOCP}-for-rhel-${VERSION_ID_MAJOR}-$(uname -m)-rpms" elif [[ "${RHOCP}" =~ ^http ]]; then url=$(echo "${RHOCP}" | cut -d, -f1) major=$(echo "${RHOCP}" | cut -d, -f2) ver=$(echo "${RHOCP}" | cut -d, -f3) - OCP_REPO_NAME="rhocp-${major}.${ver}-for-rhel-9-mirrorbeta-$(uname -i)-rpms" + OCP_REPO_NAME="rhocp-${major}.${ver}-for-rhel-${VERSION_ID_MAJOR}-mirrorbeta-$(uname -i)-rpms" sudo tee "/etc/yum.repos.d/${OCP_REPO_NAME}.repo" >/dev/null <&/dev/null; then exit 1 fi +# Detect RHEL major version for repo name construction +source /etc/os-release +RHEL_MAJOR="${VERSION_ID%%.*}" + # Get version of currently checked out branch. # It's based on values stored in Makefile.version.$ARCH.var. make_version="${REPOROOT}/Makefile.version.$(uname -m).var" @@ -80,13 +84,13 @@ fi check_major="${current_major}" check_minor="${current_minor}" for (( step=0; step < max_steps; step++ )); do - repository="rhocp-${check_major}.${check_minor}-for-rhel-9-$(uname -m)-rpms" + repository="rhocp-${check_major}.${check_minor}-for-rhel-${RHEL_MAJOR}-$(uname -m)-rpms" if sudo dnf repository-packages --showduplicates "${repository}" info cri-o 1>&2; then echo "${check_minor}" exit 0 fi - rhocp_beta_url="https://mirror.openshift.com/pub/openshift-v${check_major}/$(uname -m)/dependencies/rpms/${check_major}.${check_minor}-el9-beta/" + rhocp_beta_url="https://mirror.openshift.com/pub/openshift-v${check_major}/$(uname -m)/dependencies/rpms/${check_major}.${check_minor}-el${RHEL_MAJOR}-beta/" if sudo dnf repository-packages --showduplicates --disablerepo '*' --repofrompath "this,${rhocp_beta_url}" this info cri-o 1>&2; then echo "${rhocp_beta_url},${check_major},${check_minor}" exit 0 diff --git a/test/bin/pyutils/build_bootc_images.py b/test/bin/pyutils/build_bootc_images.py index d432db2bf3..c42a9942f6 100644 --- a/test/bin/pyutils/build_bootc_images.py +++ b/test/bin/pyutils/build_bootc_images.py @@ -38,6 +38,7 @@ GOMPLATE = common.get_env_var('GOMPLATE') MIRROR_REGISTRY = common.get_env_var('MIRROR_REGISTRY_URL') FORCE_REBUILD = False +RHEL_MAJOR = platform.freedesktop_os_release()['VERSION_ID'].split('.')[0] def cleanup_atexit(dry_run): @@ -83,7 +84,7 @@ def is_rhocp_available(major, minor): """ # Equivalent to `uname -m` architecture = platform.machine() - repository = f"rhocp-{major}.{minor}-for-rhel-9-{architecture}-rpms" + repository = f"rhocp-{major}.{minor}-for-rhel-{RHEL_MAJOR}-{architecture}-rpms" try: # Run the dnf command to check for cri-o in the specified repository @@ -105,8 +106,8 @@ def get_rhocp_beta_url_if_available(major, minor): Returns: str: The beta URL if available, otherwise empty string. """ - url_amd = f"https://mirror.openshift.com/pub/openshift-v{major}/x86_64/dependencies/rpms/{major}.{minor}-el9-beta/" - url_arm = f"https://mirror.openshift.com/pub/openshift-v{major}/aarch64/dependencies/rpms/{major}.{minor}-el9-beta/" + url_amd = f"https://mirror.openshift.com/pub/openshift-v{major}/x86_64/dependencies/rpms/{major}.{minor}-el{RHEL_MAJOR}-beta/" + url_arm = f"https://mirror.openshift.com/pub/openshift-v{major}/aarch64/dependencies/rpms/{major}.{minor}-el{RHEL_MAJOR}-beta/" try: # Run the dnf command to check for cri-o in the specified repository @@ -118,7 +119,7 @@ def get_rhocp_beta_url_if_available(major, minor): # Use specific minor version RHOCP mirror only if both arches are available. architecture = platform.machine() - return f"https://mirror.openshift.com/pub/openshift-v{major}/{architecture}/dependencies/rpms/{major}.{minor}-el9-beta/" + return f"https://mirror.openshift.com/pub/openshift-v{major}/{architecture}/dependencies/rpms/{major}.{minor}-el{RHEL_MAJOR}-beta/" except Exception: return "" @@ -739,8 +740,10 @@ def main(): extract_container_images(SOURCE_VERSION, LOCAL_REPO, CONTAINER_LIST, args.dry_run) # The following images are specific to layers that use fake rpms built from source extract_container_images(f"{FAKE_NEXT_MAJOR_VERSION}.{FAKE_NEXT_MINOR_VERSION}.*", NEXT_REPO, CONTAINER_LIST, args.dry_run) - extract_container_images(PREVIOUS_RELEASE_VERSION, PREVIOUS_RELEASE_REPO, CONTAINER_LIST, args.dry_run) - extract_container_images(YMINUS2_RELEASE_VERSION, YMINUS2_RELEASE_REPO, CONTAINER_LIST, args.dry_run) + if PREVIOUS_RELEASE_VERSION: + extract_container_images(PREVIOUS_RELEASE_VERSION, PREVIOUS_RELEASE_REPO, CONTAINER_LIST, args.dry_run) + if YMINUS2_RELEASE_VERSION: + extract_container_images(YMINUS2_RELEASE_VERSION, YMINUS2_RELEASE_REPO, CONTAINER_LIST, args.dry_run) # The following images are specific to the brew release versions if BREW_Y0_RELEASE_VERSION: extract_container_images(BREW_Y0_RELEASE_VERSION, BREW_REPO, CONTAINER_LIST, args.dry_run) diff --git a/test/bin/pyutils/generate_common_versions.py b/test/bin/pyutils/generate_common_versions.py index fea77b1532..df14f7921d 100755 --- a/test/bin/pyutils/generate_common_versions.py +++ b/test/bin/pyutils/generate_common_versions.py @@ -6,6 +6,7 @@ import requests import subprocess import os +import platform import sys import argparse import logging @@ -17,6 +18,7 @@ import ghutils # noqa: E402 ARCH = os.uname().machine +RHEL_MAJOR = platform.freedesktop_os_release()['VERSION_ID'].split('.')[0] # Version map defining the last minor version for each major version. # Used for cross-major Y-1/Y-2 calculations (e.g., 5.0's Y-1 is 4.22). @@ -80,7 +82,7 @@ def get_candidate_repo_url(major, minor, dev_preview=False): Returns: str: The URL of the candidate repository. """ - return f"https://mirror.openshift.com/pub/openshift-v{major}/{ARCH}/microshift/ocp{'-dev-preview' if dev_preview else ''}/latest-{major}.{minor}/el9/os" + return f"https://mirror.openshift.com/pub/openshift-v{major}/{ARCH}/microshift/ocp{'-dev-preview' if dev_preview else ''}/latest-{major}.{minor}/el{RHEL_MAJOR}/os" def get_dependencies_repo_url(major, minor, steps_back=0): @@ -106,7 +108,7 @@ def get_dependencies_repo_url(major, minor, steps_back=0): current_major, current_minor = major, minor for _ in range(steps_back + 1): - url = f"https://mirror.openshift.com/pub/openshift-v{current_major}/{ARCH}/dependencies/rpms/{current_major}.{current_minor}-el9-beta" + url = f"https://mirror.openshift.com/pub/openshift-v{current_major}/{ARCH}/dependencies/rpms/{current_major}.{current_minor}-el{RHEL_MAJOR}-beta" if mirror_exists(url) and repo_provides_pkg(url, "cri-o"): logging.info(f"Beta dependencies repository found for {current_major}.{current_minor}") return url @@ -180,7 +182,7 @@ def get_subscription_repo_name_if_exists(major, minor): Returns: str or None: The name of the subscription repository, or None if not available. """ - repo = f"rhocp-{major}.{minor}-for-rhel-9-{ARCH}-rpms" + repo = f"rhocp-{major}.{minor}-for-rhel-{RHEL_MAJOR}-{ARCH}-rpms" if repo_provides_pkg(repo, "microshift"): return repo @@ -286,7 +288,7 @@ def get_gitops_version(major_version, minor_version): gitops_version_ocp_compatibility = gitops_version_from_api_docs.get("openshift_compatibility") or "" gitops_version_number = gitops_version_from_api_docs.get("name") if f"{current_major}.{current_minor}" in gitops_version_ocp_compatibility: - gitops_repo = f"gitops-{gitops_version_number}-for-rhel-9-{ARCH}-rpms" + gitops_repo = f"gitops-{gitops_version_number}-for-rhel-{RHEL_MAJOR}-{ARCH}-rpms" if repo_provides_pkg(gitops_repo, "microshift-gitops"): logging.info(f"Found GitOps version: {gitops_version_number} which is compatible with OCP {gitops_version_ocp_compatibility} on {gitops_repo} repository") return gitops_version_number @@ -321,7 +323,7 @@ def generate_common_versions(major_version, minor_version): # The 'rhocp_minor_y' variable should be the minor version number, if the # current release is available through the 'rhocp' stream, otherwise empty. - rhocp_minor_y = minor_version if repo_provides_pkg(f"rhocp-{major_version}.{minor_version}-for-rhel-9-{ARCH}-rpms", "cri-o") else '""' + rhocp_minor_y = minor_version if repo_provides_pkg(f"rhocp-{major_version}.{minor_version}-for-rhel-{RHEL_MAJOR}-{ARCH}-rpms", "cri-o") else '""' rhocp_major_y = major_version if rhocp_minor_y != '""' else '""' # The beta repository, containing dependencies, should point to the @@ -332,7 +334,7 @@ def generate_common_versions(major_version, minor_version): # The 'rhocp_minor_y1' variable should be the previous minor version number, if # the previous release is available through the 'rhocp' stream, otherwise empty. - rhocp_minor_y1 = previous_minor_version if repo_provides_pkg(f"rhocp-{previous_major_version}.{previous_minor_version}-for-rhel-9-{ARCH}-rpms", "cri-o") else '""' + rhocp_minor_y1 = previous_minor_version if repo_provides_pkg(f"rhocp-{previous_major_version}.{previous_minor_version}-for-rhel-{RHEL_MAJOR}-{ARCH}-rpms", "cri-o") else '""' rhocp_major_y1 = previous_major_version if rhocp_minor_y1 != '""' else '""' # The beta repository, containing dependencies, should point to the diff --git a/test/bin/scenario.sh b/test/bin/scenario.sh index 0d1c0885a1..47768a759b 100755 --- a/test/bin/scenario.sh +++ b/test/bin/scenario.sh @@ -615,7 +615,9 @@ exit_if_image_not_set() { # Exit the script if microshift previous Z-stream version does not exist in rhocp repository exit_if_zprel_not_exist() { - local -r rhocp_repo="rhocp-${MAJOR_VERSION}.${MINOR_VERSION}-for-rhel-9-${UNAME_M}-rpms" + source /etc/os-release + local -r rhel_major="${VERSION_ID%%.*}" + local -r rhocp_repo="rhocp-${MAJOR_VERSION}.${MINOR_VERSION}-for-rhel-${rhel_major}-${UNAME_M}-rpms" local microshift_zprel if ! microshift_zprel="$(dnf repoquery -q --repo "${rhocp_repo}" --latest-limit 1 --nvr microshift 2>&1)"; then record_junit "repo ${rhocp_repo} does not exist or is not available: ${microshift_zprel}" "exit_if_zprel_not_exist" "SKIPPED" From f163de8dcab563ce0380ef0339ba5453c7e7f9fb Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Tue, 16 Jun 2026 14:15:35 +0200 Subject: [PATCH 6/8] fix: read /etc/os-release directly for Python 3.9 compatibility platform.freedesktop_os_release() requires Python 3.10+ but RHEL 9 ships Python 3.9, causing an AttributeError on all el9 bootc jobs. Replace with direct parsing of /etc/os-release which works on all Python versions. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- test/bin/pyutils/build_bootc_images.py | 9 ++++++++- test/bin/pyutils/generate_common_versions.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/test/bin/pyutils/build_bootc_images.py b/test/bin/pyutils/build_bootc_images.py index c42a9942f6..66ea0bb7cd 100644 --- a/test/bin/pyutils/build_bootc_images.py +++ b/test/bin/pyutils/build_bootc_images.py @@ -38,7 +38,14 @@ GOMPLATE = common.get_env_var('GOMPLATE') MIRROR_REGISTRY = common.get_env_var('MIRROR_REGISTRY_URL') FORCE_REBUILD = False -RHEL_MAJOR = platform.freedesktop_os_release()['VERSION_ID'].split('.')[0] +def _get_rhel_major(): + with open('/etc/os-release') as f: + for line in f: + if line.startswith('VERSION_ID='): + return line.strip().split('=')[1].strip('"').split('.')[0] + return '9' + +RHEL_MAJOR = _get_rhel_major() def cleanup_atexit(dry_run): diff --git a/test/bin/pyutils/generate_common_versions.py b/test/bin/pyutils/generate_common_versions.py index df14f7921d..e0fc9bbfb3 100755 --- a/test/bin/pyutils/generate_common_versions.py +++ b/test/bin/pyutils/generate_common_versions.py @@ -6,7 +6,6 @@ import requests import subprocess import os -import platform import sys import argparse import logging @@ -18,7 +17,14 @@ import ghutils # noqa: E402 ARCH = os.uname().machine -RHEL_MAJOR = platform.freedesktop_os_release()['VERSION_ID'].split('.')[0] +def _get_rhel_major(): + with open('/etc/os-release') as f: + for line in f: + if line.startswith('VERSION_ID='): + return line.strip().split('=')[1].strip('"').split('.')[0] + return '9' + +RHEL_MAJOR = _get_rhel_major() # Version map defining the last minor version for each major version. # Used for cross-major Y-1/Y-2 calculations (e.g., 5.0's Y-1 is 4.22). From 85df9552c6d2c843db34e0b712e25c4526cb5d09 Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Tue, 16 Jun 2026 14:35:43 +0200 Subject: [PATCH 7/8] fix: add PEP 8 blank lines around _get_rhel_major function E302/E305: need 2 blank lines before and after module-level function definitions. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- test/bin/pyutils/build_bootc_images.py | 3 +++ test/bin/pyutils/generate_common_versions.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test/bin/pyutils/build_bootc_images.py b/test/bin/pyutils/build_bootc_images.py index 66ea0bb7cd..8cab260120 100644 --- a/test/bin/pyutils/build_bootc_images.py +++ b/test/bin/pyutils/build_bootc_images.py @@ -38,6 +38,8 @@ GOMPLATE = common.get_env_var('GOMPLATE') MIRROR_REGISTRY = common.get_env_var('MIRROR_REGISTRY_URL') FORCE_REBUILD = False + + def _get_rhel_major(): with open('/etc/os-release') as f: for line in f: @@ -45,6 +47,7 @@ def _get_rhel_major(): return line.strip().split('=')[1].strip('"').split('.')[0] return '9' + RHEL_MAJOR = _get_rhel_major() diff --git a/test/bin/pyutils/generate_common_versions.py b/test/bin/pyutils/generate_common_versions.py index e0fc9bbfb3..3f534efeaf 100755 --- a/test/bin/pyutils/generate_common_versions.py +++ b/test/bin/pyutils/generate_common_versions.py @@ -17,6 +17,8 @@ import ghutils # noqa: E402 ARCH = os.uname().machine + + def _get_rhel_major(): with open('/etc/os-release') as f: for line in f: @@ -24,6 +26,7 @@ def _get_rhel_major(): return line.strip().split('=')[1].strip('"').split('.')[0] return '9' + RHEL_MAJOR = _get_rhel_major() # Version map defining the last minor version for each major version. From 39a1d6b647c839bc48bb45f3ee9cc3410c7c6e32 Mon Sep 17 00:00:00 2001 From: Alejandro Gullon Date: Wed, 17 Jun 2026 11:11:28 +0200 Subject: [PATCH 8/8] fix: skip virt-manager package on RHEL 10 virt-manager was removed in RHEL 10 (deprecated since RHEL 8). The CI only uses CLI tools (virt-install, libvirt-client) which are still available, so virt-manager can simply be skipped. Co-Authored-By: Claude Opus 4.6 pre-commit.check-secrets: ENABLED --- scripts/devenv-builder/manage-vm.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/scripts/devenv-builder/manage-vm.sh b/scripts/devenv-builder/manage-vm.sh index 0502d45f7b..90c2ca16f7 100755 --- a/scripts/devenv-builder/manage-vm.sh +++ b/scripts/devenv-builder/manage-vm.sh @@ -68,8 +68,13 @@ function get_base_isofile { } function action_config() { - local -r deps="libvirt virt-manager virt-install virt-viewer libvirt-client qemu-kvm qemu-img sshpass wget" - + source /etc/os-release + local -r rhel_major="${VERSION_ID%%.*}" + local deps="libvirt virt-install virt-viewer libvirt-client qemu-kvm qemu-img sshpass wget" + if [[ "${rhel_major}" -lt 10 ]]; then + deps+=" virt-manager" + fi + "${SCRIPTDIR}/../dnf_retry.sh" "install" "${deps}" if [ "$(systemctl is-active libvirtd.socket)" != "active" ] ; then