From 546d18f64deabe8440ac6d4ee707d7a5b69415db Mon Sep 17 00:00:00 2001 From: Matej Matuska Date: Mon, 15 Sep 2025 11:09:59 +0200 Subject: [PATCH 15/55] Generalize TargetRepositories The RHELTargetRepository model is deprecated and replaced by the DistroTargetRepository. The target TargetRepositories model is updated accordingly. TargetRepositories.rhel_repos are only filled on RHEL. --- .../libraries/checktargetrepos.py | 4 ++- .../tests/test_checktargetrepos.py | 32 +++++++++++++------ .../cloud/checkrhui/libraries/checkrhui.py | 5 ++- .../tests/component_test_checkrhui.py | 1 + .../libraries/setuptargetrepos.py | 29 +++++++++++------ .../libraries/setuptargetrepos_repomap.py | 4 +-- .../tests/test_setuptargetrepos.py | 22 ++++++++++--- .../libraries/userspacegen.py | 2 ++ .../tests/unit_test_targetuserspacecreator.py | 7 ++++ .../common/models/targetrepositories.py | 32 +++++++++++++++++-- 10 files changed, 107 insertions(+), 31 deletions(-) diff --git a/repos/system_upgrade/common/actors/checktargetrepos/libraries/checktargetrepos.py b/repos/system_upgrade/common/actors/checktargetrepos/libraries/checktargetrepos.py index c286ed4f..141cf8e4 100644 --- a/repos/system_upgrade/common/actors/checktargetrepos/libraries/checktargetrepos.py +++ b/repos/system_upgrade/common/actors/checktargetrepos/libraries/checktargetrepos.py @@ -2,12 +2,14 @@ from leapp import reporting from leapp.libraries.common import config, rhsm from leapp.libraries.common.config.version import get_target_major_version from leapp.libraries.stdlib import api -from leapp.models import CustomTargetRepositoryFile, RHUIInfo, TargetRepositories +from leapp.models import CustomTargetRepositoryFile, RHELTargetRepository, RHUIInfo, TargetRepositories +from leapp.utils.deprecation import suppress_deprecation # TODO: we need to provide this path in a shared library CUSTOM_REPO_PATH = '/etc/leapp/files/leapp_upgrade_repositories.repo' +@suppress_deprecation(RHELTargetRepository) # member of TargetRepositories def _any_custom_repo_defined(): for tr in api.consume(TargetRepositories): if tr.custom_repos: diff --git a/repos/system_upgrade/common/actors/checktargetrepos/tests/test_checktargetrepos.py b/repos/system_upgrade/common/actors/checktargetrepos/tests/test_checktargetrepos.py index c1ca8cd1..ea93ce7e 100644 --- a/repos/system_upgrade/common/actors/checktargetrepos/tests/test_checktargetrepos.py +++ b/repos/system_upgrade/common/actors/checktargetrepos/tests/test_checktargetrepos.py @@ -8,12 +8,11 @@ from leapp.libraries.stdlib import api from leapp.models import ( CustomTargetRepository, CustomTargetRepositoryFile, - EnvVar, - Report, - RepositoryData, + DistroTargetRepository, RHELTargetRepository, TargetRepositories ) +from leapp.utils.deprecation import suppress_deprecation from leapp.utils.report import is_inhibitor @@ -32,11 +31,21 @@ class MockedConsume(object): return iter([msg for msg in self._msgs if isinstance(msg, model)]) -_RHEL_REPOS = [ - RHELTargetRepository(repoid='repo1'), - RHELTargetRepository(repoid='repo2'), - RHELTargetRepository(repoid='repo3'), - RHELTargetRepository(repoid='repo4'), +@suppress_deprecation(RHELTargetRepository) +def _test_rhel_repos(): + return [ + RHELTargetRepository(repoid='repo1'), + RHELTargetRepository(repoid='repo2'), + RHELTargetRepository(repoid='repo3'), + RHELTargetRepository(repoid='repo4'), + ] + + +_DISTRO_REPOS = [ + DistroTargetRepository(repoid='repo1'), + DistroTargetRepository(repoid='repo2'), + DistroTargetRepository(repoid='repo3'), + DistroTargetRepository(repoid='repo4'), ] _CUSTOM_REPOS = [ @@ -46,8 +55,10 @@ _CUSTOM_REPOS = [ CustomTargetRepository(repoid='repo4', name='repo4name', baseurl=None, enabled=True), ] -_TARGET_REPOS_CUSTOM = TargetRepositories(rhel_repos=_RHEL_REPOS, custom_repos=_CUSTOM_REPOS) -_TARGET_REPOS_NO_CUSTOM = TargetRepositories(rhel_repos=_RHEL_REPOS) +_TARGET_REPOS_CUSTOM = TargetRepositories( + rhel_repos=_test_rhel_repos(), distro_repos=_DISTRO_REPOS, custom_repos=_CUSTOM_REPOS +) +_TARGET_REPOS_NO_CUSTOM = TargetRepositories(rhel_repos=_test_rhel_repos(), distro_repos=_DISTRO_REPOS) _CUSTOM_TARGET_REPOFILE = CustomTargetRepositoryFile(file='/etc/leapp/files/leapp_upgrade_repositories.repo') @@ -55,6 +66,7 @@ def test_checktargetrepos_rhsm(monkeypatch): monkeypatch.setattr(reporting, 'create_report', create_report_mocked()) monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: False) monkeypatch.setattr(api, 'consume', MockedConsume()) + monkeypatch.setattr(api, 'current_actor', CurrentActorMocked()) monkeypatch.setattr(checktargetrepos, 'get_target_major_version', lambda: '8') checktargetrepos.process() assert reporting.create_report.called == 0 diff --git a/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py b/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py index ea154173..5dcdd967 100644 --- a/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py +++ b/repos/system_upgrade/common/actors/cloud/checkrhui/libraries/checkrhui.py @@ -22,6 +22,7 @@ from leapp.models import ( CustomTargetRepository, DNFPluginTask, InstalledRPM, + RHELTargetRepository, RHUIInfo, RpmTransactionTasks, TargetRepositories, @@ -30,6 +31,7 @@ from leapp.models import ( TargetRHUISetupInfo, TargetUserSpacePreupgradeTasks ) +from leapp.utils.deprecation import suppress_deprecation MatchingSetup = namedtuple('MatchingSetup', ['family', 'description']) @@ -370,11 +372,12 @@ def emit_rhui_setup_tasks_based_on_config(rhui_config_dict): api.produce(rhui_info) +@suppress_deprecation(RHELTargetRepository) # member of TargetRepositories def request_configured_repos_to_be_enabled(rhui_config): config_repos_to_enable = rhui_config[RhuiTargetRepositoriesToUse.name] custom_repos = [CustomTargetRepository(repoid=repoid) for repoid in config_repos_to_enable] if custom_repos: - target_repos = TargetRepositories(custom_repos=custom_repos, rhel_repos=[]) + target_repos = TargetRepositories(custom_repos=custom_repos, rhel_repos=[], distro_repos=[]) api.produce(target_repos) diff --git a/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py b/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py index 3ac9c1b8..02ca352e 100644 --- a/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py +++ b/repos/system_upgrade/common/actors/cloud/checkrhui/tests/component_test_checkrhui.py @@ -468,6 +468,7 @@ def test_request_configured_repos_to_be_enabled(monkeypatch): target_repos = api.produce.model_instances[0] assert isinstance(target_repos, TargetRepositories) + assert not target_repos.distro_repos assert not target_repos.rhel_repos custom_repoids = sorted(custom_repo_model.repoid for custom_repo_model in target_repos.custom_repos) diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py index a6073aa3..9e5b1334 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos.py @@ -1,9 +1,10 @@ - from leapp.libraries.actor import setuptargetrepos_repomap +from leapp.libraries.common.config import get_distro_id from leapp.libraries.common.config.version import get_source_major_version, get_source_version, get_target_version from leapp.libraries.stdlib import api from leapp.models import ( CustomTargetRepository, + DistroTargetRepository, InstalledRPM, RepositoriesBlacklisted, RepositoriesFacts, @@ -15,6 +16,7 @@ from leapp.models import ( TargetRepositories, UsedRepositories ) +from leapp.utils.deprecation import suppress_deprecation RHUI_CLIENT_REPOIDS_RHEL88_TO_RHEL810 = { 'rhui-microsoft-azure-rhel8-sapapps': 'rhui-microsoft-azure-rhel8-base-sap-apps', @@ -80,6 +82,7 @@ def _get_mapped_repoids(repomap, src_repoids): return mapped_repoids +@suppress_deprecation(RHELTargetRepository) def process(): # Load relevant data from messages used_repoids_dict = _get_used_repo_dict() @@ -103,10 +106,11 @@ def process(): # installed packages that have mapping to prevent missing repositories that are disabled during the upgrade, but # can be used to upgrade installed packages. repoids_to_map = enabled_repoids.union(repoids_from_installed_packages_with_mapping) + is_rhel = get_distro_id() == 'rhel' # RHEL8.10 use a different repoid for client repository, but the repomapping mechanism cannot distinguish these # as it does not use minor versions. Therefore, we have to hardcode these changes. - if get_source_version() == '8.10': + if is_rhel and get_source_version() == '8.10': for rhel88_rhui_client_repoid, rhel810_rhui_client_repoid in RHUI_CLIENT_REPOIDS_RHEL88_TO_RHEL810.items(): if rhel810_rhui_client_repoid in repoids_to_map: # Replace RHEL8.10 rhui client repoids with RHEL8.8 repoids, @@ -119,9 +123,9 @@ def process(): default_channels = setuptargetrepos_repomap.get_default_repository_channels(repomap, repoids_to_map) repomap.set_default_channels(default_channels) - # Get target RHEL repoids based on the repomap + # Get target distro repoids based on the repomap expected_repos = repomap.get_expected_target_pesid_repos(repoids_to_map) - target_rhel_repoids = set() + target_distro_repoids = set() for target_pesid, target_pesidrepo in expected_repos.items(): if not target_pesidrepo: # NOTE this could happen only for enabled repositories part of the set, @@ -139,7 +143,7 @@ def process(): if target_pesidrepo.repoid in excluded_repoids: api.current_logger().debug('Skipping the {} repo (excluded).'.format(target_pesidrepo.repoid)) continue - target_rhel_repoids.add(target_pesidrepo.repoid) + target_distro_repoids.add(target_pesidrepo.repoid) # FIXME: this could possibly result into a try to enable multiple repositories # from the same family (pesid). But unless we have a bug in previous actors, @@ -151,7 +155,7 @@ def process(): if repo in excluded_repoids: api.current_logger().debug('Skipping the {} repo from setup task (excluded).'.format(repo)) continue - target_rhel_repoids.add(repo) + target_distro_repoids.add(repo) # On 8.10, some RHUI setups have different names than the one computed by repomapping. # Although such situation could be avoided (having another client repo when a single @@ -159,12 +163,16 @@ def process(): # solution. if get_target_version() == '8.10': for pre_810_repoid, post_810_repoid in RHUI_CLIENT_REPOIDS_RHEL88_TO_RHEL810.items(): - if pre_810_repoid in target_rhel_repoids: - target_rhel_repoids.remove(pre_810_repoid) - target_rhel_repoids.add(post_810_repoid) + if pre_810_repoid in target_distro_repoids: + target_distro_repoids.remove(pre_810_repoid) + target_distro_repoids.add(post_810_repoid) # create the final lists and sort them (for easier testing) - rhel_repos = [RHELTargetRepository(repoid=repoid) for repoid in sorted(target_rhel_repoids)] + if is_rhel: + rhel_repos = [RHELTargetRepository(repoid=repoid) for repoid in sorted(target_distro_repoids)] + else: + rhel_repos = [] + distro_repos = [DistroTargetRepository(repoid=repoid) for repoid in sorted(target_distro_repoids)] custom_repos = [repo for repo in custom_repos if repo.repoid not in excluded_repoids] custom_repos = sorted(custom_repos, key=lambda x: x.repoid) @@ -179,5 +187,6 @@ def process(): api.produce(TargetRepositories( rhel_repos=rhel_repos, + distro_repos=distro_repos, custom_repos=custom_repos, )) diff --git a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos_repomap.py b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos_repomap.py index 37be03f1..343ee2ea 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos_repomap.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/libraries/setuptargetrepos_repomap.py @@ -1,4 +1,4 @@ -from leapp.libraries.common.config import get_target_product_channel +from leapp.libraries.common.config import get_distro_id, get_target_product_channel from leapp.libraries.common.config.version import get_source_major_version, get_target_major_version from leapp.libraries.stdlib import api @@ -44,7 +44,7 @@ class RepoMapDataHandler(object): # ideal for work, but there is not any significant impact.. self.repositories = repo_map.repositories self.mapping = repo_map.mapping - self.distro = distro or api.current_actor().configuration.os_release.release_id + self.distro = distro or get_distro_id() # FIXME(pstodulk): what about default_channel -> fallback_channel # hardcoded always as ga? instead of list of channels.. # it'd be possibly confusing naming now... 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 1f898e8f..e4a30f7f 100644 --- a/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py +++ b/repos/system_upgrade/common/actors/setuptargetrepos/tests/test_setuptargetrepos.py @@ -198,11 +198,23 @@ def test_repos_mapping_for_distro(monkeypatch, distro_id): setuptargetrepos.process() assert api.produce.called + distro_repos = api.produce.model_instances[0].distro_repos rhel_repos = api.produce.model_instances[0].rhel_repos - assert len(rhel_repos) == 3 + assert len(distro_repos) == 3 + + produced_distro_repoids = {repo.repoid for repo in distro_repos} produced_rhel_repoids = {repo.repoid for repo in rhel_repos} - 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 + + expected_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_distro_repoids == expected_repoids + if distro_id == 'rhel': + assert len(rhel_repos) == 3 + assert produced_rhel_repoids == expected_repoids + else: + assert len(rhel_repos) == 0 diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py index 55877d05..407cb0b7 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py @@ -17,6 +17,7 @@ from leapp.models import ( CustomTargetRepositoryFile, PkgManagerInfo, RepositoriesFacts, + RHELTargetRepository, RHSMInfo, RHUIInfo, StorageInfo, @@ -967,6 +968,7 @@ def _get_rh_available_repoids(context, indata): return rh_repoids +@suppress_deprecation(RHELTargetRepository) # member of TargetRepositories def gather_target_repositories(context, indata): """ Get available required target repositories and inhibit or raise error if basic checks do not pass. 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 7853a7ad..f05e6bc2 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 @@ -1072,6 +1072,7 @@ def test_consume_data(monkeypatch, raised, no_rhsm, testdata): @pytest.mark.skip(reason="Currently not implemented in the actor. It's TODO.") +@suppress_deprecation(models.RHELTargetRepository) def test_gather_target_repositories(monkeypatch): monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) # The available RHSM repos @@ -1104,6 +1105,7 @@ def test_gather_target_repositories_none_available(monkeypatch): assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.' +@suppress_deprecation(models.RHELTargetRepository) def test_gather_target_repositories_rhui(monkeypatch): indata = testInData( @@ -1122,6 +1124,10 @@ def test_gather_target_repositories_rhui(monkeypatch): rhel_repos=[ models.RHELTargetRepository(repoid='rhui-1'), models.RHELTargetRepository(repoid='rhui-2') + ], + distro_repos=[ + models.DistroTargetRepository(repoid='rhui-1'), + models.DistroTargetRepository(repoid='rhui-2') ] ) ]) @@ -1130,6 +1136,7 @@ def test_gather_target_repositories_rhui(monkeypatch): assert target_repoids == set(['rhui-1', 'rhui-2']) +@suppress_deprecation(models.RHELTargetRepository) def test_gather_target_repositories_baseos_appstream_not_available(monkeypatch): # If the repos that Leapp identifies as required for the upgrade (based on the repo mapping and PES data) are not # available, an exception shall be raised diff --git a/repos/system_upgrade/common/models/targetrepositories.py b/repos/system_upgrade/common/models/targetrepositories.py index 02c6c5e5..e1a0b646 100644 --- a/repos/system_upgrade/common/models/targetrepositories.py +++ b/repos/system_upgrade/common/models/targetrepositories.py @@ -1,4 +1,5 @@ from leapp.models import fields, Model +from leapp.reporting import deprecated from leapp.topics import TransactionTopic @@ -11,10 +12,18 @@ class UsedTargetRepository(TargetRepositoryBase): pass +@deprecated( + since="2025-07-23", + message="This model is deprecated, use DistroTargetRepository instead.", +) class RHELTargetRepository(TargetRepositoryBase): pass +class DistroTargetRepository(TargetRepositoryBase): + pass + + class CustomTargetRepository(TargetRepositoryBase): name = fields.Nullable(fields.String()) baseurl = fields.Nullable(fields.String()) @@ -26,20 +35,39 @@ class TargetRepositories(Model): Repositories supposed to be used during the IPU process The list of the actually used repositories could be just subset - of these repositoies. In case of `custom_repositories`, all such repositories + of these repositories. In case of `custom_repositories`, all such repositories must be available otherwise the upgrade is inhibited. But in case of - `rhel_repos`, only BaseOS and Appstream repos are required now. If others + `distro_repos`, only BaseOS and Appstream repos are required now. If others are missing, upgrade can still continue. + + Note: `rhel_repos` are deprecated, use `distro_repos` instead. """ topic = TransactionTopic + + # DEPRECATED: this has been superseded by distro_repos rhel_repos = fields.List(fields.Model(RHELTargetRepository)) """ Expected target YUM RHEL repositories provided via RHSM + DEPRECATED - use distro_repos instead. + These repositories are stored inside /etc/yum.repos.d/redhat.repo and are expected to be used based on the provided repositories mapping. """ + distro_repos = fields.List(fields.Model(DistroTargetRepository)) + """ + Expected target DNF repositories provided by the distribution. + + On RHEL these are the repositories provided via RHSM. + These repositories are stored inside /etc/yum.repos.d/redhat.repo and + are expected to be used based on the provided repositories mapping. + + On other distributions, such as Centos Stream these are repositories + in /etc/yum.repos.d/ that are provided by the distribution and are expected + to be used based on the provided repositories mapping. + """ + custom_repos = fields.List(fields.Model(CustomTargetRepository), default=[]) """ Custom YUM repositories required to be used for the IPU -- 2.51.1