Fix assess status for super-conductor

In a cells deployment its possible that the top-level
nova-cloud-controller will have no compute nodes associated with it.
This change fixes the work load status in that scenario.

There is also a drive by fix to return empty contexts for the cell
db and amqp contexts if the relation do not yet exists.

Change-Id: Ia8eeccb6794dd016185eb0cfb05339b76cef9348
This commit is contained in:
Liam Young 2018-10-08 12:30:22 +00:00
parent fabc0c9dbb
commit 0f9ada1713
4 changed files with 65 additions and 3 deletions

View File

@ -75,6 +75,23 @@ class ApacheSSLContext(context.ApacheSSLContext):
return super(ApacheSSLContext, self).__call__()
class NovaCellV2Context(context.OSContextGenerator):
interfaces = ['nova-cell-api']
def __call__(self):
ctxt = {}
required_keys = ['cell-name', 'amqp-service', 'db-service']
for rid in relation_ids('nova-cell-api'):
for unit in related_units(rid):
data = relation_get(rid=rid, unit=unit)
if set(required_keys).issubset(data.keys()):
ctxt[data['cell-name']] = {
'amqp_service': data['amqp-service'],
'db_service': data['db-service']}
return ctxt
class NovaCellV2SharedDBContext(context.OSContextGenerator):
interfaces = ['shared-db']

View File

@ -124,7 +124,7 @@ REQUIRED_INTERFACES = {
'messaging': ['amqp'],
'identity': ['identity-service'],
'image': ['image-service'],
'compute': ['nova-compute'],
'compute': ['nova-compute', 'nova-cell-api'],
}
# removed from original: charm-helper-sh
@ -1364,6 +1364,9 @@ def assess_status(configs):
@param configs: a templating.OSConfigRenderer() object
@returns None - this function is executed for its side-effect
"""
# Add the cell context as its not used for rendering files, only for
# assessing status.
configs.register('', [nova_cc_context.NovaCellV2Context()])
assess_status_func(configs)()
os_application_version_set(VERSION_PACKAGE)
@ -1515,6 +1518,8 @@ def get_cell_db_context(db_service):
db_rid = relation_id(
relation_name='shared-db-cell',
service_or_unit=db_service)
if not db_rid:
return {}
return context.SharedDBContext(
relation_prefix='nova',
ssl_dir=NOVA_CONF_DIR,
@ -1526,6 +1531,8 @@ def get_cell_amqp_context(amqp_service):
amq_rid = relation_id(
relation_name='amqp-cell',
service_or_unit=amqp_service)
if not amq_rid:
return {}
return context.AMQPContext(
ssl_dir=NOVA_CONF_DIR,
relation_id=amq_rid)()

View File

@ -438,3 +438,40 @@ class NovaComputeContextTests(CharmTestCase):
ctxt = context.NovaMetadataContext()()
self.assertEqual(ctxt, {'enable_metadata': False})
def test_NovaCellV2Context(self):
settings = {'cell-name': 'cell32',
'amqp-service': 'rabbitmq-cell2',
'db-service': 'percona-cell2'}
def fake_rel_get(attribute=None, unit=None, rid=None):
if attribute:
return settings.get(attribute)
return settings
self.relation_get.side_effect = fake_rel_get
self.relation_ids.return_value = ['nova-cell:0']
self.related_units.return_value = ['nova-cell-conductor/0']
ctxt = context.NovaCellV2Context()()
self.assertEqual(
ctxt,
{'cell32': {
'amqp_service': 'rabbitmq-cell2',
'db_service': 'percona-cell2'}})
def test_NovaCellV2Context_missing_amqp(self):
settings = {'cell-name': 'cell32',
'db-service': 'percona-cell2'}
def fake_rel_get(attribute=None, unit=None, rid=None):
if attribute:
return settings.get(attribute)
return settings
self.relation_get.side_effect = fake_rel_get
self.relation_ids.return_value = ['nova-cell:0']
self.related_units.return_value = ['nova-cell-conductor/0']
ctxt = context.NovaCellV2Context()()
self.assertEqual(ctxt, {})

View File

@ -1035,10 +1035,11 @@ class NovaCCUtilsTests(CharmTestCase):
def test_assess_status(self):
with patch.object(utils, 'assess_status_func') as asf:
configs = MagicMock()
callee = MagicMock()
asf.return_value = callee
utils.assess_status('test-config')
asf.assert_called_once_with('test-config')
utils.assess_status(configs)
asf.assert_called_once_with(configs)
callee.assert_called_once_with()
self.os_application_version_set.assert_called_with(
utils.VERSION_PACKAGE