Allow service actions to be overridden

In order to allow child classes to use other means of controlling
service lifetime, this change introduces methods that call
systemd/upstart via charm-helpers by default but allow for something
else to be used in overrides.

The example use-case in question is the use of crm tools to restart
services:

crm_resource --restart --wait --node <node-name>

Which will restart a resource on a given node if it is running there or
return ENXIO otherwise.

Change-Id: Ifb16f6743296a1ef6dcb212cad517afd57270f7f
Closes-Bug: #1891160
This commit is contained in:
Dmitrii Shcherbakov 2020-08-12 16:40:05 +03:00
parent 7e8c5c1461
commit c9b4009810
3 changed files with 70 additions and 6 deletions

View File

@ -751,7 +751,7 @@ class HAOpenStackCharm(OpenStackAPICharm):
['a2query', '-s', 'openstack_https_frontend'])
if check_enabled:
subprocess.check_call(['a2ensite', 'openstack_https_frontend'])
ch_host.service_reload('apache2', restart_on_failure=True)
self.service_reload('apache2', restart_on_failure=True)
def configure_apache(self):
if self.apache_enabled():
@ -928,7 +928,7 @@ class HAOpenStackCharm(OpenStackAPICharm):
subprocess.check_call(['a2enmod', module])
restart = True
if restart:
ch_host.service_restart('apache2')
self.service_restart('apache2')
def configure_tls(self, certificates_interface=None):
"""Configure TLS certificates and keys
@ -969,7 +969,7 @@ class HAOpenStackCharm(OpenStackAPICharm):
os.path.join('/etc/apache2/ssl/', self.name))
if not os_utils.snap_install_requested() and changed:
self.configure_apache()
ch_host.service_reload('apache2')
self.service_reload('apache2')
self.remove_state('ssl.requested')
self.set_state('ssl.enabled', True)

View File

@ -685,6 +685,50 @@ class BaseOpenStackCharmActions(object):
"""
return self.restart_map
def service_stop(self, service_name):
"""Stop the specified service.
Meant to be overridden by child classes in scenarios where clustering
software like Pacemaker is used.
:param service_name: The service to stop.
:type service_name: str
"""
ch_host.service_stop(service_name)
def service_start(self, service_name):
"""Start the specified service.
Meant to be overridden by child classes in scenarios where clustering
software like Pacemaker is used.
:param service_name: The service to start.
:type service_name: str
"""
ch_host.service_start(service_name)
def service_restart(self, service_name):
"""Restart the specified service.
Meant to be overridden by child classes in scenarios where clustering
software like Pacemaker is used.
:param service_name: The service to restart.
:type service_name: str
"""
ch_host.service_restart(service_name)
def service_reload(self, service_name, restart_on_failure=False):
"""Reload the specified service.
Meant to be overridden by child classes in scenarios where clustering
software like Pacemaker is used.
:param service_name: The service to reload.
:type service_name: str
"""
ch_host.service_reload(service_name, restart_on_failure)
@contextlib.contextmanager
def restart_on_change(self):
"""Restart the services in the self.restart_map{} attribute if any of
@ -704,16 +748,16 @@ class BaseOpenStackCharmActions(object):
restarts += self.full_restart_map[path]
services_list = list(collections.OrderedDict.fromkeys(restarts).keys())
for service_name in services_list:
ch_host.service_stop(service_name)
self.service_stop(service_name)
for service_name in services_list:
ch_host.service_start(service_name)
self.service_start(service_name)
def restart_all(self):
"""Restart all the services configured in the self.services[]
attribute.
"""
for svc in self.services:
ch_host.service_restart(svc)
self.service_restart(svc)
def render_all_configs(self, adapters_instance=None):
"""Render (write) all of the config files identified as the keys in the

View File

@ -1066,3 +1066,23 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest):
self.target.install.assert_called_once()
self.target.remove_obsolete_packages.assert_called_once()
self.target.restart_all.assert_not_called()
def test_service_stop(self):
self.patch_object(chm_core.ch_host, 'service_stop')
self.target.service_stop('test-svc')
self.service_stop.assert_called_once_with('test-svc')
def test_service_start(self):
self.patch_object(chm_core.ch_host, 'service_start')
self.target.service_start('test-svc')
self.service_start.assert_called_once_with('test-svc')
def test_service_restart(self):
self.patch_object(chm_core.ch_host, 'service_restart')
self.target.service_restart('test-svc')
self.service_restart.assert_called_once_with('test-svc')
def test_service_reload(self):
self.patch_object(chm_core.ch_host, 'service_reload')
self.target.service_reload('test-svc')
self.service_reload.assert_called_once_with('test-svc', False)