diff --git a/certbot-apache/certbot_apache/_internal/override_centos.py b/certbot-apache/certbot_apache/_internal/override_centos.py index a436e8457..5af0f18b3 100644 --- a/certbot-apache/certbot_apache/_internal/override_centos.py +++ b/certbot-apache/certbot_apache/_internal/override_centos.py @@ -72,7 +72,20 @@ class CentOSConfigurator(configurator.ApacheConfigurator): super()._prepare_options() if not self.options.restart_cmd_alt: # pragma: no cover raise ValueError("OS option restart_cmd_alt must be set for CentOS.") - self.options.restart_cmd_alt[0] = self.options.ctl + + # Make sure new versions (>=9) of RHEL and other derived distros (that + # track RHEL's versioning scheme) use the httpd executable + os_name, os_version = util.get_os_info() + rhel_derived = os_name not in [ + "fedora", + "amazon", # Amazon has a yearly release version + ] + new = util.parse_loose_version(os_version) >= util.parse_loose_version('9') + if rhel_derived and new: + self.options.ctl = 'httpd' + self.options.version_cmd[0] = self.options.ctl + else: + self.options.restart_cmd_alt[0] = self.options.ctl def get_parser(self) -> "CentOSParser": """Initializes the ApacheParser""" diff --git a/certbot-apache/tests/centos_test.py b/certbot-apache/tests/centos_test.py index c9a820466..fb7e5dc5c 100644 --- a/certbot-apache/tests/centos_test.py +++ b/certbot-apache/tests/centos_test.py @@ -9,8 +9,8 @@ except ImportError: # pragma: no cover from certbot import errors from certbot.compat import filesystem from certbot.compat import os -from certbot_apache._internal import obj from certbot_apache._internal import override_centos +from certbot_apache._internal import obj import util @@ -88,10 +88,8 @@ class FedoraRestartTest(util.ApacheTest): ['systemctl', 'restart', 'httpd']) -class MultipleVhostsTestCentOS(util.ApacheTest): - """Multiple vhost tests for CentOS / RHEL family of distros""" - - _multiprocess_can_split_ = True +class UseCorrectApacheExecutableTest(util.ApacheTest): + """Make sure the various CentOS/RHEL versions use the right httpd executable""" def setUp(self): # pylint: disable=arguments-differ test_dir = "centos7_apache/apache" @@ -101,6 +99,43 @@ class MultipleVhostsTestCentOS(util.ApacheTest): config_root=config_root, vhost_root=vhost_root) + @mock.patch("certbot.util.get_os_info") + def test_old_centos_rhel_and_fedora(self, mock_get_os_info): + for os_info in [("centos", "7"), ("rhel", "7"), ("fedora", "28"), ("scientific", "6")]: + mock_get_os_info.return_value = os_info + config = util.get_apache_configurator( + self.config_path, self.vhost_path, self.config_dir, self.work_dir, + os_info="centos") + self.assertEqual(config.options.ctl, "apachectl") + self.assertEqual(config.options.version_cmd, ["apachectl", "-v"]) + self.assertEqual(config.options.restart_cmd, ["apachectl", "graceful"]) + + @mock.patch("certbot.util.get_os_info") + def test_new_rhel_derived(self, mock_get_os_info): + for os_info in [("centos", "9"), ("rhel", "9"), ("oracle", "9")]: + mock_get_os_info.return_value = os_info + config = util.get_apache_configurator( + self.config_path, self.vhost_path, self.config_dir, self.work_dir, + os_info="centos") + self.assertEqual(config.options.ctl, "httpd") + self.assertEqual(config.options.version_cmd, ["httpd", "-v"]) + self.assertEqual(config.options.restart_cmd, ["apachectl", "graceful"]) + + +class MultipleVhostsTestCentOS(util.ApacheTest): + """Multiple vhost tests for CentOS / RHEL family of distros""" + + _multiprocess_can_split_ = True + + @mock.patch("certbot.util.get_os_info") + def setUp(self, mock_get_os_info): # pylint: disable=arguments-differ + test_dir = "centos7_apache/apache" + config_root = "centos7_apache/apache/httpd" + vhost_root = "centos7_apache/apache/httpd/conf.d" + super().setUp(test_dir=test_dir, + config_root=config_root, + vhost_root=vhost_root) + mock_get_os_info.return_value = ("centos", "9") self.config = util.get_apache_configurator( self.config_path, self.vhost_path, self.config_dir, self.work_dir, os_info="centos") @@ -124,9 +159,9 @@ class MultipleVhostsTestCentOS(util.ApacheTest): ) def mock_get_cfg(command): """Mock httpd process stdout""" - if command == ['apachectl', '-t', '-D', 'DUMP_RUN_CFG']: + if command == ['httpd', '-t', '-D', 'DUMP_RUN_CFG']: return define_val - elif command == ['apachectl', '-t', '-D', 'DUMP_MODULES']: + elif command == ['httpd', '-t', '-D', 'DUMP_MODULES']: return mod_val return "" mock_get.side_effect = mock_get_cfg @@ -135,7 +170,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest): with mock.patch("certbot.util.get_os_info") as mock_osi: # Make sure we have the have the CentOS httpd constants - mock_osi.return_value = ("centos", "7") + mock_osi.return_value = ("centos", "9") self.config.parser.update_runtime_variables() self.assertEqual(mock_get.call_count, 3) @@ -170,7 +205,7 @@ class MultipleVhostsTestCentOS(util.ApacheTest): with mock.patch("certbot.util.get_os_info") as mock_osi: # Make sure we have the have the CentOS httpd constants - mock_osi.return_value = ("centos", "7") + mock_osi.return_value = ("centos", "9") self.config.parser.update_runtime_variables() self.assertIn("mock_define", self.config.parser.variables)