From 8bfd5c8b1336f86830c59319893dbca554d92f54 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Thu, 14 Jan 2016 15:25:37 +0000 Subject: [PATCH 1/3] Ad function to get uris when a prefix is being used --- lib/charm/openstack/adapters.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/charm/openstack/adapters.py b/lib/charm/openstack/adapters.py index 2ad31b3..4054348 100644 --- a/lib/charm/openstack/adapters.py +++ b/lib/charm/openstack/adapters.py @@ -78,7 +78,7 @@ class RabbitMQRelationAdapter(OpenStackRelationAdapter): class DatabaseRelationAdapter(OpenStackRelationAdapter): """ - Adapter for the RabbitMQRequires relation interface. + Adapter for the Database relation interface. """ interface_type = "database" @@ -98,14 +98,21 @@ class DatabaseRelationAdapter(OpenStackRelationAdapter): def type(self): return 'mysql' - @property - def uri(self): - uri = 'mysql://{}:{}@{}/{}'.format( - self.username, - self.password, - self.host, - self.database, - ) + def get_uri(self, prefix=None): + if prefix: + uri = 'mysql://{}:{}@{}/{}'.format( + self.relation.username(prefix=prefix), + self.relation.password(prefix=prefix), + self.host, + self.relation.database(prefix=prefix), + ) + else: + uri = 'mysql://{}:{}@{}/{}'.format( + self.username, + self.password, + self.host, + self.database, + ) if self.ssl_ca: uri = '{}?ssl_ca={}'.format(uri, self.ssl_ca) if self.ssl_cert: @@ -114,6 +121,12 @@ class DatabaseRelationAdapter(OpenStackRelationAdapter): return uri + @property + def uri(self): + return self.get_uri() + + + class ConfigurationAdapter(object): """ Configuration Adapter which provides python based access From 65573664a749eb3b556b1c1cfa0faa1e497e641e Mon Sep 17 00:00:00 2001 From: Liam Young Date: Thu, 28 Jan 2016 13:47:06 +0000 Subject: [PATCH 2/3] Mooore into the Charm class --- lib/charm/openstack/charm.py | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lib/charm/openstack/charm.py b/lib/charm/openstack/charm.py index 72e15cf..1840626 100644 --- a/lib/charm/openstack/charm.py +++ b/lib/charm/openstack/charm.py @@ -1,8 +1,10 @@ """Classes to support writing re-usable charms in the reactive framework""" +import os from charmhelpers.contrib.openstack.utils import ( configure_installation_source, ) +from charmhelpers.core.host import path_hash, service_restart from charmhelpers.core.hookenv import config, status_set from charmhelpers.fetch import ( apt_install, @@ -11,6 +13,10 @@ from charmhelpers.fetch import ( ) from charm.openstack.ip import PUBLIC, INTERNAL, ADMIN, canonical_url +from contextlib import contextmanager +from collections import OrderedDict +from charmhelpers.contrib.openstack.templating import get_loader +from charmhelpers.core.templating import render class OpenStackCharm(object): @@ -34,8 +40,12 @@ class OpenStackCharm(object): default_service = None """Default service for the charm""" + restart_map = {} + def __init__(self): self.config = config() + # XXX It's not always liberty! + self.release = 'liberty' def install(self): """ @@ -84,6 +94,33 @@ class OpenStackCharm(object): self.api_port(self.default_service, INTERNAL)) + @contextmanager + def restart_on_change(self): + checksums = {path: path_hash(path) for path in self.restart_map} + yield + restarts = [] + for path in self.restart_map: + if path_hash(path) != checksums[path]: + restarts += self.restart_map[path] + services_list = list(OrderedDict.fromkeys(restarts)) + for service_name in services_list: + service_restart(service_name) + + def render_all_configs(self, adapters): + self.render_configs(adapters, self.restart_map.keys()) + + def render_configs(self, adapters, configs): + with self.restart_on_change(): + for conf in self.restart_map.keys(): + render(source=os.path.basename(conf), + template_loader=get_loader('templates/', self.release), + target=conf, + context=adapters) + + def restart_all(self): + for svc in self.restart_map.keys(): + service_restart(svc) + class OpenStackCharmFactory(object): From d8c27a360054bfce1c1aec9858daccff8d258d85 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Thu, 28 Jan 2016 16:24:51 +0000 Subject: [PATCH 3/3] Updated charm class --- lib/charm/openstack/charm.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/lib/charm/openstack/charm.py b/lib/charm/openstack/charm.py index 1840626..98a50da 100644 --- a/lib/charm/openstack/charm.py +++ b/lib/charm/openstack/charm.py @@ -1,5 +1,6 @@ """Classes to support writing re-usable charms in the reactive framework""" +import subprocess import os from charmhelpers.contrib.openstack.utils import ( configure_installation_source, @@ -17,6 +18,7 @@ from contextlib import contextmanager from collections import OrderedDict from charmhelpers.contrib.openstack.templating import get_loader from charmhelpers.core.templating import render +from charmhelpers.core.hookenv import leader_get, leader_set class OpenStackCharm(object): @@ -41,11 +43,16 @@ class OpenStackCharm(object): """Default service for the charm""" restart_map = {} + sync_cmd = [] + services = [] + adapters_class = None - def __init__(self): + def __init__(self, interfaces=None): self.config = config() # XXX It's not always liberty! self.release = 'liberty' + if interfaces and self.adapters_class: + self.adapter_instance = self.adapters_class(interfaces) def install(self): """ @@ -106,21 +113,30 @@ class OpenStackCharm(object): for service_name in services_list: service_restart(service_name) - def render_all_configs(self, adapters): - self.render_configs(adapters, self.restart_map.keys()) + def render_all_configs(self): + self.render_configs(self.adapters, self.restart_map.keys()) - def render_configs(self, adapters, configs): + def render_configs(self, configs): with self.restart_on_change(): - for conf in self.restart_map.keys(): + for conf in configs: render(source=os.path.basename(conf), template_loader=get_loader('templates/', self.release), target=conf, - context=adapters) + context=self.adapter_instance) def restart_all(self): - for svc in self.restart_map.keys(): + for svc in self.services: service_restart(svc) + def db_sync(self): + sync_done = leader_get(attribute='db-sync-done') + if not sync_done: + subprocess.check_call(self.sync_cmd) + leader_set({'db-sync-done': True}) + # Restart services immediatly after db sync as + # render_domain_config needs a working system + self.restart_all() + class OpenStackCharmFactory(object): @@ -136,12 +152,12 @@ class OpenStackCharmFactory(object): """ @classmethod - def charm(cls, release=None): + def charm(cls, release=None, interfaces=None): """ Get an instance of the right charm for the configured OpenStack series """ if release and release in cls.releases: - return cls.releases[release]() + return cls.releases[release](interfaces=interfaces) else: - return cls.releases[cls.first_release]() + return cls.releases[cls.first_release](interfaces=interfaces)