certbot-apache: use httpd for newer RHEL derived distros

A change in RHEL 9 is causing apachectl to error out when used
with additional arguments, resulting in certbot errors. The CentOS
configurator now uses httpd instead for RHEL 9 (and later) derived
distros.
This commit is contained in:
Will Greenberg 2022-09-22 13:25:11 -07:00
parent db31a8c1f5
commit 6a7d8768db
2 changed files with 58 additions and 10 deletions

View file

@ -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"""

View file

@ -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)