diff --git a/coriolis/osmorphing/redhat.py b/coriolis/osmorphing/redhat.py index ea2e7f4f..7d0fa93f 100644 --- a/coriolis/osmorphing/redhat.py +++ b/coriolis/osmorphing/redhat.py @@ -209,6 +209,16 @@ def set_net_config(self, nics_info, dhcp): mac_addresses) self._add_net_udev_rules(net_ifaces_info) + def _has_package_installed(self, package_name): + cmd = 'rpm -q %s' % ("".join(package_name)) + try: + self._exec_cmd_chroot(cmd) + return True + except exception.CoriolisException: + LOG.warning(f"Package ${package_name} is not installed") + LOG.trace(utils.get_exception_details()) + return False + def _yum_install(self, package_names, enable_repos=[]): try: yum_cmd = 'yum install %s -y%s' % ( @@ -285,7 +295,10 @@ def pre_packages_install(self, package_names): super(BaseRedHatMorphingTools, self).pre_packages_install( package_names) self._yum_clean_all() - self._yum_install(['grubby']) + if not self._has_package_installed('grubby'): + self._yum_install(['grubby']) + else: + LOG.debug("Skipping package 'grubby' as it's already installed") def install_packages(self, package_names): enable_repos = self._get_repos_to_enable() diff --git a/coriolis/tests/osmorphing/test_redhat.py b/coriolis/tests/osmorphing/test_redhat.py index d34f9008..c624969e 100644 --- a/coriolis/tests/osmorphing/test_redhat.py +++ b/coriolis/tests/osmorphing/test_redhat.py @@ -363,6 +363,29 @@ def test_set_net_config_no_dhcp( mock_add_net_udev_rules.assert_called_once_with( mock_get_net_ifaces_info.return_value) + @mock.patch.object(base.BaseLinuxOSMorphingTools, '_exec_cmd_chroot') + def test_has_package_installed(self, mock_exec_cmd_chroot): + result = self.morphing_tools._has_package_installed("mock_package") + + self.assertEqual( + True, + result + ) + mock_exec_cmd_chroot.assert_called_once_with("rpm -q mock_package") + + mock_exec_cmd_chroot.reset_mock() + mock_exec_cmd_chroot.side_effect = exception.CoriolisException() + + with self.assertLogs( + 'coriolis.osmorphing.redhat', level=logging.DEBUG): + result = self.morphing_tools._has_package_installed("mock_package") + + self.assertEqual( + False, + result + ) + mock_exec_cmd_chroot.assert_called_once_with("rpm -q mock_package") + @mock.patch.object(base.BaseLinuxOSMorphingTools, '_exec_cmd_chroot') def test__yum_install(self, mock_exec_cmd_chroot): self.morphing_tools._yum_install(self.package_names, self.enable_repos) @@ -449,17 +472,38 @@ def test__find_yum_repos_not_found(self, mock_read_file, mock_list_dir): with self.assertLogs('coriolis.osmorphing.redhat', level=logging.WARN): self.morphing_tools._find_yum_repos(repos_to_enable) + @mock.patch.object(redhat.BaseRedHatMorphingTools, + '_has_package_installed') @mock.patch.object(redhat.BaseRedHatMorphingTools, '_yum_install') @mock.patch.object(redhat.BaseRedHatMorphingTools, '_yum_clean_all') @mock.patch.object(base.BaseLinuxOSMorphingTools, 'pre_packages_install') def test_pre_packages_install(self, mock_pre_packages_install, - mock_yum_clean_all, mock_yum_install): + mock_yum_clean_all, mock_yum_install, + mock_has_package_installed): + mock_has_package_installed.return_value = False + self.morphing_tools.pre_packages_install(self.package_names) mock_pre_packages_install.assert_called_once_with(self.package_names) mock_yum_clean_all.assert_called_once() mock_yum_install.assert_called_once_with(['grubby']) + @mock.patch.object(redhat.BaseRedHatMorphingTools, + '_has_package_installed') + @mock.patch.object(redhat.BaseRedHatMorphingTools, '_yum_install') + @mock.patch.object(redhat.BaseRedHatMorphingTools, '_yum_clean_all') + @mock.patch.object(base.BaseLinuxOSMorphingTools, 'pre_packages_install') + def test_pre_packages_install_has_grubby( + self, mock_pre_packages_install, mock_yum_clean_all, mock_yum_install, + mock_has_package_installed): + mock_has_package_installed.return_value = True + + self.morphing_tools.pre_packages_install(self.package_names) + + mock_pre_packages_install.assert_called_once_with(self.package_names) + mock_yum_clean_all.assert_called_once() + mock_yum_install.assert_not_called() + @mock.patch.object(redhat.BaseRedHatMorphingTools, '_yum_install') @mock.patch.object(redhat.BaseRedHatMorphingTools, '_get_repos_to_enable') def test_install_packages(self, mock_get_repos_to_enable,