0245c0
From 1b2602a4afeca35d5780e4f23913a31bc750d076 Mon Sep 17 00:00:00 2001
0245c0
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
0245c0
Date: Tue, 31 May 2022 09:38:47 +0200
0245c0
Subject: [PATCH] Leave the details of service management to the distro (#1074)
0245c0
0245c0
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
0245c0
RH-MergeRequest: 74: Leave the details of service management to the distro (#1074)
0245c0
RH-Commit: [1/1] 781e3e80d8f2d00af4cc5fff5720f690569c8de2
0245c0
RH-Bugzilla: 2091933
0245c0
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
0245c0
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
0245c0
0245c0
commit 8c89009e75c7cf6c2f87635b82656f07f58095e1
0245c0
Author: Andy Fiddaman <omnios@citrus-it.co.uk>
0245c0
Date:   Wed Oct 20 20:58:27 2021 +0000
0245c0
0245c0
    Leave the details of service management to the distro (#1074)
0245c0
0245c0
    Various modules restart services and they all have logic to try and
0245c0
    detect if they are running on a system that needs 'systemctl' or
0245c0
    'service', and then have code to decide which order the arguments
0245c0
    need to be etc. On top of that, not all modules do this in the same way.
0245c0
0245c0
    The duplication and different approaches are not ideal but this also
0245c0
    makes it hard to add support for a new distribution that does not use
0245c0
    either 'systemctl' or 'service'.
0245c0
0245c0
    This change adds a new manage_service() method to the distro class
0245c0
    and updates several modules to use it.
0245c0
0245c0
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
0245c0
---
0245c0
 cloudinit/config/cc_fan.py                    | 42 ++++++++-----------
0245c0
 cloudinit/config/cc_ntp.py                    | 20 ++-------
0245c0
 cloudinit/config/cc_rsyslog.py                | 17 +++-----
0245c0
 cloudinit/config/cc_set_passwords.py          | 17 ++------
0245c0
 cloudinit/config/tests/test_set_passwords.py  | 41 ++++++++----------
0245c0
 cloudinit/distros/__init__.py                 | 28 +++++++++++++
0245c0
 .../test_distros/test_manage_service.py       | 38 +++++++++++++++++
0245c0
 .../test_handler/test_handler_ntp.py          | 29 +++----------
0245c0
 8 files changed, 119 insertions(+), 113 deletions(-)
0245c0
 create mode 100644 tests/unittests/test_distros/test_manage_service.py
0245c0
0245c0
diff --git a/cloudinit/config/cc_fan.py b/cloudinit/config/cc_fan.py
0245c0
index 77984bca..91f50e22 100644
0245c0
--- a/cloudinit/config/cc_fan.py
0245c0
+++ b/cloudinit/config/cc_fan.py
0245c0
@@ -52,35 +52,26 @@ BUILTIN_CFG = {
0245c0
 }
0245c0
 
0245c0
 
0245c0
-def stop_update_start(service, config_file, content, systemd=False):
0245c0
-    if systemd:
0245c0
-        cmds = {'stop': ['systemctl', 'stop', service],
0245c0
-                'start': ['systemctl', 'start', service],
0245c0
-                'enable': ['systemctl', 'enable', service]}
0245c0
-    else:
0245c0
-        cmds = {'stop': ['service', 'stop'],
0245c0
-                'start': ['service', 'start']}
0245c0
-
0245c0
-    def run(cmd, msg):
0245c0
-        try:
0245c0
-            return subp.subp(cmd, capture=True)
0245c0
-        except subp.ProcessExecutionError as e:
0245c0
-            LOG.warning("failed: %s (%s): %s", service, cmd, e)
0245c0
-            return False
0245c0
-
0245c0
-    stop_failed = not run(cmds['stop'], msg='stop %s' % service)
0245c0
+def stop_update_start(distro, service, config_file, content):
0245c0
+    try:
0245c0
+        distro.manage_service('stop', service)
0245c0
+        stop_failed = False
0245c0
+    except subp.ProcessExecutionError as e:
0245c0
+        stop_failed = True
0245c0
+        LOG.warning("failed to stop %s: %s", service, e)
0245c0
+
0245c0
     if not content.endswith('\n'):
0245c0
         content += '\n'
0245c0
     util.write_file(config_file, content, omode="w")
0245c0
 
0245c0
-    ret = run(cmds['start'], msg='start %s' % service)
0245c0
-    if ret and stop_failed:
0245c0
-        LOG.warning("success: %s started", service)
0245c0
-
0245c0
-    if 'enable' in cmds:
0245c0
-        ret = run(cmds['enable'], msg='enable %s' % service)
0245c0
+    try:
0245c0
+        distro.manage_service('start', service)
0245c0
+        if stop_failed:
0245c0
+            LOG.warning("success: %s started", service)
0245c0
+    except subp.ProcessExecutionError as e:
0245c0
+        LOG.warning("failed to start %s: %s", service, e)
0245c0
 
0245c0
-    return ret
0245c0
+    distro.manage_service('enable', service)
0245c0
 
0245c0
 
0245c0
 def handle(name, cfg, cloud, log, args):
0245c0
@@ -99,7 +90,8 @@ def handle(name, cfg, cloud, log, args):
0245c0
         distro.install_packages(['ubuntu-fan'])
0245c0
 
0245c0
     stop_update_start(
0245c0
+        distro,
0245c0
         service='ubuntu-fan', config_file=mycfg.get('config_path'),
0245c0
-        content=mycfg.get('config'), systemd=distro.uses_systemd())
0245c0
+        content=mycfg.get('config'))
0245c0
 
0245c0
 # vi: ts=4 expandtab
0245c0
diff --git a/cloudinit/config/cc_ntp.py b/cloudinit/config/cc_ntp.py
0245c0
index e183993f..4f358c8a 100644
0245c0
--- a/cloudinit/config/cc_ntp.py
0245c0
+++ b/cloudinit/config/cc_ntp.py
0245c0
@@ -459,21 +459,6 @@ def write_ntp_config_template(distro_name, service_name=None, servers=None,
0245c0
         util.del_file(template_fn)
0245c0
 
0245c0
 
0245c0
-def reload_ntp(service, systemd=False):
0245c0
-    """Restart or reload an ntp system service.
0245c0
-
0245c0
-    @param service: A string specifying the name of the service to be affected.
0245c0
-    @param systemd: A boolean indicating if the distro uses systemd, defaults
0245c0
-    to False.
0245c0
-    @returns: A tuple of stdout, stderr results from executing the action.
0245c0
-    """
0245c0
-    if systemd:
0245c0
-        cmd = ['systemctl', 'reload-or-restart', service]
0245c0
-    else:
0245c0
-        cmd = ['service', service, 'restart']
0245c0
-    subp.subp(cmd, capture=True)
0245c0
-
0245c0
-
0245c0
 def supplemental_schema_validation(ntp_config):
0245c0
     """Validate user-provided ntp:config option values.
0245c0
 
0245c0
@@ -583,10 +568,11 @@ def handle(name, cfg, cloud, log, _args):
0245c0
                        packages=ntp_client_config['packages'],
0245c0
                        check_exe=ntp_client_config['check_exe'])
0245c0
     try:
0245c0
-        reload_ntp(ntp_client_config['service_name'],
0245c0
-                   systemd=cloud.distro.uses_systemd())
0245c0
+        cloud.distro.manage_service('reload',
0245c0
+                                    ntp_client_config.get('service_name'))
0245c0
     except subp.ProcessExecutionError as e:
0245c0
         LOG.exception("Failed to reload/start ntp service: %s", e)
0245c0
         raise
0245c0
 
0245c0
+
0245c0
 # vi: ts=4 expandtab
0245c0
diff --git a/cloudinit/config/cc_rsyslog.py b/cloudinit/config/cc_rsyslog.py
0245c0
index 2a2bc931..dd2bbd00 100644
0245c0
--- a/cloudinit/config/cc_rsyslog.py
0245c0
+++ b/cloudinit/config/cc_rsyslog.py
0245c0
@@ -207,16 +207,11 @@ HOST_PORT_RE = re.compile(
0245c0
     r'([:](?P<port>[0-9]+))?$')
0245c0
 
0245c0
 
0245c0
-def reload_syslog(command=DEF_RELOAD, systemd=False):
0245c0
-    service = 'rsyslog'
0245c0
+def reload_syslog(distro, command=DEF_RELOAD):
0245c0
     if command == DEF_RELOAD:
0245c0
-        if systemd:
0245c0
-            cmd = ['systemctl', 'reload-or-try-restart', service]
0245c0
-        else:
0245c0
-            cmd = ['service', service, 'restart']
0245c0
-    else:
0245c0
-        cmd = command
0245c0
-    subp.subp(cmd, capture=True)
0245c0
+        service = distro.get_option('rsyslog_svcname', 'rsyslog')
0245c0
+        return distro.manage_service('try-reload', service)
0245c0
+    return subp.subp(command, capture=True)
0245c0
 
0245c0
 
0245c0
 def load_config(cfg):
0245c0
@@ -429,9 +424,7 @@ def handle(name, cfg, cloud, log, _args):
0245c0
         return
0245c0
 
0245c0
     try:
0245c0
-        restarted = reload_syslog(
0245c0
-            command=mycfg[KEYNAME_RELOAD],
0245c0
-            systemd=cloud.distro.uses_systemd()),
0245c0
+        restarted = reload_syslog(cloud.distro, command=mycfg[KEYNAME_RELOAD])
0245c0
     except subp.ProcessExecutionError as e:
0245c0
         restarted = False
0245c0
         log.warning("Failed to reload syslog", e)
0245c0
diff --git a/cloudinit/config/cc_set_passwords.py b/cloudinit/config/cc_set_passwords.py
0245c0
index 433de751..9efbf61f 100755
0245c0
--- a/cloudinit/config/cc_set_passwords.py
0245c0
+++ b/cloudinit/config/cc_set_passwords.py
0245c0
@@ -94,18 +94,15 @@ PW_SET = (''.join([x for x in ascii_letters + digits
0245c0
                    if x not in 'loLOI01']))
0245c0
 
0245c0
 
0245c0
-def handle_ssh_pwauth(pw_auth, service_cmd=None, service_name="ssh"):
0245c0
+def handle_ssh_pwauth(pw_auth, distro):
0245c0
     """Apply sshd PasswordAuthentication changes.
0245c0
 
0245c0
     @param pw_auth: config setting from 'pw_auth'.
0245c0
                     Best given as True, False, or "unchanged".
0245c0
-    @param service_cmd: The service command list (['service'])
0245c0
-    @param service_name: The name of the sshd service for the system.
0245c0
+    @param distro: an instance of the distro class for the target distribution
0245c0
 
0245c0
     @return: None"""
0245c0
     cfg_name = "PasswordAuthentication"
0245c0
-    if service_cmd is None:
0245c0
-        service_cmd = ["service"]
0245c0
 
0245c0
     if util.is_true(pw_auth):
0245c0
         cfg_val = 'yes'
0245c0
@@ -124,11 +121,7 @@ def handle_ssh_pwauth(pw_auth, service_cmd=None, service_name="ssh"):
0245c0
         LOG.debug("No need to restart SSH service, %s not updated.", cfg_name)
0245c0
         return
0245c0
 
0245c0
-    if 'systemctl' in service_cmd:
0245c0
-        cmd = list(service_cmd) + ["restart", service_name]
0245c0
-    else:
0245c0
-        cmd = list(service_cmd) + [service_name, "restart"]
0245c0
-    subp.subp(cmd)
0245c0
+    distro.manage_service('restart', distro.get_option('ssh_svcname', 'ssh'))
0245c0
     LOG.debug("Restarted the SSH daemon.")
0245c0
 
0245c0
 
0245c0
@@ -229,9 +222,7 @@ def handle(_name, cfg, cloud, log, args):
0245c0
             if expired_users:
0245c0
                 log.debug("Expired passwords for: %s users", expired_users)
0245c0
 
0245c0
-    handle_ssh_pwauth(
0245c0
-        cfg.get('ssh_pwauth'), service_cmd=cloud.distro.init_cmd,
0245c0
-        service_name=cloud.distro.get_option('ssh_svcname', 'ssh'))
0245c0
+    handle_ssh_pwauth(cfg.get('ssh_pwauth'), cloud.distro)
0245c0
 
0245c0
     if len(errors):
0245c0
         log.debug("%s errors occured, re-raising the last one", len(errors))
0245c0
diff --git a/cloudinit/config/tests/test_set_passwords.py b/cloudinit/config/tests/test_set_passwords.py
0245c0
index bbe2ee8f..79118a12 100644
0245c0
--- a/cloudinit/config/tests/test_set_passwords.py
0245c0
+++ b/cloudinit/config/tests/test_set_passwords.py
0245c0
@@ -14,57 +14,52 @@ class TestHandleSshPwauth(CiTestCase):
0245c0
 
0245c0
     with_logs = True
0245c0
 
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
     def test_unknown_value_logs_warning(self, m_subp):
0245c0
-        setpass.handle_ssh_pwauth("floo")
0245c0
+        cloud = self.tmp_cloud(distro='ubuntu')
0245c0
+        setpass.handle_ssh_pwauth("floo", cloud.distro)
0245c0
         self.assertIn("Unrecognized value: ssh_pwauth=floo",
0245c0
                       self.logs.getvalue())
0245c0
         m_subp.assert_not_called()
0245c0
 
0245c0
     @mock.patch(MODPATH + "update_ssh_config", return_value=True)
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
     def test_systemctl_as_service_cmd(self, m_subp, m_update_ssh_config):
0245c0
         """If systemctl in service cmd: systemctl restart name."""
0245c0
-        setpass.handle_ssh_pwauth(
0245c0
-            True, service_cmd=["systemctl"], service_name="myssh")
0245c0
-        self.assertEqual(mock.call(["systemctl", "restart", "myssh"]),
0245c0
-                         m_subp.call_args)
0245c0
-
0245c0
-    @mock.patch(MODPATH + "update_ssh_config", return_value=True)
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
-    def test_service_as_service_cmd(self, m_subp, m_update_ssh_config):
0245c0
-        """If systemctl in service cmd: systemctl restart name."""
0245c0
-        setpass.handle_ssh_pwauth(
0245c0
-            True, service_cmd=["service"], service_name="myssh")
0245c0
-        self.assertEqual(mock.call(["service", "myssh", "restart"]),
0245c0
-                         m_subp.call_args)
0245c0
+        cloud = self.tmp_cloud(distro='ubuntu')
0245c0
+        cloud.distro.init_cmd = ['systemctl']
0245c0
+        setpass.handle_ssh_pwauth(True, cloud.distro)
0245c0
+        m_subp.assert_called_with(
0245c0
+            ["systemctl", "restart", "ssh"], capture=True)
0245c0
 
0245c0
     @mock.patch(MODPATH + "update_ssh_config", return_value=False)
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
     def test_not_restarted_if_not_updated(self, m_subp, m_update_ssh_config):
0245c0
         """If config is not updated, then no system restart should be done."""
0245c0
-        setpass.handle_ssh_pwauth(True)
0245c0
+        cloud = self.tmp_cloud(distro='ubuntu')
0245c0
+        setpass.handle_ssh_pwauth(True, cloud.distro)
0245c0
         m_subp.assert_not_called()
0245c0
         self.assertIn("No need to restart SSH", self.logs.getvalue())
0245c0
 
0245c0
     @mock.patch(MODPATH + "update_ssh_config", return_value=True)
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
     def test_unchanged_does_nothing(self, m_subp, m_update_ssh_config):
0245c0
         """If 'unchanged', then no updates to config and no restart."""
0245c0
-        setpass.handle_ssh_pwauth(
0245c0
-            "unchanged", service_cmd=["systemctl"], service_name="myssh")
0245c0
+        cloud = self.tmp_cloud(distro='ubuntu')
0245c0
+        setpass.handle_ssh_pwauth("unchanged", cloud.distro)
0245c0
         m_update_ssh_config.assert_not_called()
0245c0
         m_subp.assert_not_called()
0245c0
 
0245c0
-    @mock.patch(MODPATH + "subp.subp")
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
     def test_valid_change_values(self, m_subp):
0245c0
         """If value is a valid changen value, then update should be called."""
0245c0
+        cloud = self.tmp_cloud(distro='ubuntu')
0245c0
         upname = MODPATH + "update_ssh_config"
0245c0
         optname = "PasswordAuthentication"
0245c0
         for value in util.FALSE_STRINGS + util.TRUE_STRINGS:
0245c0
             optval = "yes" if value in util.TRUE_STRINGS else "no"
0245c0
             with mock.patch(upname, return_value=False) as m_update:
0245c0
-                setpass.handle_ssh_pwauth(value)
0245c0
+                setpass.handle_ssh_pwauth(value, cloud.distro)
0245c0
                 m_update.assert_called_with({optname: optval})
0245c0
         m_subp.assert_not_called()
0245c0
 
0245c0
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
0245c0
index 220bd11f..a8c57cb8 100755
0245c0
--- a/cloudinit/distros/__init__.py
0245c0
+++ b/cloudinit/distros/__init__.py
0245c0
@@ -784,6 +784,34 @@ class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
0245c0
             args.append(message)
0245c0
         return args
0245c0
 
0245c0
+    def manage_service(self, action, service):
0245c0
+        """
0245c0
+        Perform the requested action on a service. This handles the common
0245c0
+        'systemctl' and 'service' cases and may be overridden in subclasses
0245c0
+        as necessary.
0245c0
+        May raise ProcessExecutionError
0245c0
+        """
0245c0
+        init_cmd = self.init_cmd
0245c0
+        if self.uses_systemd() or 'systemctl' in init_cmd:
0245c0
+            init_cmd = ['systemctl']
0245c0
+            cmds = {'stop': ['stop', service],
0245c0
+                    'start': ['start', service],
0245c0
+                    'enable': ['enable', service],
0245c0
+                    'restart': ['restart', service],
0245c0
+                    'reload': ['reload-or-restart', service],
0245c0
+                    'try-reload': ['reload-or-try-restart', service],
0245c0
+                    }
0245c0
+        else:
0245c0
+            cmds = {'stop': [service, 'stop'],
0245c0
+                    'start': [service, 'start'],
0245c0
+                    'enable': [service, 'start'],
0245c0
+                    'restart': [service, 'restart'],
0245c0
+                    'reload': [service, 'restart'],
0245c0
+                    'try-reload': [service, 'restart'],
0245c0
+                    }
0245c0
+        cmd = list(init_cmd) + list(cmds[action])
0245c0
+        return subp.subp(cmd, capture=True)
0245c0
+
0245c0
 
0245c0
 def _apply_hostname_transformations_to_url(url: str, transformations: list):
0245c0
     """
0245c0
diff --git a/tests/unittests/test_distros/test_manage_service.py b/tests/unittests/test_distros/test_manage_service.py
0245c0
new file mode 100644
0245c0
index 00000000..47e7cfb0
0245c0
--- /dev/null
0245c0
+++ b/tests/unittests/test_distros/test_manage_service.py
0245c0
@@ -0,0 +1,38 @@
0245c0
+# This file is part of cloud-init. See LICENSE file for license information.
0245c0
+
0245c0
+from cloudinit.tests.helpers import (CiTestCase, mock)
0245c0
+from tests.unittests.util import TestingDistro
0245c0
+
0245c0
+
0245c0
+class TestManageService(CiTestCase):
0245c0
+
0245c0
+    with_logs = True
0245c0
+
0245c0
+    def setUp(self):
0245c0
+        super(TestManageService, self).setUp()
0245c0
+        self.dist = TestingDistro()
0245c0
+
0245c0
+    @mock.patch.object(TestingDistro, 'uses_systemd', return_value=False)
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
+    def test_manage_service_systemctl_initcmd(self, m_subp, m_sysd):
0245c0
+        self.dist.init_cmd = ['systemctl']
0245c0
+        self.dist.manage_service('start', 'myssh')
0245c0
+        m_subp.assert_called_with(['systemctl', 'start', 'myssh'],
0245c0
+                                  capture=True)
0245c0
+
0245c0
+    @mock.patch.object(TestingDistro, 'uses_systemd', return_value=False)
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
+    def test_manage_service_service_initcmd(self, m_subp, m_sysd):
0245c0
+        self.dist.init_cmd = ['service']
0245c0
+        self.dist.manage_service('start', 'myssh')
0245c0
+        m_subp.assert_called_with(['service', 'myssh', 'start'], capture=True)
0245c0
+
0245c0
+    @mock.patch.object(TestingDistro, 'uses_systemd', return_value=True)
0245c0
+    @mock.patch("cloudinit.distros.subp.subp")
0245c0
+    def test_manage_service_systemctl(self, m_subp, m_sysd):
0245c0
+        self.dist.init_cmd = ['ignore']
0245c0
+        self.dist.manage_service('start', 'myssh')
0245c0
+        m_subp.assert_called_with(['systemctl', 'start', 'myssh'],
0245c0
+                                  capture=True)
0245c0
+
0245c0
+# vi: ts=4 sw=4 expandtab
0245c0
diff --git a/tests/unittests/test_handler/test_handler_ntp.py b/tests/unittests/test_handler/test_handler_ntp.py
0245c0
index 6b9c8377..c059e2e6 100644
0245c0
--- a/tests/unittests/test_handler/test_handler_ntp.py
0245c0
+++ b/tests/unittests/test_handler/test_handler_ntp.py
0245c0
@@ -112,22 +112,6 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
                                   check_exe='timesyncd')
0245c0
         install_func.assert_called_once_with([])
0245c0
 
0245c0
-    @mock.patch("cloudinit.config.cc_ntp.subp")
0245c0
-    def test_reload_ntp_defaults(self, mock_subp):
0245c0
-        """Test service is restarted/reloaded (defaults)"""
0245c0
-        service = 'ntp_service_name'
0245c0
-        cmd = ['service', service, 'restart']
0245c0
-        cc_ntp.reload_ntp(service)
0245c0
-        mock_subp.subp.assert_called_with(cmd, capture=True)
0245c0
-
0245c0
-    @mock.patch("cloudinit.config.cc_ntp.subp")
0245c0
-    def test_reload_ntp_systemd(self, mock_subp):
0245c0
-        """Test service is restarted/reloaded (systemd)"""
0245c0
-        service = 'ntp_service_name'
0245c0
-        cc_ntp.reload_ntp(service, systemd=True)
0245c0
-        cmd = ['systemctl', 'reload-or-restart', service]
0245c0
-        mock_subp.subp.assert_called_with(cmd, capture=True)
0245c0
-
0245c0
     def test_ntp_rename_ntp_conf(self):
0245c0
         """When NTP_CONF exists, rename_ntp moves it."""
0245c0
         ntpconf = self.tmp_path("ntp.conf", self.new_root)
0245c0
@@ -488,10 +472,11 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
             cc_ntp.handle('notimportant', cfg, mycloud, None, None)
0245c0
             self.assertEqual(0, m_select.call_count)
0245c0
 
0245c0
+    @mock.patch("cloudinit.distros.subp")
0245c0
     @mock.patch("cloudinit.config.cc_ntp.subp")
0245c0
     @mock.patch('cloudinit.config.cc_ntp.select_ntp_client')
0245c0
     @mock.patch("cloudinit.distros.Distro.uses_systemd")
0245c0
-    def test_ntp_the_whole_package(self, m_sysd, m_select, m_subp):
0245c0
+    def test_ntp_the_whole_package(self, m_sysd, m_select, m_subp, m_dsubp):
0245c0
         """Test enabled config renders template, and restarts service """
0245c0
         cfg = {'ntp': {'enabled': True}}
0245c0
         for distro in cc_ntp.distros:
0245c0
@@ -509,7 +494,7 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
 
0245c0
             if distro == 'alpine':
0245c0
                 uses_systemd = False
0245c0
-                expected_service_call = ['service', service_name, 'restart']
0245c0
+                expected_service_call = ['rc-service', service_name, 'restart']
0245c0
                 # _mock_ntp_client_config call above did not specify a client
0245c0
                 # value and so it defaults to "ntp" which on Alpine Linux only
0245c0
                 # supports servers and not pools.
0245c0
@@ -525,7 +510,7 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
                 m_util.is_false.return_value = util.is_false(
0245c0
                     cfg['ntp']['enabled'])
0245c0
                 cc_ntp.handle('notimportant', cfg, mycloud, None, None)
0245c0
-                m_subp.subp.assert_called_with(
0245c0
+                m_dsubp.subp.assert_called_with(
0245c0
                     expected_service_call, capture=True)
0245c0
 
0245c0
             self.assertEqual(expected_content, util.load_file(confpath))
0245c0
@@ -673,9 +658,8 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
             self.assertEqual(sorted(expected_cfg), sorted(result))
0245c0
             m_which.assert_has_calls([])
0245c0
 
0245c0
-    @mock.patch('cloudinit.config.cc_ntp.reload_ntp')
0245c0
     @mock.patch('cloudinit.config.cc_ntp.install_ntp_client')
0245c0
-    def test_ntp_user_provided_config_with_template(self, m_install, m_reload):
0245c0
+    def test_ntp_user_provided_config_with_template(self, m_install):
0245c0
         custom = r'\n#MyCustomTemplate'
0245c0
         user_template = NTP_TEMPLATE + custom
0245c0
         confpath = os.path.join(self.new_root, 'etc/myntp/myntp.conf')
0245c0
@@ -702,11 +686,10 @@ class TestNtp(FilesystemMockingTestCase):
0245c0
                 util.load_file(confpath))
0245c0
 
0245c0
     @mock.patch('cloudinit.config.cc_ntp.supplemental_schema_validation')
0245c0
-    @mock.patch('cloudinit.config.cc_ntp.reload_ntp')
0245c0
     @mock.patch('cloudinit.config.cc_ntp.install_ntp_client')
0245c0
     @mock.patch('cloudinit.config.cc_ntp.select_ntp_client')
0245c0
     def test_ntp_user_provided_config_template_only(self, m_select, m_install,
0245c0
-                                                    m_reload, m_schema):
0245c0
+                                                    m_schema):
0245c0
         """Test custom template for default client"""
0245c0
         custom = r'\n#MyCustomTemplate'
0245c0
         user_template = NTP_TEMPLATE + custom
0245c0
-- 
0245c0
2.35.3
0245c0