Update manila to support new interface for configuration

The manila-plugin interface is changed to make writing configuration
plugin charms easier to write.  This updates the manila charm to support
that interface.

Change-Id: I260ce1d1287a7127838198d5aefea64454de8d3c
Depends-On: I76866007e3c89bb16bc7985a692fbd8f3e136a71
This commit is contained in:
Alex Kavanagh 2017-02-03 17:40:33 +00:00
parent fdd1e1a70f
commit 417a70eb01
5 changed files with 97 additions and 61 deletions

View File

@ -307,28 +307,56 @@ class ManilaCharm(charms_openstack.charm.HAOpenStackCharm):
"""Return the list of configuration lines for `config_file` as returned
by manila-plugin backend charms.
TODO: Note that it is not clear how we get this from multiple plugin
charms -- still to be worked out
The configuration from the adapter looks like:
{
"<name1>": {
"<config file path>": <string>,
"<config file path 2>": <string>
},
"<name2>": {
"<config file path>": <string>,
},
}
:param config_file: string, filename for configuration lines
:returns: list of strings: config lines for `config_file`
"""
adapter = self.get_adapter('manila-plugin.available')
if adapter is not None:
# get the configuration data for all plugins
config_data = adapter.relation.get_configuration_data()
if config_file not in config_data:
return []
config_lines = []
for section, lines in config_data[config_file].items():
if section == 'complete':
# if the 'lines' is not truthy, then this conf isn't
# complete, so just break out.
if not lines:
break
continue
config_lines.append(section)
config_lines.extend(lines)
config_lines.append('')
return config_lines
return []
if adapter is None:
return []
# get the configuration data for all plugins
config_data = adapter.relation.get_configuration_data()
# make the config_data <config_file>: {<name>: string} format
inverted_config_data = {}
for name, config_files in config_data.items():
for file, data in config_files.items():
if file not in inverted_config_data:
inverted_config_data[file] = {}
inverted_config_data[file][name] = data
# now see if it's the one we want
if config_file not in inverted_config_data:
return []
config_lines = []
for name, chunk in inverted_config_data[config_file].items():
config_lines.append(chunk)
config_lines.append('')
return config_lines
def config_files(self):
"""Return a set of all the config files that want to be written by the
subordinate charms.
:returns: [list of config files]
"""
adapter = self.get_adapter('manila-plugin.available')
if adapter is None:
return []
# get the configuration data for all plugins
config_data = adapter.relation.get_configuration_data()
config_files = set()
for name, data in config_data.items():
for config_file, chunks in data.items():
config_files.add(config_file)
return list(config_files)

View File

@ -31,11 +31,13 @@ charms_openstack.charm.use_defaults(
# 'identity-service.connected',
'identity-service.available', # enables SSL support
# 'config.changed',
# 'update-status'
'update-status'
)
@charms.reactive.when('identity-service.connected')
@charms.reactive.when_not('identity-service.available',
'update-status')
def register_endpoints(keystone):
"""Register the endpoints when the identity-service connects.
Note that this charm doesn't use the default endpoint registration function
@ -49,12 +51,13 @@ def register_endpoints(keystone):
@charms.reactive.when('identity-service.connected',
'manila-plugin.connected')
def share_to_manila_plugins_auth(keystone, manila_plugin):
@charms.reactive.when_not('update-status')
def share_to_manila_plugins_auth(keystone, manila_plugin, *args):
"""When we have the identity-service and (a) backend plugin, share the auth
plugin with the back end.
TODO: if we have multiple manila-plugin's does this get called for each
relation that gets connected?
Note that the interface deals with ensurign that each plugin gets the same
data.
"""
data = {
'username': keystone.service_username(),
@ -78,6 +81,7 @@ def share_to_manila_plugins_auth(keystone, manila_plugin):
@charms.reactive.when('shared-db.available',
'manila.config.rendered')
@charms.reactive.when_not('update-status')
def maybe_do_syncdb(shared_db):
"""Sync the database when the shared-db becomes available. Note that the
charms.openstack.OpenStackCharm.db_sync() default method checks that only
@ -92,20 +96,31 @@ def maybe_do_syncdb(shared_db):
@charms.reactive.when('shared-db.available',
'identity-service.available',
'amqp.available')
@charms.reactive.when_not('update-status')
def render_stuff(*args):
"""Render the configuration for Manila when all the interfaces are
available.
Note that the charm class actually calls on the manila-plugin directly to
get the config, so we unconditionally clear the changed status here, if it
was set.
"""
with charms_openstack.charm.provide_charm_instance() as manila_charm:
manila_charm.render_with_interfaces(args)
manila_charm.assess_status()
charms.reactive.set_state('manila.config.rendered')
manila_plugin = charms.reactive.RelationBase.from_state(
'manila-plugin.changed')
if manila_plugin:
manila_plugin.clear_changed()
@charms.reactive.when('config.changed',
'shared-db.available',
@charms.reactive.when('shared-db.available',
'identity-service.available',
'amqp.available')
@charms.reactive.when_any('config-changed',
'manila-plugin.changed')
@charms.reactive.when_not('update-status')
def config_changed(*args):
"""When the configuration is changed, check that we have all the interfaces
and then re-render all the configuration files. Note that this means that

View File

@ -64,8 +64,7 @@ class ManilaBasicDeployment(OpenStackAmuletDeployment):
'constraints': {'mem': '3072M'}},
{'name': 'rabbitmq-server'},
{'name': 'keystone'},
{'name': 'manila-generic',
'location': 'cs:~ajkavanagh/xenial/manila-generic-1'}
{'name': 'manila-generic'}
]
super(ManilaBasicDeployment, self)._add_services(
this_service, other_services)

View File

@ -248,36 +248,13 @@ class TestManilaCharm(Helper):
self.out.relation.get_configuration_data.return_value = {}
self.assertEqual(c.config_lines_for('conf'), [])
config = {
'conf': {
'complete': True,
'[section1]': (
'line1', 'line2'),
'[section2]': (
'line3', ),
},
'conf2': {
'complete': True,
'[section3]': (
'line4', 'line5'),
},
'conf3': {
'complete': False,
'[section4]': (
'line6', 'line7'),
'other-end': {
'conf': "conf-string",
'conf2': "conf2-string",
'conf3': "conf3-string",
}
}
self.out.relation.get_configuration_data.return_value = config
self.assertEqual(c.config_lines_for('conf'), [
'[section1]',
'line1',
'line2',
'',
'[section2]',
'line3',
''])
self.assertEqual(c.config_lines_for('conf2'), [
'[section3]',
'line4',
'line5',
''])
self.assertEqual(c.config_lines_for('conf3'), [])
self.assertEqual(c.config_lines_for('conf'), ["conf-string", ''])
self.assertEqual(c.config_lines_for('conf2'), ["conf2-string", ''])
self.assertEqual(c.config_lines_for('conf3'), ["conf3-string", ''])

View File

@ -41,11 +41,23 @@ class TestRegisteredHooks(test_utils.TestRegisteredHooks):
'manila-plugin.connected', ),
'maybe_do_syncdb': ('shared-db.available',
'manila.config.rendered', ),
'config_changed': ('config.changed',
'shared-db.available',
'config_changed': ('shared-db.available',
'identity-service.available',
'amqp.available', )
}
},
'when_not': {
'register_endpoints': ('identity-service.available',
'update-status', ),
'config_changed': ('update-status', ),
'render_stuff': ('update-status', ),
'share_to_manila_plugins_auth': ('update-status', ),
'maybe_do_syncdb': ('update-status', ),
},
'when_any': {
'config_changed': ('config-changed',
'manila-plugin.changed', ),
},
}
# test that the hooks were registered via the
# reactive.barbican_handlers
@ -78,11 +90,16 @@ class TestRenderStuff(test_utils.PatchHelper):
manila_charm = self._patch_provide_charm_instance()
self.patch('charms.reactive.set_state', name='set_state')
manila_plugin = mock.MagicMock()
self.patch('charms.reactive.RelationBase.from_state',
name='from_state',
return_value=manila_plugin)
handlers.render_stuff('arg1', 'arg2')
manila_charm.render_with_interfaces.assert_called_once_with(
('arg1', 'arg2', ))
manila_charm.assess_status.assert_called_once_with()
self.set_state.assert_called_once_with('manila.config.rendered')
manila_plugin.clear_changed.assert_called_once_with()
def test_config_changed(self):
self.patch_object(handlers, 'render_stuff')