From c994dbba073fab843ef43e6385c37db65bc26595 Mon Sep 17 00:00:00 2001 From: Yuriy Kohut Date: Mon, 28 Jul 2025 15:13:35 +0300 Subject: [PATCH] Add Vendors patch created against upstream hash 9658b0b0190fff131502d0e7516518d0e240adcc Bump version to 0.22.0-5.elevate.2 --- SOURCES/leapp-repository-0.22.0-elevate.patch | 1048 +++++++++++++++-- SPECS/leapp-repository.spec | 6 +- 2 files changed, 966 insertions(+), 88 deletions(-) diff --git a/SOURCES/leapp-repository-0.22.0-elevate.patch b/SOURCES/leapp-repository-0.22.0-elevate.patch index 85f761a..466ce5a 100644 --- a/SOURCES/leapp-repository-0.22.0-elevate.patch +++ b/SOURCES/leapp-repository-0.22.0-elevate.patch @@ -3421,6 +3421,103 @@ index 00000000..370758e6 + end + end +end +diff --git a/commands/command_utils.py b/commands/command_utils.py +index e6ba6ba4..d5ecb131 100644 +--- a/commands/command_utils.py ++++ b/commands/command_utils.py +@@ -36,11 +36,13 @@ class _VersionKind(str, Enum): + class DistroIDs(str, Enum): + RHEL = 'rhel' + CENTOS = 'centos' ++ ALMALINUX = 'almalinux' + + + _DISTRO_VERSION_FORMATS = { + DistroIDs.RHEL: VersionFormats.MAJOR_MINOR, + DistroIDs.CENTOS: VersionFormats.MAJOR_ONLY, ++ DistroIDs.ALMALINUX: VersionFormats.MAJOR_MINOR, + } + """ + Maps distro ID to the expected OS version format. +@@ -134,6 +136,16 @@ def get_os_release_version_id(filepath): + return _retrieve_os_release_contents(_os_release_path=filepath).get('VERSION_ID', '') + + ++def get_distro_id(): ++ """ ++ Retrieve the OS release ID from /etc/os-release. ++ ++ :return: The OS release ID from /etc/os-release ++ :rtype: str ++ """ ++ return _retrieve_os_release_contents('/etc/os-release').get('VERSION_ID', '') ++ ++ + def get_upgrade_paths_config(): + # NOTE(ivasilev) Importing here not to have circular dependencies + from leapp.cli.commands.upgrade import util # noqa: C415; pylint: disable=import-outside-toplevel +@@ -203,8 +215,7 @@ def get_target_release(args): + + target_ver = env_version_override or args.target + if target_ver: +- os_release_contents = _retrieve_os_release_contents() +- distro_id = os_release_contents.get('ID', '') ++ distro_id = get_distro_id() + expected_version_format = _DISTRO_VERSION_FORMATS.get(distro_id, VersionFormats.MAJOR_MINOR).value + assert_version_format(target_ver, expected_version_format, _VersionKind.TARGET) + return (target_ver, flavor) +diff --git a/commands/preupgrade/__init__.py b/commands/preupgrade/__init__.py +index e52b6561..6443bd8a 100644 +--- a/commands/preupgrade/__init__.py ++++ b/commands/preupgrade/__init__.py +@@ -20,8 +20,12 @@ from leapp.utils.output import beautify_actor_exception, report_errors, report_i + choices=list(util.EXPERIMENTAL_FEATURES), default=[]) + @command_opt('debug', is_flag=True, help='Enable debug mode', inherit=False) + @command_opt('verbose', is_flag=True, help='Enable verbose logging', inherit=False) +-@command_opt('no-rhsm', is_flag=True, help='Use only custom repositories and skip actions' +- ' with Red Hat Subscription Manager') ++@command_opt( ++ 'no-rhsm', ++ is_flag=True, ++ help='Use only custom repositories and skip actions with Red Hat Subscription Manager.' ++ ' This only has effect on Red Hat Enterprise Linux systems.' ++) + @command_opt('no-insights-register', is_flag=True, help='Do not register into Red Hat Insights') + @command_opt('no-rhsm-facts', is_flag=True, help='Do not store migration information using Red Hat ' + 'Subscription Manager. Automatically implied by --no-rhsm.') +diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py +index 6f7504bf..36be0719 100644 +--- a/commands/upgrade/__init__.py ++++ b/commands/upgrade/__init__.py +@@ -26,8 +26,12 @@ from leapp.utils.output import beautify_actor_exception, report_errors, report_i + choices=list(util.EXPERIMENTAL_FEATURES), default=[]) + @command_opt('debug', is_flag=True, help='Enable debug mode', inherit=False) + @command_opt('verbose', is_flag=True, help='Enable verbose logging', inherit=False) +-@command_opt('no-rhsm', is_flag=True, help='Use only custom repositories and skip actions' +- ' with Red Hat Subscription Manager') ++@command_opt( ++ 'no-rhsm', ++ is_flag=True, ++ help='Use only custom repositories and skip actions with Red Hat Subscription Manager.' ++ ' This only has effect on Red Hat Enterprise Linux systems.' ++) + @command_opt('no-insights-register', is_flag=True, help='Do not register into Red Hat Insights') + @command_opt('no-rhsm-facts', is_flag=True, help='Do not store migration information using Red Hat ' + 'Subscription Manager. Automatically implied by --no-rhsm.') +diff --git a/commands/upgrade/util.py b/commands/upgrade/util.py +index 7d5b563e..dadfe7de 100644 +--- a/commands/upgrade/util.py ++++ b/commands/upgrade/util.py +@@ -222,7 +222,8 @@ def prepare_configuration(args): + os.environ['LEAPP_EXPERIMENTAL'] = '1' + + os.environ['LEAPP_UNSUPPORTED'] = '0' if os.getenv('LEAPP_UNSUPPORTED', '0') == '0' else '1' +- if args.no_rhsm: ++ # force no rhsm on non-rhel systems, regardless of whether the binary is there ++ if args.no_rhsm or command_utils.get_distro_id() != 'rhel': + os.environ['LEAPP_NO_RHSM'] = '1' + elif not os.path.exists('/usr/sbin/subscription-manager'): + os.environ['LEAPP_NO_RHSM'] = '1' diff --git a/etc/leapp/files/pes-events.json b/etc/leapp/files/pes-events.json index e9da4873..e945cf3b 100644 --- a/etc/leapp/files/pes-events.json @@ -11623,6 +11720,50 @@ index 56016513..7ae1dd5a 100644 produces = (DistributionSignedRPM, InstalledRedHatSignedRPM, InstalledUnsignedRPM,) tags = (IPUWorkflowTag, FactsPhaseTag) +diff --git a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py +index f138bcb2..af21bc8d 100644 +--- a/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py ++++ b/repos/system_upgrade/common/actors/distributionsignedrpmscanner/tests/test_distributionsignedrpmscanner.py +@@ -110,6 +110,39 @@ def test_actor_execution_with_signed_unsigned_data_centos(current_actor_context) + assert len(current_actor_context.consume(InstalledUnsignedRPM)[0].items) == 6 + + ++def test_actor_execution_with_signed_unsigned_data_almalinux(current_actor_context): ++ ALMALINUX_PACKAGER = 'AlmaLinux Packaging Team ' ++ config = mock_configs.CONFIG ++ ++ config.os_release = OSRelease( ++ release_id='almalinux', ++ name='AlmaLinux', ++ pretty_name='AlmaLinux 8.10 (Cerulean Leopard)', ++ version='8.10 (Cerulean Leopard)', ++ version_id='8.10' ++ ) ++ ++ installed_rpm = [ ++ RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', ++ pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 2ae81e8aced7258b'), ++ RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', ++ pgpsig='SOME_OTHER_SIG_X'), ++ RPM(name='sample03', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', ++ pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 51d6647ec21ad6ea'), ++ RPM(name='sample04', version='0.1', release='1.sm01', epoch='1', packager=ALMALINUX_PACKAGER, arch='noarch', ++ pgpsig='SOME_OTHER_SIG_X'), ++ ] ++ ++ current_actor_context.feed(InstalledRPM(items=installed_rpm)) ++ current_actor_context.run(config_model=config) ++ assert current_actor_context.consume(DistributionSignedRPM) ++ assert len(current_actor_context.consume(DistributionSignedRPM)[0].items) == 2 ++ assert current_actor_context.consume(InstalledRedHatSignedRPM) ++ assert not current_actor_context.consume(InstalledRedHatSignedRPM)[0].items ++ assert current_actor_context.consume(InstalledUnsignedRPM) ++ assert len(current_actor_context.consume(InstalledUnsignedRPM)[0].items) == 2 ++ ++ + def test_actor_execution_with_unknown_distro(current_actor_context): + config = mock_configs.CONFIG + diff --git a/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py b/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py index f42909f0..6383a56f 100644 --- a/repos/system_upgrade/common/actors/efibootorderfix/finalization/actor.py @@ -11785,6 +11926,58 @@ index 582a5821..18f2c33f 100644 + to_reinstall=list(to_reinstall), modules_to_reset=list(modules_to_reset.values()), modules_to_enable=list(modules_to_enable.values()))) +diff --git a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py +index 6184121b..8b7faffb 100644 +--- a/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py ++++ b/repos/system_upgrade/common/actors/ipuworkflowconfig/tests/test_ipuworkflowconfig.py +@@ -129,6 +129,13 @@ def test_construct_models_for_paths_matching_source_major(source_major_version, + '9': ['10.0'] + } + ), ++ ( ++ 'almalinux', 'default', ++ { ++ '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], ++ '9.6': ['10.0'] ++ } ++ ), + ) + ) + def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flavour, expected_result): +@@ -147,6 +154,12 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav + '9.6': ['10.0'], + '9': ['10.0'] + } ++ }, ++ 'almalinux': { ++ 'default': { ++ '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], ++ '9.6': ['10.0'] ++ } + } + } + +@@ -160,6 +173,7 @@ def test_load_raw_upgrade_paths_for_distro_and_flavour(monkeypatch, distro, flav + [ + (('centos', '8', '9'), ('8.10', '9.5')), + (('rhel', '8.10', '9.4'), ('8.10', '9.4')), ++ (('almalinux', '8.10', '9.6'), ('8.10', '9.6')), + ] + ) + def test_virtual_version_construction(construction_params, expected_versions): +@@ -186,6 +200,12 @@ def test_virtual_version_construction(construction_params, expected_versions): + '9': '9.5', + } + }, ++ 'almalinux': { ++ 'default': { ++ '8.10': ['9.0', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6'], ++ '9.6': ['10.0'] ++ } ++ }, + } + + result = ipuworkflowconfig.construct_virtual_versions(defined_upgrade_paths, *construction_params) diff --git a/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py b/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py index 32e4527b..1e595e9a 100644 --- a/repos/system_upgrade/common/actors/missinggpgkeysinhibitor/libraries/missinggpgkey.py @@ -12035,6 +12228,44 @@ index e6741293..7a7e9ebf 100644 if rpm_tasks: + rpm_tasks.to_reinstall = sorted(pkgs_to_reinstall) api.produce(rpm_tasks) +diff --git a/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py b/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py +index 3dcf5d95..37f60179 100644 +--- a/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py ++++ b/repos/system_upgrade/common/actors/reportsettargetrelease/libraries/reportsettargetrelease.py +@@ -1,5 +1,6 @@ + from leapp import reporting + from leapp.libraries.common import rhsm ++from leapp.libraries.common.config import get_distro_id + from leapp.libraries.stdlib import api + + +@@ -49,6 +50,7 @@ def _report_unhandled_release(): + + def process(): + if rhsm.skip_rhsm(): +- _report_unhandled_release() ++ if get_distro_id() == 'rhel': ++ _report_unhandled_release() + else: + _report_set_release() +diff --git a/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py b/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py +index d8665645..37300c46 100644 +--- a/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py ++++ b/repos/system_upgrade/common/actors/reportsettargetrelease/tests/test_targetreleasereport_reportsettargetrelease.py +@@ -26,3 +26,13 @@ def test_report_unhandled_release(monkeypatch): + reportsettargetrelease.process() + assert reporting.create_report.called == 1 + assert 'is going to be kept' in reporting.create_report.report_fields['title'] ++ ++ ++def test_no_report_on_non_rhel(monkeypatch): ++ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(release_id='centos')) ++ monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: True) # this is always the case on nonrhel ++ monkeypatch.setattr(reporting, 'create_report', create_report_mocked()) ++ ++ reportsettargetrelease.process() ++ ++ assert reporting.create_report.called == 0 diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py b/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py index d4a64793..4ec1d6e0 100644 --- a/repos/system_upgrade/common/actors/repositoriesmapping/libraries/repositoriesmapping.py @@ -12169,6 +12400,86 @@ index d4a64793..4ec1d6e0 100644 def _inhibit_upgrade(msg): local_path = os.path.join('/etc/leapp/file', REPOMAP_FILE) hint = ( +diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json b/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json +index 1f04d72d..9ce8c410 100644 +--- a/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json ++++ b/repos/system_upgrade/common/actors/repositoriesmapping/tests/files/repomap_example.json +@@ -120,6 +120,45 @@ + "distro": "centos" + } + ] ++ }, ++ { ++ "pesid": "pesid8", ++ "entries": [ ++ { ++ "major_version": "8", ++ "repoid": "some-almalinux-8-repoid1", ++ "arch": "x86_64", ++ "repo_type": "rpm", ++ "channel": "ga", ++ "distro": "almalinux" ++ } ++ ] ++ }, ++ { ++ "pesid": "pesid9", ++ "entries": [ ++ { ++ "major_version": "9", ++ "repoid": "some-almalinux-9-repoid1", ++ "arch": "x86_64", ++ "repo_type": "rpm", ++ "channel": "ga", ++ "distro": "almalinux" ++ } ++ ] ++ }, ++ { ++ "pesid": "pesid10", ++ "entries": [ ++ { ++ "major_version": "10", ++ "repoid": "some-almalinux-10-repoid1", ++ "arch": "x86_64", ++ "repo_type": "rpm", ++ "channel": "ga", ++ "distro": "almalinux" ++ } ++ ] + } + ] + } +diff --git a/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py b/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py +index 9d781125..6d1a173a 100644 +--- a/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py ++++ b/repos/system_upgrade/common/actors/repositoriesmapping/tests/unit_test_repositoriesmapping.py +@@ -52,7 +52,7 @@ def test_scan_existing_valid_data(monkeypatch, adjust_cwd): + # 2. Verify that only repositories valid for the current IPU are produced + pesid_repos = repo_mapping.repositories + fail_description = 'Actor produced incorrect number of IPU-relevant pesid repos.' +- assert len(pesid_repos) == 5, fail_description ++ assert len(pesid_repos) == 6, fail_description + + expected_pesid_repos = [ + PESIDRepositoryEntry( +@@ -105,6 +105,16 @@ def test_scan_existing_valid_data(monkeypatch, adjust_cwd): + rhui='', + distro='centos', + ), ++ PESIDRepositoryEntry( ++ pesid='pesid8', ++ major_version='8', ++ repoid='some-almalinux-8-repoid1', ++ arch='x86_64', ++ repo_type='rpm', ++ channel='ga', ++ rhui='', ++ distro='almalinux', ++ ), + ] + + fail_description = 'Expected pesid repo is not present in the deserialization output.' diff --git a/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py b/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py index 43ac1fc4..62aefaf4 100644 --- a/repos/system_upgrade/common/actors/rpmtransactionconfigtaskscollector/libraries/rpmtransactionconfigtaskscollector.py @@ -12584,6 +12895,204 @@ index a6073aa3..dfa565c1 100644 # produce message about skipped repositories enabled_repoids_with_mapping = _get_mapped_repoids(repomap, enabled_repoids) skipped_repoids = enabled_repoids & set(used_repoids_dict.keys()) - enabled_repoids_with_mapping +diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py +index af40c443..1b0a3122 100644 +--- a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py ++++ b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_repomapping.py +@@ -75,6 +75,9 @@ def repomap_data_multiple_distros(): + make_pesid_repo("pesid3", "10", "pesid3-repoid-eus", channel="eus"), + make_pesid_repo("pesid3", "10", "pesid3-repoid-aws", rhui="aws"), + make_pesid_repo("pesid3", "10", "pesid3-repoid-centos", distro="centos"), ++ make_pesid_repo("pesid1", "9", "pesid1-repoid-almalinux", distro="almalinux"), ++ make_pesid_repo("pesid2", "10", "pesid2-repoid-almalinux", distro="almalinux"), ++ make_pesid_repo("pesid3", "10", "pesid3-repoid-almalinux", distro="almalinux"), + ], + ) + return repomap_data +@@ -106,7 +109,7 @@ def test_get_pesid_repo_entry(monkeypatch, repomap_data_for_pesid_repo_retrieval + assert handler.get_pesid_repo_entry('nonexisting-repo', '7') is None, fail_description + + +-@pytest.mark.parametrize('distro', ('rhel', 'centos')) ++@pytest.mark.parametrize('distro', ('rhel', 'centos', 'almalinux')) + def test_get_pesid_repo_entry_distro( + monkeypatch, repomap_data_multiple_distros, distro + ): +@@ -163,7 +166,7 @@ def test_get_target_pesids(monkeypatch, repomap_data_for_pesid_repo_retrieval): + assert [] == handler.get_target_pesids('pesid_no_mapping'), fail_description + + +-@pytest.mark.parametrize('distro', ('rhel', 'centos')) ++@pytest.mark.parametrize('distro', ('rhel', 'centos', 'almalinux')) + def test_get_target_pesids_distro( + monkeypatch, repomap_data_multiple_distros, distro + ): +@@ -199,6 +202,7 @@ def test_get_target_pesids_distro( + [ + ('rhel', [5, 6, 7], [0, 1]), + ('centos', [8], [2]), ++ ('almalinux', [11], [9]), + ] + ) + def test_get_pesid_repos( +@@ -251,6 +255,7 @@ def test_get_pesid_repos( + [ + ('rhel', [0, 1]), + ('centos', []), ++ ('almalinux', []), + ] + ) + def test_get_source_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retrieval, distro, expected_repos_index): +@@ -291,6 +296,7 @@ def test_get_source_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retriev + [ + ('rhel', [3, 4, 5]), + ('centos', []), ++ ('almalinux', []), + ] + ) + def test_get_target_pesid_repos(monkeypatch, repomap_data_for_pesid_repo_retrieval, distro, expected_repos_index): +diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py +index 91d9cd24..1f898e8f 100644 +--- a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py ++++ b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py +@@ -100,94 +100,99 @@ def test_repositories_setup_tasks(monkeypatch): + assert rhel_repos[0].repoid == 'rhel-8-server-rpms' + + +-def test_repos_mapping(monkeypatch): ++@pytest.mark.parametrize('distro_id', ['rhel', 'centos', 'almalinux']) ++def test_repos_mapping_for_distro(monkeypatch, distro_id): + """ + Tests whether actor correctly determines what repositories should be enabled on target based + on the information about what repositories are enabled on the source system using +- the RepositoriesMapping information. ++ the RepositoriesMapping information for a specific distro. + """ + repos_data = [ +- RepositoryData(repoid='rhel-7-server-rpms', name='RHEL 7 Server'), +- RepositoryData(repoid='rhel-7-blacklisted-rpms', name='RHEL 7 Blacklisted')] ++ RepositoryData(repoid='{}-7-server-rpms'.format(distro_id), name='{} 7 Server'.format(distro_id)), ++ RepositoryData(repoid='{}-7-blacklisted-rpms'.format(distro_id), name='{} 7 Blacklisted'.format(distro_id))] + + repos_files = [RepositoryFile(file='/etc/yum.repos.d/redhat.repo', data=repos_data)] + facts = RepositoriesFacts(repositories=repos_files) + installed_rpms = InstalledRPM( +- items=[mock_package('foreman', 'rhel-7-for-x86_64-satellite-extras-rpms'), +- mock_package('foreman-proxy', 'nosuch-rhel-7-for-x86_64-satellite-extras-rpms')]) ++ items=[mock_package('foreman', '{}-7-for-x86_64-satellite-extras-rpms'.format(distro_id)), ++ mock_package('foreman-proxy', 'nosuch-{}-7-for-x86_64-satellite-extras-rpms'.format(distro_id))]) + + repomap = RepositoriesMapping( +- mapping=[RepoMapEntry(source='rhel7-base', target=['rhel8-baseos', 'rhel8-appstream', 'rhel8-blacklist']), +- RepoMapEntry(source='rhel7-satellite-extras', target=['rhel8-satellite-extras'])], ++ mapping=[RepoMapEntry(source='{0}7-base'.format(distro_id), ++ target=['{0}8-baseos'.format(distro_id), ++ '{0}8-appstream'.format(distro_id), ++ '{0}8-blacklist'.format(distro_id)]), ++ RepoMapEntry(source='{0}7-satellite-extras'.format(distro_id), ++ target=['{0}8-satellite-extras'.format(distro_id)])], + repositories=[ + PESIDRepositoryEntry( +- pesid='rhel7-base', +- repoid='rhel-7-server-rpms', ++ pesid='{0}7-base'.format(distro_id), ++ repoid='{0}-7-server-rpms'.format(distro_id), + major_version='7', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + PESIDRepositoryEntry( +- pesid='rhel8-baseos', +- repoid='rhel-8-for-x86_64-baseos-htb-rpms', ++ pesid='{0}8-baseos'.format(distro_id), ++ repoid='{0}-8-for-x86_64-baseos-htb-rpms'.format(distro_id), + major_version='8', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + PESIDRepositoryEntry( +- pesid='rhel8-appstream', +- repoid='rhel-8-for-x86_64-appstream-htb-rpms', ++ pesid='{0}8-appstream'.format(distro_id), ++ repoid='{0}-8-for-x86_64-appstream-htb-rpms'.format(distro_id), + major_version='8', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + PESIDRepositoryEntry( +- pesid='rhel8-blacklist', +- repoid='rhel-8-blacklisted-rpms', ++ pesid='{0}8-blacklist'.format(distro_id), ++ repoid='{0}-8-blacklisted-rpms'.format(distro_id), + major_version='8', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + PESIDRepositoryEntry( +- pesid='rhel7-satellite-extras', +- repoid='rhel-7-for-x86_64-satellite-extras-rpms', ++ pesid='{0}7-satellite-extras'.format(distro_id), ++ repoid='{0}-7-for-x86_64-satellite-extras-rpms'.format(distro_id), + major_version='7', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + PESIDRepositoryEntry( +- pesid='rhel8-satellite-extras', +- repoid='rhel-8-for-x86_64-satellite-extras-rpms', ++ pesid='{0}8-satellite-extras'.format(distro_id), ++ repoid='{0}-8-for-x86_64-satellite-extras-rpms'.format(distro_id), + major_version='8', + arch='x86_64', + repo_type='rpm', + channel='ga', + rhui='', +- distro='rhel', ++ distro=distro_id, + ), + ] + ) + +- repos_blacklisted = RepositoriesBlacklisted(repoids=['rhel-8-blacklisted-rpms']) ++ repos_blacklisted = RepositoriesBlacklisted(repoids=['{}-8-blacklisted-rpms'.format(distro_id)]) + + msgs = [facts, repomap, repos_blacklisted, installed_rpms] + +- monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs)) ++ monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(msgs=msgs, release_id=distro_id)) + monkeypatch.setattr(api, 'produce', produce_mocked()) + + setuptargetrepos.process() +@@ -197,6 +202,7 @@ def test_repos_mapping(monkeypatch): + assert len(rhel_repos) == 3 + + produced_rhel_repoids = {repo.repoid for repo in rhel_repos} +- expected_rhel_repoids = {'rhel-8-for-x86_64-baseos-htb-rpms', 'rhel-8-for-x86_64-appstream-htb-rpms', +- 'rhel-8-for-x86_64-satellite-extras-rpms'} ++ expected_rhel_repoids = {'{0}-8-for-x86_64-baseos-htb-rpms'.format(distro_id), ++ '{0}-8-for-x86_64-appstream-htb-rpms'.format(distro_id), ++ '{0}-8-for-x86_64-satellite-extras-rpms'.format(distro_id)} + assert produced_rhel_repoids == expected_rhel_repoids diff --git a/repos/system_upgrade/common/actors/systemfacts/actor.py b/repos/system_upgrade/common/actors/systemfacts/actor.py index 59b12c87..85d4a09e 100644 --- a/repos/system_upgrade/common/actors/systemfacts/actor.py @@ -12598,9 +13107,18 @@ index 59b12c87..85d4a09e 100644 def process(self): self.produce(systemfacts.get_sysctls_status()) diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py -index 9ec4ecac..c4a31f80 100644 +index 9ec4ecac..0b7a5b3a 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +@@ -7,7 +7,7 @@ from leapp import reporting + from leapp.exceptions import StopActorExecution, StopActorExecutionError + from leapp.libraries.actor import constants + from leapp.libraries.common import dnfplugin, mounting, overlaygen, repofileutils, rhsm, utils +-from leapp.libraries.common.config import get_env, get_product_type ++from leapp.libraries.common.config import get_distro_id, get_env, get_product_type + from leapp.libraries.common.config.version import get_target_major_version + from leapp.libraries.common.gpg import get_path_to_gpg_certs, is_nogpgcheck_set + from leapp.libraries.stdlib import api, CalledProcessError, config, run @@ -152,9 +152,10 @@ def _import_gpg_keys(context, install_root_dir, target_major_version): # Import the RHEL X+1 GPG key to be able to verify the installation of initial packages try: @@ -12623,6 +13141,178 @@ index 9ec4ecac..c4a31f80 100644 run(['rm', '-rf', os.path.join(target_etc, 'rhsm')]) context.copytree_from('/etc/rhsm', os.path.join(target_etc, 'rhsm')) +@@ -673,7 +675,15 @@ def _prep_repository_access(context, target_userspace): + def _get_product_certificate_path(): + """ + Retrieve the required / used product certificate for RHSM. ++ ++ Product certificates are only used on RHEL, on non-RHEL systems the function returns None. ++ ++ :return: The path to the product certificate or None on non-RHEL systems ++ :raises: StopActorExecution if a certificate cannot be found + """ ++ if get_distro_id() != 'rhel': ++ return None ++ + architecture = api.current_actor().configuration.architecture + target_version = api.current_actor().configuration.version.target + target_product_type = get_product_type('target') +@@ -1083,6 +1093,26 @@ def _install_custom_repofiles(context, custom_repofiles): + context.copy_to(rfile.file, _dst_path) + + ++def adjust_dnf_stream_variable(context, varfile='/etc/dnf/vars/stream'): ++ """ ++ Adjust the version in the dnf 'stream' variable to the target version. ++ ++ URLs in CentOS Stream repofiles contain the $stream variable which, ++ if not adjusted, retains the value from the source system making ++ the URLs point to repos for the source version. This function adjusts ++ the variable so that the URLs point to the target version repos. ++ """ ++ ++ target_version = get_target_major_version() ++ try: ++ with context.open(varfile, 'w') as f: ++ f.write(target_version + '-stream\n') ++ except (FileNotFoundError, OSError) as e: ++ raise StopActorExecutionError( ++ message='Failed to adjust dnf variable in {} to "{}".'.format(varfile, target_version + '-stream'), ++ details={'details': str(e)}) ++ ++ + def _gather_target_repositories(context, indata, prod_cert_path): + """ + This is wrapper function to gather the target repoids. +@@ -1101,6 +1131,9 @@ def _gather_target_repositories(context, indata, prod_cert_path): + rhsm.set_container_mode(context) + rhsm.switch_certificate(context, indata.rhsm_info, prod_cert_path) + ++ if api.current_actor().configuration.os_release.release_id == 'centos': ++ adjust_dnf_stream_variable(context) ++ + _install_custom_repofiles(context, indata.custom_repofiles) + return gather_target_repositories(context, indata) + +diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py +index 267c064e..7853a7ad 100644 +--- a/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py ++++ b/repos/system_upgrade/common/actors/targetuserspacecreator/tests/unit_test_targetuserspacecreator.py +@@ -3,6 +3,7 @@ from __future__ import division, print_function + import os + import subprocess + import sys ++import tempfile + from collections import namedtuple + + import pytest +@@ -40,6 +41,9 @@ class MockedMountingBase(object): + self.called_copytree_from = [] + self.target = '' + ++ def open(self, fullpath, *args, **kwargs): ++ return open(self, fullpath, *args, **kwargs) ++ + def copytree_from(self, src, dst): + self.called_copytree_from.append((src, dst)) + +@@ -876,6 +880,13 @@ def test_get_product_certificate_path(monkeypatch, adjust_cwd, result, dst_ver, + assert userspacegen._get_product_certificate_path() in result + + ++def test_get_product_certificate_path_nonrhel(monkeypatch): ++ actor = CurrentActorMocked(release_id='notrhel') ++ monkeypatch.setattr(userspacegen.api, 'current_actor', actor) ++ path = userspacegen._get_product_certificate_path() ++ assert path is None ++ ++ + @suppress_deprecation(models.RequiredTargetUserspacePackages) + def _gen_packages_msgs(): + _cfiles = [ +@@ -1207,20 +1218,26 @@ def mocked_consume_data(): + + + # TODO: come up with additional tests for the main function +-def test_perform_ok(monkeypatch): ++@pytest.mark.parametrize( ++ "distro,cert_path", [("rhel", _DEFAULT_CERT_PATH), ("centos", None)] ++) ++def test_perform_ok(monkeypatch, distro, cert_path): + repoids = ['repoidX', 'repoidY'] + monkeypatch.setattr(userspacegen, '_InputData', mocked_consume_data) +- monkeypatch.setattr(userspacegen, '_get_product_certificate_path', lambda: _DEFAULT_CERT_PATH) ++ monkeypatch.setattr(userspacegen, '_get_product_certificate_path', lambda: cert_path) + monkeypatch.setattr(overlaygen, 'create_source_overlay', MockedMountingBase) + monkeypatch.setattr(userspacegen, '_gather_target_repositories', lambda *x: repoids) + monkeypatch.setattr(userspacegen, '_create_target_userspace', lambda *x: None) + monkeypatch.setattr(userspacegen, 'setup_target_rhui_access_if_needed', lambda *x: None) +- monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) ++ monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked(release_id=distro)) + monkeypatch.setattr(userspacegen.api, 'produce', produce_mocked()) + monkeypatch.setattr(repofileutils, 'get_repodirs', lambda: ['/etc/yum.repos.d']) ++ + userspacegen.perform() ++ + msg_target_repos = models.UsedTargetRepositories( + repos=[models.UsedTargetRepository(repoid=repo) for repo in repoids]) ++ + assert userspacegen.api.produce.called == 3 + assert isinstance(userspacegen.api.produce.model_instances[0], models.TMPTargetRepositoriesFacts) + assert userspacegen.api.produce.model_instances[1] == msg_target_repos +@@ -1325,3 +1342,52 @@ def test__get_files_owned_by_rpms_recursive(monkeypatch): + ) + assert has_dbgmsg('SKIP the tls/certs/server.crt file: not owned by any rpm') + assert has_dbgmsg('Found the file owned by an rpm: rpm-gpg/RPM-GPG-KEY-2.') ++ ++ ++def test_writing_stream_varfile(monkeypatch): ++ ++ monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) ++ monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') ++ ++ with tempfile.NamedTemporaryFile(mode='w+') as tmpf: ++ tmpf.write('incorrect-stream-value\n') ++ tmpf.flush() ++ userspacegen.adjust_dnf_stream_variable(MockedMountingBase, tmpf.name) ++ tmpf.seek(0) ++ content = tmpf.read() ++ ++ assert content == '10-stream\n' ++ ++ ++def test_failing_stream_varfile_write(monkeypatch): ++ monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) ++ monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') ++ with pytest.raises(StopActorExecutionError) as err: ++ userspacegen.adjust_dnf_stream_variable(MockedMountingBase, '/path/not/exists') ++ ++ assert 'Failed to adjust dnf variable' in str(err.value) ++ ++ ++@pytest.mark.parametrize("distro,should_adjust", [('rhel', False), ('centos', True)]) ++def test_if_adjust_dnf_stream_variable_only_for_centos(monkeypatch, distro, should_adjust): ++ ++ def do_nothing(*args, **kwargs): ++ pass ++ ++ def mock_adjust_stream_variable(context, varfile='/etc/dnf/vars/stream'): ++ assert varfile == '/etc/dnf/vars/stream' ++ nonlocal adjust_called ++ adjust_called = True ++ ++ monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked(release_id=distro)) ++ monkeypatch.setattr(userspacegen, 'get_target_major_version', lambda: '10') ++ monkeypatch.setattr(rhsm, 'set_container_mode', do_nothing) ++ monkeypatch.setattr(rhsm, 'switch_certificate', do_nothing) ++ monkeypatch.setattr(userspacegen, '_install_custom_repofiles', do_nothing) ++ monkeypatch.setattr(userspacegen, 'adjust_dnf_stream_variable', mock_adjust_stream_variable) ++ monkeypatch.setattr(userspacegen, 'gather_target_repositories', do_nothing) ++ ++ adjust_called = False ++ ++ userspacegen._gather_target_repositories(MockedMountingBase, testInData, None) ++ assert adjust_called == should_adjust diff --git a/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py b/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py index 6377f767..4c5420f6 100644 --- a/repos/system_upgrade/common/actors/trustedgpgkeysscanner/libraries/trustedgpgkeys.py @@ -12852,10 +13542,10 @@ index 00000000..6a41d4e5 + # self.produce(repomap) diff --git a/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json b/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json new file mode 100644 -index 00000000..51607273 +index 00000000..0629d123 --- /dev/null +++ b/repos/system_upgrade/common/files/distro/almalinux/gpg-signatures.json -@@ -0,0 +1,25 @@ +@@ -0,0 +1,26 @@ +{ + "keys": [ + "51d6647ec21ad6ea", @@ -12875,12 +13565,106 @@ index 00000000..51607273 + "gpg-pubkey-d4082792-5b32db75", + "gpg-pubkey-3abb34f8-5ffd890e", + "gpg-pubkey-6275f250-5e26cb2e", -+ "gpg-pubkey-73e3b907-6581b071" ++ "gpg-pubkey-73e3b907-6581b071", ++ "gpg-pubkey-ced7258b-6525146f" + ], -+ "10": [] ++ "10": ["gpg-pubkey-b86b3716-61e69f29"] + } -+ ++ +} +diff --git a/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 +new file mode 100644 +index 00000000..5228281c +--- /dev/null ++++ b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/10/RPM-GPG-KEY-AlmaLinux-10 +@@ -0,0 +1,29 @@ ++-----BEGIN PGP PUBLIC KEY BLOCK----- ++ ++mQINBGaP6O8BEACvg8IlAxGayV8zOi9Ex+Pd8lrj2BrBzloG8ri84ORp9o8ojq7l ++ykKmIElHe11cQD2Lf/a4lcQQ4Ec3baiD786X6K2eVSlBEAnZMzfjDg8R63SfsBuu ++8Yk+lUyqlBrDnSDYaPruOAzLIz2r82ikIC1jDbipZsMFPFHPI4/hayyWxJ3oGxRe ++0mbtYLB9ElEKngt+/hfo7JLklakbznyIRuVEF3VrZb91XC6r/idqfJoNyBXSKidj ++z0IwqOhgkLUk84rzltDo3AzwGqusd7PEuhOmqinOhp0hMdXsztD4TVyhw82iXu/O ++onOAObZTZYfM6Z8btmDqkoo0aT+oPPCuZ3yC/caU9dhvCSXET/CGoXc3hL55u9PV ++qmcVm/mwvuEImEAvxVc0/dBzEUk+FwW8KsaN3HoUKrC4/NqgmaQz8/42np7u2j+B ++OOJ4hAckNEdWd8rB86CYN00sdxnvLBsp8V3IwEqXLhGOoBsagy61Z8hKCM+siOGn ++xmbbybgaLOs+DPlxt9LrtgLJHODwmD96oysUPJuA0lv8KMiSpId0tSpp9Wn/wHBG ++kRgxGYfzQu7WRvRZqQaleft1JTXXOjNzPur0RkJyb3yFwAoxpePyo/WrupM41OHW ++58cEqdC6riCnJcS4U84RLj+hwvufBVB7areQ75sETnKeyozZW+P16E1t/wARAQAB ++tChBbG1hTGludXggT1MgMTAgPHBhY2thZ2VyQGFsbWFsaW51eC5vcmc+iQJMBBMB ++CgA2FiEE7m23uY9b9e3Z2g3l3uXBHMKh5XIFAmaP6O8CGwMECwkIBwQVCgkIBRYC ++AwEAAh4FAheAAAoJEN7lwRzCoeVy32AP/A2+KI+JhmsxnactSptkAWGyAAf1YBWW ++Js2sc9OJdKj7uIkzszCx7c7VIVeF/VLijIYpM/zwUgir5S5SimzQmY+FumwbKIml ++K5RBsoSog22i7Edho0MLa1pa6qvnKS0nkl9DEcu8EbMUhucWbxGnCG/22EEMTrY+ ++Si1IZNkDGtlBHHBKMC+STbqqTxtdy4tAd2NYwWh3sBIh6PF7T4NLRAugu7PZQr5K ++amS4z2lV3ebshGjieA0Zoznwh0AXgN0gZ/0pC/LXI25gcgtrvkCyL8Fe0AyZUMd8 ++UvZXaRSsm3SkCUIlGjPrvuItn1D7tHmqVSCDKXDM2TqjfiRm1JF+2OFCBNvGz19V ++LxWd/Gf+0qw0dtKxRMKzGh0mxXY40hjtmYZulrPxhG5itNDjStovgrevM1HBsXs9 ++ikrkOGQ0pFcqizTn4ZKAmMozEMuIuV89Vof2bBCg7pHT1FmXVdAaYJxb6a7A/CgN ++qHjoh8AxBiGw/Q2NM4YJlUVhHqqd+/lUG3WJqACNEnqSlZkYQ3HqNNaKhHVbD4mN ++q/g6v+f8aWWDZDsI6IAfbJUB+KPEnIvQJQleWuHrq7kcUMhEq3dwBMIoTVEHhUUr ++RQKToSEM1rN7PcanaXQM2gy141dS7tFLxhapG8ug75LkIUnEOpPMtUjvrU1ZELGq ++36vVHBB+dTDg ++=tJCw ++-----END PGP PUBLIC KEY BLOCK----- +diff --git a/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 +new file mode 100644 +index 00000000..d4165d58 +--- /dev/null ++++ b/repos/system_upgrade/common/files/distro/almalinux/rpm-gpg/9/RPM-GPG-KEY-AlmaLinux-9 +@@ -0,0 +1,52 @@ ++-----BEGIN PGP PUBLIC KEY BLOCK----- ++ ++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 ++1WKL ++=jk2t ++-----END PGP PUBLIC KEY BLOCK----- diff --git a/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json b/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json index 547b13e7..73a9598f 100644 --- a/repos/system_upgrade/common/files/distro/centos/gpg-signatures.json @@ -13079,61 +13863,42 @@ index 4f76a61d..27824406 100644 if self.opts.tid[0] == 'check': diff --git a/repos/system_upgrade/common/files/upgrade_paths.json b/repos/system_upgrade/common/files/upgrade_paths.json -index 279e6eaa..a78a0a01 100644 +index 279e6eaa..f99d9c48 100644 --- a/repos/system_upgrade/common/files/upgrade_paths.json +++ b/repos/system_upgrade/common/files/upgrade_paths.json -@@ -1,20 +1,8 @@ - { -- "rhel": { -+ "almalinux": { - "default": { -- "7.9": ["8.10"], -- "8.10": ["9.4", "9.6"], -- "9.6": ["10.0"], -- "7": ["8.10"], -- "8": ["9.4", "9.6"], -- "9": ["10.0"] -- }, -- "saphana": { -- "7.9": ["8.10"], -- "7": ["8.10"], -- "8.10": ["9.6", "9.4"], -- "8": ["9.6", "9.4"], -- "9.6": ["10.0"], -- "9": ["10.0"] -+ "8.10": ["9.0", "9.1", "9.2", "9.3", "9.4", "9.5", "9.6"], -+ "9.6": ["10.0"] - } - }, - "centos": { -@@ -27,5 +15,10 @@ +@@ -27,5 +27,11 @@ "9": "9.6", "10": "10.0" } + }, -+ "rocky": { ++ "almalinux": { + "default": { -+ "8.10": ["9.6"] ++ "8.10": ["9.0", "9.1", "9.2", "9.3", "9.4", "9.5", "9.6"], ++ "9.6": ["10.0"] + } } } -diff --git a/repos/system_upgrade/common/libraries/config/version.py b/repos/system_upgrade/common/libraries/config/version.py -index 7f29c9cd..d8ed9eaa 100644 ---- a/repos/system_upgrade/common/libraries/config/version.py -+++ b/repos/system_upgrade/common/libraries/config/version.py -@@ -18,9 +18,9 @@ OP_MAP = { - # These will not be supported fo IPU 9 -> 10 - _SUPPORTED_VERSIONS = { - # Note: 'rhel-alt' is detected when on 'rhel' with kernel 4.x -- '7': {'rhel': ['7.9'], 'rhel-alt': [], 'rhel-saphana': ['7.9']}, -- '8': {'rhel': ['8.10'], 'rhel-saphana': ['8.10']}, -- '9': {'rhel': ['9.6'], 'rhel-saphana': ['9.6']}, -+ '7': {'rhel': ['7.9'], 'rhel-alt': [], 'rhel-saphana': ['7.9'], 'centos': ['7.9'], 'ol': ['7.9'], 'scientific': ['7.9']}, -+ '8': {'rhel': ['8.10'], 'rhel-saphana': ['8.10'], 'centos': ['8.5', '8'], 'almalinux': ['8.10'], 'rocky': ['8.10']}, -+ '9': {'rhel': ['9.6'], 'rhel-saphana': ['9.6'], 'centos': ['9'], 'almalinux': ['9.6']}, - } - - +diff --git a/repos/system_upgrade/common/libraries/config/__init__.py b/repos/system_upgrade/common/libraries/config/__init__.py +index 38519d7b..0c737f93 100644 +--- a/repos/system_upgrade/common/libraries/config/__init__.py ++++ b/repos/system_upgrade/common/libraries/config/__init__.py +@@ -97,3 +97,16 @@ def get_target_product_channel(default='ga'): + def get_consumed_data_stream_id(): + """Get the identifier of the asset family used by leapp.""" + return CONSUMED_DATA_STREAM_ID ++ ++ ++def get_distro_id(): ++ """ ++ Retrieve the distro ID. ++ ++ This is the ID string from /etc/os_release. ++ E.g. "rhel" for Red Hat Enterprise Linux ++ ++ :return: The ID string from /etc/os_release ++ :rtype: str ++ """ ++ return api.current_actor().configuration.os_release.release_id diff --git a/repos/system_upgrade/common/libraries/distro.py b/repos/system_upgrade/common/libraries/distro.py index 2ed5eacd..219d31d1 100644 --- a/repos/system_upgrade/common/libraries/distro.py @@ -13371,51 +14136,160 @@ index 00000000..39b7d662 + + return combined_repomapping diff --git a/repos/system_upgrade/common/libraries/rhsm.py b/repos/system_upgrade/common/libraries/rhsm.py -index e7b074aa..0b260c86 100644 +index e7b074aa..79164cca 100644 --- a/repos/system_upgrade/common/libraries/rhsm.py +++ b/repos/system_upgrade/common/libraries/rhsm.py -@@ -94,7 +94,7 @@ def _handle_rhsm_exceptions(hint=None): +@@ -7,7 +7,7 @@ import time + from leapp import reporting + from leapp.exceptions import StopActorExecutionError + from leapp.libraries.common import repofileutils +-from leapp.libraries.common.config import get_env ++from leapp.libraries.common.config import get_distro_id, get_env + from leapp.libraries.stdlib import api, CalledProcessError + from leapp.models import RHSMInfo - def skip_rhsm(): - """Check whether we should skip RHSM related code.""" -- return get_env('LEAPP_NO_RHSM', '0') == '1' -+ return True +@@ -331,10 +331,19 @@ def set_container_mode(context): + /etc/pki/entitlement directories exists, even when leapp is executed with + --no-rhsm option. If any of these directories are missing, skip other + actions - most likely RHSM is not installed in such a case. ++ Note that this only true on RHEL systems, on non-RHEL (which don't use RHSM) ++ this function does nothing. - - def with_rhsm(f): -@@ -327,11 +327,6 @@ def set_container_mode(context): - could be affected and the generated repo file in the container could be - affected as well (e.g. when the release is set, using rhsm, on the host). - -- We want to put RHSM into the container mode always when /etc/rhsm and -- /etc/pki/entitlement directories exists, even when leapp is executed with -- --no-rhsm option. If any of these directories are missing, skip other -- actions - most likely RHSM is not installed in such a case. -- :param context: An instance of a mounting.IsolatedActions class :type context: mounting.IsolatedActions class """ -@@ -339,20 +334,8 @@ def set_container_mode(context): ++ # this has to happen even with skip_rhsm, but only on RHEL ++ if get_distro_id() != 'rhel': ++ api.current_logger().info( ++ 'Skipping setting RHSM into container mode on non-RHEL systems.' ++ ) ++ return ++ + if not context.is_isolated(): api.current_logger().error('Trying to set RHSM into the container mode' 'on host. Skipping the action.') - return -- # TODO(pstodulk): check "rhsm identity" whether system is registered -- # and the container mode should be required -- if (not os.path.exists(context.full_path('/etc/rhsm')) -- or not os.path.exists(context.full_path('/etc/pki/entitlement'))): -- api.current_logger().warning( -- 'Cannot set the container mode for the subscription-manager as' -- ' one of required directories is missing. Most likely RHSM is not' -- ' installed. Skipping other actions.' -- ) -- return -- - try: - context.call(['ln', '-s', '/etc/rhsm', '/etc/rhsm-host']) -- context.call(['ln', '-s', '/etc/pki/entitlement', '/etc/pki/entitlement-host']) - except CalledProcessError: - raise StopActorExecutionError( - message='Cannot set the container mode for the subscription-manager.') +diff --git a/repos/system_upgrade/common/libraries/tests/test_gpg.py b/repos/system_upgrade/common/libraries/tests/test_gpg.py +index 82b51abb..47617ad8 100644 +--- a/repos/system_upgrade/common/libraries/tests/test_gpg.py ++++ b/repos/system_upgrade/common/libraries/tests/test_gpg.py +@@ -18,6 +18,8 @@ from leapp.models import GpgKey, InstalledRPM, RPM + ('9.2', 'ga', 'rhel', '../../files/distro/rhel/rpm-gpg/9'), + ('10.0', 'ga', 'rhel', '../../files/distro/rhel/rpm-gpg/10'), + ('10', 'ga', 'centos', '../../files/distro/centos/rpm-gpg/10'), ++ ('9.6', 'ga', 'almalinux', '../../files/distro/almalinux/rpm-gpg/9'), ++ ('10.0', 'ga', 'almalinux', '../../files/distro/almalinux/rpm-gpg/10'), + ]) + def test_get_path_to_gpg_certs(monkeypatch, target, product_type, distro, exp): + current_actor = CurrentActorMocked(dst_ver=target, release_id=distro, +diff --git a/repos/system_upgrade/common/libraries/tests/test_rhsm.py b/repos/system_upgrade/common/libraries/tests/test_rhsm.py +index 190fd0de..b643cd0d 100644 +--- a/repos/system_upgrade/common/libraries/tests/test_rhsm.py ++++ b/repos/system_upgrade/common/libraries/tests/test_rhsm.py +@@ -8,7 +8,7 @@ from leapp.exceptions import StopActorExecutionError + from leapp.libraries.common import repofileutils, rhsm + from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, logger_mocked + from leapp.libraries.stdlib import api, CalledProcessError +-from leapp.models import RepositoryData, RepositoryFile ++from leapp.models import RepositoryData, RepositoryFile, RHSMInfo + from leapp.utils.report import is_inhibitor + + Repository = namedtuple('Repository', ['repoid', 'file']) +@@ -67,10 +67,15 @@ class IsolatedActionsMocked(object): + self.commands_called = [] + self.call_return = {'stdout': call_stdout, 'stderr': None} + self.raise_err = raise_err ++ self.remove_called = [] ++ self.copy_to_called = [] + + # A map from called commands to their mocked output + self.mocked_command_call_outputs = dict() + ++ def is_isolated(self): ++ return True ++ + def call(self, cmd, *args, **dummy_kwargs): + self.commands_called.append(cmd) + if self.raise_err: +@@ -91,6 +96,12 @@ class IsolatedActionsMocked(object): + def full_path(self, path): + return path + ++ def remove(self, path): ++ self.remove_called.append(path) ++ ++ def copy_to(self, src, dst): ++ self.copy_to_called.append((src, dst)) ++ + + @pytest.fixture + def actor_mocked(monkeypatch): +@@ -409,3 +420,66 @@ def test_is_registered_error(context_mocked): + rhsm.is_rhsm_registered(context_mocked) + + assert 'A subscription-manager command failed to execute' in str(err) ++ ++ ++def test_set_container_mode(monkeypatch, context_mocked): ++ actor = CurrentActorMocked(release_id='rhel') ++ monkeypatch.setattr(api, 'current_actor', actor) ++ monkeypatch.setattr( ++ os.path, "exists", lambda path: path in ("/etc/rhsm", "/etc/pki/entitlement") ++ ) ++ ++ rhsm.set_container_mode(context_mocked) ++ ++ assert context_mocked.commands_called == [ ++ ["ln", "-s", "/etc/rhsm", "/etc/rhsm-host"], ++ ['ln', '-s', '/etc/pki/entitlement', '/etc/pki/entitlement-host'], ++ ] ++ ++ ++def test_set_container_mode_nonrhel_skip(monkeypatch, context_mocked): ++ actor = CurrentActorMocked(release_id='notrhel') ++ monkeypatch.setattr(api, 'current_actor', actor) ++ ++ rhsm.set_container_mode(context_mocked) ++ ++ assert context_mocked.commands_called == [] ++ ++ ++def mocked_rhsm_info(): ++ return RHSMInfo( ++ attached_skus=['SKU1', 'SKU2'], ++ available_repos=['Repo1', 'Repo2'], ++ enabled_repos=['Repo2'], ++ release='7.9', ++ existing_product_certificates=['Cert1', 'Cert2', 'Cert3'], ++ sca_detected=True, ++ ) ++ ++ ++def test_switch_certificate(monkeypatch, context_mocked, actor_mocked): ++ monkeypatch.setattr( ++ os.path, 'isdir', lambda path: path in ('/etc/pki/product', '/etc/pki/product-default') ++ ) ++ ++ cert_path = '/etc/leapp/repos.d/system_upgrade/common/files/prod-certs/10/479.pem' ++ rhsm.switch_certificate(context_mocked, mocked_rhsm_info(), cert_path) ++ ++ assert context_mocked.remove_called == mocked_rhsm_info().existing_product_certificates ++ assert context_mocked.copy_to_called == [ ++ (cert_path, os.path.join(target_path, "479.pem")) ++ for target_path in ("/etc/pki/product", "/etc/pki/product-default") ++ ] ++ ++ ++def test_switch_certificate_respect_with_rhsm(monkeypatch, context_mocked): ++ """Test whether switch_certificate is skipped when LEAPP_NO_RHSM=1""" ++ ++ mocked_actor = CurrentActorMocked(envars={'LEAPP_NO_RHSM': '1'}) ++ monkeypatch.setattr(api, 'current_actor', mocked_actor) ++ ++ cert_path = '/etc/leapp/repos.d/system_upgrade/common/files/prod-certs/10/479.pem' ++ rhsm.switch_certificate(context_mocked, mocked_rhsm_info(), cert_path) ++ ++ assert context_mocked.remove_called == [] ++ assert context_mocked.copy_to_called == [] diff --git a/repos/system_upgrade/common/models/activevendorlist.py b/repos/system_upgrade/common/models/activevendorlist.py new file mode 100644 index 00000000..de4056fb diff --git a/SPECS/leapp-repository.spec b/SPECS/leapp-repository.spec index 63b3ed2..6e7b87f 100644 --- a/SPECS/leapp-repository.spec +++ b/SPECS/leapp-repository.spec @@ -53,7 +53,7 @@ py2_byte_compile "%1" "%2"} Epoch: 1 Name: leapp-repository Version: 0.22.0 -Release: 5%{?dist}.elevate.1 +Release: 5%{?dist}.elevate.2 Summary: Repositories for leapp License: ASL 2.0 @@ -471,6 +471,10 @@ ln -s 10.0 %{next_major_ver} # no files here %changelog +* Tue Jul 28 2025 Yuriy Kohut - 0.22.0-5.elevate.2 +- Update ELevate patch: + - rebase to upstream 0.22.0-5 (hash 9658b0b0190fff131502d0e7516518d0e240adcc) + * Mon Jul 21 2025 Yuriy Kohut - 0.22.0-5.elevate.1 - Update ELevate patch: - rebase to upstream 0.22.0-5 (hash 3356c045fe2982f3a26b26b46258398b490a6d67)