From ffdc2f4aa43483e89cfe5cd3772b91802ec774fc Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 9 Sep 2014 13:03:02 +0000 Subject: [PATCH] Add 0mq support --- charm-helpers-hooks.yaml | 2 +- .../charmhelpers/contrib/openstack/context.py | 14 +++++++ hooks/charmhelpers/contrib/openstack/utils.py | 1 + hooks/charmhelpers/core/hookenv.py | 41 ++++++++++++------- hooks/charmhelpers/core/services/base.py | 3 ++ hooks/quantum_hooks.py | 17 ++++++++ hooks/quantum_utils.py | 17 +++++++- hooks/zeromq-configuration-relation-changed | 1 + hooks/zeromq-configuration-relation-joined | 1 + metadata.yaml | 3 ++ templates/icehouse/neutron.conf | 3 +- templates/parts/zeromq | 6 +++ 12 files changed, 92 insertions(+), 17 deletions(-) create mode 120000 hooks/zeromq-configuration-relation-changed create mode 120000 hooks/zeromq-configuration-relation-joined create mode 100644 templates/parts/zeromq diff --git a/charm-helpers-hooks.yaml b/charm-helpers-hooks.yaml index 1a98c81c..3e16f32a 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/quantum_hooks.py b/hooks/quantum_hooks.py index af048362..a86b2ab1 100755 --- a/hooks/quantum_hooks.py +++ b/hooks/quantum_hooks.py @@ -41,6 +41,7 @@ from quantum_utils import ( get_packages, get_early_packages, get_common_package, + get_topics, valid_plugin, configure_ovs, reassign_agent_resources, @@ -85,6 +86,8 @@ def config_changed(): amqp_joined(relation_id=r_id) for r_id in relation_ids('amqp-nova'): amqp_nova_joined(relation_id=r_id) + for rid in relation_ids('zeromq-configuration'): + zeromq_configuration_relation_joined(rid) if valid_plugin(): CONFIGS.write_all() configure_ovs() @@ -195,6 +198,20 @@ def cluster_departed(): def stop(): stop_services() + +@hooks.hook('zeromq-configuration-relation-joined') +def zeromq_configuration_relation_joined(relid=None): + relation_set(relation_id=relid, + topics=" ".join(get_topics()), + users="neutron") + + +@hooks.hook('zeromq-configuration-relation-changed') +@restart_on_change(restart_map(), stopstart=True) +def zeromq_configuration_relation_changed(): + CONFIGS.write_all() + + if __name__ == '__main__': try: hooks.execute(sys.argv) diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index 57ec670e..f9b31e3e 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -227,7 +227,8 @@ QUANTUM_OVS_CONFIG_FILES = { QUANTUM_CONF: { 'hook_contexts': [context.AMQPContext(ssl_dir=QUANTUM_CONF_DIR), QuantumGatewayContext(), - SyslogContext()], + SyslogContext(), + context.ZeroMQContext()], 'services': ['quantum-l3-agent', 'quantum-dhcp-agent', 'quantum-metadata-agent', @@ -532,3 +533,17 @@ def configure_ovs(): ext_port_ctx = ExternalPortContext()() if ext_port_ctx is not None and ext_port_ctx['ext_port']: add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port']) + + +def get_topics(): + # metering_agent + topics = [] + if 'neutron-l3-agent' in services(): + topics.append('l3_agent') + if 'neutron-dhcp-agent' in services(): + topics.append('dhcp_agent') + if 'neutron-metering-agent' in services(): + topics.append('metering_agent') + if 'neutron-lbaas-agent' in services(): + topics.append('n-lbaas_agent') + return topics diff --git a/hooks/zeromq-configuration-relation-changed b/hooks/zeromq-configuration-relation-changed new file mode 120000 index 00000000..9a2da58e --- /dev/null +++ b/hooks/zeromq-configuration-relation-changed @@ -0,0 +1 @@ +quantum_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..9a2da58e --- /dev/null +++ b/hooks/zeromq-configuration-relation-joined @@ -0,0 +1 @@ +quantum_hooks.py \ No newline at end of file diff --git a/metadata.yaml b/metadata.yaml index c15d03fd..45d6b7b3 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -27,6 +27,9 @@ requires: interface: rabbitmq amqp-nova: interface: rabbitmq + zeromq-configuration: + interface: zeromq-configuration + scope: container peers: cluster: interface: quantum-gateway-ha diff --git a/templates/icehouse/neutron.conf b/templates/icehouse/neutron.conf index 6db71eb4..b96e64d2 100644 --- a/templates/icehouse/neutron.conf +++ b/templates/icehouse/neutron.conf @@ -8,8 +8,9 @@ debug = {{ debug }} lock_path = /var/lock/neutron core_plugin = {{ core_plugin }} {% include "parts/rabbitmq" %} +{% include "parts/zeromq" %} control_exchange = neutron notification_driver = neutron.openstack.common.notifier.list_notifier list_notifier_drivers = neutron.openstack.common.notifier.rabbit_notifier [agent] -root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf \ No newline at end of file +root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf 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 -%}