Fix handling of recursion in notify_rbd_mirrors

The committed iteration had a problem:
In the event the ``ceph-rbd-mirror`` charm created a new pool
on a remote cluster and set the relation data on the ceph
leader unit, members of other instances of the ``rbd-mirror``
relation would not be updated with pool information.

Also limit number of times notify_mons() is run

Change-Id: I2a03ca02285e7a99c2cae48dbafc014fb478fb84
This commit is contained in:
Frode Nordahl 2019-02-28 00:07:26 +01:00
parent e3bf76a1c4
commit f6d9a61cb6
2 changed files with 27 additions and 15 deletions

View File

@ -39,7 +39,6 @@ from charmhelpers.core.hookenv import (
is_relation_made,
relation_get,
relation_set,
relation_type,
leader_set, leader_get,
is_leader,
remote_unit,
@ -475,7 +474,7 @@ def notify_radosgws():
def notify_rbd_mirrors():
for relid in relation_ids('rbd-mirror'):
for unit in related_units(relid):
rbd_mirror_relation(relid=relid, unit=unit)
rbd_mirror_relation(relid=relid, unit=unit, recurse=False)
def notify_client():
@ -509,7 +508,8 @@ def notify_mons():
relation_settings={'nonce': nonce})
def handle_broker_request(relid, unit, add_legacy_response=False):
def handle_broker_request(relid, unit, add_legacy_response=False,
recurse=True):
"""Retrieve broker request from relation, process, return response data.
:param relid: Realtion ID
@ -519,6 +519,10 @@ def handle_broker_request(relid, unit, add_legacy_response=False):
:param add_legacy_response: (Optional) Adds the legacy ``broker_rsp`` key
to the response in addition to the new way.
:type add_legacy_response: bool
:param recurse: Whether we should call out to update relation functions or
not. Mainly used to handle recursion when called from
notify_rbd_mirrors()
:type recurse: bool
:returns: Dictionary of response data ready for use with relation_set.
:rtype: dict
"""
@ -537,19 +541,19 @@ def handle_broker_request(relid, unit, add_legacy_response=False):
if add_legacy_response:
response.update({'broker_rsp': rsp})
# prevent recursion when called from rbd_mirror_relation()
if relation_type() != 'rbd-mirror':
if relation_ids('rbd-mirror') and recurse:
# update ``rbd-mirror`` relations for this unit with
# information about new pools.
log('Notifying this units rbd-mirror relations after '
'processing broker request.', level=DEBUG)
notify_rbd_mirrors()
# notify mons to flag that the other mon units should update
# their ``rbd-mirror`` relations with information about new pools.
log('Notifying peers after processing broker request.',
level=DEBUG)
notify_mons()
# notify mons to flag that the other mon units should update
# their ``rbd-mirror`` relations with information about new
# pools.
log('Notifying peers after processing broker request.',
level=DEBUG)
notify_mons()
return response
@ -672,14 +676,14 @@ def radosgw_relation(relid=None, unit=None):
@hooks.hook('rbd-mirror-relation-joined')
@hooks.hook('rbd-mirror-relation-changed')
def rbd_mirror_relation(relid=None, unit=None):
def rbd_mirror_relation(relid=None, unit=None, recurse=True):
if ready_for_service():
log('mon cluster in quorum and osds bootstrapped '
'- providing rbd-mirror client with keys')
if not unit:
unit = remote_unit()
# handle broker requests first to get a updated pool map
data = (handle_broker_request(relid, unit))
data = (handle_broker_request(relid, unit, recurse=recurse))
data.update({
'auth': config('auth-supported'),
'ceph-public-address': get_public_addr(),

View File

@ -261,7 +261,8 @@ class CephHooksTestCase(unittest.TestCase):
mock_relation_ids.assert_called_once_with('rbd-mirror')
mock_related_units.assert_called_once_with('arelid')
mock_rbd_mirror_relation.assert_called_once_with(relid='arelid',
unit='aunit')
unit='aunit',
recurse=False)
@patch.object(ceph_hooks, 'uuid')
@patch.object(ceph_hooks, 'relation_set')
@ -360,6 +361,7 @@ class RelatedUnitsTestCase(unittest.TestCase):
'broker-rsp-glance-0': 'AOK',
'broker_rsp': 'AOK'})
@patch.object(ceph_hooks, 'relation_ids')
@patch.object(ceph_hooks, 'notify_mons')
@patch.object(ceph_hooks, 'notify_rbd_mirrors')
@patch.object(ceph_hooks, 'process_requests')
@ -370,7 +372,8 @@ class RelatedUnitsTestCase(unittest.TestCase):
mock_ceph_is_leader,
mock_broker_process_requests,
mock_notify_rbd_mirrors,
mock_notify_mons):
mock_notify_mons,
mock_relation_ids):
mock_remote_unit.return_value = 'glance/0'
ceph_hooks.handle_broker_request('rel1', None)
mock_remote_unit.assert_called_once_with()
@ -388,6 +391,11 @@ class RelatedUnitsTestCase(unittest.TestCase):
ceph_hooks.handle_broker_request('rel1', 'glance/0',
add_legacy_response=True),
{'broker_rsp': 'AOK', 'broker-rsp-glance-0': 'AOK'})
mock_notify_rbd_mirrors.reset_mock()
mock_notify_mons.reset_mock()
ceph_hooks.handle_broker_request('rel1', None, recurse=False)
self.assertFalse(mock_notify_rbd_mirrors.called)
self.assertFalse(mock_notify_mons.called)
class BootstrapSourceTestCase(test_utils.CharmTestCase):
@ -615,7 +623,7 @@ class RBDMirrorRelationTestCase(test_utils.CharmTestCase):
}
ceph_hooks.rbd_mirror_relation('rbd-mirror:51', 'ceph-rbd-mirror/0')
self.handle_broker_request.assert_called_with(
'rbd-mirror:51', 'ceph-rbd-mirror/0')
'rbd-mirror:51', 'ceph-rbd-mirror/0', recurse=True)
self.relation_set.assert_called_with(
relation_id='rbd-mirror:51',
relation_settings=base_relation_settings)