Block when RBD Mirroring enabled with incorrect RBD features
If the ``default-rbd-features`` configuration option is not set the correct feature bitmap will be computed automatically. However, if the user has explicitly set the configuration option we will honour that, but block if it does not contain the required bits for RBD Mirroring. Change-Id: I84ab445780d2208dc87c36b1eb8171b27a992a1e
This commit is contained in:
parent
e899641dae
commit
443afd96cc
|
@ -81,11 +81,13 @@ from charmhelpers.core.templating import render
|
|||
from charmhelpers.contrib.storage.linux.ceph import (
|
||||
CephConfContext)
|
||||
from utils import (
|
||||
add_rbd_mirror_features,
|
||||
assert_charm_supports_ipv6,
|
||||
get_cluster_addr,
|
||||
get_networks,
|
||||
get_public_addr,
|
||||
get_rbd_features,
|
||||
has_rbd_mirrors,
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.charmsupport import nrpe
|
||||
|
@ -878,6 +880,17 @@ def assess_status():
|
|||
status_set('waiting', 'Peer units detected, waiting for addresses')
|
||||
return
|
||||
|
||||
configured_rbd_features = config('default-rbd-features')
|
||||
if has_rbd_mirrors() and configured_rbd_features:
|
||||
if add_rbd_mirror_features(
|
||||
configured_rbd_features) != configured_rbd_features:
|
||||
# The configured RBD features bitmap does not contain the features
|
||||
# required for RBD Mirroring
|
||||
status_set('blocked', 'Configuration mismatch: RBD Mirroring '
|
||||
'enabled but incorrect value set for '
|
||||
'``default-rbd-features``')
|
||||
return
|
||||
|
||||
# active - bootstrapped + quorum status check
|
||||
if ceph.is_bootstrapped() and ceph.is_quorum():
|
||||
expected_osd_count = config('expected-osd-count') or 3
|
||||
|
|
|
@ -193,18 +193,27 @@ def get_default_rbd_features():
|
|||
return int(line.split('=')[1].lstrip().rstrip())
|
||||
|
||||
|
||||
def add_rbd_mirror_features(rbd_features):
|
||||
"""Take a RBD Features bitmap and add the features required for Mirroring.
|
||||
|
||||
:param rbd_features: Input bitmap
|
||||
:type rbd_features: int
|
||||
:returns: Bitmap bitwise OR'ed with the features required for Mirroring.
|
||||
:rtype: int
|
||||
"""
|
||||
RBD_FEATURE_EXCLUSIVE_LOCK = 4
|
||||
RBD_FEATURE_JOURNALING = 64
|
||||
return rbd_features | RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING
|
||||
|
||||
|
||||
def get_rbd_features():
|
||||
"""Determine if we should set, and what the rbd default features should be.
|
||||
|
||||
:returns: None or the apropriate value to use
|
||||
:rtype: Option[int, None]
|
||||
"""
|
||||
RBD_FEATURE_EXCLUSIVE_LOCK = 4
|
||||
RBD_FEATURE_JOURNALING = 64
|
||||
|
||||
rbd_feature_config = config('default-rbd-features')
|
||||
if rbd_feature_config:
|
||||
return int(rbd_feature_config)
|
||||
elif has_rbd_mirrors():
|
||||
return (get_default_rbd_features() |
|
||||
RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_JOURNALING)
|
||||
return add_rbd_mirror_features(get_default_rbd_features())
|
||||
|
|
|
@ -49,6 +49,15 @@ class CephUtilsTestCase(test_utils.CharmTestCase):
|
|||
['ceph', '-c', '/dev/null', '--show-config'],
|
||||
universal_newlines=True)
|
||||
|
||||
def test_add_mirror_rbd_features(self):
|
||||
DEFAULT_FEATURES = 61
|
||||
RBD_FEATURE_EXCLUSIVE_LOCK = 4
|
||||
RBD_FEATURE_JOURNALING = 64
|
||||
COMBINED_FEATURES = (DEFAULT_FEATURES | RBD_FEATURE_EXCLUSIVE_LOCK |
|
||||
RBD_FEATURE_JOURNALING)
|
||||
self.assertEqual(utils.add_rbd_mirror_features(DEFAULT_FEATURES),
|
||||
COMBINED_FEATURES)
|
||||
|
||||
@mock.patch.object(utils, 'get_default_rbd_features')
|
||||
@mock.patch.object(utils, 'has_rbd_mirrors')
|
||||
@mock.patch.object(utils, 'config')
|
||||
|
|
|
@ -81,30 +81,51 @@ class ServiceStatusTestCase(test_utils.CharmTestCase):
|
|||
self.status_set.assert_called_with('waiting', mock.ANY)
|
||||
self.application_version_set.assert_called_with('10.2.2')
|
||||
|
||||
@mock.patch.object(hooks, 'has_rbd_mirrors')
|
||||
@mock.patch.object(hooks, 'sufficient_osds')
|
||||
@mock.patch.object(hooks, 'get_peer_units')
|
||||
def test_assess_status_peers_complete_active(self, _peer_units,
|
||||
_sufficient_osds):
|
||||
_sufficient_osds,
|
||||
_has_rbd_mirrors):
|
||||
_peer_units.return_value = ENOUGH_PEERS_COMPLETE
|
||||
_sufficient_osds.return_value = True
|
||||
self.ceph.is_bootstrapped.return_value = True
|
||||
self.ceph.is_quorum.return_value = True
|
||||
_has_rbd_mirrors.return_value = False
|
||||
hooks.assess_status()
|
||||
self.status_set.assert_called_with('active', mock.ANY)
|
||||
self.application_version_set.assert_called_with('10.2.2')
|
||||
|
||||
@mock.patch.object(hooks, 'has_rbd_mirrors')
|
||||
@mock.patch.object(hooks, 'sufficient_osds')
|
||||
@mock.patch.object(hooks, 'get_peer_units')
|
||||
def test_assess_status_peers_complete_down(self, _peer_units,
|
||||
_sufficient_osds):
|
||||
_sufficient_osds,
|
||||
_has_rbd_mirrors):
|
||||
_peer_units.return_value = ENOUGH_PEERS_COMPLETE
|
||||
_sufficient_osds.return_value = True
|
||||
self.ceph.is_bootstrapped.return_value = False
|
||||
self.ceph.is_quorum.return_value = False
|
||||
_has_rbd_mirrors.return_value = False
|
||||
hooks.assess_status()
|
||||
self.status_set.assert_called_with('blocked', mock.ANY)
|
||||
self.application_version_set.assert_called_with('10.2.2')
|
||||
|
||||
@mock.patch.object(hooks, 'has_rbd_mirrors')
|
||||
@mock.patch.object(hooks, 'sufficient_osds')
|
||||
@mock.patch.object(hooks, 'get_peer_units')
|
||||
def test_assess_status_rbd_feature_mismatch(self, _peer_units,
|
||||
_sufficient_osds,
|
||||
_has_rbd_mirrors):
|
||||
_peer_units.return_value = ENOUGH_PEERS_COMPLETE
|
||||
_sufficient_osds.return_value = True
|
||||
self.ceph.is_bootstrapped.return_value = True
|
||||
self.ceph.is_quorum.return_value = True
|
||||
_has_rbd_mirrors.return_value = True
|
||||
self.test_config.set('default-rbd-features', 61)
|
||||
hooks.assess_status()
|
||||
self.status_set.assert_called_once_with('blocked', mock.ANY)
|
||||
|
||||
def test_get_peer_units_no_peers(self):
|
||||
self.relation_ids.return_value = ['mon:1']
|
||||
self.related_units.return_value = []
|
||||
|
|
Loading…
Reference in New Issue