Handle RBD mirroring mode set in the relation
Change-Id: I423eb38f5197879c5f8f7999acb11ece3d26a6a4 Co-authored-by: Marius Oprin <morpin@cloudbasesolutions.com> Signed-off-by: Marius Oprin <moprin@cloudbasesolutions.com>
This commit is contained in:
parent
3b1527df25
commit
3562e11bda
|
@ -126,8 +126,8 @@ class CephRBDMirrorCharm(charms_openstack.plugins.CephCharm):
|
|||
universal_newlines=True)
|
||||
return json.loads(output)
|
||||
|
||||
def mirror_pool_enabled(self, pool):
|
||||
return self._mirror_pool_info(pool).get('mode', None) == 'pool'
|
||||
def mirror_pool_enabled(self, pool, mode='pool'):
|
||||
return self._mirror_pool_info(pool).get('mode', None) == mode
|
||||
|
||||
def mirror_pool_has_peers(self, pool):
|
||||
return len(self._mirror_pool_info(pool).get('peers', [])) > 0
|
||||
|
@ -151,9 +151,9 @@ class CephRBDMirrorCharm(charms_openstack.plugins.CephCharm):
|
|||
stats['image_states'][state] += value
|
||||
return stats
|
||||
|
||||
def mirror_pool_enable(self, pool):
|
||||
def mirror_pool_enable(self, pool, mode='pool'):
|
||||
base_cmd = ['rbd', '--id', self.ceph_id, 'mirror', 'pool']
|
||||
subprocess.check_call(base_cmd + ['enable', pool, 'pool'])
|
||||
subprocess.check_call(base_cmd + ['enable', pool, mode])
|
||||
subprocess.check_call(base_cmd + ['peer', 'add', pool,
|
||||
'client.{}@remote'
|
||||
.format(self.ceph_id)])
|
||||
|
@ -176,6 +176,32 @@ class CephRBDMirrorCharm(charms_openstack.plugins.CephCharm):
|
|||
result_set.add(op['name'])
|
||||
return result_set
|
||||
|
||||
def pool_mirroring_mode(self, pool, broker_requests=[]):
|
||||
"""Get the Ceph RBD mirroring mode for the pool.
|
||||
|
||||
Checks if the pool RBD mirroring mode was explicitly set as part of
|
||||
the 'create-pool' operation into any of the given broker requests.
|
||||
If this is true, its value is returned, otherwise the default 'pool'
|
||||
mirroring mode is used.
|
||||
|
||||
:param pool: Pool name
|
||||
:type pool: str
|
||||
:param broker_requests: List of broker requests
|
||||
:type broker_requests: List[ch_ceph.CephBrokerRq]
|
||||
:returns: Ceph RBD mirroring mode
|
||||
:rtype: str
|
||||
"""
|
||||
default_mirroring_mode = 'pool'
|
||||
for rq in broker_requests:
|
||||
if not rq:
|
||||
continue
|
||||
assert rq.api_version == 1
|
||||
for op in rq.ops:
|
||||
if op['op'] == 'create-pool' and op['name'] == pool:
|
||||
return op.get(
|
||||
'rbd-mirroring-mode', default_mirroring_mode)
|
||||
return default_mirroring_mode
|
||||
|
||||
def collapse_and_filter_broker_requests(self, broker_requests,
|
||||
allowed_ops, require_vp=None):
|
||||
"""Extract allowed ops from broker requests into one collapsed request.
|
||||
|
|
|
@ -117,12 +117,16 @@ def configure_pools():
|
|||
pools_in_rq |= charm_instance.pools_in_broker_request(
|
||||
remote_rq) if remote_rq else set()
|
||||
for pool, attrs in charm_instance.eligible_pools(local.pools).items():
|
||||
if not (charm_instance.mirror_pool_enabled(pool) and
|
||||
charm_instance.mirror_pool_has_peers(pool)):
|
||||
pool_mirroring_mode = charm_instance.pool_mirroring_mode(
|
||||
pool, [rq, remote_rq])
|
||||
mirroring_enabled = charm_instance.mirror_pool_enabled(
|
||||
pool, pool_mirroring_mode)
|
||||
has_peers = charm_instance.mirror_pool_has_peers(pool)
|
||||
if not (mirroring_enabled and has_peers):
|
||||
ch_core.hookenv.log('Enabling mirroring for pool "{}"'
|
||||
.format(pool),
|
||||
level=ch_core.hookenv.INFO)
|
||||
charm_instance.mirror_pool_enable(pool)
|
||||
charm_instance.mirror_pool_enable(pool, pool_mirroring_mode)
|
||||
if (pool not in pools_in_rq and
|
||||
'erasure_code_profile' not in attrs['parameters']):
|
||||
# A pool exists that there is no broker request for which means
|
||||
|
|
|
@ -157,11 +157,17 @@ class TestCephRBDMirrorHandlers(test_utils.PatchHelper):
|
|||
self.patch_object(handlers.reactive, 'endpoint_from_flag')
|
||||
endpoint_local = mock.MagicMock()
|
||||
endpoint_remote = mock.MagicMock()
|
||||
self.crm_charm.collapse_and_filter_broker_requests.side_effect = [
|
||||
endpoint_local, endpoint_remote]
|
||||
endpoint_local.endpoint_name = 'ceph-local'
|
||||
endpoint_local.pools = {
|
||||
'cinder-ceph': {
|
||||
'applications': {'rbd': {}},
|
||||
'parameters': {'pg_num': 42, 'size': 3},
|
||||
'parameters': {
|
||||
'pg_num': 42,
|
||||
'size': 3,
|
||||
'rbd-mirroring-mode': 'pool'
|
||||
},
|
||||
'quota': {'max_bytes': 1024, 'max_objects': 51},
|
||||
},
|
||||
}
|
||||
|
@ -170,6 +176,8 @@ class TestCephRBDMirrorHandlers(test_utils.PatchHelper):
|
|||
endpoint_remote]
|
||||
self.crm_charm.eligible_pools.return_value = endpoint_local.pools
|
||||
self.crm_charm.mirror_pool_enabled.return_value = False
|
||||
self.crm_charm.pool_mirroring_mode.return_value = 'pool'
|
||||
|
||||
handlers.configure_pools()
|
||||
self.endpoint_from_flag.assert_has_calls([
|
||||
mock.call('ceph-local.available'),
|
||||
|
@ -177,8 +185,10 @@ class TestCephRBDMirrorHandlers(test_utils.PatchHelper):
|
|||
])
|
||||
self.crm_charm.eligible_pools.assert_called_once_with(
|
||||
endpoint_local.pools)
|
||||
self.crm_charm.pool_mirroring_mode.assert_called_once_with(
|
||||
'cinder-ceph', [endpoint_local, endpoint_remote])
|
||||
self.crm_charm.mirror_pool_enabled.assert_called_once_with(
|
||||
'cinder-ceph')
|
||||
'cinder-ceph', 'pool')
|
||||
self.crm_charm.mirror_pool_enable.assert_called_once_with(
|
||||
'cinder-ceph')
|
||||
endpoint_remote.maybe_send_rq.assert_called_once_with(mock.ANY)
|
||||
'cinder-ceph', 'pool')
|
||||
endpoint_remote.maybe_send_rq.assert_called_once_with(endpoint_local)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import collections
|
||||
import mock
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
import charms_openstack.test_utils as test_utils
|
||||
|
@ -92,10 +93,10 @@ class TestCephRBDMirrorCharm(Helper):
|
|||
'client.rbd-mirror.juju-c50b1a-zaza-4ce96f1e7e43-12'}]
|
||||
}
|
||||
crmc._mirror_pool_info = _mirror_pool_info
|
||||
self.assertTrue(crmc.mirror_pool_enabled('apool'))
|
||||
self.assertTrue(crmc.mirror_pool_enabled('apool', mode='pool'))
|
||||
_mirror_pool_info.assert_called_once_with('apool')
|
||||
_mirror_pool_info.return_value = {'mode': 'disabled'}
|
||||
self.assertFalse(crmc.mirror_pool_enabled('apool'))
|
||||
self.assertFalse(crmc.mirror_pool_enabled('apool', mode='pool'))
|
||||
|
||||
def test_mirror_pool_has_peers(self):
|
||||
self.patch_object(ceph_rbd_mirror.socket, 'gethostname')
|
||||
|
@ -192,3 +193,55 @@ class TestCephRBDMirrorCharm(Helper):
|
|||
{'app-name': 'rbd', 'name': 'pool-rq2', 'op': 'create-pool',
|
||||
'someotherkey': 'value'})
|
||||
self.assertTrue(len(rq.ops) == 1)
|
||||
|
||||
def test_pool_mirroring_mode(self):
|
||||
self.patch_object(ceph_rbd_mirror.ch_ceph, 'CephBrokerRq')
|
||||
|
||||
class FakeCephBrokerRq(object):
|
||||
def __init__(self, raw_request_data=None):
|
||||
request_data = json.loads(raw_request_data)
|
||||
self.api_version = request_data['api-version']
|
||||
self.request_id = request_data['request-id']
|
||||
self.set_ops(request_data['ops'])
|
||||
|
||||
def set_ops(self, ops):
|
||||
self.ops = ops
|
||||
|
||||
def add_op(self, op):
|
||||
self.ops.append(op)
|
||||
|
||||
self.CephBrokerRq.side_effect = FakeCephBrokerRq
|
||||
|
||||
brq1_data = json.dumps({
|
||||
'api-version': 1,
|
||||
'request-id': 'broker_rq1',
|
||||
'ops': [
|
||||
{
|
||||
'op': 'create-pool',
|
||||
'name': 'pool-rq0',
|
||||
'app-name': 'rbd-pool',
|
||||
'rbd-mirroring-mode': 'pool'
|
||||
},
|
||||
]
|
||||
})
|
||||
brq2_data = json.dumps({
|
||||
'api-version': 1,
|
||||
'request-id': 'broker_rq2',
|
||||
'ops': [
|
||||
{
|
||||
'op': 'create-pool',
|
||||
'name': 'pool-rq1',
|
||||
'app-name': 'rbd-image',
|
||||
'rbd-mirroring-mode': 'image'
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
brq1 = self.CephBrokerRq(raw_request_data=brq1_data)
|
||||
brq2 = self.CephBrokerRq(raw_request_data=brq2_data)
|
||||
broker_requests = [brq1, brq2, None]
|
||||
crmc = ceph_rbd_mirror.CephRBDMirrorCharm()
|
||||
rq0 = crmc.pool_mirroring_mode('pool-rq0', broker_requests)
|
||||
self.assertEqual('pool', rq0)
|
||||
rq1 = crmc.pool_mirroring_mode('pool-rq1', broker_requests)
|
||||
self.assertEqual('image', rq1)
|
||||
|
|
Loading…
Reference in New Issue