Add support for systemd
Systemd support is in corosync, but currently the add_init_service handles adding an upstart service only. This results in Charmed Kubernetes having incorrectly monitored services. Change-Id: I935613292ce6b78cf645469fda6d21b0aa695c28 Closes-Bug: #1843933
This commit is contained in:
parent
10af229842
commit
e1d44c258a
49
common.py
49
common.py
|
@ -53,6 +53,7 @@ class CRM(dict):
|
|||
self['clones'] = {}
|
||||
self['locations'] = {}
|
||||
self['init_services'] = []
|
||||
self['systemd_services'] = []
|
||||
super(CRM, self).__init__(*args, **kwargs)
|
||||
|
||||
def primitive(self, name, agent, description=None, **kwargs):
|
||||
|
@ -363,6 +364,23 @@ class CRM(dict):
|
|||
"""
|
||||
self['init_services'] = resources
|
||||
|
||||
def systemd_services(self, *resources):
|
||||
"""Specifies that the service(s) is a systemd service.
|
||||
|
||||
Services (resources) which are noted as systemd services are
|
||||
disabled, stopped, and left to pacemaker to manage the resource.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
resources: str or list of str, varargs
|
||||
The resources which should be noted as systemd services.
|
||||
|
||||
Returns
|
||||
-------
|
||||
None
|
||||
"""
|
||||
self['systemd_services'] = resources
|
||||
|
||||
def ms(self, name, resource, description=None, **kwargs):
|
||||
"""Create a master/slave resource type.
|
||||
|
||||
|
@ -669,3 +687,34 @@ class DNSEntry(ResourceDescriptor):
|
|||
if self.ip:
|
||||
res_params = '{} ip_address="{}"'.format(res_params, self.ip)
|
||||
crm.primitive(res_key, res_type, params=res_params)
|
||||
|
||||
|
||||
class SystemdService(ResourceDescriptor):
|
||||
def __init__(self, service_name, systemd_service_name, clone=True):
|
||||
"""Class for managing systemd resource
|
||||
|
||||
:param service_name: string - Name of service
|
||||
:param systemd_service_name: string - Name service uses in
|
||||
systemd system
|
||||
:param clone: bool - clone service across all units
|
||||
:returns: None
|
||||
"""
|
||||
self.service_name = service_name
|
||||
self.systemd_service_name = systemd_service_name
|
||||
self.clone = clone
|
||||
|
||||
def configure_resource(self, crm):
|
||||
""""Configure new systemd system service resource in crm
|
||||
|
||||
:param crm: CRM() instance - Config object for Pacemaker resources
|
||||
:returns: None
|
||||
"""
|
||||
res_key = 'res_{}_{}'.format(
|
||||
self.service_name.replace('-', '_'),
|
||||
self.systemd_service_name.replace('-', '_'))
|
||||
res_type = 'systemd:{}'.format(self.systemd_service_name)
|
||||
crm.primitive(res_key, res_type, op='monitor interval="5s"')
|
||||
crm.systemd_services(self.systemd_service_name)
|
||||
if self.clone:
|
||||
clone_key = 'cl_{}'.format(res_key)
|
||||
crm.clone(clone_key, res_key)
|
||||
|
|
27
requires.py
27
requires.py
|
@ -199,6 +199,33 @@ class HAClusterRequires(RelationBase):
|
|||
service.replace('-', '_'))
|
||||
self.delete_resource(res_key)
|
||||
|
||||
def add_systemd_service(self, name, service, clone=True):
|
||||
"""Add a SystemdService object to self.resources
|
||||
|
||||
:param name: string - Name of service
|
||||
:param service: string - Name service uses in systemd
|
||||
:returns: None
|
||||
"""
|
||||
resource_dict = self.get_local('resources')
|
||||
if resource_dict:
|
||||
resources = relations.hacluster.common.CRM(**resource_dict)
|
||||
else:
|
||||
resources = relations.hacluster.common.CRM()
|
||||
resources.add(
|
||||
relations.hacluster.common.SystemdService(name, service, clone))
|
||||
self.set_local(resources=resources)
|
||||
|
||||
def remove_systemd_service(self, name, service):
|
||||
"""Remove a systemd service
|
||||
|
||||
:param name: string - Name of service
|
||||
:param service: string - Name of service used in systemd
|
||||
"""
|
||||
res_key = 'res_{}_{}'.format(
|
||||
name.replace('-', '_'),
|
||||
service.replace('-', '_'))
|
||||
self.delete_resource(res_key)
|
||||
|
||||
def add_dnsha(self, name, ip, fqdn, endpoint_type):
|
||||
"""Add a DNS entry to self.resources
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ class TestHAClusterCommonCRM(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
self.assertEqual(
|
||||
crm,
|
||||
|
@ -259,6 +260,20 @@ class TestHAClusterCommonCRM(unittest.TestCase):
|
|||
crm['ms']['disk1'],
|
||||
'drbd1 description="useful desc"')
|
||||
|
||||
def test_systemd_services(self):
|
||||
crm = common.CRM()
|
||||
crm.systemd_services('haproxy')
|
||||
self.assertEqual(
|
||||
crm['systemd_services'],
|
||||
('haproxy',))
|
||||
|
||||
def test_systemd_services_multi(self):
|
||||
crm = common.CRM()
|
||||
crm.systemd_services('haproxy', 'apache2')
|
||||
self.assertEqual(
|
||||
crm['systemd_services'],
|
||||
('haproxy', 'apache2'))
|
||||
|
||||
# The method signature of 'order' seems broken. Leaving out unit tests for
|
||||
# it as they would just confirm broken behaviour.
|
||||
|
||||
|
@ -384,3 +399,48 @@ class TestHAClusterCommonDNSEntry(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
crm['resource_params']['res_keystone_admin_hostname'],
|
||||
' params fqdn="keystone.admin" ip_address="10.110.1.1"')
|
||||
|
||||
|
||||
class TestHAClusterCommonSystemdService(unittest.TestCase):
|
||||
|
||||
def test_systemd(self):
|
||||
systemd_svc = common.SystemdService('apache', 'apache2')
|
||||
self.assertEqual(
|
||||
systemd_svc.service_name,
|
||||
'apache')
|
||||
self.assertEqual(
|
||||
systemd_svc.systemd_service_name,
|
||||
'apache2')
|
||||
self.assertTrue(systemd_svc.clone)
|
||||
|
||||
def test_systemd_no_clone(self):
|
||||
systemd_svc = common.SystemdService('apache', 'apache2', clone=False)
|
||||
self.assertFalse(systemd_svc.clone)
|
||||
|
||||
def test_configure_resource(self):
|
||||
crm = common.CRM()
|
||||
systemd_svc = common.SystemdService('apache', 'apache2')
|
||||
systemd_svc.configure_resource(crm)
|
||||
self.assertEqual(
|
||||
crm['resources']['res_apache_apache2'],
|
||||
'systemd:apache2')
|
||||
self.assertEqual(
|
||||
crm['resource_params']['res_apache_apache2'],
|
||||
(' op monitor interval="5s"'))
|
||||
self.assertEqual(crm['systemd_services'], ('apache2',))
|
||||
self.assertEqual(
|
||||
crm['clones']['cl_res_apache_apache2'],
|
||||
'res_apache_apache2')
|
||||
|
||||
def test_configure_resource_no_clone(self):
|
||||
crm = common.CRM()
|
||||
systemd_svc = common.SystemdService('apache', 'apache2', clone=False)
|
||||
systemd_svc.configure_resource(crm)
|
||||
self.assertEqual(
|
||||
crm['resources']['res_apache_apache2'],
|
||||
'systemd:apache2')
|
||||
self.assertEqual(
|
||||
crm['resource_params']['res_apache_apache2'],
|
||||
(' op monitor interval="5s"'))
|
||||
self.assertEqual(crm['systemd_services'], ('apache2',))
|
||||
self.assertFalse(crm['clones'].get('cl_res_apache_apache2'))
|
||||
|
|
|
@ -246,7 +246,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
self.mock_reactive_db(existing_data)
|
||||
self.cr.delete_resource('res_mysql_ens3_vip')
|
||||
self.assertEqual(
|
||||
|
@ -275,7 +276,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': ('telnetd',)}
|
||||
'init_services': ('telnetd',),
|
||||
'systemd_services': []}
|
||||
self.mock_reactive_db(existing_data)
|
||||
self.cr.delete_resource('res_mysql_ens3_vip')
|
||||
self.cr.delete_resource('res_mysql_ens4_vip')
|
||||
|
@ -309,7 +311,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
self.mock_reactive_db()
|
||||
self.cr.add_vip('mysql', '10.110.5.43')
|
||||
|
@ -330,7 +333,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
expected = {
|
||||
'resources': {
|
||||
|
@ -352,7 +356,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
self.mock_reactive_db(existing_resource)
|
||||
self.cr.add_vip('mysql', '10.120.5.43')
|
||||
|
@ -371,7 +376,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {'cl_res_mysql_telnetd': 'res_mysql_telnetd'},
|
||||
'locations': {},
|
||||
'init_services': ('telnetd',)}
|
||||
'init_services': ('telnetd',),
|
||||
'systemd_services': []}
|
||||
self.mock_reactive_db()
|
||||
self.cr.add_init_service('mysql', 'telnetd')
|
||||
self.set_local.assert_called_once_with(resources=expected)
|
||||
|
@ -391,7 +397,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
self.mock_reactive_db()
|
||||
self.cr.add_dnsha(
|
||||
|
@ -416,7 +423,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
expected = {
|
||||
'resources': {
|
||||
'res_keystone_public_hostname': 'ocf:maas:dns',
|
||||
|
@ -437,7 +445,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'colocations': {},
|
||||
'clones': {},
|
||||
'locations': {},
|
||||
'init_services': []}
|
||||
'init_services': [],
|
||||
'systemd_services': []}
|
||||
|
||||
self.mock_reactive_db(existing_resource)
|
||||
self.cr.add_dnsha(
|
||||
|
@ -462,7 +471,8 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
'app2/0': {
|
||||
'key1': 'value1',
|
||||
'key2': 'value3'}},
|
||||
'rid:3': {}}
|
||||
'rid:3': {},
|
||||
'systemd_services': []}
|
||||
|
||||
def get_unit_data(key, unit, relation_id):
|
||||
return unit_data[relation_id].get(unit, {}).get(key, {})
|
||||
|
@ -489,3 +499,22 @@ class TestHAClusterRequires(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
self.cr.get_remote_all('key100', default='defaultvalue'),
|
||||
['defaultvalue'])
|
||||
|
||||
def test_add_systemd_service(self):
|
||||
expected = {
|
||||
'resources': {
|
||||
'res_mysql_telnetd': 'systemd:telnetd'},
|
||||
'delete_resources': [],
|
||||
'resource_params': {
|
||||
'res_mysql_telnetd': ' op monitor interval="5s"'},
|
||||
'groups': {},
|
||||
'ms': {},
|
||||
'orders': {},
|
||||
'colocations': {},
|
||||
'clones': {'cl_res_mysql_telnetd': 'res_mysql_telnetd'},
|
||||
'locations': {},
|
||||
'init_services': [],
|
||||
'systemd_services': ('telnetd',)}
|
||||
self.mock_reactive_db()
|
||||
self.cr.add_systemd_service('mysql', 'telnetd')
|
||||
self.set_local.assert_called_once_with(resources=expected)
|
||||
|
|
Loading…
Reference in New Issue