diff --git a/convert2rhel/actions/conversion/pkg_manager_config.py b/convert2rhel/actions/conversion/pkg_manager_config.py
new file mode 100644
index 0000000000..cca27f9926
--- /dev/null
+++ b/convert2rhel/actions/conversion/pkg_manager_config.py
@@ -0,0 +1,39 @@
+# 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 .
+
+__metaclass__ = type
+
+import logging
+
+from convert2rhel import actions, redhatrelease
+
+
+logger = logging.getLogger(__name__)
+
+
+class ConfigurePkgManager(actions.Action):
+ id = "CONFIGURE_PKG_MANAGER"
+ dependencies = ("CONVERT_SYSTEM_PACKAGES",)
+
+ def run(self):
+ """
+ Check if the distroverpkg tag inside the package manager config has been modified before the conversion and if so
+ comment it out and write to the file.
+ """
+ super(ConfigurePkgManager, self).run()
+
+ logger.task("Convert: Patch package manager configuration file")
+ pmc = redhatrelease.PkgManagerConf()
+ pmc.patch()
diff --git a/convert2rhel/main.py b/convert2rhel/main.py
index 04587b0700..dfde484b13 100644
--- a/convert2rhel/main.py
+++ b/convert2rhel/main.py
@@ -395,8 +395,7 @@ def post_ponr_changes():
def post_ponr_conversion():
"""Perform main steps for system conversion."""
- loggerinst.task("Convert: Patch yum configuration file")
- redhatrelease.YumConf().patch()
+
loggerinst.task("Convert: Lock releasever in RHEL repositories")
subscription.lock_releasever_in_rhel_repositories()
diff --git a/convert2rhel/redhatrelease.py b/convert2rhel/redhatrelease.py
index 0d91eeca40..6dda1d9d79 100644
--- a/convert2rhel/redhatrelease.py
+++ b/convert2rhel/redhatrelease.py
@@ -49,45 +49,56 @@ def get_system_release_content():
loggerinst.critical("%s\n%s file is essential for running this tool." % (err, filepath))
-class YumConf:
- _yum_conf_path = "/etc/yum.conf"
+class PkgManagerConf:
+ """
+ Check if the config file of the systems package manager has been modified and if it has then
+ remove those changes before the conversion completes.
+ .. note::
+ The pkg manager config file path only needs to be set to yum.conf as there is a symlink between yum and dnf.
+ This means that on dnf systems the dnf.conf will be modified even the path is for the yum.conf.
+ """
- def __init__(self):
- self._yum_conf_content = utils.get_file_content(self._yum_conf_path)
+ _pkg_manager_conf_path = "" # type: str
+ _pkg_manager_conf_content = "" # type: str
+
+ def __init__(self, config_path=None): # type: (str|None) -> None
+ if not config_path:
+ self._pkg_manager_conf_path = "/etc/yum.conf" if pkgmanager.TYPE == "yum" else "/etc/dnf/dnf.conf"
+ else:
+ self._pkg_manager_conf_path = config_path
+ self._pkg_manager_conf_content = utils.get_file_content(self._pkg_manager_conf_path)
def patch(self):
"""Comment out the distroverpkg variable in yum.conf so yum can determine
release version ($releasever) based on the installed redhat-release
package.
"""
- if YumConf.is_modified():
- # When the user touches the yum.conf before executing the conversion, then during the conversion yum as a
+ if self.is_modified():
+ # When the user touches the yum/dnf config before executing the conversion, then during the conversion yum/dmf as a
# package is replaced but this config file is left unchanged and it keeps the original distroverpkg setting.
self._comment_out_distroverpkg_tag()
- self._write_altered_yum_conf()
- loggerinst.info("%s patched." % self._yum_conf_path)
+ self._write_altered_pkg_manager_conf()
+ loggerinst.info("%s patched." % self._pkg_manager_conf_path)
else:
- loggerinst.info("Skipping patching, yum configuration file not modified")
+ loggerinst.info("Skipping patching, package manager configuration file has not been modified.")
return
def _comment_out_distroverpkg_tag(self):
- if re.search(r"^distroverpkg=", self._yum_conf_content, re.MULTILINE):
- self._yum_conf_content = re.sub(r"\n(distroverpkg=).*", r"\n#\1", self._yum_conf_content)
+ if re.search(r"^distroverpkg=", self._pkg_manager_conf_content, re.MULTILINE):
+ self._pkg_manager_conf_content = re.sub(r"\n(distroverpkg=).*", r"\n#\1", self._pkg_manager_conf_content)
- def _write_altered_yum_conf(self):
- with open(self._yum_conf_path, "w") as file_to_write:
- file_to_write.write(self._yum_conf_content)
+ def _write_altered_pkg_manager_conf(self):
+ with open(self._pkg_manager_conf_path, "w") as file_to_write:
+ file_to_write.write(self._pkg_manager_conf_content)
- @staticmethod
- def is_modified():
+ def is_modified(self):
"""Return true if the YUM/DNF configuration file has been modified by the user."""
- conf = "/etc/yum.conf" if pkgmanager.TYPE == "yum" else "/etc/dnf/dnf.conf"
- output, _ = utils.run_subprocess(["rpm", "-Vf", conf], print_output=False)
+ output, _ = utils.run_subprocess(["rpm", "-Vf", self._pkg_manager_conf_path], print_output=False)
# rpm -Vf does not return information about the queried file but about all files owned by the rpm
# that owns the queried file. Character '5' on position 3 means that the file was modified.
- return True if re.search(r"^.{2}5.*? %s$" % conf, output, re.MULTILINE) else False
+ return True if re.search(r"^.{2}5.*? %s$" % self._pkg_manager_conf_path, output, re.MULTILINE) else False
# Code to be executed upon module import
diff --git a/convert2rhel/unit_tests/actions/conversion/pkg_manager_config_test.py b/convert2rhel/unit_tests/actions/conversion/pkg_manager_config_test.py
new file mode 100644
index 0000000000..0546ca47b2
--- /dev/null
+++ b/convert2rhel/unit_tests/actions/conversion/pkg_manager_config_test.py
@@ -0,0 +1,38 @@
+# 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 .
+
+__metaclass__ = type
+import pytest
+import six
+
+from convert2rhel import redhatrelease
+from convert2rhel.actions.conversion import pkg_manager_config
+
+
+six.add_move(six.MovedModule("mock", "mock", "unittest.mock"))
+from six.moves import mock
+
+
+@pytest.fixture
+def pkg_manager_config_instance():
+ return pkg_manager_config.ConfigurePkgManager()
+
+
+def test_pkg_manager_config(pkg_manager_config_instance, monkeypatch):
+ redhat_release_mock = mock.Mock()
+ monkeypatch.setattr(redhatrelease.PkgManagerConf, "patch", redhat_release_mock)
+ pkg_manager_config_instance.run()
+
+ assert redhat_release_mock.call_count == 1
diff --git a/convert2rhel/unit_tests/main_test.py b/convert2rhel/unit_tests/main_test.py
index a0c07ec7b7..1e1c02eb22 100644
--- a/convert2rhel/unit_tests/main_test.py
+++ b/convert2rhel/unit_tests/main_test.py
@@ -208,15 +208,12 @@ def test_show_eula_nonexisting_file(self, caplog, monkeypatch, tmpdir):
def test_post_ponr_conversion(monkeypatch):
post_ponr_set_efi_configuration_mock = mock.Mock()
- yum_conf_patch_mock = mock.Mock()
lock_releasever_in_rhel_repositories_mock = mock.Mock()
- monkeypatch.setattr(redhatrelease.YumConf, "patch", yum_conf_patch_mock)
monkeypatch.setattr(subscription, "lock_releasever_in_rhel_repositories", lock_releasever_in_rhel_repositories_mock)
main.post_ponr_conversion()
- assert yum_conf_patch_mock.call_count == 1
assert lock_releasever_in_rhel_repositories_mock.call_count == 1
diff --git a/convert2rhel/unit_tests/redhatrelease_test.py b/convert2rhel/unit_tests/redhatrelease_test.py
index 41cc1b51c4..a3e9e980ac 100644
--- a/convert2rhel/unit_tests/redhatrelease_test.py
+++ b/convert2rhel/unit_tests/redhatrelease_test.py
@@ -29,16 +29,16 @@
from convert2rhel import unit_tests # Imports unit_tests/__init__.py
from convert2rhel import pkgmanager, redhatrelease, systeminfo, utils
-from convert2rhel.redhatrelease import YumConf, get_system_release_filepath
+from convert2rhel.redhatrelease import PkgManagerConf, get_system_release_filepath
from convert2rhel.systeminfo import system_info
-YUM_CONF_WITHOUT_DISTROVERPKG = """[main]
+PKG_MANAGER_CONF_WITHOUT_DISTROVERPKG = """[main]
installonly_limit=3
# This is the default"""
-YUM_CONF_WITH_DISTROVERPKG = """[main]
+PKG_MANAGER_CONF_WITH_DISTROVERPKG = """[main]
installonly_limit=3
distroverpkg=centos-release
@@ -48,40 +48,42 @@
SUPPORTED_RHEL_VERSIONS = [7, 8]
-def test_get_yum_conf_content(monkeypatch):
- monkeypatch.setattr(redhatrelease.YumConf, "_yum_conf_path", unit_tests.DUMMY_FILE)
+@pytest.fixture()
+def pkg_manager_conf_instance():
+ return PkgManagerConf()
- yum_conf = redhatrelease.YumConf()
- assert "Dummy file to read" in yum_conf._yum_conf_content
+def test_get_pkg_manager_conf_content(monkeypatch):
+ pkg_manager_conf = redhatrelease.PkgManagerConf(config_path=unit_tests.DUMMY_FILE)
+ assert "Dummy file to read" in pkg_manager_conf._pkg_manager_conf_content
@pytest.mark.parametrize("version", SUPPORTED_RHEL_VERSIONS)
-def test_patch_yum_conf_missing_distroverpkg(version, monkeypatch):
- monkeypatch.setattr(redhatrelease.YumConf, "_yum_conf_path", unit_tests.DUMMY_FILE)
+def test_patch_pkg_manager_conf_missing_distroverpkg(version, monkeypatch, pkg_manager_conf_instance):
+
monkeypatch.setattr(system_info, "version", version)
- yum_conf = redhatrelease.YumConf()
- yum_conf._yum_conf_content = YUM_CONF_WITHOUT_DISTROVERPKG
+ pkg_manager_conf = pkg_manager_conf_instance
+ pkg_manager_conf._pkg_manager_conf_content = PKG_MANAGER_CONF_WITHOUT_DISTROVERPKG
# Call just this function to avoid unmockable built-in write func
- yum_conf._comment_out_distroverpkg_tag()
+ pkg_manager_conf._comment_out_distroverpkg_tag()
- assert "distroverpkg=" not in yum_conf._yum_conf_content
- assert yum_conf._yum_conf_content.count("distroverpkg=") == 0
+ assert "distroverpkg=" not in pkg_manager_conf._pkg_manager_conf_content
+ assert pkg_manager_conf._pkg_manager_conf_content.count("distroverpkg=") == 0
@pytest.mark.parametrize("version", SUPPORTED_RHEL_VERSIONS)
-def test_patch_yum_conf_existing_distroverpkg(version, monkeypatch):
- monkeypatch.setattr(redhatrelease.YumConf, "_yum_conf_path", unit_tests.DUMMY_FILE)
+def test_patch_pkg_manager_conf_existing_distroverpkg(version, monkeypatch, pkg_manager_conf_instance):
+
monkeypatch.setattr(system_info, "version", systeminfo.Version(version, 0))
- yum_conf = redhatrelease.YumConf()
- yum_conf._yum_conf_content = YUM_CONF_WITH_DISTROVERPKG
+ pkg_manager_conf = pkg_manager_conf_instance
+ pkg_manager_conf._pkg_manager_conf_content = PKG_MANAGER_CONF_WITH_DISTROVERPKG
# Call just this function to avoid unmockable built-in write func
- yum_conf._comment_out_distroverpkg_tag()
+ pkg_manager_conf._comment_out_distroverpkg_tag()
- assert "#distroverpkg=" in yum_conf._yum_conf_content
- assert yum_conf._yum_conf_content.count("#distroverpkg=") == 1
+ assert "#distroverpkg=" in pkg_manager_conf._pkg_manager_conf_content
+ assert pkg_manager_conf._pkg_manager_conf_content.count("#distroverpkg=") == 1
@pytest.mark.parametrize(
@@ -96,36 +98,39 @@ def test_patch_yum_conf_existing_distroverpkg(version, monkeypatch):
("unknown", "anything", False),
),
)
-def test_yum_is_modified(monkeypatch, pkg_type, subprocess_ret, expected_result):
+def test_pkg_manager_is_modified(monkeypatch, pkg_type, subprocess_ret, expected_result):
monkeypatch.setattr(pkgmanager, "TYPE", value=pkg_type)
run_subprocess = unit_tests.RunSubprocessMocked(return_string=subprocess_ret)
monkeypatch.setattr(utils, "run_subprocess", value=run_subprocess)
+ pkg_manager_conf = redhatrelease.PkgManagerConf()
- assert YumConf.is_modified() == expected_result
+ assert pkg_manager_conf.is_modified() == expected_result
@pytest.mark.parametrize("modified", (True, False))
-def test_yum_patch(monkeypatch, modified, caplog):
+def test_pkg_manager_patch(monkeypatch, modified, caplog, tmp_path):
is_modified = mock.Mock(return_value=modified)
- monkeypatch.setattr(YumConf, "is_modified", value=is_modified)
+ monkeypatch.setattr(PkgManagerConf, "is_modified", value=is_modified)
_comment_out_distroverpkg_tag = mock.Mock()
monkeypatch.setattr(
- YumConf,
+ PkgManagerConf,
"_comment_out_distroverpkg_tag",
value=_comment_out_distroverpkg_tag,
)
- _write_altered_yum_conf = mock.Mock()
- monkeypatch.setattr(YumConf, "_write_altered_yum_conf", value=_write_altered_yum_conf)
-
- YumConf().patch()
+ monkeypatch.setattr(
+ PkgManagerConf,
+ "_pkg_manager_conf_path",
+ value=tmp_path,
+ )
+ PkgManagerConf(config_path=str(tmp_path / "yum.conf")).patch()
if modified:
_comment_out_distroverpkg_tag.assert_called_once()
assert "patched" in caplog.text
else:
_comment_out_distroverpkg_tag.assert_not_called()
- assert "Skipping patching, yum configuration file not modified" in caplog.text
+ assert "Skipping patching, package manager configuration file has not been modified" in caplog.text
@pytest.mark.parametrize(("is_file", "exception"), ((True, False), (False, True)))
diff --git a/tests/integration/tier1/destructive/changed-yum-conf/test_patch_yum_conf.py b/tests/integration/tier1/destructive/changed-yum-conf/test_patch_yum_conf.py
index aa784c1e9d..cb1d28adaa 100644
--- a/tests/integration/tier1/destructive/changed-yum-conf/test_patch_yum_conf.py
+++ b/tests/integration/tier1/destructive/changed-yum-conf/test_patch_yum_conf.py
@@ -1,4 +1,4 @@
-from conftest import TEST_VARS
+from conftest import TEST_VARS, SystemInformationRelease
def test_yum_conf_patch(convert2rhel, shell):
@@ -9,6 +9,9 @@ def test_yum_conf_patch(convert2rhel, shell):
expanding the $releasever variable properly.
"""
shell("echo '#random text' >> /etc/yum.conf")
+ pkgmanager_conf = "/etc/yum.conf"
+ if SystemInformationRelease.version.major >= 8:
+ pkgmanager_conf = "/etc/dnf/dnf.conf"
with convert2rhel(
"-y --serverurl {} --username {} --password {} --pool {} --debug".format(
@@ -18,7 +21,7 @@ def test_yum_conf_patch(convert2rhel, shell):
TEST_VARS["RHSM_POOL"],
)
) as c2r:
- c2r.expect("/etc/yum.conf patched.")
+ c2r.expect("{} patched.".format(pkgmanager_conf))
assert c2r.exitstatus == 0
# The tsflags will prevent updating the RHEL-8.5 versions to RHEL-8.6