From 35d22f3063acd24ee1e3ba2f2a21c0b17e251bfc Mon Sep 17 00:00:00 2001 From: ina vasilevskaya Date: Fri, 20 Jan 2023 17:06:32 +0100 Subject: [PATCH 63/63] Ensure a baseos and appstream repos are available when upgrade with RHSM (#1001) Previously we have tested if 2+ rhsm respositories are available. However, this led to various issues when the repositories provided via satellite were e.g. *baseos* and *supplementary*. The original check passed in such a case, but the upgrade transaction failed due to missing rpms from the missing *appstream* repository. The current check include the verification that both repositories are present, searching the *baseos* and *appstream* substrings in repoids - when speaking about RHSM repositories. If such repositories are not discovered, the upgrade is inhibit. The responsibility for custom repositories is kept on user as before. --- .../libraries/userspacegen.py | 5 +- .../tests/unit_test_targetuserspacecreator.py | 50 +++++++++++++++---- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py index f2391ee8..6335eb5b 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py @@ -494,7 +494,10 @@ def _get_rhsm_available_repoids(context): # TODO: very similar thing should happens for all other repofiles in container # repoids = rhsm.get_available_repo_ids(context) - if not repoids or len(repoids) < 2: + # NOTE(ivasilev) For the moment at least AppStream and BaseOS repos are required. While we are still + # contemplating on what can be a generic solution to checking this, let's introduce a minimal check for + # at-least-one-appstream and at-least-one-baseos among present repoids + if not repoids or all("baseos" not in ri for ri in repoids) or all("appstream" not in ri for ri in repoids): reporting.create_report([ reporting.Title('Cannot find required basic RHEL target repositories.'), reporting.Summary( 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 5f544471..a519275e 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 @@ -302,17 +302,20 @@ def test_gather_target_repositories_rhui(monkeypatch): assert target_repoids == set(['rhui-1', 'rhui-2']) -@pytest.mark.skip(reason="Currently not implemented in the actor. It's TODO.") -def test_gather_target_repositories_required_not_available(monkeypatch): +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 + indata = testInData( + _PACKAGES_MSGS, _RHSMINFO_MSG, None, _XFS_MSG, _STORAGEINFO_MSG, None + ) + monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: False) + mocked_produce = produce_mocked() monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) monkeypatch.setattr(userspacegen.api.current_actor(), 'produce', mocked_produce) # The available RHSM repos monkeypatch.setattr(rhsm, 'get_available_repo_ids', lambda x: ['repoidA', 'repoidB', 'repoidC']) - monkeypatch.setattr(rhsm, 'skip_rhsm', lambda: False) # The required RHEL repos based on the repo mapping and PES data + custom repos required by third party actors monkeypatch.setattr(userspacegen.api, 'consume', lambda x: iter([models.TargetRepositories( rhel_repos=[models.RHELTargetRepository(repoid='repoidX'), @@ -320,12 +323,41 @@ def test_gather_target_repositories_required_not_available(monkeypatch): custom_repos=[models.CustomTargetRepository(repoid='repoidCustom')])])) with pytest.raises(StopActorExecution): - userspacegen.gather_target_repositories(None) - assert mocked_produce.called - reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)] - inhibitors = [m for m in reports if 'INHIBITOR' in m.get('flags', ())] - assert len(inhibitors) == 1 - assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.' + userspacegen.gather_target_repositories(None, indata) + assert mocked_produce.called + reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)] + inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())] + assert len(inhibitors) == 1 + assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.' + # Now test the case when either of AppStream and BaseOs is not available, upgrade should be inhibited + mocked_produce = produce_mocked() + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(userspacegen.api.current_actor(), 'produce', mocked_produce) + monkeypatch.setattr(rhsm, 'get_available_repo_ids', lambda x: ['repoidA', 'repoidB', 'repoidC-appstream']) + monkeypatch.setattr(userspacegen.api, 'consume', lambda x: iter([models.TargetRepositories( + rhel_repos=[models.RHELTargetRepository(repoid='repoidC-appstream'), + models.RHELTargetRepository(repoid='repoidA')], + custom_repos=[models.CustomTargetRepository(repoid='repoidCustom')])])) + with pytest.raises(StopActorExecution): + userspacegen.gather_target_repositories(None, indata) + reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)] + inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())] + assert len(inhibitors) == 1 + assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.' + mocked_produce = produce_mocked() + monkeypatch.setattr(userspacegen.api, 'current_actor', CurrentActorMocked()) + monkeypatch.setattr(userspacegen.api.current_actor(), 'produce', mocked_produce) + monkeypatch.setattr(rhsm, 'get_available_repo_ids', lambda x: ['repoidA', 'repoidB', 'repoidC-baseos']) + monkeypatch.setattr(userspacegen.api, 'consume', lambda x: iter([models.TargetRepositories( + rhel_repos=[models.RHELTargetRepository(repoid='repoidC-baseos'), + models.RHELTargetRepository(repoid='repoidA')], + custom_repos=[models.CustomTargetRepository(repoid='repoidCustom')])])) + with pytest.raises(StopActorExecution): + userspacegen.gather_target_repositories(None, indata) + reports = [m.report for m in mocked_produce.model_instances if isinstance(m, reporting.Report)] + inhibitors = [m for m in reports if 'inhibitor' in m.get('groups', ())] + assert len(inhibitors) == 1 + assert inhibitors[0].get('title', '') == 'Cannot find required basic RHEL target repositories.' def mocked_consume_data(): -- 2.39.0