diff --git a/hooks/cinder_contexts.py b/hooks/cinder_contexts.py index a4c8d3ab..4b699780 100644 --- a/hooks/cinder_contexts.py +++ b/hooks/cinder_contexts.py @@ -2,6 +2,8 @@ from charmhelpers.core.hookenv import ( config, relation_ids, service_name, + related_units, + relation_get, ) from charmhelpers.contrib.openstack.context import ( @@ -83,3 +85,20 @@ class ApacheSSLContext(SSLContext): if not service_enabled('cinder-api'): return {} return super(ApacheSSLContext, self).__call__() + + +class StorageBackendContext(OSContextGenerator): + interfaces = ['storage-backend'] + + def __call__(self): + backends = [] + for rid in relation_ids('storage-backend'): + for unit in related_units(rid): + backend_name = relation_get('backend_name', + unit, rid) + if backend_name: + backends.append(backend_name) + if len(backends) > 0: + return {'backends': ",".join(backends)} + else: + return {} diff --git a/hooks/cinder_hooks.py b/hooks/cinder_hooks.py index d21f1011..28581ee8 100755 --- a/hooks/cinder_hooks.py +++ b/hooks/cinder_hooks.py @@ -316,6 +316,13 @@ def upgrade_charm(): amqp_joined(relation_id=rel_id) +@hooks.hook('storage-backend-relation-changed') +@hooks.hook('storage-backend-relation-broken') +@restart_on_change(restart_map()) +def storage_backend(): + CONFIGS.write(CINDER_CONF) + + if __name__ == '__main__': try: hooks.execute(sys.argv) diff --git a/hooks/cinder_utils.py b/hooks/cinder_utils.py index 27e85bf3..58dda88b 100644 --- a/hooks/cinder_utils.py +++ b/hooks/cinder_utils.py @@ -119,7 +119,12 @@ CONFIG_FILES = OrderedDict([ context.SyslogContext(), cinder_contexts.CephContext(), cinder_contexts.HAProxyContext(), - cinder_contexts.ImageServiceContext()], + cinder_contexts.ImageServiceContext(), + context.SubordinateConfigContext( + interface='storage-backend', + service='cinder', + config_file=CINDER_CONF), + cinder_contexts.StorageBackendContext()], 'services': ['cinder-api', 'cinder-volume', 'cinder-scheduler', 'haproxy'] }), diff --git a/hooks/storage-backend-relation-broken b/hooks/storage-backend-relation-broken new file mode 120000 index 00000000..6dcd0084 --- /dev/null +++ b/hooks/storage-backend-relation-broken @@ -0,0 +1 @@ +cinder_hooks.py \ No newline at end of file diff --git a/hooks/storage-backend-relation-changed b/hooks/storage-backend-relation-changed new file mode 120000 index 00000000..6dcd0084 --- /dev/null +++ b/hooks/storage-backend-relation-changed @@ -0,0 +1 @@ +cinder_hooks.py \ No newline at end of file diff --git a/hooks/storage-backend-relation-departed b/hooks/storage-backend-relation-departed new file mode 120000 index 00000000..6dcd0084 --- /dev/null +++ b/hooks/storage-backend-relation-departed @@ -0,0 +1 @@ +cinder_hooks.py \ No newline at end of file diff --git a/hooks/storage-backend-relation-joined b/hooks/storage-backend-relation-joined new file mode 120000 index 00000000..6dcd0084 --- /dev/null +++ b/hooks/storage-backend-relation-joined @@ -0,0 +1 @@ +cinder_hooks.py \ No newline at end of file diff --git a/metadata.yaml b/metadata.yaml index 2aba29b6..451898dc 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -24,6 +24,9 @@ requires: ha: interface: hacluster scope: container + storage-backend: + interface: cinder-backend + scope: container peers: cluster: interface: cinder-ha diff --git a/templates/cinder.conf b/templates/cinder.conf index c16f28ad..340ef0b4 100644 --- a/templates/cinder.conf +++ b/templates/cinder.conf @@ -62,3 +62,4 @@ glance_api_version = {{ glance_api_version }} {% endfor -%} {% endif -%} +{% include "parts/backends" %} diff --git a/templates/grizzly/cinder.conf b/templates/grizzly/cinder.conf index 3da554c3..4dee7899 100644 --- a/templates/grizzly/cinder.conf +++ b/templates/grizzly/cinder.conf @@ -53,3 +53,4 @@ glance_api_version = {{ glance_api_version }} {% endfor -%} {% endif -%} +{% include "parts/backends" %} diff --git a/templates/icehouse/cinder.conf b/templates/icehouse/cinder.conf index 92c5e0f2..1a7338a9 100644 --- a/templates/icehouse/cinder.conf +++ b/templates/icehouse/cinder.conf @@ -50,4 +50,6 @@ glance_api_version = {{ glance_api_version }} {% endfor -%} {% endif -%} +{% include "parts/backends" %} + {% include "parts/section-database" %} diff --git a/templates/parts/backends b/templates/parts/backends new file mode 100644 index 00000000..887fd7c4 --- /dev/null +++ b/templates/parts/backends @@ -0,0 +1,18 @@ +{% if sections and 'DEFAULT' in sections -%} +{% for key, value in sections['DEFAULT'] -%} +{{ key }} = {{ value }} +{% endfor -%} +{% endif -%} + +{% if backends -%} +enabled_backends = {{ backends }} +{% endif -%} + +{% for section in sections -%} +{% if section != 'DEFAULT' -%} +[{{ section }}] +{% for key, value in sections[section] -%} +{{ key }} = {{ value }} +{% endfor -%} +{% endif -%} +{% endfor -%} \ No newline at end of file diff --git a/unit_tests/test_cinder_contexts.py b/unit_tests/test_cinder_contexts.py index 7f0e0470..13f11f05 100644 --- a/unit_tests/test_cinder_contexts.py +++ b/unit_tests/test_cinder_contexts.py @@ -16,7 +16,9 @@ TO_PATCH = [ 'service_name', 'determine_apache_port', 'determine_api_port', - 'get_os_codename_install_source' + 'get_os_codename_install_source', + 'related_units', + 'relation_get' ] @@ -74,6 +76,25 @@ class TestCinderContext(CharmTestCase): service_enabled.return_value = False self.assertEquals(contexts.ApacheSSLContext()(), {}) + def test_storage_backend_no_backends(self): + self.relation_ids.return_value = [] + self.assertEquals(contexts.StorageBackendContext()(), {}) + + def test_storage_backend_single_backend(self): + self.relation_ids.return_value = ['cinder-ceph:0'] + self.related_units.return_value = ['cinder-ceph/0'] + self.relation_get.return_value = 'cinder-ceph' + self.assertEquals(contexts.StorageBackendContext()(), + {'backends': 'cinder-ceph'}) + + def test_storage_backend_multi_backend(self): + self.relation_ids.return_value = ['cinder-ceph:0', 'cinder-vmware:0'] + self.related_units.side_effect = [['cinder-ceph/0'], + ['cinder-vmware/0']] + self.relation_get.side_effect = ['cinder-ceph', 'cinder-vmware'] + self.assertEquals(contexts.StorageBackendContext()(), + {'backends': 'cinder-ceph,cinder-vmware'}) + @patch('charmhelpers.contrib.openstack.context.is_clustered') @patch('charmhelpers.contrib.openstack.context.determine_apache_port') @patch('charmhelpers.contrib.openstack.context.determine_api_port') diff --git a/unit_tests/test_cinder_hooks.py b/unit_tests/test_cinder_hooks.py index 73a3a96e..580927d0 100644 --- a/unit_tests/test_cinder_hooks.py +++ b/unit_tests/test_cinder_hooks.py @@ -253,6 +253,14 @@ class TestChangedHooks(CharmTestCase): hooks.hooks.execute(['hooks/image-service-relation-broken']) self.assertTrue(self.CONFIGS.write_all.called) + def test_storage_backend_changed(self): + hooks.hooks.execute(['hooks/storage-backend-relation-changed']) + self.CONFIGS.write.assert_called_with(utils.CINDER_CONF) + + def test_storage_backend_broken(self): + hooks.hooks.execute(['hooks/storage-backend-relation-broken']) + self.CONFIGS.write.assert_called_with(utils.CINDER_CONF) + class TestJoinedHooks(CharmTestCase):