From e0f2d4c96a9fb0c83488d2757b1f90e8621265f6 Mon Sep 17 00:00:00 2001 From: Peter Hine Date: Wed, 26 Aug 2026 12:52:14 +1000 Subject: [PATCH 01/19] Initial commit for almalinux-deploy.sh changes --- README.md | 7 ++- README_PRESERVE_RHSM.md | 48 ++++++++++++++ almalinux-deploy.sh | 134 +++++++++++++++++++++++++++++----------- 3 files changed, 151 insertions(+), 38 deletions(-) create mode 100644 README_PRESERVE_RHSM.md diff --git a/README.md b/README.md index 291f0d8..d628e6d 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,9 @@ The script supports the following options: - `-d, --downgrade` - Allow downgrade from CentOS Stream to AlmaLinux stable - `-v, --version` - Print script version and exit - `-l=URL, --local-repo=URL` - Use AlmaLinux local repositories at specified URL/path (for systems without internet access) +- `--preserve-rhsm` - Preserve Red Hat Subscription Manager configuration. + Administrators need to ensure the correct repositories are set. + Only compatible with the -e option below, all other options will be ignored - `-e=pkg1*,pkg2*, --exclude=pkg1*,pkg2*` - Comma-separated list of packages to exclude during dnf distro-sync ### Environment Variables @@ -183,6 +186,7 @@ When migrating from RHEL, the script automatically: - Removes subscription-manager related packages - Disables RHEL-specific DNF plugins - Backs up and removes RHEL repository files +Using the '--preserve-rhsm' stops this behavior and preserves the subscription-manager configuration. Administrators must ensure the correct repositories are set for AlmaLinux. ### Container Environments The script detects OCI-compliant container environments and automatically: @@ -199,7 +203,7 @@ The script backs up and restores system alternatives (e.g., Python, Java version ### UEFI Secure Boot Support The script fully supports UEFI Secure Boot environments. During migration, it: - Reinstalls all Secure Boot related packages (shim, grub2, fwupd) with AlmaLinux signed versions -- Reinstalls the kernel package with AlmaLinux signed version +- Reinstalls the kernel package with AlmaLinux signed version. - Creates appropriate EFI boot entries using shim bootloaders (shimx64.efi for x86_64, shimaa64.efi for aarch64) - Handles BTRFS subvolume paths correctly for EL10+ systems @@ -210,6 +214,7 @@ For Oracle Linux migrations, the script automatically resets and restores module ### Repository Mapping The script intelligently maps enabled repositories from your source distribution to equivalent AlmaLinux repositories: +Using the '--preserve-rhsm' option does not do these mappings. It is up to the Administrator to ensure the correct repositories are set for AlmaLinux. - **extras** - Extra packages for Enterprise Linux - Maps: CentOS/Rocky `extras`, `extras-common`, MiracleLinux `9/10-latest-extras`, Oracle Linux `ol8/9/10_addons` diff --git a/README_PRESERVE_RHSM.md b/README_PRESERVE_RHSM.md new file mode 100644 index 0000000..2cee721 --- /dev/null +++ b/README_PRESERVE_RHSM.md @@ -0,0 +1,48 @@ +The '--preserve-rhsm' option is used to preserve the Red Hat Subscription Manager (RHSM) configuration. +This option totally removes all the intelligence the authors have put into the script to manage repositories. + +In addition the script will install `python3-dnf-plugin-post-transaction-actions `and create `/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf`. +`/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf` will remove `/etc/yum.repos.d/almalinux*.repo` files as soon as an AlmaLinux release or repos RPM creates them. +This enables your servers to not have a proxy setup in `dnf.conf` or other access to the internet. + +You, the Administrator, must make sure your systems are ready for migration and that the repositories are configured correctly. +You will probably do this by running a preparation script on the target server. + +An simple example will be: +``` +#!/usr/bin/bash + +. /etc/os-release +OS_VER=${VERSION_ID%.*} + +CodeReadyRepoInstalled=$(/usr/bin/dnf repolist | /usr/bin/awk '/codeready-builder/{print $1}') +if [ "${CodeReadyRepoInstalled}" ]; then + case ${OS_VER} in + 8) + CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_PowerTools --disable ${CodeReadyRepoInstalled}" + ;; + 9|10) + CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_CRB --disable ${CodeReadyRepoInstalled}" + ;; + esac +fi + +# We have no satellite-client repository in AlmaLinux +/usr/bin/dnf remove $(/usr/bin/dnf list installed | /usr/bin/awk '/satellite-client/{print $1}') +/usr/bin/dnf upgrade -y >/dev/null || exit 1 + +# Your Repo naming is different. This is an example only. +/usr/bin/subscription-manager repos --enable ORG_AlmaLinux_${OS_VER}_BaseOS_RPMs \ + --enable ORG_AlmaLinux_${OS_VER}_AppStream_RPMs \ + --enable ORG_EPEL_EPEL${OS_VER} \ + --enable ORG_Zabbix_7_4-AL${OS_VER} \ + --disable rhel-${OS_VER}-for-x86_64-appstream-rpms \ + --disable rhel-${OS_VER}-for-x86_64-baseos-rpms \ + --disable satellite-client-6-for-rhel-${OS_VER}-x86_64-rpms \ + --disable ORG_Zabbix_7_4-RHEL${OS_VER} ${CRB_REPO} +``` + +The Zabbix repository is shown here as an example of a non RedHat repository that has a RedHat and AlmaLinux version. + +Download the almalinux-deploy.sh script from your internal systems (pub directory of the foreman server is a suggestion); + and run it with the '--preserve-rhsm' option. diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 93d4cf2..892d69b 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -22,6 +22,7 @@ VERSION='0.1.13' DOWNGRADE='NO' REPO_URL=https://repo.almalinux.org/almalinux LOCAL_REPO='NO' +PRESERVE_RHSM='NO' BRANDING_PKGS=("centos-backgrounds" "centos-logos" "centos-indexhtml" \ "centos-logos-ipa" "centos-logos-httpd" \ @@ -179,6 +180,8 @@ show_usage() { echo ' -v , --version print version information and exit' echo ' -l=URL/path , --local-repo=URL/path use AlmaLinux local repositories at URL/path, like http://mirror.example.com/almalinux' echo ' in case if migrated system does not have internet access' + echo ' --preserve-rhsm Preserve Red Hat Subscription Manager configuration' + echo ' Only compatible with the -e option below, all other options will be ignored.' echo ' -e=pkg1*,pkg2 , --exclude=pkg1*,pkg2* list of packages separated with comma to exclude on dnf distro-sync' } @@ -493,9 +496,14 @@ assert_dnf_plugins_core() { # # Prints almalinux-release RPM package download URL. get_release_file_url() { - local -r os_version="${1%%.*}" - local -r arch="${2}" - echo "${ALMA_RELEASE_URL:-${REPO_URL}/almalinux-release-latest-${os_version}.${arch}.rpm}" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + local -r os_version="${1%%.*}" + local -r arch="${2}" + echo "${ALMA_RELEASE_URL:-${REPO_URL}/almalinux-release-latest-${os_version}.${arch}.rpm}" + else + # get the url of this system's almalinux-release package from dnf + dnf download --url almalinux-release 2>/dev/null | grep http + fi } # Returns a latest almalinux-repos RPM package download URL. @@ -505,9 +513,14 @@ get_release_file_url() { # # Prints almalinux-release RPM package download URL. get_repos_file_url() { - local -r os_version="${1%%.*}" - local -r arch="${2}" - echo "${ALMA_REPOS_URL:-${REPO_URL}/almalinux-repos-latest-${os_version}.${arch}.rpm}" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + local -r os_version="${1%%.*}" + local -r arch="${2}" + echo "${ALMA_REPOS_URL:-${REPO_URL}/almalinux-repos-latest-${os_version}.${arch}.rpm}" + else + # get the url of this system's almalinux-release package from dnf + dnf download --url almalinux-repos 2>/dev/null | grep http + fi } # Returns a latest almalinux-gpg-keys RPM package download URL. @@ -517,9 +530,14 @@ get_repos_file_url() { # # Prints almalinux-gpg-keys RPM package download URL. get_gpg_keys_file_url() { - local -r os_version="${1%%.*}" - local -r arch="${2}" - echo "${ALMA_REPOS_URL:-${REPO_URL}/almalinux-gpg-keys-latest-${os_version}.${arch}.rpm}" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + local -r os_version="${1%%.*}" + local -r arch="${2}" + echo "${ALMA_REPOS_URL:-${REPO_URL}/almalinux-gpg-keys-latest-${os_version}.${arch}.rpm}" + else + # get the url of this system's almalinux-release package from dnf + dnf download --url almalinux-gpg-keys 2>/dev/null | grep http + fi } # Downloads and installs the AlmaLinux public PGP key. @@ -532,7 +550,12 @@ install_rpm_pubkey() { fi local -r tmp_dir="${1}" local -r os_version="${2%%.*}" - local -r pubkey_url="${ALMA_PUBKEY_URL:-${REPO_URL}/RPM-GPG-KEY-AlmaLinux-${os_version}}" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + local -r pubkey_url="${ALMA_PUBKEY_URL:-${REPO_URL}/RPM-GPG-KEY-AlmaLinux-${os_version}}" + else + local -r repo=$(dnf repolist | awk '/BaseOS/{print $1}') + local -r pubkey_url=$(python3 -c "import configparser; c = configparser.ConfigParser(); c.read('/etc/yum.repos.d/redhat.repo'); print(c.get('$repo', 'gpgkey'))") + fi local -r pubkey_path="${tmp_dir}/RPM-GPG-KEY-AlmaLinux" local -r step='Download RPM-GPG-KEY-AlmaLinux' local output @@ -557,7 +580,7 @@ install_rpm_pubkey() { download_release_files() { local -r tmp_dir="${1}" local -r release_url="${2}" - local -r release_path="${tmp_dir}/almalinux-release-latest.rpm" + [[ "${PRESERVE_RHSM}" == "NO" ]] && local -r release_path="${tmp_dir}/almalinux-release-latest.rpm" || local -r release_path="${tmp_dir}/almalinux-release.rpm" local output if ! output=$(curl -f -s -S -o "${release_path}" "${release_url}" 2>&1); then report_step_error 'Download almalinux packages - release' "${output}" @@ -726,9 +749,9 @@ cleanup_sss_cache() { fi if [[ "${DOWNGRADE}" == 'YES' ]]; then for file in /var/lib/sss/db/cache_*.ldb; do - if [ -f "${file}" ]; then - mv -f "${file}" "${file}.bak" - fi + if [ -f "${file}" ]; then + mv -f "${file}" "${file}.bak" + fi done fi save_status_of_stage "cleanup_sss_cache" @@ -785,6 +808,11 @@ install_almalinux_release_package() { fi local -r release_path="${1}" rpm -Uvh --nodeps "${release_path}" + case "${os_version}" in + 8*) + [[ "${PRESERVE_RHSM}" == "YES" ]] && rm -f /etc/yum.repos.d/almalinux*.repo + ;; + esac report_step_done 'Install almalinux-release package' save_status_of_stage "install_almalinux_release_package" } @@ -796,6 +824,7 @@ install_almalinux_repos_package() { fi local -r repos_path="${1}" rpm -Uvh --nodeps "${repos_path}" + [[ "${PRESERVE_RHSM}" == "YES" ]] && rm -f /etc/yum.repos.d/almalinux*.repo report_step_done 'Install almalinux-repos package' save_status_of_stage "install_almalinux_repos_package" } @@ -909,14 +938,17 @@ distro_sync() { local -r step='Run dnf distro-sync -y' local ret_code=0 local -r os_version="${1}" - case "${os_version}" in - 8*) - local dnf_repos="--enablerepo=powertools" - ;; - 9*|10*) - local dnf_repos="--enablerepo=crb" - ;; - esac + local dnf_repos="" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + case "${os_version}" in + 8*) + local dnf_repos="--enablerepo=powertools" + ;; + 9*|10*) + local dnf_repos="--enablerepo=crb" + ;; + esac + fi local exclude_pkgs="--exclude=" # create needed repo if [ "${panel_type}" == "plesk" ]; then @@ -938,11 +970,20 @@ distro_sync() { if [ -n "${EXCLUDE_PKGS}" ]; then exclude_pkgs+=",${EXCLUDE_PKGS}" fi - dnf distro-sync -y "${dnf_repos}" "${exclude_pkgs}" || { - ret_code=${?} - report_step_error "${step}. Exit code: ${ret_code}" - exit ${ret_code} - } + # We can't have a empty dnf_repos variable, because dnf will fail with "No package installed." (note double space) + if [[ "${dnf_repos}" == "" ]]; then + dnf distro-sync -y "${exclude_pkgs}" || { + ret_code=${?} + report_step_error "${step}. Exit code: ${ret_code}" + exit ${ret_code} + } + else + dnf distro-sync -y "${dnf_repos}" "${exclude_pkgs}" || { + ret_code=${?} + report_step_error "${step}. Exit code: ${ret_code}" + exit ${ret_code} + } + fi # remove unnecessary repo if [ "${panel_type}" == "plesk" ]; then plesk installer --select-release-current --show-components @@ -1251,7 +1292,6 @@ _restore_alternative() { fi done done - } # backup existing alternatives, including the current states of alternatives @@ -1346,7 +1386,8 @@ reinstall_secure_boot_packages() { local kernel_package for pkg in $(rpm -qa | grep -E 'shim|fwupd|grub2'); do if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "$pkg")" ]]; then - yum reinstall "${pkg}" -y + # There is a timing issue where some packages are available on RHEL but not yet on AlmaLinux mirrors, so we ignore errors here + yum reinstall -y "${pkg}" || true fi done kernel_path="$(grubby --default-kernel)" @@ -1362,7 +1403,8 @@ reinstall_secure_boot_packages() { fi kernel_package="$(rpm -qf "$kernel_path")" if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "${kernel_package}")" ]]; then - yum reinstall "${kernel_package}" -y + # There is a timing issue where kernel packages are available on RHEL but not yet on AlmaLinux mirrors, so we ignore errors here + yum reinstall -y "$kernel_package" || true fi fi report_step_done "All Secure Boot related packages which were not released by AlmaLinux are reinstalled" @@ -1413,7 +1455,12 @@ remove_redhat_rhsm_rpms() { if get_status_of_stage "remove_redhat_rhsm_rpms"; then return 0 fi - rpm -e --nodeps "${REDHAT_RHSM_RPMS[@]}" >/dev/null 2>&1 || true + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + rpm -e --nodeps "${REDHAT_RHSM_RPMS[@]}" >/dev/null 2>&1 || true + else + # We want dependencies here + dnf remove -y insights-core rhc >/dev/null 2>&1 || true + fi report_step_done "Red Hat Subscription Manager packages are removed (with rpm --nodeps)" save_status_of_stage "remove_redhat_rhsm_rpms" } @@ -1451,7 +1498,7 @@ main() { assert_supported_system "${os_type}" "${os_version}" "${arch}" assert_supported_filesystem "${os_version}" assert_dnf_plugins_core - check_local_repo "${os_version}" "${arch}" + [[ "${PRESERVE_RHSM}" == "NO" ]] && check_local_repo "${os_version}" "${arch}" get_enabled_repos read -r panel_type panel_version < <(get_panel_info) @@ -1482,9 +1529,11 @@ main() { backup_issue if [[ "${os_type}" == "rhel" ]]; then - subscription_manager_unregister "${os_version}" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + subscription_manager_unregister "${os_version}" + remove_redhat_repo_files + fi remove_redhat_rhsm_rpms - remove_redhat_repo_files fi case "${os_version}" in @@ -1511,9 +1560,9 @@ main() { esac backup_alternatives - switch_to_local_repo "${os_version}" "${arch}" + [[ "${PRESERVE_RHSM}" == "NO" ]] && switch_to_local_repo "${os_version}" "${arch}" reset_wrong_module_streams - enable_repos "${os_version}" + [[ "${PRESERVE_RHSM}" == "NO" ]] && enable_repos "${os_version}" distro_sync "${os_version}" restore_module_streams restore_alternatives @@ -1540,7 +1589,7 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then exit 0 ;; -f | --full) - dnf_upgrade + DNF_UPGRADE='YES' ;; -v | --version) echo "${VERSION}" @@ -1552,6 +1601,9 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then -t | --tests) exit 0 ;; + --preserve-rhsm) + PRESERVE_RHSM='YES' + ;; -e=* | --exclude=*) EXCLUDE_PKGS="${opt#*=}" shift @@ -1568,6 +1620,14 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then ;; esac done + if [[ "${PRESERVE_RHSM}" == "YES" ]]; then + LOCAL_REPO='NO' + REPO_URL='' + DNF_UPGRADE='NO' + dnf install -y python3-dnf-plugin-post-transaction-actions >/dev/null + echo -e '# AlmaLinux Repo files break dnf if no proxy is available\nalmalinux-re*:in:/usr/bin/rm -f /etc/yum.repos.d/almalinux*.repo' > /etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf + fi + [[ "${DNF_UPGRADE}" == "YES" ]] && dnf_upgrade setup_log_files set -x main From 5b77ba72816c8639c859e3542014ca711fb489cf Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:40:30 +1000 Subject: [PATCH 02/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 892d69b..7ca0ffc 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1478,6 +1478,31 @@ remove_redhat_repo_files() { report_step_done "Remove RHEL repositories' files if any" save_status_of_stage "remove_redhat_repo_files" } +# Installs the dnf post-transaction-actions plugin and a hook which removes +# AlmaLinux repository files as soon as almalinux-release/almalinux-repos +# create them. Only used with --preserve-rhsm, where repositories are +# managed by subscription-manager (Foreman/Katello). +setup_preserve_rhsm_hook() { + if [[ "${PRESERVE_RHSM}" != "YES" ]]; then + return 0 + fi + if get_status_of_stage "setup_preserve_rhsm_hook"; then + return 0 + fi + local -r step='Install dnf post-transaction-actions hook for --preserve-rhsm' + local -r hook_dir='/etc/dnf/plugins/post-transaction-actions.d' + local output + if ! output=$(dnf install -y python3-dnf-plugin-post-transaction-actions 2>&1); then + report_step_error "${step}" "${output}" + exit 1 + fi + mkdir -p "${hook_dir}" + printf '%s\n' '# AlmaLinux Repo files break dnf if no proxy is available' \ + 'almalinux-re*:in:/usr/bin/rm -f /etc/yum.repos.d/almalinux*.repo' \ + > "${hook_dir}/almalinux-repos.conf" + report_step_done "${step}" + save_status_of_stage "setup_preserve_rhsm_hook" +} main() { is_migration_completed From dec3c5026a83b1dc93239a69ec2ee0f7c773f244 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:54:39 +1000 Subject: [PATCH 03/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 7ca0ffc..0575273 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1514,7 +1514,7 @@ main() { local release_path local panel_type local panel_version - assert_run_as_root + setup_preserve_rhsm_hook arch="$(get_system_arch)" os_type="$(get_os_release_var 'ID')" os_version="$(get_os_version "${os_type}")" From 0afc12a6ad3b2f6dfcf3449944acc8296b4f8585 Mon Sep 17 00:00:00 2001 From: Peter Hine Date: Thu, 27 Aug 2026 10:07:41 +1000 Subject: [PATCH 04/19] Update almalinux-deploy.sh for suggested changes --- almalinux-deploy.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 0575273..812afbc 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -23,6 +23,7 @@ DOWNGRADE='NO' REPO_URL=https://repo.almalinux.org/almalinux LOCAL_REPO='NO' PRESERVE_RHSM='NO' +DNF_UPGRADE='NO' BRANDING_PKGS=("centos-backgrounds" "centos-logos" "centos-indexhtml" \ "centos-logos-ipa" "centos-logos-httpd" \ @@ -1386,8 +1387,8 @@ reinstall_secure_boot_packages() { local kernel_package for pkg in $(rpm -qa | grep -E 'shim|fwupd|grub2'); do if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "$pkg")" ]]; then - # There is a timing issue where some packages are available on RHEL but not yet on AlmaLinux mirrors, so we ignore errors here - yum reinstall -y "${pkg}" || true + yum reinstall -y "${pkg}" + fi done kernel_path="$(grubby --default-kernel)" @@ -1483,7 +1484,7 @@ remove_redhat_repo_files() { # create them. Only used with --preserve-rhsm, where repositories are # managed by subscription-manager (Foreman/Katello). setup_preserve_rhsm_hook() { - if [[ "${PRESERVE_RHSM}" != "YES" ]]; then + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then return 0 fi if get_status_of_stage "setup_preserve_rhsm_hook"; then @@ -1514,6 +1515,7 @@ main() { local release_path local panel_type local panel_version + assert_run_as_root setup_preserve_rhsm_hook arch="$(get_system_arch)" os_type="$(get_os_release_var 'ID')" From 562fad12aba8699cdd28bfeb75b0781e19a6d921 Mon Sep 17 00:00:00 2001 From: Peter Hine Date: Thu, 27 Aug 2026 10:11:34 +1000 Subject: [PATCH 05/19] Remove random blank line from almalinux-deploy.sh --- almalinux-deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 812afbc..c13acf6 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1388,7 +1388,6 @@ reinstall_secure_boot_packages() { for pkg in $(rpm -qa | grep -E 'shim|fwupd|grub2'); do if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "$pkg")" ]]; then yum reinstall -y "${pkg}" - fi done kernel_path="$(grubby --default-kernel)" From ac23f40dfe4136094c3f57e404e27d93960b517c Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Fri, 28 Aug 2026 06:13:02 +1000 Subject: [PATCH 06/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index c13acf6..3b58a5b 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1651,7 +1651,6 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then REPO_URL='' DNF_UPGRADE='NO' dnf install -y python3-dnf-plugin-post-transaction-actions >/dev/null - echo -e '# AlmaLinux Repo files break dnf if no proxy is available\nalmalinux-re*:in:/usr/bin/rm -f /etc/yum.repos.d/almalinux*.repo' > /etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf fi [[ "${DNF_UPGRADE}" == "YES" ]] && dnf_upgrade setup_log_files From 73a724986007200caa340889a9f431357e54f06c Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Fri, 28 Aug 2026 06:16:48 +1000 Subject: [PATCH 07/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 3b58a5b..16a6c97 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1650,7 +1650,6 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then LOCAL_REPO='NO' REPO_URL='' DNF_UPGRADE='NO' - dnf install -y python3-dnf-plugin-post-transaction-actions >/dev/null fi [[ "${DNF_UPGRADE}" == "YES" ]] && dnf_upgrade setup_log_files From 42b9c848de7bdab17eb261b46ca006419d27b2d2 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Fri, 28 Aug 2026 06:18:46 +1000 Subject: [PATCH 08/19] Update almalinux-deploy.sh for kernel update change Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 16a6c97..172e41e 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1404,7 +1404,23 @@ reinstall_secure_boot_packages() { kernel_package="$(rpm -qf "$kernel_path")" if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "${kernel_package}")" ]]; then # There is a timing issue where kernel packages are available on RHEL but not yet on AlmaLinux mirrors, so we ignore errors here - yum reinstall -y "$kernel_package" || true + if ! yum reinstall -y "$kernel_package"; then + # This exact kernel version isn't in AlmaLinux repositories yet. + # A kernel signed by another vendor won't boot with Secure Boot enabled, + # so make sure the latest AlmaLinux kernel is installed and is the default. + dnf install -y kernel + local alma_kernel + alma_kernel="$(rpm -q kernel --queryformat '%{VENDOR}|%{VERSION}-%{RELEASE}.%{ARCH}\n' \ + | awk -F'|' '$1 == "AlmaLinux" {print $2}' | sort -V | tail -n 1)" + if [[ -z "${alma_kernel}" ]]; then + report_step_error 'Install AlmaLinux kernel' \ + "${kernel_package} is not available in AlmaLinux repositories and no AlmaLinux kernel is installed" + exit 1 + fi + grubby --set-default "/boot/vmlinuz-${alma_kernel}" + echo "${kernel_package} is not available in AlmaLinux repositories yet;" \ + "default kernel set to ${alma_kernel}. The remaining kernel(s) are reported below." + fi fi fi report_step_done "All Secure Boot related packages which were not released by AlmaLinux are reinstalled" From d53658414085b7b66ce15dbb22205587951b6366 Mon Sep 17 00:00:00 2001 From: Peter Hine Date: Thu, 27 Aug 2026 10:13:00 +1000 Subject: [PATCH 09/19] Insert a blank line in front of setup_preserve_rhsm_hook --- almalinux-deploy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 172e41e..cc3609f 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1494,6 +1494,7 @@ remove_redhat_repo_files() { report_step_done "Remove RHEL repositories' files if any" save_status_of_stage "remove_redhat_repo_files" } + # Installs the dnf post-transaction-actions plugin and a hook which removes # AlmaLinux repository files as soon as almalinux-release/almalinux-repos # create them. Only used with --preserve-rhsm, where repositories are From 9258cd196d2f86db419ac6614425e04cecd35fd8 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Fri, 28 Aug 2026 07:01:28 +1000 Subject: [PATCH 10/19] Update almalinux-deploy.sh. remove comment Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index cc3609f..0fd482c 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1403,7 +1403,6 @@ reinstall_secure_boot_packages() { fi kernel_package="$(rpm -qf "$kernel_path")" if [[ "AlmaLinux" != "$(rpm -q --queryformat '%{vendor}' "${kernel_package}")" ]]; then - # There is a timing issue where kernel packages are available on RHEL but not yet on AlmaLinux mirrors, so we ignore errors here if ! yum reinstall -y "$kernel_package"; then # This exact kernel version isn't in AlmaLinux repositories yet. # A kernel signed by another vendor won't boot with Secure Boot enabled, From 2e5769fdf0decd705017b5929ded7b0ed59cc280 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:50:35 +1000 Subject: [PATCH 11/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 0fd482c..a986262 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1476,7 +1476,12 @@ remove_redhat_rhsm_rpms() { # We want dependencies here dnf remove -y insights-core rhc >/dev/null 2>&1 || true fi - report_step_done "Red Hat Subscription Manager packages are removed (with rpm --nodeps)" + if [[ "${PRESERVE_RHSM}" == "NO" ]]; then + report_step_done "Red Hat Subscription Manager packages are removed (with rpm --nodeps)" + else + report_step_done "Red Hat Insights packages (insights-core, rhc) are removed, subscription-manager is preserved" + fi + save_status_of_stage "remove_redhat_rhsm_rpms" } From 64a701c9dcab60a2764d429262cb5a19bbfc0e64 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:51:27 +1000 Subject: [PATCH 12/19] Update README.md Co-authored-by: Yuriy Kohut --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d628e6d..f87056b 100644 --- a/README.md +++ b/README.md @@ -114,9 +114,9 @@ The script supports the following options: - `-d, --downgrade` - Allow downgrade from CentOS Stream to AlmaLinux stable - `-v, --version` - Print script version and exit - `-l=URL, --local-repo=URL` - Use AlmaLinux local repositories at specified URL/path (for systems without internet access) -- `--preserve-rhsm` - Preserve Red Hat Subscription Manager configuration. - Administrators need to ensure the correct repositories are set. - Only compatible with the -e option below, all other options will be ignored +- `--preserve-rhsm` - Preserve Red Hat Subscription Manager configuration (Foreman/Katello managed hosts). + Administrators need to ensure the correct repositories are set. + Can be combined only with `-e/--exclude`; other options are rejected. - `-e=pkg1*,pkg2*, --exclude=pkg1*,pkg2*` - Comma-separated list of packages to exclude during dnf distro-sync ### Environment Variables From a662004e042c9b8ed6a0c60c6046e9349c74b07e Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:52:27 +1000 Subject: [PATCH 13/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index a986262..4589550 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -809,11 +809,9 @@ install_almalinux_release_package() { fi local -r release_path="${1}" rpm -Uvh --nodeps "${release_path}" - case "${os_version}" in - 8*) - [[ "${PRESERVE_RHSM}" == "YES" ]] && rm -f /etc/yum.repos.d/almalinux*.repo - ;; - esac + if [[ "${PRESERVE_RHSM}" == "YES" ]]; then + disable_almalinux_repo_files + fi report_step_done 'Install almalinux-release package' save_status_of_stage "install_almalinux_release_package" } From c88598bd6822cf4870fb6d7cc8e566b9c5954ab6 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:52:42 +1000 Subject: [PATCH 14/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 4589550..e545a93 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -823,7 +823,9 @@ install_almalinux_repos_package() { fi local -r repos_path="${1}" rpm -Uvh --nodeps "${repos_path}" - [[ "${PRESERVE_RHSM}" == "YES" ]] && rm -f /etc/yum.repos.d/almalinux*.repo + if [[ "${PRESERVE_RHSM}" == "YES" ]]; then + disable_almalinux_repo_files + fi report_step_done 'Install almalinux-repos package' save_status_of_stage "install_almalinux_repos_package" } From 184ec5589d874a373366df9895f6b9fdbdabae2b Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:55:16 +1000 Subject: [PATCH 15/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index e545a93..2ca7b04 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1499,32 +1499,6 @@ remove_redhat_repo_files() { save_status_of_stage "remove_redhat_repo_files" } -# Installs the dnf post-transaction-actions plugin and a hook which removes -# AlmaLinux repository files as soon as almalinux-release/almalinux-repos -# create them. Only used with --preserve-rhsm, where repositories are -# managed by subscription-manager (Foreman/Katello). -setup_preserve_rhsm_hook() { - if [[ "${PRESERVE_RHSM}" == "NO" ]]; then - return 0 - fi - if get_status_of_stage "setup_preserve_rhsm_hook"; then - return 0 - fi - local -r step='Install dnf post-transaction-actions hook for --preserve-rhsm' - local -r hook_dir='/etc/dnf/plugins/post-transaction-actions.d' - local output - if ! output=$(dnf install -y python3-dnf-plugin-post-transaction-actions 2>&1); then - report_step_error "${step}" "${output}" - exit 1 - fi - mkdir -p "${hook_dir}" - printf '%s\n' '# AlmaLinux Repo files break dnf if no proxy is available' \ - 'almalinux-re*:in:/usr/bin/rm -f /etc/yum.repos.d/almalinux*.repo' \ - > "${hook_dir}/almalinux-repos.conf" - report_step_done "${step}" - save_status_of_stage "setup_preserve_rhsm_hook" -} - main() { is_migration_completed local arch From 20f544327bff74b954d16f1ab5fedee9cfabd08f Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:55:50 +1000 Subject: [PATCH 16/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 2ca7b04..bca826d 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1641,10 +1641,10 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then ;; esac done - if [[ "${PRESERVE_RHSM}" == "YES" ]]; then - LOCAL_REPO='NO' - REPO_URL='' - DNF_UPGRADE='NO' + if [[ "${PRESERVE_RHSM}" == "YES" ]] && \ + [[ "${LOCAL_REPO}" == "YES" || "${DNF_UPGRADE}" == "YES" || "${DOWNGRADE}" == "YES" ]]; then + echo "Error: --preserve-rhsm can be combined only with the -e/--exclude option" >&2 + exit 2 fi [[ "${DNF_UPGRADE}" == "YES" ]] && dnf_upgrade setup_log_files From 5bd55e40a777a27c5902a64faf9c3b5624cfc3fb Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:56:04 +1000 Subject: [PATCH 17/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index bca826d..2bd105d 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -182,7 +182,8 @@ show_usage() { echo ' -l=URL/path , --local-repo=URL/path use AlmaLinux local repositories at URL/path, like http://mirror.example.com/almalinux' echo ' in case if migrated system does not have internet access' echo ' --preserve-rhsm Preserve Red Hat Subscription Manager configuration' - echo ' Only compatible with the -e option below, all other options will be ignored.' + echo ' Can be combined only with the -e/--exclude option below.' + echo ' -e=pkg1*,pkg2 , --exclude=pkg1*,pkg2* list of packages separated with comma to exclude on dnf distro-sync' } From 2ae5007c71d2611169831a48d91738bc9e37d872 Mon Sep 17 00:00:00 2001 From: nlaphine <156731130+nlaphine@users.noreply.github.com> Date: Sat, 29 Aug 2026 09:56:19 +1000 Subject: [PATCH 18/19] Update almalinux-deploy.sh Co-authored-by: Yuriy Kohut --- almalinux-deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 2bd105d..9860322 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -1511,7 +1511,6 @@ main() { local panel_type local panel_version assert_run_as_root - setup_preserve_rhsm_hook arch="$(get_system_arch)" os_type="$(get_os_release_var 'ID')" os_version="$(get_os_version "${os_type}")" From feea73846d1b7010c1cded31da1d9ab8c168a1fb Mon Sep 17 00:00:00 2001 From: Peter Hine Date: Sat, 29 Aug 2026 10:10:04 +1000 Subject: [PATCH 19/19] Remove README_PRESERVE_RHSM.md --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++ README_PRESERVE_RHSM.md | 48 -------------------------------------- almalinux-deploy.sh | 3 +-- 3 files changed, 52 insertions(+), 50 deletions(-) delete mode 100644 README_PRESERVE_RHSM.md diff --git a/README.md b/README.md index f87056b..668f611 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,57 @@ Using the '--preserve-rhsm' option does not do these mappings. It is up to the A This ensures that if you had specific repositories enabled before migration, the equivalent AlmaLinux repositories will be automatically enabled after migration. +### Preserving Red Hat Subscription Manager (RHSM) Configuration + +The '--preserve-rhsm' option is used to preserve the Red Hat Subscription Manager (RHSM) configuration. +This option totally removes all the intelligence the authors have put into the script to manage repositories. + +In addition the script will install `python3-dnf-plugin-post-transaction-actions `and create `/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf`. +`/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf` will remove `/etc/yum.repos.d/almalinux*.repo` files as soon as an AlmaLinux release or repos RPM creates them. +This enables your servers to not have a proxy setup in `dnf.conf` or other access to the internet. + +You, the Administrator, must make sure your systems are ready for migration and that the repositories are configured correctly. +You will probably do this by running a preparation script on the target server. + +An simple example will be: +``` +#!/usr/bin/bash + +. /etc/os-release +OS_VER=${VERSION_ID%.*} + +CodeReadyRepoInstalled=$(/usr/bin/dnf repolist | /usr/bin/awk '/codeready-builder/{print $1}') +if [ "${CodeReadyRepoInstalled}" ]; then + case ${OS_VER} in + 8) + CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_PowerTools --disable ${CodeReadyRepoInstalled}" + ;; + 9|10) + CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_CRB --disable ${CodeReadyRepoInstalled}" + ;; + esac +fi + +# We have no satellite-client repository in AlmaLinux. Alma Linux foreman Client can be considered if you want. +/usr/bin/dnf remove -y $(/usr/bin/dnf list installed | /usr/bin/awk '/satellite-client/{print $1}') +/usr/bin/dnf upgrade -y >/dev/null || exit 1 + +# Your Repo naming is different. This is an example only. +/usr/bin/subscription-manager repos --enable ORG_AlmaLinux_${OS_VER}_BaseOS_RPMs \ + --enable ORG_AlmaLinux_${OS_VER}_AppStream_RPMs \ + --enable ORG_EPEL_EPEL${OS_VER} \ + --enable ORG_Zabbix_7_4-AL${OS_VER} \ + --disable rhel-${OS_VER}-for-x86_64-appstream-rpms \ + --disable rhel-${OS_VER}-for-x86_64-baseos-rpms \ + --disable satellite-client-6-for-rhel-${OS_VER}-x86_64-rpms \ + --disable ORG_Zabbix_7_4-RHEL${OS_VER} ${CRB_REPO} +``` + +The Zabbix repository is shown here as an example of a non RedHat repository that has a RedHat and AlmaLinux version. + +Download the almalinux-deploy.sh script from your internal systems (pub directory of the foreman server is a suggestion); + and run it with the '--preserve-rhsm' option. + ## Known Limitations - **GRUB2 bootloader only**: For bare metal servers and virtual machines, only systems using GRUB2 as the bootloader are supported. Systems using alternative bootloaders (LILO, syslinux, systemd-boot, etc.) cannot be migrated. Container environments don't require a bootloader and are fully supported. diff --git a/README_PRESERVE_RHSM.md b/README_PRESERVE_RHSM.md deleted file mode 100644 index 2cee721..0000000 --- a/README_PRESERVE_RHSM.md +++ /dev/null @@ -1,48 +0,0 @@ -The '--preserve-rhsm' option is used to preserve the Red Hat Subscription Manager (RHSM) configuration. -This option totally removes all the intelligence the authors have put into the script to manage repositories. - -In addition the script will install `python3-dnf-plugin-post-transaction-actions `and create `/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf`. -`/etc/dnf/plugins/post-transaction-actions.d/almalinux-repos.conf` will remove `/etc/yum.repos.d/almalinux*.repo` files as soon as an AlmaLinux release or repos RPM creates them. -This enables your servers to not have a proxy setup in `dnf.conf` or other access to the internet. - -You, the Administrator, must make sure your systems are ready for migration and that the repositories are configured correctly. -You will probably do this by running a preparation script on the target server. - -An simple example will be: -``` -#!/usr/bin/bash - -. /etc/os-release -OS_VER=${VERSION_ID%.*} - -CodeReadyRepoInstalled=$(/usr/bin/dnf repolist | /usr/bin/awk '/codeready-builder/{print $1}') -if [ "${CodeReadyRepoInstalled}" ]; then - case ${OS_VER} in - 8) - CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_PowerTools --disable ${CodeReadyRepoInstalled}" - ;; - 9|10) - CRB_REPO="--enable=ORG_AlmaLinux_${OS_VER}_CRB --disable ${CodeReadyRepoInstalled}" - ;; - esac -fi - -# We have no satellite-client repository in AlmaLinux -/usr/bin/dnf remove $(/usr/bin/dnf list installed | /usr/bin/awk '/satellite-client/{print $1}') -/usr/bin/dnf upgrade -y >/dev/null || exit 1 - -# Your Repo naming is different. This is an example only. -/usr/bin/subscription-manager repos --enable ORG_AlmaLinux_${OS_VER}_BaseOS_RPMs \ - --enable ORG_AlmaLinux_${OS_VER}_AppStream_RPMs \ - --enable ORG_EPEL_EPEL${OS_VER} \ - --enable ORG_Zabbix_7_4-AL${OS_VER} \ - --disable rhel-${OS_VER}-for-x86_64-appstream-rpms \ - --disable rhel-${OS_VER}-for-x86_64-baseos-rpms \ - --disable satellite-client-6-for-rhel-${OS_VER}-x86_64-rpms \ - --disable ORG_Zabbix_7_4-RHEL${OS_VER} ${CRB_REPO} -``` - -The Zabbix repository is shown here as an example of a non RedHat repository that has a RedHat and AlmaLinux version. - -Download the almalinux-deploy.sh script from your internal systems (pub directory of the foreman server is a suggestion); - and run it with the '--preserve-rhsm' option. diff --git a/almalinux-deploy.sh b/almalinux-deploy.sh index 9860322..133837e 100755 --- a/almalinux-deploy.sh +++ b/almalinux-deploy.sh @@ -182,8 +182,7 @@ show_usage() { echo ' -l=URL/path , --local-repo=URL/path use AlmaLinux local repositories at URL/path, like http://mirror.example.com/almalinux' echo ' in case if migrated system does not have internet access' echo ' --preserve-rhsm Preserve Red Hat Subscription Manager configuration' - echo ' Can be combined only with the -e/--exclude option below.' - + echo ' Can be combined only with the -e/--exclude option below' echo ' -e=pkg1*,pkg2 , --exclude=pkg1*,pkg2* list of packages separated with comma to exclude on dnf distro-sync' }