Skip to content

Commit

Permalink
[RHELC-1333] Port lock_releasever_in_rhel_repositories to Action fram…
Browse files Browse the repository at this point in the history
…ework (#1326)

* Port lock_releasever_in_rhel_repositories to Action framework.

* Added unit test, changed failure result to warning.

* Remove unused imports.

* Update convert2rhel/actions/post_conversion/lock_releasever.py

Co-authored-by: Rodolfo Olivieri <[email protected]>

* Simplify control flow per r0x0d suggestion.

* Paging Dr. DeMorgan: fixed an incorrect if-test.

* Update convert2rhel/actions/post_conversion/lock_releasever.py

Co-authored-by: Adam Hošek <[email protected]>

* Update convert2rhel/actions/post_conversion/lock_releasever.py

Co-authored-by: Adam Hošek <[email protected]>

* Move to conversion folder

* Remove post_ponr_conversion and mocks

* Apply suggestions from code review

Co-authored-by: Adam Hošek <[email protected]>

* Fix unit tests after applying suggestions

---------

Co-authored-by: Rodolfo Olivieri <[email protected]>
Co-authored-by: Preston Watson <[email protected]>
Co-authored-by: Adam Hošek <[email protected]>
Co-authored-by: Rodolfo Olivieri <[email protected]>
  • Loading branch information
5 people authored Aug 16, 2024
1 parent e07bc6b commit 6c8df0f
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 99 deletions.
70 changes: 70 additions & 0 deletions convert2rhel/actions/conversion/lock_releasever.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright(C) 2024 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

__metaclass__ = type

import logging

from convert2rhel import actions, utils
from convert2rhel.systeminfo import system_info
from convert2rhel.toolopts import tool_opts


loggerinst = logging.getLogger(__name__)


class LockReleaseverInRHELRepositories(actions.Action):
id = "LOCK_RELEASEVER_IN_RHEL_REPOSITORIES"
dependencies = ()

def run(self):
"""Lock the releasever in the RHEL repositories located under /etc/yum.repos.d/redhat.repo
After converting to a RHEL EUS minor version, we need to lock the releasever in the redhat.repo file to prevent
future errors such as, running `yum update` and not being able to find the repositories metadata.
.. note::
This function should only run if the system corresponds to a RHEL EUS version to make sure the converted system
keeps receiving updates for the specific EUS minor version instead of the latest minor version which is the
default.
"""
super(LockReleaseverInRHELRepositories, self).run()
loggerinst.task("Convert: Lock releasever in RHEL repositories")
# We only lock the releasever on rhel repos if we detect that the running system is an EUS correspondent and if
# rhsm is used, otherwise, there's no need to lock the releasever as the subscription-manager won't be
# available.
if not system_info.eus_system or tool_opts.no_rhsm:
loggerinst.info("Skipping locking RHEL repositories to a specific EUS minor version.")
self.add_message(
id="SKIPPED_LOCK_RELEASEVER_IN_RHEL_REPOSITORIES",
level="INFO",
title="Skipped releasever lock",
description="Releasever lock is needed only when converting to RHEL EUS using RHSM.",
)
return
loggerinst.info(
"Updating /etc/yum.repos.d/rehat.repo to point to RHEL %s instead of the default latest minor version."
% system_info.releasever
)
cmd = [
"subscription-manager",
"release",
"--set=%s" % system_info.releasever,
]
_, ret_code = utils.run_subprocess(cmd, print_output=False)
if ret_code != 0:
loggerinst.warning("Locking RHEL repositories failed.")
return
loggerinst.info("RHEL repositories locked to the %s minor version." % system_info.releasever)
9 changes: 0 additions & 9 deletions convert2rhel/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,6 @@ def prepare_system():

def post_ponr_changes():
"""Start the conversion itself"""
post_ponr_conversion()

loggerinst.task("Final: Update GRUB2 configuration")
grub.update_grub_after_conversion()

Expand All @@ -393,13 +391,6 @@ def post_ponr_changes():
subscription.update_rhsm_custom_facts()


def post_ponr_conversion():
"""Perform main steps for system conversion."""

loggerinst.task("Convert: Lock releasever in RHEL repositories")
subscription.lock_releasever_in_rhel_repositories()


#
# Cleanup and exit
#
Expand Down
38 changes: 0 additions & 38 deletions convert2rhel/subscription.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,44 +899,6 @@ def _relevant_subscription_manager_pkgs():
return relevant_pkgs


def lock_releasever_in_rhel_repositories():
"""Lock the releasever in the RHEL repositories located under /etc/yum.repos.d/redhat.repo
After converting to a RHEL EUS minor version, we need to lock the releasever in the redhat.repo file
to prevent future errors such as, running `yum update` and not being able to find the repositories metadata.
.. note::
This function should only run if the system corresponds to a RHEL EUS version to make sure the converted system
keeps receiving updates for the specific EUS minor version instead of the latest minor version which is the
default.
"""

# We only lock the releasever on rhel repos if we detect that the running system is an EUS correspondent and if
# rhsm is used, otherwise, there's no need to lock the releasever as the subscription-manager won't be available.
if system_info.eus_system and not tool_opts.no_rhsm:
loggerinst.info(
"Updating /etc/yum.repos.d/rehat.repo to point to RHEL %s instead of the default latest minor version."
% system_info.releasever
)
cmd = [
"subscription-manager",
"release",
"--set=%s" % system_info.releasever,
]

output, ret_code = utils.run_subprocess(cmd, print_output=False)
if ret_code != 0:
loggerinst.warning(
"Locking RHEL repositories failed with return code %d and message:\n%s",
ret_code,
output,
)
else:
loggerinst.info("RHEL repositories locked to the %s minor version." % system_info.releasever)
else:
loggerinst.info("Skipping locking RHEL repositories to a specific EUS minor version.")


def update_rhsm_custom_facts():
"""Update the RHSM custom facts in the candlepin server.
Expand Down
86 changes: 86 additions & 0 deletions convert2rhel/unit_tests/actions/conversion/lock_releasever_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright(C) 2024 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

__metaclass__ = type


import pytest
import six

from convert2rhel import actions, utils
from convert2rhel.actions.conversion import lock_releasever
from convert2rhel.systeminfo import Version, system_info
from convert2rhel.unit_tests import RunSubprocessMocked
from convert2rhel.unit_tests.conftest import centos8


six.add_move(six.MovedModule("mock", "mock", "unittest.mock"))

from convert2rhel import unit_tests


@pytest.fixture
def lock_releasever_in_rhel_repositories_instance():
return lock_releasever.LockReleaseverInRHELRepositories()


@pytest.mark.parametrize(
("subprocess", "expected"),
(
(("output", 0), "RHEL repositories locked"),
(("output", 1), "Locking RHEL repositories failed"),
),
)
@centos8
def test_lock_releasever_in_rhel_repositories(
lock_releasever_in_rhel_repositories_instance, subprocess, expected, monkeypatch, caplog, pretend_os
):
cmd = ["subscription-manager", "release", "--set=%s" % system_info.releasever]
run_subprocess_mock = RunSubprocessMocked(
side_effect=unit_tests.run_subprocess_side_effect(
(cmd, subprocess),
)
)
version = Version(8, 6)
monkeypatch.setattr(system_info, "version", version)
monkeypatch.setattr(
utils,
"run_subprocess",
value=run_subprocess_mock,
)
monkeypatch.setattr(system_info, "eus_system", value=True)
lock_releasever_in_rhel_repositories_instance.run()

assert expected in caplog.records[-1].message
assert run_subprocess_mock.call_count == 1


def test_lock_releasever_in_rhel_repositories_not_eus(lock_releasever_in_rhel_repositories_instance, caplog):
lock_releasever_in_rhel_repositories_instance.run()
expected = set(
(
actions.ActionMessage(
level="INFO",
id="SKIPPED_LOCK_RELEASEVER_IN_RHEL_REPOSITORIES",
title="Skipped releasever lock",
description="Releasever lock is needed only when converting to RHEL EUS using RHSM.",
diagnosis=None,
remediations=None,
),
)
)
assert "Skipping locking RHEL repositories to a specific EUS minor version." in caplog.records[-1].message
assert expected.issuperset(lock_releasever_in_rhel_repositories_instance.messages)
assert expected.issubset(lock_releasever_in_rhel_repositories_instance.messages)
19 changes: 2 additions & 17 deletions convert2rhel/unit_tests/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,17 +206,6 @@ def test_show_eula_nonexisting_file(self, caplog, monkeypatch, tmpdir):
assert len(caplog.records) == 1


def test_post_ponr_conversion(monkeypatch):
post_ponr_set_efi_configuration_mock = mock.Mock()
lock_releasever_in_rhel_repositories_mock = mock.Mock()

monkeypatch.setattr(subscription, "lock_releasever_in_rhel_repositories", lock_releasever_in_rhel_repositories_mock)

main.post_ponr_conversion()

assert lock_releasever_in_rhel_repositories_mock.call_count == 1


def test_help_exit(monkeypatch, tmp_path):
"""
Check that --help exits before we enter main_locked().
Expand Down Expand Up @@ -252,7 +241,6 @@ def test_main(monkeypatch, tmp_path):
run_post_actions_mock = mock.Mock()
clear_versionlock_mock = mock.Mock()
ask_to_continue_mock = mock.Mock()
post_ponr_conversion_mock = mock.Mock()
rpm_files_diff_mock = mock.Mock()
update_grub_after_conversion_mock = mock.Mock()
remove_tmp_dir_mock = mock.Mock()
Expand Down Expand Up @@ -280,7 +268,6 @@ def test_main(monkeypatch, tmp_path):
monkeypatch.setattr(main, "_raise_for_skipped_failures", raise_for_skipped_failures_mock)
monkeypatch.setattr(report, "_summary", report_summary_mock)
monkeypatch.setattr(utils, "ask_to_continue", ask_to_continue_mock)
monkeypatch.setattr(main, "post_ponr_conversion", post_ponr_conversion_mock)
monkeypatch.setattr(grub, "update_grub_after_conversion", update_grub_after_conversion_mock)
monkeypatch.setattr(utils, "remove_tmp_dir", remove_tmp_dir_mock)
monkeypatch.setattr(utils, "restart_system", restart_system_mock)
Expand All @@ -306,7 +293,6 @@ def test_main(monkeypatch, tmp_path):
assert report_summary_mock.call_count == 2
assert clear_versionlock_mock.call_count == 1
assert ask_to_continue_mock.call_count == 1
assert post_ponr_conversion_mock.call_count == 1
assert remove_tmp_dir_mock.call_count == 1
assert restart_system_mock.call_count == 1
assert finish_collection_mock.call_count == 1
Expand Down Expand Up @@ -639,11 +625,11 @@ def test_main_rollback_post_ponr_changes_phase(self, monkeypatch, caplog, tmp_pa
clean_yum_metadata_mock = mock.Mock()
run_pre_actions_mock = mock.Mock()
run_post_actions_mock = mock.Mock()
post_ponr_changes_mock = mock.Mock(side_effect=Exception)
find_actions_of_severity_mock = mock.Mock(return_value=[])
report_summary_mock = mock.Mock()
clear_versionlock_mock = mock.Mock()
ask_to_continue_mock = mock.Mock()
post_ponr_conversion_mock = mock.Mock(side_effect=Exception)
summary_as_json_mock = mock.Mock()
summary_as_txt_mock = mock.Mock()

Expand All @@ -667,7 +653,7 @@ def test_main_rollback_post_ponr_changes_phase(self, monkeypatch, caplog, tmp_pa
monkeypatch.setattr(actions, "find_actions_of_severity", find_actions_of_severity_mock)
monkeypatch.setattr(report, "_summary", report_summary_mock)
monkeypatch.setattr(utils, "ask_to_continue", ask_to_continue_mock)
monkeypatch.setattr(main, "post_ponr_conversion", post_ponr_conversion_mock)
monkeypatch.setattr(main, "post_ponr_changes", post_ponr_changes_mock)
monkeypatch.setattr(breadcrumbs, "finish_collection", finish_collection_mock)
monkeypatch.setattr(subscription, "update_rhsm_custom_facts", update_rhsm_custom_facts_mock)
monkeypatch.setattr(report, "summary_as_json", summary_as_json_mock)
Expand All @@ -688,7 +674,6 @@ def test_main_rollback_post_ponr_changes_phase(self, monkeypatch, caplog, tmp_pa
assert clear_versionlock_mock.call_count == 1
assert report_summary_mock.call_count == 2
assert ask_to_continue_mock.call_count == 1
assert post_ponr_conversion_mock.call_count == 1
assert finish_collection_mock.call_count == 1
assert summary_as_json_mock.call_count == 1
assert summary_as_txt_mock.call_count == 1
Expand Down
35 changes: 0 additions & 35 deletions convert2rhel/unit_tests/subscription_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,41 +1136,6 @@ def test_enable_repos_toolopts_enablerepo(
assert run_subprocess_mock.call_count == 1


@pytest.mark.parametrize(
("subprocess", "expected"),
(
(("output", 0), "RHEL repositories locked"),
(("output", 1), "Locking RHEL repositories failed"),
),
)
@centos8
def test_lock_releasever_in_rhel_repositories(subprocess, expected, monkeypatch, caplog, pretend_os):
cmd = ["subscription-manager", "release", "--set=%s" % system_info.releasever]
run_subprocess_mock = RunSubprocessMocked(
side_effect=unit_tests.run_subprocess_side_effect(
(cmd, subprocess),
)
)
version = Version(8, 6)
monkeypatch.setattr(system_info, "version", version)
monkeypatch.setattr(
utils,
"run_subprocess",
value=run_subprocess_mock,
)
monkeypatch.setattr(system_info, "eus_system", value=True)
subscription.lock_releasever_in_rhel_repositories()

assert expected in caplog.records[-1].message
assert run_subprocess_mock.call_count == 1


@centos7
def test_lock_releasever_in_rhel_repositories_not_eus(pretend_os, caplog):
subscription.lock_releasever_in_rhel_repositories()
assert "Skipping locking RHEL repositories to a specific EUS minor version." in caplog.records[-1].message


@pytest.mark.parametrize(
("subprocess", "expected"),
(
Expand Down

0 comments on commit 6c8df0f

Please sign in to comment.