diff --git a/charm-helpers-hooks.yaml b/charm-helpers-hooks.yaml index e8d393c9..b7008eaa 100644 --- a/charm-helpers-hooks.yaml +++ b/charm-helpers-hooks.yaml @@ -1,4 +1,4 @@ -branch: lp:charm-helpers +branch: lp:~openstack-charmers/charm-helpers/0mq destination: hooks/charmhelpers include: - core diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index d41b74a2..988bef19 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -21,6 +21,7 @@ from charmhelpers.core.hookenv import ( relation_get, relation_ids, related_units, + is_relation_made, relation_set, unit_get, unit_private_ip, @@ -787,3 +788,16 @@ class SyslogContext(OSContextGenerator): 'use_syslog': config('use-syslog') } return ctxt + + +class ZeroMQContext(OSContextGenerator): + interfaces = ['zeromq-configuration'] + + def __call__(self): + ctxt = {} + if is_relation_made('zeromq-configuration', 'host'): + for rid in relation_ids('zeromq-configuration'): + for unit in related_units(rid): + ctxt['zmq_nonce'] = relation_get('nonce', unit, rid) + ctxt['zmq_host'] = relation_get('host', unit, rid) + return ctxt \ No newline at end of file diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index 20943c20..23d237de 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -70,6 +70,7 @@ SWIFT_CODENAMES = OrderedDict([ ('1.13.0', 'icehouse'), ('1.12.0', 'icehouse'), ('1.11.0', 'icehouse'), + ('2.0.0', 'juno'), ]) DEFAULT_LOOPBACK_SIZE = '5G' diff --git a/hooks/charmhelpers/core/hookenv.py b/hooks/charmhelpers/core/hookenv.py index eb4aa092..f396e03a 100644 --- a/hooks/charmhelpers/core/hookenv.py +++ b/hooks/charmhelpers/core/hookenv.py @@ -156,12 +156,15 @@ def hook_name(): class Config(dict): - """A Juju charm config dictionary that can write itself to - disk (as json) and track which values have changed since - the previous hook invocation. + """A dictionary representation of the charm's config.yaml, with some + extra features: - Do not instantiate this object directly - instead call - ``hookenv.config()`` + - See which values in the dictionary have changed since the previous hook. + - For values that have changed, see what the previous value was. + - Store arbitrary data for use in a later hook. + + NOTE: Do not instantiate this object directly - instead call + ``hookenv.config()``, which will return an instance of :class:`Config`. Example usage:: @@ -170,8 +173,8 @@ class Config(dict): >>> config = hookenv.config() >>> config['foo'] 'bar' + >>> # store a new key/value for later use >>> config['mykey'] = 'myval' - >>> config.save() >>> # user runs `juju set mycharm foo=baz` @@ -188,22 +191,23 @@ class Config(dict): >>> # keys/values that we add are preserved across hooks >>> config['mykey'] 'myval' - >>> # don't forget to save at the end of hook! - >>> config.save() """ CONFIG_FILE_NAME = '.juju-persistent-config' def __init__(self, *args, **kw): super(Config, self).__init__(*args, **kw) + self.implicit_save = True self._prev_dict = None self.path = os.path.join(charm_dir(), Config.CONFIG_FILE_NAME) if os.path.exists(self.path): self.load_previous() def load_previous(self, path=None): - """Load previous copy of config from disk so that current values - can be compared to previous values. + """Load previous copy of config from disk. + + In normal usage you don't need to call this method directly - it + is called automatically at object initialization. :param path: @@ -218,8 +222,8 @@ class Config(dict): self._prev_dict = json.load(f) def changed(self, key): - """Return true if the value for this key has changed since - the last save. + """Return True if the current value for this key is different from + the previous value. """ if self._prev_dict is None: @@ -228,7 +232,7 @@ class Config(dict): def previous(self, key): """Return previous value for this key, or None if there - is no "previous" value. + is no previous value. """ if self._prev_dict: @@ -238,7 +242,13 @@ class Config(dict): def save(self): """Save this config to disk. - Preserves items in _prev_dict that do not exist in self. + If the charm is using the :mod:`Services Framework ` + or :meth:'@hook ' decorator, this + is called automatically at the end of successful hook execution. + Otherwise, it should be called directly by user code. + + To disable automatic saves, set ``implicit_save=False`` on this + instance. """ if self._prev_dict: @@ -478,6 +488,9 @@ class Hooks(object): hook_name = os.path.basename(args[0]) if hook_name in self._hooks: self._hooks[hook_name]() + cfg = config() + if cfg.implicit_save: + cfg.save() else: raise UnregisteredHookError(hook_name) diff --git a/hooks/charmhelpers/core/services/base.py b/hooks/charmhelpers/core/services/base.py index 6b5a1b9f..87ecb130 100644 --- a/hooks/charmhelpers/core/services/base.py +++ b/hooks/charmhelpers/core/services/base.py @@ -118,6 +118,9 @@ class ServiceManager(object): else: self.provide_data() self.reconfigure_services() + cfg = hookenv.config() + if cfg.implicit_save: + cfg.save() def provide_data(self): """ diff --git a/hooks/nova_cc_hooks.py b/hooks/nova_cc_hooks.py index 39e7b1f9..01aeb23e 100755 --- a/hooks/nova_cc_hooks.py +++ b/hooks/nova_cc_hooks.py @@ -59,6 +59,7 @@ from nova_cc_utils import ( migrate_database, neutron_plugin, save_script_rc, + services, ssh_compute_add, ssh_compute_remove, ssh_known_hosts_lines, @@ -74,6 +75,7 @@ from nova_cc_utils import ( console_attributes, service_guard, guard_map, + get_topics, ) from charmhelpers.contrib.hahelpers.cluster import ( @@ -132,7 +134,8 @@ def config_changed(): for rid in relation_ids('cloud-compute')] for r_id in relation_ids('identity-service'): identity_joined(rid=r_id) - + for rid in relation_ids('zeromq-configuration'): + zeromq_configuration_relation_joined(rid) @hooks.hook('amqp-relation-joined') def amqp_joined(relation_id=None): @@ -698,6 +701,19 @@ def neutron_api_relation_broken(): quantum_joined(rid=rid) +@hooks.hook('zeromq-configuration-relation-joined') +def zeromq_configuration_relation_joined(relid=None): + relation_set(relation_id=relid, + topics=" ".join(get_topics()), + users="nova") + + +@hooks.hook('zeromq-configuration-relation-changed') +@restart_on_change(restart_map(), stopstart=True) +def zeromq_configuration_relation_changed(): + CONFIGS.write(NOVA_CONF) + + def main(): try: hooks.execute(sys.argv) diff --git a/hooks/nova_cc_utils.py b/hooks/nova_cc_utils.py index 98301eea..ad37496d 100644 --- a/hooks/nova_cc_utils.py +++ b/hooks/nova_cc_utils.py @@ -108,7 +108,8 @@ BASE_RESOURCE_MAP = OrderedDict([ context.SyslogContext(), nova_cc_context.HAProxyContext(), nova_cc_context.IdentityServiceContext(), - nova_cc_context.VolumeServiceContext()], + nova_cc_context.VolumeServiceContext(), + context.ZeroMQContext()], }), (NOVA_API_PASTE, { 'services': [s for s in BASE_SERVICES if 'api' in s], @@ -859,3 +860,10 @@ def service_guard(guard_map, contexts, active=False): f(*args) return wrapped_f return wrap + + +def get_topics(): + topics = ['scheduler'] + if 'nova-consoleauth' in services(): + topics.append('consoleauth') + return topics diff --git a/hooks/zeromq-configuration-relation-changed b/hooks/zeromq-configuration-relation-changed new file mode 120000 index 00000000..f6702415 --- /dev/null +++ b/hooks/zeromq-configuration-relation-changed @@ -0,0 +1 @@ +nova_cc_hooks.py \ No newline at end of file diff --git a/hooks/zeromq-configuration-relation-joined b/hooks/zeromq-configuration-relation-joined new file mode 120000 index 00000000..f6702415 --- /dev/null +++ b/hooks/zeromq-configuration-relation-joined @@ -0,0 +1 @@ +nova_cc_hooks.py \ No newline at end of file diff --git a/metadata.yaml b/metadata.yaml index e11b0571..2dd6380d 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -38,6 +38,9 @@ requires: nova-vmware: interface: nova-vmware scope: container + zeromq-configuration: + interface: zeromq-configuration + scope: container peers: cluster: interface: nova-ha diff --git a/templates/icehouse/nova.conf b/templates/icehouse/nova.conf index ec8b72e6..e7fac254 100644 --- a/templates/icehouse/nova.conf +++ b/templates/icehouse/nova.conf @@ -30,6 +30,8 @@ keystone_ec2_url = {{ keystone_ec2_url }} {% include "parts/rabbitmq" %} +{% include "parts/zeromq" %} + {% if glance_api_servers -%} glance_api_servers = {{ glance_api_servers }} {% endif -%} diff --git a/templates/parts/zeromq b/templates/parts/zeromq new file mode 100644 index 00000000..3e32288c --- /dev/null +++ b/templates/parts/zeromq @@ -0,0 +1,6 @@ +{% if zmq_host -%} +# ZeroMQ configuration (restart-nonce: {{ zmq_nonce }}) +rpc_backend = zmq +rpc_zmq_matchmaker = oslo.messaging._drivers.matchmaker_ring.MatchMakerRing +rpc_zmq_host = {{ zmq_host }} +{% endif -%}