From 5d267c3f368a68329c3e6b492dab182661e2c682 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Fri, 10 Apr 2015 14:22:04 +0000 Subject: [PATCH 01/10] Deploy from source --- .bzrignore | 1 + Makefile | 6 +- README.md | 88 +++ actions.yaml | 2 + actions/git-reinstall | 1 + actions/git_reinstall.py | 40 ++ config.yaml | 16 + .../charmhelpers/contrib/openstack/context.py | 9 +- .../contrib/openstack/templates/git.upstart | 2 + hooks/charmhelpers/contrib/openstack/utils.py | 10 +- hooks/charmhelpers/core/hookenv.py | 15 +- hooks/quantum_hooks.py | 24 +- hooks/quantum_utils.py | 583 +++++++++++++++++- .../cron.d/neutron-dhcp-agent-netns-cleanup | 4 + .../cron.d/neutron-l3-agent-netns-cleanup | 4 + .../cron.d/neutron-lbaas-agent-netns-cleanup | 4 + templates/neutron_sudoers | 4 + templates/upstart/neutron-agent.upstart | 25 + templates/upstart/neutron-ovs-cleanup.upstart | 13 + templates/upstart/neutron-server.upstart | 22 + tests/12-basic-precise-grizzly | 11 - tests/13-basic-precise-havana | 11 - tests/16-basic-trusty-icehouse-git | 9 + tests/17-basic-trusty-juno | 11 + tests/18-basic-trusty-juno-git | 12 + tests/basic_deployment.py | 124 +--- unit_tests/__init__.py | 2 + unit_tests/test_actions_git_reinstall.py | 85 +++ unit_tests/test_quantum_hooks.py | 95 ++- unit_tests/test_quantum_utils.py | 487 ++++++++++++++- 30 files changed, 1567 insertions(+), 153 deletions(-) create mode 100644 actions.yaml create mode 120000 actions/git-reinstall create mode 100755 actions/git_reinstall.py create mode 100644 templates/cron.d/neutron-dhcp-agent-netns-cleanup create mode 100644 templates/cron.d/neutron-l3-agent-netns-cleanup create mode 100644 templates/cron.d/neutron-lbaas-agent-netns-cleanup create mode 100644 templates/neutron_sudoers create mode 100644 templates/upstart/neutron-agent.upstart create mode 100644 templates/upstart/neutron-ovs-cleanup.upstart create mode 100644 templates/upstart/neutron-server.upstart delete mode 100755 tests/12-basic-precise-grizzly delete mode 100755 tests/13-basic-precise-havana create mode 100755 tests/16-basic-trusty-icehouse-git create mode 100755 tests/17-basic-trusty-juno create mode 100755 tests/18-basic-trusty-juno-git create mode 100644 unit_tests/test_actions_git_reinstall.py diff --git a/.bzrignore b/.bzrignore index a2c7a097..421e2bda 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,2 +1,3 @@ bin .coverage +tags diff --git a/Makefile b/Makefile index 29cc596e..c2bddd9b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PYTHON := /usr/bin/env python lint: - @flake8 --exclude hooks/charmhelpers hooks unit_tests tests + @flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests @charm proof unit_test: @@ -24,7 +24,9 @@ test: # raise_status() messages to stderr: # https://bugs.launchpad.net/amulet/+bug/1320357 @juju test -v -p AMULET_HTTP_PROXY --timeout 900 \ - 00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse + 00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse \ + 16-basic-trusty-icehouse-git 17-basic-trusty-juno \ + 18-basic-trusty-juno-git publish: lint unit_test bzr push lp:charms/quantum-gateway diff --git a/README.md b/README.md index afade695..22debdba 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,94 @@ OpenStack upstream documentation recomments a MTU value of 1400: Note that this option was added in Havana and will be ignored in older releases. +Deploying from source +===================== + +The minimum openstack-origin-git config required to deploy from source is: + + openstack-origin-git: + "repositories: + - {name: requirements, + repository: 'git://git.openstack.org/openstack/requirements', + branch: stable/juno} + - {name: neutron, + repository: 'git://git.openstack.org/openstack/neutron', + branch: stable/juno}" + +Note that there are only two 'name' values the charm knows about: 'requirements' +and 'neutron'. These repositories must correspond to these 'name' values. +Additionally, the requirements repository must be specified first and the +neutron repository must be specified last. All other repostories are installed +in the order in which they are specified. + +The following is a full list of current tip repos (may not be up-to-date): + + openstack-origin-git: + "repositories: + - {name: requirements, + repository: 'git://git.openstack.org/openstack/requirements', + branch: master} + - {name: oslo-concurrency, + repository: 'git://git.openstack.org/openstack/oslo.concurrency', + branch: master} + - {name: oslo-config, + repository: 'git://git.openstack.org/openstack/oslo.config', + branch: master} + - {name: oslo-context, + repository: 'git://git.openstack.org/openstack/oslo.context.git', + branch: master} + - {name: oslo-db, + repository: 'git://git.openstack.org/openstack/oslo.db', + branch: master} + - {name: oslo-i18n, + repository: 'git://git.openstack.org/openstack/oslo.i18n', + branch: master} + - {name: oslo-messaging, + repository: 'git://git.openstack.org/openstack/oslo.messaging.git', + branch: master} + - {name: oslo-middleware, + repository': 'git://git.openstack.org/openstack/oslo.middleware.git', + branch: master} + - {name: oslo-rootwrap', + repository: 'git://git.openstack.org/openstack/oslo.rootwrap.git', + branch: master} + - {name: oslo-serialization, + repository: 'git://git.openstack.org/openstack/oslo.serialization', + branch: master} + - {name: oslo-utils, + repository: 'git://git.openstack.org/openstack/oslo.utils', + branch: master} + - {name: pbr, + repository: 'git://git.openstack.org/openstack-dev/pbr', + branch: master} + - {name: stevedore, + repository: 'git://git.openstack.org/openstack/stevedore.git', + branch: 'master'} + - {name: python-keystoneclient, + repository: 'git://git.openstack.org/openstack/python-keystoneclient', + branch: master} + - {name: python-neutronclient, + repository: 'git://git.openstack.org/openstack/python-neutronclient.git', + branch: master} + - {name: python-novaclient, + repository': 'git://git.openstack.org/openstack/python-novaclient.git', + branch: master} + - {name: keystonemiddleware, + repository: 'git://git.openstack.org/openstack/keystonemiddleware', + branch: master} + - {name: neutron-fwaas, + repository': 'git://git.openstack.org/openstack/neutron-fwaas.git', + branch: master} + - {name: neutron-lbaas, + repository: 'git://git.openstack.org/openstack/neutron-lbaas.git', + branch: master} + - {name: neutron-vpnaas, + repository: 'git://git.openstack.org/openstack/neutron-vpnaas.git', + branch: master} + - {name: neutron, + repository: 'git://git.openstack.org/openstack/neutron', + branch: master}" + TODO ---- diff --git a/actions.yaml b/actions.yaml new file mode 100644 index 00000000..40828caa --- /dev/null +++ b/actions.yaml @@ -0,0 +1,2 @@ +git-reinstall: + description: Reinstall quantum-gateway from the openstack-origin-git repositories. diff --git a/actions/git-reinstall b/actions/git-reinstall new file mode 120000 index 00000000..ff684984 --- /dev/null +++ b/actions/git-reinstall @@ -0,0 +1 @@ +git_reinstall.py \ No newline at end of file diff --git a/actions/git_reinstall.py b/actions/git_reinstall.py new file mode 100755 index 00000000..2eab3a33 --- /dev/null +++ b/actions/git_reinstall.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +import sys +import traceback + +sys.path.append('hooks/') + +from charmhelpers.contrib.openstack.utils import ( + git_install_requested, +) + +from charmhelpers.core.hookenv import ( + action_set, + action_fail, + config, +) + +from quantum_utils import ( + git_install, +) + + +def git_reinstall(): + """Reinstall from source and restart services. + + If the openstack-origin-git config option was used to install openstack + from source git repositories, then this action can be used to reinstall + from updated git repositories, followed by a restart of services.""" + if not git_install_requested(): + action_fail('openstack-origin-git is not configured') + return + + try: + git_install(config('openstack-origin-git')) + except: + action_set({'traceback': traceback.format_exc()}) + action_fail('git-reinstall resulted in an unexpected error') + + +if __name__ == '__main__': + git_reinstall() diff --git a/config.yaml b/config.yaml index 6bf27e47..abff70d5 100644 --- a/config.yaml +++ b/config.yaml @@ -37,6 +37,22 @@ options: - deb http://my.archive.com/ubuntu main|KEYID . Note that quantum/neutron is only supported >= Folsom. + + Note that when openstack-origin-git is specified, openstack + specific packages will be installed from source rather than + from the openstack-origin repository. + openstack-origin-git: + default: + type: string + description: | + Specifies a YAML-formatted dictionary listing the git + repositories and branches from which to install OpenStack and + its dependencies. + + Note that the installed config files will be determined based on + the OpenStack release of the openstack-origin option. + + For more details see README.md. run-internal-router: type: string default: all diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 45e65790..dd51bfbb 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -320,14 +320,15 @@ def db_ssl(rdata, ctxt, ssl_dir): class IdentityServiceContext(OSContextGenerator): - interfaces = ['identity-service'] - def __init__(self, service=None, service_user=None): + def __init__(self, service=None, service_user=None, rel_name='identity-service'): self.service = service self.service_user = service_user + self.rel_name = rel_name + self.interfaces = [self.rel_name] def __call__(self): - log('Generating template context for identity-service', level=DEBUG) + log('Generating template context for ' + self.rel_name, level=DEBUG) ctxt = {} if self.service and self.service_user: @@ -341,7 +342,7 @@ class IdentityServiceContext(OSContextGenerator): ctxt['signing_dir'] = cachedir - for rid in relation_ids('identity-service'): + for rid in relation_ids(self.rel_name): for unit in related_units(rid): rdata = relation_get(rid=rid, unit=unit) serv_host = rdata.get('service_host') diff --git a/hooks/charmhelpers/contrib/openstack/templates/git.upstart b/hooks/charmhelpers/contrib/openstack/templates/git.upstart index da94ad12..62af9204 100644 --- a/hooks/charmhelpers/contrib/openstack/templates/git.upstart +++ b/hooks/charmhelpers/contrib/openstack/templates/git.upstart @@ -9,5 +9,7 @@ respawn exec start-stop-daemon --start --chuid {{ user_name }} \ --chdir {{ start_dir }} --name {{ process_name }} \ --exec {{ executable_name }} -- \ + {% for config_file in config_files -%} --config-file={{ config_file }} \ + {% endfor -%} --log-file={{ log_file }} diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index 78c5e2df..5a12c9d6 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -510,8 +510,10 @@ def git_clone_and_install(projects_yaml, core_project): repository: 'git://git.openstack.org/openstack/requirements.git', branch: 'stable/icehouse'} directory: /mnt/openstack-git + http_proxy: http://squid.internal:3128 + https_proxy: https://squid.internal:3128 - The directory key is optional. + The directory, http_proxy, and https_proxy keys are optional. """ global requirements_dir parent_dir = '/mnt/openstack-git' @@ -522,6 +524,12 @@ def git_clone_and_install(projects_yaml, core_project): projects = yaml.load(projects_yaml) _git_validate_projects_yaml(projects, core_project) + if 'http_proxy' in projects.keys(): + os.environ['http_proxy'] = projects['http_proxy'] + + if 'https_proxy' in projects.keys(): + os.environ['https_proxy'] = projects['https_proxy'] + if 'directory' in projects.keys(): parent_dir = projects['directory'] diff --git a/hooks/charmhelpers/core/hookenv.py b/hooks/charmhelpers/core/hookenv.py index 715dd4c5..86f805f1 100644 --- a/hooks/charmhelpers/core/hookenv.py +++ b/hooks/charmhelpers/core/hookenv.py @@ -20,11 +20,13 @@ # Authors: # Charm Helpers Developers +from __future__ import print_function import os import json import yaml import subprocess import sys +import errno from subprocess import CalledProcessError import six @@ -87,7 +89,18 @@ def log(message, level=None): if not isinstance(message, six.string_types): message = repr(message) command += [message] - subprocess.call(command) + # Missing juju-log should not cause failures in unit tests + # Send log output to stderr + try: + subprocess.call(command) + except OSError as e: + if e.errno == errno.ENOENT: + if level: + message = "{}: {}".format(level, message) + message = "juju-log: {}".format(message) + print(message, file=sys.stderr) + else: + raise class Serializable(UserDict): diff --git a/hooks/quantum_hooks.py b/hooks/quantum_hooks.py index 61e81f7a..f01de3fd 100755 --- a/hooks/quantum_hooks.py +++ b/hooks/quantum_hooks.py @@ -30,6 +30,7 @@ from charmhelpers.contrib.hahelpers.apache import( install_ca_cert ) from charmhelpers.contrib.openstack.utils import ( + config_value_changed, configure_installation_source, openstack_upgrade_available, os_requires_version, @@ -50,6 +51,8 @@ from quantum_utils import ( get_early_packages, get_common_package, get_topics, + git_install, + git_install_requested, valid_plugin, configure_ovs, stop_services, @@ -82,6 +85,7 @@ def install(): fatal=True) apt_install(filter_installed_packages(get_packages()), fatal=True) + git_install(config('openstack-origin-git')) else: log('Please provide a valid plugin config', level=ERROR) sys.exit(1) @@ -94,8 +98,15 @@ def install(): @restart_on_change(restart_map()) def config_changed(): global CONFIGS - if openstack_upgrade_available(get_common_package()): - CONFIGS = do_openstack_upgrade() + if git_install_requested(): + if config_value_changed('openstack-origin-git'): + git_install(config('openstack-origin-git')) + CONFIGS.write_all() + else: + if openstack_upgrade_available(get_common_package()): + do_openstack_upgrade() + CONFIGS.write_all() + update_nrpe_config() sysctl_dict = config('sysctl') @@ -120,10 +131,11 @@ def config_changed(): log('Please provide a valid plugin config', level=ERROR) sys.exit(1) if config('plugin') == 'n1kv': - if config('enable-l3-agent'): - apt_install(filter_installed_packages('neutron-l3-agent')) - else: - apt_purge('neutron-l3-agent') + if not git_install_requested(): + if config('enable-l3-agent'): + apt_install(filter_installed_packages('neutron-l3-agent')) + else: + apt_purge('neutron-l3-agent') # Setup legacy ha configurations update_legacy_ha_files() diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index d96475b8..3dd8fa1b 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -1,14 +1,20 @@ import os +import shutil import subprocess from shutil import copy2 from charmhelpers.core.host import ( + adduser, + add_group, + add_user_to_group, + lsb_release, mkdir, service_running, service_stop, service_restart, - lsb_release, + write_file, ) from charmhelpers.core.hookenv import ( + charm_dir, log, DEBUG, INFO, @@ -18,6 +24,7 @@ from charmhelpers.core.hookenv import ( unit_private_ip, is_relation_made, ) +from charmhelpers.core.templating import render from charmhelpers.fetch import ( apt_upgrade, apt_update, @@ -32,6 +39,9 @@ from charmhelpers.contrib.openstack.utils import ( configure_installation_source, get_os_codename_install_source, get_os_codename_package, + git_install_requested, + git_clone_and_install, + git_src_dir, get_hostname ) @@ -174,6 +184,39 @@ LEGACY_FILES_MAP = { LEGACY_RES_MAP = ['res_monitor'] L3HA_PACKAGES = ['keepalived'] +BASE_GIT_PACKAGES = [ + 'dnsmasq', + 'libxml2-dev', + 'libxslt1-dev', + 'python-dev', + 'python-pip', + 'python-setuptools', + 'zlib1g-dev', +] + +# ubuntu packages that should not be installed when deploying from git +GIT_PACKAGE_BLACKLIST = [ + 'nova-api-metadata', + 'neutron-common', + 'neutron-dhcp-agent', + 'neutron-l3-agent', + 'neutron-lbaas-agent', + 'neutron-metadata-agent', + 'neutron-metering-agent', + 'neutron-plugin-cisco', + 'neutron-plugin-metering-agent', + 'neutron-plugin-openvswitch-agent', + 'neutron-plugin-vpn-agent', + 'neutron-vpn-agent', + 'python-neutron-fwaas', + 'python-oslo.config', + 'quantum-common', + 'quantum-dhcp-agent', + 'quantum-l3-agent', + 'quantum-metadata-agent', + 'quantum-plugin-openvswitch-agent', +] + def get_early_packages(): '''Return a list of package for pre-install based on configured plugin''' @@ -204,6 +247,15 @@ def get_packages(): if source >= 'kilo': packages.append('python-neutron-fwaas') packages.extend(determine_l3ha_packages()) + + if git_install_requested(): + packages = list(set(packages)) + packages.extend(BASE_GIT_PACKAGES) + # don't include packages that will be installed from git + for p in GIT_PACKAGE_BLACKLIST: + if p in packages: + packages.remove(p) + return packages @@ -612,12 +664,6 @@ def do_openstack_upgrade(): apt_install(get_early_packages(), fatal=True) apt_install(get_packages(), fatal=True) - # set CONFIGS to load templates from new release - configs = register_configs() - configs.write_all() - [service_restart(s) for s in services()] - return configs - def configure_ovs(): if config('plugin') == OVS: @@ -760,3 +806,526 @@ def get_topics(): topics.append('q-agent-notifier-dvr-update') topics.append('q-agent-notifier-l2population-update') return topics + + +def git_install(projects_yaml): + """Perform setup, and install git repos specified in yaml parameter.""" + if git_install_requested(): + git_pre_install() + git_clone_and_install(projects_yaml, core_project='neutron') + git_post_install(projects_yaml) + + +def git_pre_install(): + """Perform pre-install setup.""" + dirs = [ + '/etc/neutron', + '/etc/neutron/rootwrap.d', + '/etc/neutron/plugins', + '/etc/nova', + '/var/lib/neutron', + '/var/lib/neutron/lock', + '/var/log/neutron', + ] + + logs = [ + '/var/log/neutron/bigswitch-agent.log', + '/var/log/neutron/dhcp-agent.log', + '/var/log/neutron/l3-agent.log', + '/var/log/neutron/lbaas-agent.log', + '/var/log/neutron/ibm-agent.log', + '/var/log/neutron/linuxbridge-agent.log', + '/var/log/neutron/metadata-agent.log', + '/var/log/neutron/metering_agent.log', + '/var/log/neutron/mlnx-agent.log', + '/var/log/neutron/nec-agent.log', + '/var/log/neutron/nvsd-agent.log', + '/var/log/neutron/openflow-agent.log', + '/var/log/neutron/openvswitch-agent.log', + '/var/log/neutron/ovs-cleanup.log', + '/var/log/neutron/ryu-agent.log', + '/var/log/neutron/server.log', + '/var/log/neutron/sriov-agent.log', + '/var/log/neutron/vpn_agent.log', + ] + + adduser('neutron', shell='/bin/bash', system_user=True) + add_group('neutron', system_group=True) + add_user_to_group('neutron', 'neutron') + + for d in dirs: + mkdir(d, owner='neutron', group='neutron', perms=0700, force=False) + + for l in logs: + write_file(l, '', owner='neutron', group='neutron', perms=0644) + + +def git_post_install(projects_yaml): + """Perform post-install setup.""" + src_etc = os.path.join(git_src_dir(projects_yaml, 'neutron'), 'etc') + etc_configs = { + 'api-paste': { + 'src': os.path.join(src_etc, 'api-paste.ini'), + 'dest': '/etc/neutron/api-paste.ini', + }, + 'dhcp_agent': { + 'src': os.path.join(src_etc, 'dhcp_agent.ini'), + 'dest': '/etc/neutron/dhcp_agent.ini', + }, + 'fwaas_driver': { + 'src': os.path.join(src_etc, 'fwaas_driver.ini'), + 'dest': '/etc/neutron/fwaas_driver.ini', + }, + 'l3_agent': { + 'src': os.path.join(src_etc, 'l3_agent.ini'), + 'dest': '/etc/neutron/l3_agent.ini', + }, + 'lbaas_agent': { + 'src': os.path.join(src_etc, 'lbaas_agent.ini'), + 'dest': '/etc/neutron/lbaas_agent.ini', + }, + 'metadata_agent': { + 'src': os.path.join(src_etc, 'metadata_agent.ini'), + 'dest': '/etc/neutron/metadata_agent.ini', + }, + 'metering_agent': { + 'src': os.path.join(src_etc, 'metering_agent.ini'), + 'dest': '/etc/neutron/metering_agent.ini', + }, + 'policy': { + 'src': os.path.join(src_etc, 'policy.json'), + 'dest': '/etc/neutron/policy.json', + }, + 'rootwrap': { + 'src': os.path.join(src_etc, 'rootwrap.conf'), + 'dest': '/etc/neutron/rootwrap.conf', + }, + 'vpn_agent': { + 'src': os.path.join(src_etc, 'vpn_agent.ini'), + 'dest': '/etc/neutron/vpn_agent.ini', + }, + } + + for conf, files in etc_configs.iteritems(): + if os.path.exists(files['src']): + shutil.copyfile(files['src'], files['dest']) + + src_plugins = os.path.join(src_etc, 'neutron/plugins') + plugins_configs = { + 'bigswitch': { + 'src': os.path.join(src_plugins, 'bigswitch'), + 'dest': '/etc/neutron/plugins/bigswitch', + }, + 'brocade': { + 'src': os.path.join(src_plugins, 'brocade'), + 'dest': '/etc/neutron/plugins/brocade', + }, + 'cisco': { + 'src': os.path.join(src_plugins, 'cisco'), + 'dest': '/etc/neutron/plugins/cisco', + }, + 'hyperv': { + 'src': os.path.join(src_plugins, 'hyperv'), + 'dest': '/etc/neutron/plugins/hyperv', + }, + 'ibm': { + 'src': os.path.join(src_plugins, 'ibm'), + 'dest': '/etc/neutron/plugins/ibm', + }, + 'metaplugin': { + 'src': os.path.join(src_plugins, 'metaplugin'), + 'dest': '/etc/neutron/plugins/metaplugin', + }, + 'midonet': { + 'src': os.path.join(src_plugins, 'midonet'), + 'dest': '/etc/neutron/plugins/midonet', + }, + 'ml2': { + 'src': os.path.join(src_plugins, 'ml2'), + 'dest': '/etc/neutron/plugins/ml2', + }, + 'mlnx': { + 'src': os.path.join(src_plugins, 'mlnx'), + 'dest': '/etc/neutron/plugins/mlnx', + }, + 'nec': { + 'src': os.path.join(src_plugins, 'nec'), + 'dest': '/etc/neutron/plugins/nec', + }, + 'nuage': { + 'src': os.path.join(src_plugins, 'nuage'), + 'dest': '/etc/neutron/plugins/nuage', + }, + 'oneconvergence': { + 'src': os.path.join(src_plugins, 'oneconvergence'), + 'dest': '/etc/neutron/plugins/oneconvergence', + }, + 'opencontrail': { + 'src': os.path.join(src_plugins, 'opencontrail'), + 'dest': '/etc/neutron/plugins/opencontrail', + }, + 'plumgrid': { + 'src': os.path.join(src_plugins, 'plumgrid'), + 'dest': '/etc/neutron/plugins/plumgrid', + }, + 'ryu': { + 'src': os.path.join(src_plugins, 'ryu'), + 'dest': '/etc/neutron/plugins/ryu', + }, + 'vmware': { + 'src': os.path.join(src_plugins, 'vmware'), + 'dest': '/etc/neutron/plugins/vmware', + }, + } + + for conf, dirs in plugins_configs.iteritems(): + if os.path.exists(dirs['src']): + if os.path.exists(dirs['dest']): + shutil.rmtree(dirs['dest']) + shutil.copytree(dirs['src'], dirs['dest']) + + src_rootwrap = os.path.join(src_etc, 'neutron/rootwrap.d') + rootwrap_configs = { + 'debug-filters': { + 'src': os.path.join(src_rootwrap, 'debug.filters'), + 'dest': '/etc/neutron/rootwrap.d/debug.filters', + }, + 'dhcp-filters': { + 'src': os.path.join(src_rootwrap, 'dhcp.filters'), + 'dest': '/etc/neutron/rootwrap.d/dhcp.filters', + }, + 'ipset-firewall-filters': { + 'src': os.path.join(src_rootwrap, 'ipset-firewall.filters'), + 'dest': '/etc/neutron/rootwrap.d/ipset-firewall.filters', + }, + 'iptables-firewall-filters': { + 'src': os.path.join(src_rootwrap, 'iptables-firewall.filters'), + 'dest': '/etc/neutron/rootwrap.d/iptables-firewall.filters', + }, + 'l3-filters': { + 'src': os.path.join(src_rootwrap, 'l3.filters'), + 'dest': '/etc/neutron/rootwrap.d/l3.filters', + }, + 'lbaas-haproxy': { + 'src': os.path.join(src_rootwrap, 'lbaas-haproxy.filters'), + 'dest': '/etc/neutron/rootwrap.d/lbaas-haproxy.filters', + }, + 'linuxbridge-plugin': { + 'src': os.path.join(src_rootwrap, 'linuxbridge-plugin.filters'), + 'dest': '/etc/neutron/rootwrap.d/linuxbridge-plugin.filters', + }, + 'nec-plugin': { + 'src': os.path.join(src_rootwrap, 'nec-plugin.filters'), + 'dest': '/etc/neutron/rootwrap.d/nec-plugin.filters', + }, + 'openvswitch-plugin': { + 'src': os.path.join(src_rootwrap, 'openvswitch-plugin.filters'), + 'dest': '/etc/neutron/rootwrap.d/openvswitch-plugin.filters', + }, + 'ryu-plugin': { + 'src': os.path.join(src_rootwrap, 'ryu-plugin.filters'), + 'dest': '/etc/neutron/rootwrap.d/ryu-plugin.filters', + }, + 'vpnaas': { + 'src': os.path.join(src_rootwrap, 'vpnaas.filters'), + 'dest': '/etc/neutron/rootwrap.d/vpnaas.filters', + }, + } + + for conf, files in rootwrap_configs.iteritems(): + if os.path.exists(files['src']): + shutil.copyfile(files['src'], files['dest']) + + symlinks = [ + {'src': '/usr/local/bin/neutron-rootwrap', + 'link': '/usr/bin/neutron-rootwrap'}, + ] + + for s in symlinks: + if os.path.lexists(s['link']): + os.remove(s['link']) + os.symlink(s['src'], s['link']) + + render('neutron_sudoers', + '/etc/sudoers.d/neutron_sudoers', {}, perms=0o440) + render('cron.d/neutron-dhcp-agent-netns-cleanup', + '/etc/cron.d/neutron-dhcp-agent-netns-cleanup', {}, perms=0o755) + render('cron.d/neutron-l3-agent-netns-cleanup', + '/etc/cron.d/neutron-l3-agent-netns-cleanup', {}, perms=0o755) + render('cron.d/neutron-lbaas-agent-netns-cleanup', + '/etc/cron.d/neutron-lbaas-agent-netns-cleanup', {}, perms=0o755) + + service_name = 'quantum-gateway' + user_name = 'neutron' + neutron_api_context = { + 'service_description': 'Neutron API server', + 'service_name': service_name, + 'process_name': 'neutron-server', + } + neutron_dhcp_agent_context = { + 'service_description': 'Neutron DHCP Agent', + 'service_name': service_name, + 'process_name': 'neutron-dhcp-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/dhcp_agent.ini'], + 'log_file': '/var/log/neutron/dhcp-agent.log', + } + neutron_l3_agent_context = { + 'service_description': 'Neutron L3 Agent', + 'service_name': service_name, + 'process_name': 'neutron-l3-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/l3_agent.ini', + '/etc/neutron/fwaas_driver.ini'], + 'log_file': '/var/log/neutron/l3-agent.log', + } + neutron_lbaas_agent_context = { + 'service_description': 'Neutron LBaaS Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-lbaas-agent', + 'executable_name': '/usr/local/bin/neutron-lbaas-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/lbaas_agent.ini'], + 'log_file': '/var/log/neutron/lbaas-agent.log', + } + neutron_metadata_agent_context = { + 'service_description': 'Neutron Metadata Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-metadata-agent', + 'executable_name': '/usr/local/bin/neutron-metadata-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/metadata_agent.ini'], + 'log_file': '/var/log/neutron/metadata-agent.log', + } + neutron_metering_agent_context = { + 'service_description': 'Neutron Metering Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-metering-agent', + 'executable_name': '/usr/local/bin/neutron-metering-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/metering_agent.ini'], + 'log_file': '/var/log/neutron/metering-agent.log', + } + neutron_ovs_cleanup_context = { + 'service_description': 'Neutron OVS cleanup', + 'service_name': service_name, + 'process_name': 'neutron-ovs-cleanup', + 'config_file': '/etc/neutron/neutron.conf', + 'log_file': '/var/log/neutron/ovs-cleanup.log', + } + neutron_plugin_bigswitch_context = { + 'service_description': 'Neutron BigSwitch Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-restproxy-agent', + 'executable_name': '/usr/local/bin/neutron-restproxy-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/bigswitch/restproxy.ini'], + 'log_file': '/var/log/neutron/bigswitch-agent.log', + } + neutron_plugin_ibm_context = { + 'service_description': 'Neutron IBM SDN Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ibm-agent', + 'executable_name': '/usr/local/bin/neutron-ibm-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini'], + 'log_file': '/var/log/neutron/ibm-agent.log', + } + neutron_plugin_linuxbridge_context = { + 'service_description': 'Neutron Linux Bridge Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-linuxbridge-agent', + 'executable_name': '/usr/local/bin/neutron-linuxbridge-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf.ini'], + 'log_file': '/var/log/neutron/linuxbridge-agent.log', + } + neutron_plugin_mlnx_context = { + 'service_description': 'Neutron MLNX Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-mlnx-agent', + 'executable_name': '/usr/local/bin/neutron-mlnx-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/mlnx/mlnx_conf.ini'], + 'log_file': '/var/log/neutron/mlnx-agent.log', + } + neutron_plugin_nec_context = { + 'service_description': 'Neutron NEC Plugin Agent', + 'service_name': service_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-nec-agent', + 'executable_name': '/usr/local/bin/neutron-nec-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/nec/nec.ini'], + 'log_file': '/var/log/neutron/nec-agent.log', + } + neutron_plugin_oneconvergence_context = { + 'service_description': 'Neutron One Convergence Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-nvsd-agent', + 'executable_name': '/usr/local/bin/neutron-nvsd-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/oneconvergence/nvsdplugin.ini'], + 'log_file': '/var/log/neutron/nvsd-agent.log', + } + neutron_plugin_openflow_context = { + 'service_description': 'Neutron OpenFlow Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ofagent-agent', + 'executable_name': '/usr/local/bin/neutron-ofagent-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf_ofa.ini'], + 'log_file': '/var/log/neutron/openflow-agent.log', + } + neutron_plugin_openvswitch_context = { + 'service_description': 'Neutron OpenvSwitch Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-openvswitch-agent', + 'executable_name': '/usr/local/bin/neutron-openvswitch-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf.ini'], + 'log_file': '/var/log/neutron/openvswitch-agent.log', + } + neutron_plugin_ryu_context = { + 'service_description': 'Neutron RYU Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ryu-agent', + 'executable_name': '/usr/local/bin/neutron-ryu-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ryu/ryu.ini'], + 'log_file': '/var/log/neutron/ryu-agent.log', + } + neutron_plugin_sriov_context = { + 'service_description': 'Neutron SRIOV SDN Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-sriov-nic-agent', + 'executable_name': '/usr/local/bin/neutron-sriov-nic-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf_sriov'], + 'log_file': '/var/log/neutron/sriov-agent.log', + } + neutron_vpn_agent_context = { + 'service_description': 'Neutron VPN Agent', + 'service_name': service_name, + 'process_name': 'neutron-vpn-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/vpn_agent.ini', + '/etc/neutron/l3_agent.ini', + '/etc/neutron/fwaas_driver.ini'], + 'log_file': '/var/log/neutron/vpn_agent.log', + } + + # NOTE(coreycb): Needs systemd support + templates_dir = 'hooks/charmhelpers/contrib/openstack/templates' + templates_dir = os.path.join(charm_dir(), templates_dir) + render('upstart/neutron-agent.upstart', + '/etc/init/neutron-dhcp-agent.conf', + neutron_dhcp_agent_context, perms=0o644) + render('upstart/neutron-agent.upstart', + '/etc/init/neutron-l3-agent.conf', + neutron_l3_agent_context, perms=0o644) + render('git.upstart', + '/etc/init/neutron-lbaas-agent.conf', + neutron_lbaas_agent_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-metadata-agent.conf', + neutron_metadata_agent_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-metering-agent.conf', + neutron_metering_agent_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-ovs-cleanup.conf', + neutron_ovs_cleanup_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-bigswitch-agent.conf', + neutron_plugin_bigswitch_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-ibm-agent.conf', + neutron_plugin_ibm_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-linuxbridge-agent.conf', + neutron_plugin_linuxbridge_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-mlnx-agent.conf', + neutron_plugin_mlnx_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-nec-agent.conf', + neutron_plugin_nec_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-oneconvergence-agent.conf', + neutron_plugin_oneconvergence_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-openflow-agent.conf', + neutron_plugin_openflow_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-openvswitch-agent.conf', + neutron_plugin_openvswitch_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-ryu-agent.conf', + neutron_plugin_ryu_context, perms=0o644, + templates_dir=templates_dir) + render('git.upstart', + '/etc/init/neutron-plugin-sriov-agent.conf', + neutron_plugin_sriov_context, perms=0o644, + templates_dir=templates_dir) + render('upstart/neutron-server.upstart', + '/etc/init/neutron-server.conf', + neutron_api_context, perms=0o644) + render('upstart/neutron-agent.upstart', + '/etc/init/neutron-vpn-agent.conf', + neutron_vpn_agent_context, perms=0o644) + + service_restart('neutron-dhcp-agent') + service_restart('neutron-l3-agent') + service_restart('neutron-lbaas-agent') + service_restart('neutron-metadata-agent') + service_restart('neutron-metering-agent') + service_restart('neutron-ovs-cleanup') + service_restart('neutron-plugin-bigswitch') + service_restart('neutron-plugin-ibm-agent') + service_restart('neutron-plugin-linuxbridge-agent') + service_restart('neutron-plugin-mlnx-agent') + service_restart('neutron-plugin-nec-agent') + service_restart('neutron-plugin-oneconvergence-agent') + service_restart('neutron-plugin-openflow-agent') + service_restart('neutron-plugin-openvswitch-agent') + service_restart('neutron-plugin-ryu-agent') + service_restart('neutron-plugin-sriov-agent') + service_restart('neutron-server') + service_restart('neutron-vpn-agent') diff --git a/templates/cron.d/neutron-dhcp-agent-netns-cleanup b/templates/cron.d/neutron-dhcp-agent-netns-cleanup new file mode 100644 index 00000000..f42d71e2 --- /dev/null +++ b/templates/cron.d/neutron-dhcp-agent-netns-cleanup @@ -0,0 +1,4 @@ +# vim: set filetype=crontab: +# Periodically cleans Neutron's network namespaces on behalf of the Neutron +# DHCP agent. +30 * * * * neutron if [ -x /usr/local/bin/neutron-netns-cleanup ] ; then /usr/local/bin/neutron-netns-cleanup --config-file=/etc/neutron/neutron.conf --config-file=/etc/neutron/dhcp_agent.ini >/dev/null 2>&1; fi diff --git a/templates/cron.d/neutron-l3-agent-netns-cleanup b/templates/cron.d/neutron-l3-agent-netns-cleanup new file mode 100644 index 00000000..f13bfb11 --- /dev/null +++ b/templates/cron.d/neutron-l3-agent-netns-cleanup @@ -0,0 +1,4 @@ +# vim: set filetype=crontab: +# Periodically cleans Neutron's network namespaces on behalf of the Neutron +# L3 agent. +0 * * * * neutron if [ -x /usr/local/bin/neutron-netns-cleanup ] ; then /usr/local/bin/neutron-netns-cleanup --config-file=/etc/neutron/neutron.conf --config-file=/etc/neutron/l3_agent.ini >/dev/null 2>&1; fi diff --git a/templates/cron.d/neutron-lbaas-agent-netns-cleanup b/templates/cron.d/neutron-lbaas-agent-netns-cleanup new file mode 100644 index 00000000..6ffaa7cf --- /dev/null +++ b/templates/cron.d/neutron-lbaas-agent-netns-cleanup @@ -0,0 +1,4 @@ +# vim: set filetype=crontab: +# Periodically cleans Neutron's network namespaces on behalf of the Neutron +# L3 agent. +0 * * * * neutron if [ -x /usr/local/bin/neutron-netns-cleanup ] ; then /usr/local/bin/neutron-netns-cleanup --config-file=/etc/neutron/neutron.conf --config-file=/etc/neutron/lbaas_agent.ini >/dev/null 2>&1; fi diff --git a/templates/neutron_sudoers b/templates/neutron_sudoers new file mode 100644 index 00000000..d6fec647 --- /dev/null +++ b/templates/neutron_sudoers @@ -0,0 +1,4 @@ +Defaults:neutron !requiretty + +neutron ALL = (root) NOPASSWD: /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf * + diff --git a/templates/upstart/neutron-agent.upstart b/templates/upstart/neutron-agent.upstart new file mode 100644 index 00000000..3853caa4 --- /dev/null +++ b/templates/upstart/neutron-agent.upstart @@ -0,0 +1,25 @@ +description "{{ service_description }}" +author "Juju {{ service_name }} Charm " + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn + +chdir /var/run + +pre-start script + mkdir -p /var/run/neutron + chown neutron:root /var/run/neutron + # Check to see if openvswitch plugin in use by checking + # status of cleanup upstart configuration + if status neutron-ovs-cleanup; then + start wait-for-state WAIT_FOR=neutron-ovs-cleanup WAIT_STATE=running WAITER={{ process_name }} + fi +end script + +exec start-stop-daemon --start --chuid neutron --exec /usr/local/bin/{{ process_name }} -- \ + {% for config_file in config_files -%} + --config-file={{ config_file }} \ + {% endfor -%} + --log-file={{ log_file }} diff --git a/templates/upstart/neutron-ovs-cleanup.upstart b/templates/upstart/neutron-ovs-cleanup.upstart new file mode 100644 index 00000000..fa2c2149 --- /dev/null +++ b/templates/upstart/neutron-ovs-cleanup.upstart @@ -0,0 +1,13 @@ +description "{{ service_description }}" +author "Juju {{ service_name }} Charm " + +start on started openvswitch-switch +stop on runlevel [!2345] + +pre-start script + [ ! -x /usr/local/bin/{{ process_name }} ] && exit 0 + start-stop-daemon --start --chuid neutron \ + --exec /usr/local/bin/{{ process_name }} -- \ + --log-file {{ log_file }} \ + --config-file {{ config_file }} --verbose +end script diff --git a/templates/upstart/neutron-server.upstart b/templates/upstart/neutron-server.upstart new file mode 100644 index 00000000..2d2c73a2 --- /dev/null +++ b/templates/upstart/neutron-server.upstart @@ -0,0 +1,22 @@ +description "{{ service_description }}" +author "Juju {{ service_name }} Charm " + +start on runlevel [2345] +stop on runlevel [!2345] + +respawn + +chdir /var/run + +pre-start script + mkdir -p /var/run/neutron + chown neutron:root /var/run/neutron +end script + +script + [ -r /etc/default/{{ process_name }} ] && . /etc/default/{{ process_name }} + [ -r "$NEUTRON_PLUGIN_CONFIG" ] && CONF_ARG="--config-file $NEUTRON_PLUGIN_CONFIG" + exec start-stop-daemon --start --chuid neutron --exec /usr/local/bin/neutron-server -- \ + --config-file /etc/neutron/neutron.conf \ + --log-file /var/log/neutron/server.log $CONF_ARG +end script diff --git a/tests/12-basic-precise-grizzly b/tests/12-basic-precise-grizzly deleted file mode 100755 index 29c358b9..00000000 --- a/tests/12-basic-precise-grizzly +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/python - -"""Amulet tests on a basic quantum-gateway deployment on precise-grizzly.""" - -from basic_deployment import QuantumGatewayBasicDeployment - -if __name__ == '__main__': - deployment = QuantumGatewayBasicDeployment(series='precise', - openstack='cloud:precise-grizzly', - source='cloud:precise-updates/grizzly') - deployment.run_tests() diff --git a/tests/13-basic-precise-havana b/tests/13-basic-precise-havana deleted file mode 100755 index 285fc333..00000000 --- a/tests/13-basic-precise-havana +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/python - -"""Amulet tests on a basic quantum-gateway deployment on precise-havana.""" - -from basic_deployment import QuantumGatewayBasicDeployment - -if __name__ == '__main__': - deployment = QuantumGatewayBasicDeployment(series='precise', - openstack='cloud:precise-havana', - source='cloud:precise-updates/havana') - deployment.run_tests() diff --git a/tests/16-basic-trusty-icehouse-git b/tests/16-basic-trusty-icehouse-git new file mode 100755 index 00000000..a24daec0 --- /dev/null +++ b/tests/16-basic-trusty-icehouse-git @@ -0,0 +1,9 @@ +#!/usr/bin/python + +"""Amulet tests on a basic quantum-gateway git deployment on trusty-icehouse.""" + +from basic_deployment import QuantumGatewayBasicDeployment + +if __name__ == '__main__': + deployment = QuantumGatewayBasicDeployment(series='trusty', git=True) + deployment.run_tests() diff --git a/tests/17-basic-trusty-juno b/tests/17-basic-trusty-juno new file mode 100755 index 00000000..525ffb5c --- /dev/null +++ b/tests/17-basic-trusty-juno @@ -0,0 +1,11 @@ +#!/usr/bin/python + +"""Amulet tests on a basic quantum-gateway deployment on trusty-juno.""" + +from basic_deployment import QuantumGatewayBasicDeployment + +if __name__ == '__main__': + deployment = QuantumGatewayBasicDeployment(series='trusty', + openstack='cloud:trusty-juno', + source='cloud:trusty-updates/juno') + deployment.run_tests() diff --git a/tests/18-basic-trusty-juno-git b/tests/18-basic-trusty-juno-git new file mode 100755 index 00000000..92e3c194 --- /dev/null +++ b/tests/18-basic-trusty-juno-git @@ -0,0 +1,12 @@ +#!/usr/bin/python + +"""Amulet tests on a basic quantum-gateway git deployment on trusty-juno.""" + +from basic_deployment import QuantumGatewayBasicDeployment + +if __name__ == '__main__': + deployment = QuantumGatewayBasicDeployment(series='trusty', + openstack='cloud:trusty-juno', + source='cloud:trusty-updates/juno', + git=True) + deployment.run_tests() diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 9e771a68..ced1909a 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -2,6 +2,7 @@ import amulet import time +import yaml try: from quantumclient.v2_0 import client as neutronclient except ImportError: @@ -18,16 +19,18 @@ from charmhelpers.contrib.openstack.amulet.utils import ( ) # Use DEBUG to turn on debug logging -u = OpenStackAmuletUtils(ERROR) +u = OpenStackAmuletUtils(DEBUG) class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): """Amulet tests on a basic quantum-gateway deployment.""" - def __init__(self, series, openstack=None, source=None, stable=False): + def __init__(self, series, openstack=None, source=None, git=False, + stable=False): """Deploy the entire test environment.""" super(QuantumGatewayBasicDeployment, self).__init__(series, openstack, source, stable) + self.git = git self._add_services() self._add_relations() self._configure_services() @@ -64,11 +67,29 @@ class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): def _configure_services(self): """Configure all of the services.""" + quantum_gateway_config = {} + if self.git: + branch = 'stable/' + self._get_openstack_release_string() + openstack_origin_git = { + 'repositories': [ + {'name': 'requirements', + 'repository': 'git://git.openstack.org/openstack/requirements', + 'branch': branch}, + {'name': 'neutron', + 'repository': 'git://git.openstack.org/openstack/neutron', + 'branch': branch}, + ], + 'directory': '/mnt/openstack-git', + 'http_proxy': 'http://squid.internal:3128', + 'https_proxy': 'https://squid.internal:3128', + } + quantum_gateway_config['openstack-origin-git'] = yaml.dump(openstack_origin_git) keystone_config = {'admin-password': 'openstack', 'admin-token': 'ubuntutesting'} nova_cc_config = {'network-manager': 'Quantum', 'quantum-security-groups': 'yes'} - configs = {'keystone': keystone_config, + configs = {'quantum-gateway': quantum_gateway_config, + 'keystone': keystone_config, 'nova-cloud-controller': nova_cc_config} super(QuantumGatewayBasicDeployment, self)._configure_services(configs) @@ -269,7 +290,7 @@ class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): self.d.configure('quantum-gateway', {'debug': 'True'}) - time = 20 + time = 40 for s in services: if not u.service_restarted(self.quantum_gateway_sentry, s, conf, pgrep_full=True, sleep_time=time): @@ -388,101 +409,6 @@ class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): message = "ml2 config error: {}".format(ret) amulet.raise_status(amulet.FAIL, msg=message) - def test_api_paste_config(self): - """Verify the data in the api paste config file.""" - unit = self.quantum_gateway_sentry - if self._get_openstack_release() >= self.precise_havana: - conf = '/etc/neutron/api-paste.ini' - expected = { - 'composite:neutron': { - 'use': 'egg:Paste#urlmap', - '/': 'neutronversions', - '/v2.0': 'neutronapi_v2_0' - }, - 'filter:keystonecontext': { - 'paste.filter_factory': 'neutron.auth:' - 'NeutronKeystoneContext.factory' - }, - 'filter:authtoken': { - 'paste.filter_factory': 'keystoneclient.middleware.' - 'auth_token:filter_factory' - }, - 'filter:extensions': { - 'paste.filter_factory': 'neutron.api.extensions:' - 'plugin_aware_extension_middleware_' - 'factory' - }, - 'app:neutronversions': { - 'paste.app_factory': 'neutron.api.versions:Versions.factory' - }, - 'app:neutronapiapp_v2_0': { - 'paste.app_factory': 'neutron.api.v2.router:APIRouter.' - 'factory' - } - } - if self._get_openstack_release() == self.precise_havana: - expected_additional = { - 'composite:neutronapi_v2_0': { - 'use': 'call:neutron.auth:pipeline_factory', - 'noauth': 'extensions neutronapiapp_v2_0', - 'keystone': 'authtoken keystonecontext extensions ' - 'neutronapiapp_v2_0' - } - } - else: - expected_additional = { - 'composite:neutronapi_v2_0': { - 'use': 'call:neutron.auth:pipeline_factory', - 'noauth': 'request_id catch_errors extensions ' - 'neutronapiapp_v2_0', - 'keystone': 'request_id catch_errors authtoken ' - 'keystonecontext extensions ' - 'neutronapiapp_v2_0' - } - } - expected = dict(expected.items() + expected_additional.items()) - else: - conf = '/etc/quantum/api-paste.ini' - expected = { - 'composite:quantum': { - 'use': 'egg:Paste#urlmap', - '/': 'quantumversions', - '/v2.0': 'quantumapi_v2_0' - }, - 'composite:quantumapi_v2_0': { - 'use': 'call:quantum.auth:pipeline_factory', - 'noauth': 'extensions quantumapiapp_v2_0', - 'keystone': 'authtoken keystonecontext extensions ' - 'quantumapiapp_v2_0', - }, - 'filter:keystonecontext': { - 'paste.filter_factory': 'quantum.auth:' - 'QuantumKeystoneContext.factory' - }, - 'filter:authtoken': { - 'paste.filter_factory': 'keystoneclient.middleware.' - 'auth_token:filter_factory' - }, - 'filter:extensions': { - 'paste.filter_factory': 'quantum.api.extensions:' - 'plugin_aware_extension_middleware_' - 'factory' - }, - 'app:quantumversions': { - 'paste.app_factory': 'quantum.api.versions:Versions.factory' - }, - 'app:quantumapiapp_v2_0': { - 'paste.app_factory': 'quantum.api.v2.router:APIRouter.' - 'factory' - } - } - - for section, pairs in expected.iteritems(): - ret = u.validate_config_data(unit, conf, section, pairs) - if ret: - message = "api paste config error: {}".format(ret) - amulet.raise_status(amulet.FAIL, msg=message) - def test_dhcp_agent_config(self): """Verify the data in the dhcp agent config file.""" unit = self.quantum_gateway_sentry diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py index f80aab3d..c9fd5a96 100644 --- a/unit_tests/__init__.py +++ b/unit_tests/__init__.py @@ -1,2 +1,4 @@ import sys + +sys.path.append('actions') sys.path.append('hooks') diff --git a/unit_tests/test_actions_git_reinstall.py b/unit_tests/test_actions_git_reinstall.py new file mode 100644 index 00000000..e38fb6b7 --- /dev/null +++ b/unit_tests/test_actions_git_reinstall.py @@ -0,0 +1,85 @@ +from mock import patch + +with patch('charmhelpers.core.hookenv.config') as config: + config.return_value = 'neutron' + import quantum_utils as utils # noqa + +import git_reinstall + +from test_utils import ( + CharmTestCase +) + +TO_PATCH = [ + 'config', +] + + +openstack_origin_git = \ + """repositories: + - {name: requirements, + repository: 'git://git.openstack.org/openstack/requirements', + branch: stable/juno} + - {name: neutron, + repository: 'git://git.openstack.org/openstack/neutron', + branch: stable/juno}""" + + +class TestNeutronAPIActions(CharmTestCase): + + def setUp(self): + super(TestNeutronAPIActions, self).setUp(git_reinstall, TO_PATCH) + self.config.side_effect = self.test_config.get + + @patch.object(git_reinstall, 'action_set') + @patch.object(git_reinstall, 'action_fail') + @patch.object(git_reinstall, 'git_install') + def test_git_reinstall(self, git_install, action_fail, action_set): + self.test_config.set('openstack-origin-git', openstack_origin_git) + + git_reinstall.git_reinstall() + + git_install.assert_called_with(openstack_origin_git) + self.assertTrue(git_install.called) + self.assertFalse(action_set.called) + self.assertFalse(action_fail.called) + + @patch.object(git_reinstall, 'action_set') + @patch.object(git_reinstall, 'action_fail') + @patch.object(git_reinstall, 'git_install') + @patch('charmhelpers.contrib.openstack.utils.config') + def test_git_reinstall_not_configured(self, _config, git_install, + action_fail, action_set): + _config.return_value = None + + git_reinstall.git_reinstall() + + msg = 'openstack-origin-git is not configured' + action_fail.assert_called_with(msg) + self.assertFalse(git_install.called) + self.assertFalse(action_set.called) + + @patch.object(git_reinstall, 'action_set') + @patch.object(git_reinstall, 'action_fail') + @patch.object(git_reinstall, 'git_install') + @patch('charmhelpers.contrib.openstack.utils.config') + def test_git_reinstall_exception(self, _config, git_install, + action_fail, action_set): + _config.return_value = openstack_origin_git + e = OSError('something bad happened') + git_install.side_effect = e + traceback = ( + "Traceback (most recent call last):\n" + " File \"actions/git_reinstall.py\", line 33, in git_reinstall\n" + " git_install(config(\'openstack-origin-git\'))\n" + " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 964, in __call__\n" # noqa + " return _mock_self._mock_call(*args, **kwargs)\n" + " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 1019, in _mock_call\n" # noqa + " raise effect\n" + "OSError: something bad happened\n") + + git_reinstall.git_reinstall() + + msg = 'git-reinstall resulted in an unexpected error' + action_fail.assert_called_with(msg) + action_set.assert_called_with({'traceback': traceback}) diff --git a/unit_tests/test_quantum_hooks.py b/unit_tests/test_quantum_hooks.py index dc5d5d50..a530352e 100644 --- a/unit_tests/test_quantum_hooks.py +++ b/unit_tests/test_quantum_hooks.py @@ -1,4 +1,5 @@ from mock import MagicMock, patch, call +import yaml import charmhelpers.core.hookenv as hookenv hookenv.config = MagicMock() import quantum_utils as utils @@ -23,6 +24,7 @@ TO_PATCH = [ 'filter_installed_packages', 'get_early_packages', 'get_packages', + 'git_install', 'log', 'do_openstack_upgrade', 'openstack_upgrade_available', @@ -103,9 +105,46 @@ class TestQuantumHooks(CharmTestCase): self.assertTrue(self.log.called) _exit.assert_called_with(1) - def test_config_changed(self): + @patch.object(utils, 'git_install_requested') + def test_install_hook_git(self, git_requested): + git_requested.return_value = True + self.valid_plugin.return_value = True + _pkgs = ['foo', 'bar'] + self.filter_installed_packages.return_value = _pkgs + repo = 'cloud:trusty-juno' + openstack_origin_git = { + 'repositories': [ + {'name': 'requirements', + 'repository': 'git://git.openstack.org/openstack/requirements', # noqa + 'branch': 'stable/juno'}, + {'name': 'neutron', + 'repository': 'git://git.openstack.org/openstack/neutron', + 'branch': 'stable/juno'} + ], + 'directory': '/mnt/openstack-git', + } + projects_yaml = yaml.dump(openstack_origin_git) + self.test_config.set('openstack-origin', repo) + self.test_config.set('openstack-origin-git', projects_yaml) + self._call_hook('install') + self.configure_installation_source.assert_called_with( + 'cloud:trusty-juno' + ) + self.apt_update.assert_called_with(fatal=True) + self.apt_install.assert_has_calls([ + call(_pkgs, fatal=True), + call(_pkgs, fatal=True), + ]) + self.assertTrue(self.get_early_packages.called) + self.assertTrue(self.get_packages.called) + self.git_install.assert_called_with(projects_yaml) + self.assertTrue(self.execd_preinstall.called) + + @patch.object(hooks, 'git_install_requested') + def test_config_changed(self, git_requested): def mock_relids(rel): return ['relid'] + git_requested.return_value = False self.test_config.set('sysctl', '{ kernel.max_pid: "1337"}') self.openstack_upgrade_available.return_value = True self.valid_plugin.return_value = True @@ -125,14 +164,18 @@ class TestQuantumHooks(CharmTestCase): self.assertTrue(_zmq_joined.called) self.create_sysctl.assert_called() - def test_config_changed_upgrade(self): + @patch.object(hooks, 'git_install_requested') + def test_config_changed_upgrade(self, git_requested): + git_requested.return_value = False self.openstack_upgrade_available.return_value = True self.valid_plugin.return_value = True self._call_hook('config-changed') self.assertTrue(self.do_openstack_upgrade.called) self.assertTrue(self.configure_ovs.called) - def test_config_changed_n1kv(self): + @patch.object(hooks, 'git_install_requested') + def test_config_changed_n1kv(self, git_requested): + git_requested.return_value = False self.openstack_upgrade_available.return_value = False self.valid_plugin.return_value = True self.filter_installed_packages.side_effect = lambda p: p @@ -144,12 +187,56 @@ class TestQuantumHooks(CharmTestCase): self.apt_purge.assert_called_with('neutron-l3-agent') @patch('sys.exit') - def test_config_changed_invalid_plugin(self, _exit): + @patch.object(hooks, 'git_install_requested') + def test_config_changed_invalid_plugin(self, git_requested, _exit): + git_requested.return_value = False self.valid_plugin.return_value = False self._call_hook('config-changed') self.assertTrue(self.log.called) _exit.assert_called_with(1) + @patch.object(hooks, 'git_install_requested') + @patch.object(hooks, 'config_value_changed') + def test_config_changed_git(self, config_val_changed, git_requested): + def mock_relids(rel): + return ['relid'] + git_requested.return_value = True + self.test_config.set('sysctl', '{ kernel.max_pid: "1337"}') + self.openstack_upgrade_available.return_value = True + self.valid_plugin.return_value = True + self.relation_ids.side_effect = mock_relids + _db_joined = self.patch('db_joined') + _pgsql_db_joined = self.patch('pgsql_db_joined') + _amqp_joined = self.patch('amqp_joined') + _amqp_nova_joined = self.patch('amqp_nova_joined') + _zmq_joined = self.patch('zeromq_configuration_relation_joined') + repo = 'cloud:trusty-juno' + openstack_origin_git = { + 'repositories': [ + {'name': 'requirements', + 'repository': + 'git://git.openstack.org/openstack/requirements', + 'branch': 'stable/juno'}, + {'name': 'neutron', + 'repository': 'git://git.openstack.org/openstack/neutron', + 'branch': 'stable/juno'} + ], + 'directory': '/mnt/openstack-git', + } + projects_yaml = yaml.dump(openstack_origin_git) + self.test_config.set('openstack-origin', repo) + self.test_config.set('openstack-origin-git', projects_yaml) + self._call_hook('config-changed') + self.git_install.assert_called_with(projects_yaml) + self.assertFalse(self.do_openstack_upgrade.called) + self.assertTrue(self.configure_ovs.called) + self.assertTrue(_db_joined.called) + self.assertTrue(_pgsql_db_joined.called) + self.assertTrue(_amqp_joined.called) + self.assertTrue(_amqp_nova_joined.called) + self.assertTrue(_zmq_joined.called) + self.create_sysctl.assert_called() + def test_upgrade_charm(self): _install = self.patch('install') _config_changed = self.patch('config_changed') diff --git a/unit_tests/test_quantum_utils.py b/unit_tests/test_quantum_utils.py index 7fa472c6..5ad5f00b 100644 --- a/unit_tests/test_quantum_utils.py +++ b/unit_tests/test_quantum_utils.py @@ -49,6 +49,15 @@ TO_PATCH = [ 'NeutronAPIContext', ] +openstack_origin_git = \ + """repositories: + - {name: requirements, + repository: 'git://git.openstack.org/openstack/requirements', + branch: stable/juno} + - {name: neutron, + repository: 'git://git.openstack.org/openstack/neutron', + branch: stable/juno}""" + class TestQuantumUtils(CharmTestCase): @@ -110,36 +119,48 @@ class TestQuantumUtils(CharmTestCase): self.assertEquals(quantum_utils.get_early_packages(), []) - def test_get_packages_ovs(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_ovs(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'havana' self.assertNotEqual(quantum_utils.get_packages(), []) - def test_get_packages_ovs_icehouse(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_ovs_icehouse(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'icehouse' self.assertTrue('neutron-vpn-agent' in quantum_utils.get_packages()) self.assertFalse('neutron-l3-agent' in quantum_utils.get_packages()) - def test_get_packages_ovs_juno_utopic(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_ovs_juno_utopic(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'juno' self._set_distrib_codename('utopic') self.assertFalse('neutron-vpn-agent' in quantum_utils.get_packages()) self.assertTrue('neutron-l3-agent' in quantum_utils.get_packages()) - def test_get_packages_ovs_juno_trusty(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_ovs_juno_trusty(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'juno' self.assertTrue('neutron-vpn-agent' in quantum_utils.get_packages()) self.assertFalse('neutron-l3-agent' in quantum_utils.get_packages()) - def test_get_packages_ovs_kilo(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_ovs_kilo(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'kilo' self.assertTrue('python-neutron-fwaas' in quantum_utils.get_packages()) - def test_get_packages_l3ha(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_get_packages_l3ha(self, git_requested): + git_requested.return_value = False self.config.return_value = 'ovs' self.get_os_codename_install_source.return_value = 'juno' self.assertTrue('keepalived' in quantum_utils.get_packages()) @@ -204,7 +225,9 @@ class TestQuantumUtils(CharmTestCase): # Not called since we have a bogus bridge in data-ports self.assertFalse(self.add_bridge_port.called) - def test_do_openstack_upgrade(self): + @patch.object(quantum_utils, 'git_install_requested') + def test_do_openstack_upgrade(self, git_requested): + git_requested.return_value = False self.config.side_effect = self.test_config.get self.is_relation_made.return_value = False self.test_config.set('openstack-origin', 'cloud:precise-havana') @@ -671,3 +694,453 @@ class TestQuantumAgentReallocation(CharmTestCase): self.assertTrue(self.log.called) assert not dummy_client.remove_router_from_l3_agent.called assert not dummy_client.remove_network_from_dhcp_agent.called + + @patch.object(quantum_utils, 'git_install_requested') + @patch.object(quantum_utils, 'git_clone_and_install') + @patch.object(quantum_utils, 'git_post_install') + @patch.object(quantum_utils, 'git_pre_install') + def test_git_install(self, git_pre, git_post, git_clone_and_install, + git_requested): + projects_yaml = openstack_origin_git + git_requested.return_value = True + quantum_utils.git_install(projects_yaml) + self.assertTrue(git_pre.called) + git_clone_and_install.assert_called_with(openstack_origin_git, + core_project='neutron') + self.assertTrue(git_post.called) + + @patch.object(quantum_utils, 'mkdir') + @patch.object(quantum_utils, 'write_file') + @patch.object(quantum_utils, 'add_user_to_group') + @patch.object(quantum_utils, 'add_group') + @patch.object(quantum_utils, 'adduser') + def test_git_pre_install(self, adduser, add_group, add_user_to_group, + write_file, mkdir): + quantum_utils.git_pre_install() + adduser.assert_called_with('neutron', shell='/bin/bash', + system_user=True) + add_group.assert_called_with('neutron', system_group=True) + add_user_to_group.assert_called_with('neutron', 'neutron') + expected = [ + call('/etc/neutron', owner='neutron', + group='neutron', perms=0700, force=False), + call('/etc/neutron/rootwrap.d', owner='neutron', + group='neutron', perms=0700, force=False), + call('/etc/neutron/plugins', owner='neutron', + group='neutron', perms=0700, force=False), + call('/etc/nova', owner='neutron', + group='neutron', perms=0700, force=False), + call('/var/lib/neutron', owner='neutron', + group='neutron', perms=0700, force=False), + call('/var/lib/neutron/lock', owner='neutron', + group='neutron', perms=0700, force=False), + call('/var/log/neutron', owner='neutron', + group='neutron', perms=0700, force=False), + ] + self.assertEquals(mkdir.call_args_list, expected) + expected = [ + call('/var/log/neutron/bigswitch-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/dhcp-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/l3-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/lbaas-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/ibm-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/linuxbridge-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/metadata-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/metering_agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/mlnx-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/nec-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/nvsd-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/openflow-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/openvswitch-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/ovs-cleanup.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/ryu-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/server.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/sriov-agent.log', '', owner='neutron', + group='neutron', perms=0644), + call('/var/log/neutron/vpn_agent.log', '', owner='neutron', + group='neutron', perms=0644), + ] + self.assertEquals(write_file.call_args_list, expected) + + @patch.object(quantum_utils, 'git_src_dir') + @patch.object(quantum_utils, 'render') + @patch('os.path.join') + @patch('os.path.exists') + @patch('os.symlink') + @patch('shutil.rmtree') + @patch('shutil.copyfile') + @patch('shutil.copytree') + def test_git_post_install(self, copytree, copyfile, rmtree, symlink, + exists, join, render, git_src_dir): + projects_yaml = openstack_origin_git + join.return_value = 'joined-string' + quantum_utils.git_post_install(projects_yaml) + expected = [ + call('joined-string', '/etc/neutron/api-paste.ini'), + call('joined-string', '/etc/neutron/dhcp_agent.ini'), + call('joined-string', '/etc/neutron/fwaas_driver.ini'), + call('joined-string', '/etc/neutron/l3_agent.ini'), + call('joined-string', '/etc/neutron/lbaas_agent.ini'), + call('joined-string', '/etc/neutron/metadata_agent.ini'), + call('joined-string', '/etc/neutron/metering_agent.ini'), + call('joined-string', '/etc/neutron/policy.json'), + call('joined-string', '/etc/neutron/rootwrap.conf'), + call('joined-string', '/etc/neutron/vpn_agent.ini'), + ] + copyfile.assert_has_calls(expected, any_order=True) + expected = [ + call('joined-string', '/etc/neutron/plugins/bigswitch'), + call('joined-string', '/etc/neutron/plugins/brocade'), + call('joined-string', '/etc/neutron/plugins/cisco'), + call('joined-string', '/etc/neutron/plugins/hyperv'), + call('joined-string', '/etc/neutron/plugins/ibm'), + call('joined-string', '/etc/neutron/plugins/metaplugin'), + call('joined-string', '/etc/neutron/plugins/midonet'), + call('joined-string', '/etc/neutron/plugins/ml2'), + call('joined-string', '/etc/neutron/plugins/mlnx'), + call('joined-string', '/etc/neutron/plugins/nec'), + call('joined-string', '/etc/neutron/plugins/nuage'), + call('joined-string', '/etc/neutron/plugins/oneconvergence'), + call('joined-string', '/etc/neutron/plugins/opencontrail'), + call('joined-string', '/etc/neutron/plugins/plumgrid'), + call('joined-string', '/etc/neutron/plugins/ryu'), + call('joined-string', '/etc/neutron/plugins/vmware'), + ] + copytree.assert_has_calls(expected, any_order=True) + expected = [ + call('joined-string', + '/etc/neutron/rootwrap.d/dhcp.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/ipset-firewall.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/iptables-firewall.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/l3.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/lbaas-haproxy.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/linuxbridge-plugin.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/nec-plugin.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/openvswitch-plugin.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/ryu-plugin.filters'), + call('joined-string', + '/etc/neutron/rootwrap.d/vpnaas.filters'), + ] + copyfile.assert_has_calls(expected, any_order=True) + expected = [ + call('/usr/local/bin/neutron-rootwrap', + '/usr/bin/neutron-rootwrap'), + ] + symlink.assert_has_calls(expected) + service_name = 'quantum-gateway' + user_name = 'neutron' + neutron_api_context = { + 'service_description': 'Neutron API server', + 'charm_name': 'neutron-api', + 'process_name': 'neutron-server', + } + neutron_dhcp_agent_context = { + 'service_description': 'Neutron DHCP Agent', + 'service_name': service_name, + 'process_name': 'neutron-dhcp-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/dhcp_agent.ini'], + 'log_file': '/var/log/neutron/dhcp-agent.log', + } + neutron_l3_agent_context = { + 'service_description': 'Neutron L3 Agent', + 'service_name': service_name, + 'process_name': 'neutron-l3-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/l3_agent.ini', + '/etc/neutron/fwaas_driver.ini'], + 'log_file': '/var/log/neutron/l3-agent.log', + } + neutron_lbaas_agent_context = { + 'service_description': 'Neutron LBaaS Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-lbaas-agent', + 'executable_name': '/usr/local/bin/neutron-lbaas-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/lbaas_agent.ini'], + 'log_file': '/var/log/neutron/lbaas-agent.log', + } + neutron_metadata_agent_context = { + 'service_description': 'Neutron Metadata Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-metadata-agent', + 'executable_name': '/usr/local/bin/neutron-metadata-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/metadata_agent.ini'], + 'log_file': '/var/log/neutron/metadata-agent.log', + } + neutron_metering_agent_context = { + 'service_description': 'Neutron Metering Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-metering-agent', + 'executable_name': '/usr/local/bin/neutron-metering-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/metering_agent.ini'], + 'log_file': '/var/log/neutron/metering-agent.log', + } + neutron_ovs_cleanup_context = { + 'service_description': 'Neutron OVS cleanup', + 'service_name': service_name, + 'process_name': 'neutron-ovs-cleanup', + 'config_file': '/etc/neutron/neutron.conf', + 'log_file': '/var/log/neutron/ovs-cleanup.log', + } + neutron_plugin_bigswitch_context = { + 'service_description': 'Neutron BigSwitch Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-restproxy-agent', + 'executable_name': '/usr/local/bin/neutron-restproxy-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/bigswitch/restproxy.ini'], + 'log_file': '/var/log/neutron/bigswitch-agent.log', + } + neutron_plugin_ibm_context = { + 'service_description': 'Neutron IBM SDN Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ibm-agent', + 'executable_name': '/usr/local/bin/neutron-ibm-agent', + 'config_files': + ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ibm/sdnve_neutron_plugin.ini'], + 'log_file': '/var/log/neutron/ibm-agent.log', + } + neutron_plugin_linuxbridge_context = { + 'service_description': 'Neutron Linux Bridge Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-linuxbridge-agent', + 'executable_name': '/usr/local/bin/neutron-linuxbridge-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf.ini'], + 'log_file': '/var/log/neutron/linuxbridge-agent.log', + } + neutron_plugin_mlnx_context = { + 'service_description': 'Neutron MLNX Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-mlnx-agent', + 'executable_name': '/usr/local/bin/neutron-mlnx-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/mlnx/mlnx_conf.ini'], + 'log_file': '/var/log/neutron/mlnx-agent.log', + } + neutron_plugin_nec_context = { + 'service_description': 'Neutron NEC Plugin Agent', + 'service_name': service_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-nec-agent', + 'executable_name': '/usr/local/bin/neutron-nec-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/nec/nec.ini'], + 'log_file': '/var/log/neutron/nec-agent.log', + } + neutron_plugin_oneconvergence_context = { + 'service_description': 'Neutron One Convergence Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-nvsd-agent', + 'executable_name': '/usr/local/bin/neutron-nvsd-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/oneconvergence/nvsdplugin.ini'], + 'log_file': '/var/log/neutron/nvsd-agent.log', + } + neutron_plugin_openflow_context = { + 'service_description': 'Neutron OpenFlow Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ofagent-agent', + 'executable_name': '/usr/local/bin/neutron-ofagent-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf_ofa.ini'], + 'log_file': '/var/log/neutron/openflow-agent.log', + } + neutron_plugin_openvswitch_context = { + 'service_description': 'Neutron OpenvSwitch Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-openvswitch-agent', + 'executable_name': '/usr/local/bin/neutron-openvswitch-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf.ini'], + 'log_file': '/var/log/neutron/openvswitch-agent.log', + } + neutron_plugin_ryu_context = { + 'service_description': 'Neutron RYU Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-ryu-agent', + 'executable_name': '/usr/local/bin/neutron-ryu-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ryu/ryu.ini'], + 'log_file': '/var/log/neutron/ryu-agent.log', + } + neutron_plugin_sriov_context = { + 'service_description': 'Neutron SRIOV SDN Plugin Agent', + 'service_name': service_name, + 'user_name': user_name, + 'start_dir': '/var/lib/neutron', + 'process_name': 'neutron-sriov-nic-agent', + 'executable_name': '/usr/local/bin/neutron-sriov-nic-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/plugins/ml2/ml2_conf_sriov'], + 'log_file': '/var/log/neutron/sriov-agent.log', + } + neutron_api_context = { + 'service_description': 'Neutron API server', + 'service_name': service_name, + 'process_name': 'neutron-server', + } + neutron_vpn_agent_context = { + 'service_description': 'Neutron VPN Agent', + 'service_name': service_name, + 'process_name': 'neutron-vpn-agent', + 'config_files': ['/etc/neutron/neutron.conf', + '/etc/neutron/vpn_agent.ini', + '/etc/neutron/l3_agent.ini', + '/etc/neutron/fwaas_driver.ini'], + 'log_file': '/var/log/neutron/vpn_agent.log', + } + expected = [ + call('neutron_sudoers', + '/etc/sudoers.d/neutron_sudoers', + {}, perms=0o440), + call('cron.d/neutron-dhcp-agent-netns-cleanup', + '/etc/cron.d/neutron-dhcp-agent-netns-cleanup', + {}, perms=0o755), + call('cron.d/neutron-l3-agent-netns-cleanup', + '/etc/cron.d/neutron-l3-agent-netns-cleanup', + {}, perms=0o755), + call('cron.d/neutron-lbaas-agent-netns-cleanup', + '/etc/cron.d/neutron-lbaas-agent-netns-cleanup', + {}, perms=0o755), + call('upstart/neutron-agent.upstart', + '/etc/init/neutron-dhcp-agent.conf', + neutron_dhcp_agent_context, perms=0o644), + call('upstart/neutron-agent.upstart', + '/etc/init/neutron-l3-agent.conf', + neutron_l3_agent_context, perms=0o644), + call('git.upstart', + '/etc/init/neutron-lbaas-agent.conf', + neutron_lbaas_agent_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-metadata-agent.conf', + neutron_metadata_agent_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-metering-agent.conf', + neutron_metering_agent_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-ovs-cleanup.conf', + neutron_ovs_cleanup_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-bigswitch-agent.conf', + neutron_plugin_bigswitch_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-ibm-agent.conf', + neutron_plugin_ibm_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-linuxbridge-agent.conf', + neutron_plugin_linuxbridge_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-mlnx-agent.conf', + neutron_plugin_mlnx_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-nec-agent.conf', + neutron_plugin_nec_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-oneconvergence-agent.conf', + neutron_plugin_oneconvergence_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-openflow-agent.conf', + neutron_plugin_openflow_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-openvswitch-agent.conf', + neutron_plugin_openvswitch_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-ryu-agent.conf', + neutron_plugin_ryu_context, perms=0o644, + templates_dir='joined-string'), + call('git.upstart', + '/etc/init/neutron-plugin-sriov-agent.conf', + neutron_plugin_sriov_context, perms=0o644, + templates_dir='joined-string'), + call('upstart/neutron-server.upstart', + '/etc/init/neutron-server.conf', + neutron_api_context, perms=0o644), + call('upstart/neutron-agent.upstart', + '/etc/init/neutron-vpn-agent.conf', + neutron_vpn_agent_context, perms=0o644), + ] + self.assertEquals(render.call_args_list, expected) + expected = [ + call('neutron-dhcp-agent'), + call('neutron-l3-agent'), + call('neutron-lbaas-agent'), + call('neutron-metadata-agent'), + call('neutron-metering-agent'), + call('neutron-ovs-cleanup'), + call('neutron-plugin-bigswitch'), + call('neutron-plugin-ibm-agent'), + call('neutron-plugin-linuxbridge-agent'), + call('neutron-plugin-mlnx-agent'), + call('neutron-plugin-nec-agent'), + call('neutron-plugin-oneconvergence-agent'), + call('neutron-plugin-openflow-agent'), + call('neutron-plugin-openvswitch-agent'), + call('neutron-plugin-ryu-agent'), + call('neutron-plugin-sriov-agent'), + call('neutron-server'), + call('neutron-vpn-agent'), + ] + self.assertEquals(self.service_restart.call_args_list, expected) From 3a1c1b2007f2c601e33219c353756663e8d838f9 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Mon, 13 Apr 2015 12:13:17 +0000 Subject: [PATCH 02/10] Get http_proxy from AMULET_HTTP_PROXY env var --- tests/basic_deployment.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index ced1909a..98367abc 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -1,6 +1,7 @@ #!/usr/bin/python import amulet +import os import time import yaml try: @@ -70,6 +71,7 @@ class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): quantum_gateway_config = {} if self.git: branch = 'stable/' + self._get_openstack_release_string() + amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY') openstack_origin_git = { 'repositories': [ {'name': 'requirements', @@ -80,8 +82,8 @@ class QuantumGatewayBasicDeployment(OpenStackAmuletDeployment): 'branch': branch}, ], 'directory': '/mnt/openstack-git', - 'http_proxy': 'http://squid.internal:3128', - 'https_proxy': 'https://squid.internal:3128', + 'http_proxy': amulet_http_proxy, + 'https_proxy': amulet_http_proxy, } quantum_gateway_config['openstack-origin-git'] = yaml.dump(openstack_origin_git) keystone_config = {'admin-password': 'openstack', From e81544c2242c5d81d19f9feaeacea150577b7e73 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Mon, 13 Apr 2015 14:24:40 +0000 Subject: [PATCH 03/10] Move deploy from source template files to templates/git --- hooks/quantum_utils.py | 16 ++++++++-------- .../cron.d/neutron-dhcp-agent-netns-cleanup | 0 .../cron.d/neutron-l3-agent-netns-cleanup | 0 .../cron.d/neutron-lbaas-agent-netns-cleanup | 0 templates/{ => git}/neutron_sudoers | 0 .../{ => git}/upstart/neutron-agent.upstart | 0 .../upstart/neutron-ovs-cleanup.upstart | 0 .../{ => git}/upstart/neutron-server.upstart | 0 unit_tests/test_quantum_utils.py | 16 ++++++++-------- 9 files changed, 16 insertions(+), 16 deletions(-) rename templates/{ => git}/cron.d/neutron-dhcp-agent-netns-cleanup (100%) rename templates/{ => git}/cron.d/neutron-l3-agent-netns-cleanup (100%) rename templates/{ => git}/cron.d/neutron-lbaas-agent-netns-cleanup (100%) rename templates/{ => git}/neutron_sudoers (100%) rename templates/{ => git}/upstart/neutron-agent.upstart (100%) rename templates/{ => git}/upstart/neutron-ovs-cleanup.upstart (100%) rename templates/{ => git}/upstart/neutron-server.upstart (100%) diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index 3dd8fa1b..3e96221f 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -1046,13 +1046,13 @@ def git_post_install(projects_yaml): os.remove(s['link']) os.symlink(s['src'], s['link']) - render('neutron_sudoers', + render('git/neutron_sudoers', '/etc/sudoers.d/neutron_sudoers', {}, perms=0o440) - render('cron.d/neutron-dhcp-agent-netns-cleanup', + render('git/cron.d/neutron-dhcp-agent-netns-cleanup', '/etc/cron.d/neutron-dhcp-agent-netns-cleanup', {}, perms=0o755) - render('cron.d/neutron-l3-agent-netns-cleanup', + render('git/cron.d/neutron-l3-agent-netns-cleanup', '/etc/cron.d/neutron-l3-agent-netns-cleanup', {}, perms=0o755) - render('cron.d/neutron-lbaas-agent-netns-cleanup', + render('git/cron.d/neutron-lbaas-agent-netns-cleanup', '/etc/cron.d/neutron-lbaas-agent-netns-cleanup', {}, perms=0o755) service_name = 'quantum-gateway' @@ -1242,10 +1242,10 @@ def git_post_install(projects_yaml): # NOTE(coreycb): Needs systemd support templates_dir = 'hooks/charmhelpers/contrib/openstack/templates' templates_dir = os.path.join(charm_dir(), templates_dir) - render('upstart/neutron-agent.upstart', + render('git/upstart/neutron-agent.upstart', '/etc/init/neutron-dhcp-agent.conf', neutron_dhcp_agent_context, perms=0o644) - render('upstart/neutron-agent.upstart', + render('git/upstart/neutron-agent.upstart', '/etc/init/neutron-l3-agent.conf', neutron_l3_agent_context, perms=0o644) render('git.upstart', @@ -1304,10 +1304,10 @@ def git_post_install(projects_yaml): '/etc/init/neutron-plugin-sriov-agent.conf', neutron_plugin_sriov_context, perms=0o644, templates_dir=templates_dir) - render('upstart/neutron-server.upstart', + render('git/upstart/neutron-server.upstart', '/etc/init/neutron-server.conf', neutron_api_context, perms=0o644) - render('upstart/neutron-agent.upstart', + render('git/upstart/neutron-agent.upstart', '/etc/init/neutron-vpn-agent.conf', neutron_vpn_agent_context, perms=0o644) diff --git a/templates/cron.d/neutron-dhcp-agent-netns-cleanup b/templates/git/cron.d/neutron-dhcp-agent-netns-cleanup similarity index 100% rename from templates/cron.d/neutron-dhcp-agent-netns-cleanup rename to templates/git/cron.d/neutron-dhcp-agent-netns-cleanup diff --git a/templates/cron.d/neutron-l3-agent-netns-cleanup b/templates/git/cron.d/neutron-l3-agent-netns-cleanup similarity index 100% rename from templates/cron.d/neutron-l3-agent-netns-cleanup rename to templates/git/cron.d/neutron-l3-agent-netns-cleanup diff --git a/templates/cron.d/neutron-lbaas-agent-netns-cleanup b/templates/git/cron.d/neutron-lbaas-agent-netns-cleanup similarity index 100% rename from templates/cron.d/neutron-lbaas-agent-netns-cleanup rename to templates/git/cron.d/neutron-lbaas-agent-netns-cleanup diff --git a/templates/neutron_sudoers b/templates/git/neutron_sudoers similarity index 100% rename from templates/neutron_sudoers rename to templates/git/neutron_sudoers diff --git a/templates/upstart/neutron-agent.upstart b/templates/git/upstart/neutron-agent.upstart similarity index 100% rename from templates/upstart/neutron-agent.upstart rename to templates/git/upstart/neutron-agent.upstart diff --git a/templates/upstart/neutron-ovs-cleanup.upstart b/templates/git/upstart/neutron-ovs-cleanup.upstart similarity index 100% rename from templates/upstart/neutron-ovs-cleanup.upstart rename to templates/git/upstart/neutron-ovs-cleanup.upstart diff --git a/templates/upstart/neutron-server.upstart b/templates/git/upstart/neutron-server.upstart similarity index 100% rename from templates/upstart/neutron-server.upstart rename to templates/git/upstart/neutron-server.upstart diff --git a/unit_tests/test_quantum_utils.py b/unit_tests/test_quantum_utils.py index 5ad5f00b..b64f3f37 100644 --- a/unit_tests/test_quantum_utils.py +++ b/unit_tests/test_quantum_utils.py @@ -1041,22 +1041,22 @@ class TestQuantumAgentReallocation(CharmTestCase): 'log_file': '/var/log/neutron/vpn_agent.log', } expected = [ - call('neutron_sudoers', + call('git/neutron_sudoers', '/etc/sudoers.d/neutron_sudoers', {}, perms=0o440), - call('cron.d/neutron-dhcp-agent-netns-cleanup', + call('git/cron.d/neutron-dhcp-agent-netns-cleanup', '/etc/cron.d/neutron-dhcp-agent-netns-cleanup', {}, perms=0o755), - call('cron.d/neutron-l3-agent-netns-cleanup', + call('git/cron.d/neutron-l3-agent-netns-cleanup', '/etc/cron.d/neutron-l3-agent-netns-cleanup', {}, perms=0o755), - call('cron.d/neutron-lbaas-agent-netns-cleanup', + call('git/cron.d/neutron-lbaas-agent-netns-cleanup', '/etc/cron.d/neutron-lbaas-agent-netns-cleanup', {}, perms=0o755), - call('upstart/neutron-agent.upstart', + call('git/upstart/neutron-agent.upstart', '/etc/init/neutron-dhcp-agent.conf', neutron_dhcp_agent_context, perms=0o644), - call('upstart/neutron-agent.upstart', + call('git/upstart/neutron-agent.upstart', '/etc/init/neutron-l3-agent.conf', neutron_l3_agent_context, perms=0o644), call('git.upstart', @@ -1115,10 +1115,10 @@ class TestQuantumAgentReallocation(CharmTestCase): '/etc/init/neutron-plugin-sriov-agent.conf', neutron_plugin_sriov_context, perms=0o644, templates_dir='joined-string'), - call('upstart/neutron-server.upstart', + call('git/upstart/neutron-server.upstart', '/etc/init/neutron-server.conf', neutron_api_context, perms=0o644), - call('upstart/neutron-agent.upstart', + call('git/upstart/neutron-agent.upstart', '/etc/init/neutron-vpn-agent.conf', neutron_vpn_agent_context, perms=0o644), ] From b8cd0419f044b5b51f5364c65d90b881b0d23d69 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Mon, 13 Apr 2015 18:56:12 +0000 Subject: [PATCH 04/10] Bulk copy files to /etc/neutron --- hooks/quantum_utils.py | 183 ++----------------------------- unit_tests/test_quantum_utils.py | 57 +--------- 2 files changed, 16 insertions(+), 224 deletions(-) diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index 3e96221f..e3726260 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -863,178 +863,19 @@ def git_pre_install(): def git_post_install(projects_yaml): """Perform post-install setup.""" src_etc = os.path.join(git_src_dir(projects_yaml, 'neutron'), 'etc') - etc_configs = { - 'api-paste': { - 'src': os.path.join(src_etc, 'api-paste.ini'), - 'dest': '/etc/neutron/api-paste.ini', - }, - 'dhcp_agent': { - 'src': os.path.join(src_etc, 'dhcp_agent.ini'), - 'dest': '/etc/neutron/dhcp_agent.ini', - }, - 'fwaas_driver': { - 'src': os.path.join(src_etc, 'fwaas_driver.ini'), - 'dest': '/etc/neutron/fwaas_driver.ini', - }, - 'l3_agent': { - 'src': os.path.join(src_etc, 'l3_agent.ini'), - 'dest': '/etc/neutron/l3_agent.ini', - }, - 'lbaas_agent': { - 'src': os.path.join(src_etc, 'lbaas_agent.ini'), - 'dest': '/etc/neutron/lbaas_agent.ini', - }, - 'metadata_agent': { - 'src': os.path.join(src_etc, 'metadata_agent.ini'), - 'dest': '/etc/neutron/metadata_agent.ini', - }, - 'metering_agent': { - 'src': os.path.join(src_etc, 'metering_agent.ini'), - 'dest': '/etc/neutron/metering_agent.ini', - }, - 'policy': { - 'src': os.path.join(src_etc, 'policy.json'), - 'dest': '/etc/neutron/policy.json', - }, - 'rootwrap': { - 'src': os.path.join(src_etc, 'rootwrap.conf'), - 'dest': '/etc/neutron/rootwrap.conf', - }, - 'vpn_agent': { - 'src': os.path.join(src_etc, 'vpn_agent.ini'), - 'dest': '/etc/neutron/vpn_agent.ini', - }, - } + configs = [ + {'src': src_etc, + 'dest': '/etc/neutron'}, + {'src': os.path.join(src_etc, 'neutron/plugins'), + 'dest': '/etc/neutron/plugins'}, + {'src': os.path.join(src_etc, 'neutron/rootwrap.d'), + 'dest': '/etc/neutron/rootwrap.d'}, + ] - for conf, files in etc_configs.iteritems(): - if os.path.exists(files['src']): - shutil.copyfile(files['src'], files['dest']) - - src_plugins = os.path.join(src_etc, 'neutron/plugins') - plugins_configs = { - 'bigswitch': { - 'src': os.path.join(src_plugins, 'bigswitch'), - 'dest': '/etc/neutron/plugins/bigswitch', - }, - 'brocade': { - 'src': os.path.join(src_plugins, 'brocade'), - 'dest': '/etc/neutron/plugins/brocade', - }, - 'cisco': { - 'src': os.path.join(src_plugins, 'cisco'), - 'dest': '/etc/neutron/plugins/cisco', - }, - 'hyperv': { - 'src': os.path.join(src_plugins, 'hyperv'), - 'dest': '/etc/neutron/plugins/hyperv', - }, - 'ibm': { - 'src': os.path.join(src_plugins, 'ibm'), - 'dest': '/etc/neutron/plugins/ibm', - }, - 'metaplugin': { - 'src': os.path.join(src_plugins, 'metaplugin'), - 'dest': '/etc/neutron/plugins/metaplugin', - }, - 'midonet': { - 'src': os.path.join(src_plugins, 'midonet'), - 'dest': '/etc/neutron/plugins/midonet', - }, - 'ml2': { - 'src': os.path.join(src_plugins, 'ml2'), - 'dest': '/etc/neutron/plugins/ml2', - }, - 'mlnx': { - 'src': os.path.join(src_plugins, 'mlnx'), - 'dest': '/etc/neutron/plugins/mlnx', - }, - 'nec': { - 'src': os.path.join(src_plugins, 'nec'), - 'dest': '/etc/neutron/plugins/nec', - }, - 'nuage': { - 'src': os.path.join(src_plugins, 'nuage'), - 'dest': '/etc/neutron/plugins/nuage', - }, - 'oneconvergence': { - 'src': os.path.join(src_plugins, 'oneconvergence'), - 'dest': '/etc/neutron/plugins/oneconvergence', - }, - 'opencontrail': { - 'src': os.path.join(src_plugins, 'opencontrail'), - 'dest': '/etc/neutron/plugins/opencontrail', - }, - 'plumgrid': { - 'src': os.path.join(src_plugins, 'plumgrid'), - 'dest': '/etc/neutron/plugins/plumgrid', - }, - 'ryu': { - 'src': os.path.join(src_plugins, 'ryu'), - 'dest': '/etc/neutron/plugins/ryu', - }, - 'vmware': { - 'src': os.path.join(src_plugins, 'vmware'), - 'dest': '/etc/neutron/plugins/vmware', - }, - } - - for conf, dirs in plugins_configs.iteritems(): - if os.path.exists(dirs['src']): - if os.path.exists(dirs['dest']): - shutil.rmtree(dirs['dest']) - shutil.copytree(dirs['src'], dirs['dest']) - - src_rootwrap = os.path.join(src_etc, 'neutron/rootwrap.d') - rootwrap_configs = { - 'debug-filters': { - 'src': os.path.join(src_rootwrap, 'debug.filters'), - 'dest': '/etc/neutron/rootwrap.d/debug.filters', - }, - 'dhcp-filters': { - 'src': os.path.join(src_rootwrap, 'dhcp.filters'), - 'dest': '/etc/neutron/rootwrap.d/dhcp.filters', - }, - 'ipset-firewall-filters': { - 'src': os.path.join(src_rootwrap, 'ipset-firewall.filters'), - 'dest': '/etc/neutron/rootwrap.d/ipset-firewall.filters', - }, - 'iptables-firewall-filters': { - 'src': os.path.join(src_rootwrap, 'iptables-firewall.filters'), - 'dest': '/etc/neutron/rootwrap.d/iptables-firewall.filters', - }, - 'l3-filters': { - 'src': os.path.join(src_rootwrap, 'l3.filters'), - 'dest': '/etc/neutron/rootwrap.d/l3.filters', - }, - 'lbaas-haproxy': { - 'src': os.path.join(src_rootwrap, 'lbaas-haproxy.filters'), - 'dest': '/etc/neutron/rootwrap.d/lbaas-haproxy.filters', - }, - 'linuxbridge-plugin': { - 'src': os.path.join(src_rootwrap, 'linuxbridge-plugin.filters'), - 'dest': '/etc/neutron/rootwrap.d/linuxbridge-plugin.filters', - }, - 'nec-plugin': { - 'src': os.path.join(src_rootwrap, 'nec-plugin.filters'), - 'dest': '/etc/neutron/rootwrap.d/nec-plugin.filters', - }, - 'openvswitch-plugin': { - 'src': os.path.join(src_rootwrap, 'openvswitch-plugin.filters'), - 'dest': '/etc/neutron/rootwrap.d/openvswitch-plugin.filters', - }, - 'ryu-plugin': { - 'src': os.path.join(src_rootwrap, 'ryu-plugin.filters'), - 'dest': '/etc/neutron/rootwrap.d/ryu-plugin.filters', - }, - 'vpnaas': { - 'src': os.path.join(src_rootwrap, 'vpnaas.filters'), - 'dest': '/etc/neutron/rootwrap.d/vpnaas.filters', - }, - } - - for conf, files in rootwrap_configs.iteritems(): - if os.path.exists(files['src']): - shutil.copyfile(files['src'], files['dest']) + for c in configs: + if os.path.exists(c['dest']): + shutil.rmtree(c['dest']) + shutil.copytree(c['src'], c['dest']) symlinks = [ {'src': '/usr/local/bin/neutron-rootwrap', diff --git a/unit_tests/test_quantum_utils.py b/unit_tests/test_quantum_utils.py index b64f3f37..7af25565 100644 --- a/unit_tests/test_quantum_utils.py +++ b/unit_tests/test_quantum_utils.py @@ -792,60 +792,11 @@ class TestQuantumAgentReallocation(CharmTestCase): join.return_value = 'joined-string' quantum_utils.git_post_install(projects_yaml) expected = [ - call('joined-string', '/etc/neutron/api-paste.ini'), - call('joined-string', '/etc/neutron/dhcp_agent.ini'), - call('joined-string', '/etc/neutron/fwaas_driver.ini'), - call('joined-string', '/etc/neutron/l3_agent.ini'), - call('joined-string', '/etc/neutron/lbaas_agent.ini'), - call('joined-string', '/etc/neutron/metadata_agent.ini'), - call('joined-string', '/etc/neutron/metering_agent.ini'), - call('joined-string', '/etc/neutron/policy.json'), - call('joined-string', '/etc/neutron/rootwrap.conf'), - call('joined-string', '/etc/neutron/vpn_agent.ini'), + call('joined-string', '/etc/neutron'), + call('joined-string', '/etc/neutron/plugins'), + call('joined-string', '/etc/neutron/rootwrap.d'), ] - copyfile.assert_has_calls(expected, any_order=True) - expected = [ - call('joined-string', '/etc/neutron/plugins/bigswitch'), - call('joined-string', '/etc/neutron/plugins/brocade'), - call('joined-string', '/etc/neutron/plugins/cisco'), - call('joined-string', '/etc/neutron/plugins/hyperv'), - call('joined-string', '/etc/neutron/plugins/ibm'), - call('joined-string', '/etc/neutron/plugins/metaplugin'), - call('joined-string', '/etc/neutron/plugins/midonet'), - call('joined-string', '/etc/neutron/plugins/ml2'), - call('joined-string', '/etc/neutron/plugins/mlnx'), - call('joined-string', '/etc/neutron/plugins/nec'), - call('joined-string', '/etc/neutron/plugins/nuage'), - call('joined-string', '/etc/neutron/plugins/oneconvergence'), - call('joined-string', '/etc/neutron/plugins/opencontrail'), - call('joined-string', '/etc/neutron/plugins/plumgrid'), - call('joined-string', '/etc/neutron/plugins/ryu'), - call('joined-string', '/etc/neutron/plugins/vmware'), - ] - copytree.assert_has_calls(expected, any_order=True) - expected = [ - call('joined-string', - '/etc/neutron/rootwrap.d/dhcp.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/ipset-firewall.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/iptables-firewall.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/l3.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/lbaas-haproxy.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/linuxbridge-plugin.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/nec-plugin.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/openvswitch-plugin.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/ryu-plugin.filters'), - call('joined-string', - '/etc/neutron/rootwrap.d/vpnaas.filters'), - ] - copyfile.assert_has_calls(expected, any_order=True) + copytree.assert_has_calls(expected) expected = [ call('/usr/local/bin/neutron-rootwrap', '/usr/bin/neutron-rootwrap'), From 2c4b167557fbbc53a1307e559b6c715c921e7714 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Tue, 14 Apr 2015 00:48:21 +0000 Subject: [PATCH 05/10] Defer starting of services to config-changed when deploying from source --- hooks/quantum_utils.py | 19 ------------------- unit_tests/test_quantum_utils.py | 21 --------------------- 2 files changed, 40 deletions(-) diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index e3726260..d369d9ca 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -1151,22 +1151,3 @@ def git_post_install(projects_yaml): render('git/upstart/neutron-agent.upstart', '/etc/init/neutron-vpn-agent.conf', neutron_vpn_agent_context, perms=0o644) - - service_restart('neutron-dhcp-agent') - service_restart('neutron-l3-agent') - service_restart('neutron-lbaas-agent') - service_restart('neutron-metadata-agent') - service_restart('neutron-metering-agent') - service_restart('neutron-ovs-cleanup') - service_restart('neutron-plugin-bigswitch') - service_restart('neutron-plugin-ibm-agent') - service_restart('neutron-plugin-linuxbridge-agent') - service_restart('neutron-plugin-mlnx-agent') - service_restart('neutron-plugin-nec-agent') - service_restart('neutron-plugin-oneconvergence-agent') - service_restart('neutron-plugin-openflow-agent') - service_restart('neutron-plugin-openvswitch-agent') - service_restart('neutron-plugin-ryu-agent') - service_restart('neutron-plugin-sriov-agent') - service_restart('neutron-server') - service_restart('neutron-vpn-agent') diff --git a/unit_tests/test_quantum_utils.py b/unit_tests/test_quantum_utils.py index 7af25565..63bfbde0 100644 --- a/unit_tests/test_quantum_utils.py +++ b/unit_tests/test_quantum_utils.py @@ -1074,24 +1074,3 @@ class TestQuantumAgentReallocation(CharmTestCase): neutron_vpn_agent_context, perms=0o644), ] self.assertEquals(render.call_args_list, expected) - expected = [ - call('neutron-dhcp-agent'), - call('neutron-l3-agent'), - call('neutron-lbaas-agent'), - call('neutron-metadata-agent'), - call('neutron-metering-agent'), - call('neutron-ovs-cleanup'), - call('neutron-plugin-bigswitch'), - call('neutron-plugin-ibm-agent'), - call('neutron-plugin-linuxbridge-agent'), - call('neutron-plugin-mlnx-agent'), - call('neutron-plugin-nec-agent'), - call('neutron-plugin-oneconvergence-agent'), - call('neutron-plugin-openflow-agent'), - call('neutron-plugin-openvswitch-agent'), - call('neutron-plugin-ryu-agent'), - call('neutron-plugin-sriov-agent'), - call('neutron-server'), - call('neutron-vpn-agent'), - ] - self.assertEquals(self.service_restart.call_args_list, expected) From f6ed4a92f7a86661904db5b189cb21beec8eaf76 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Tue, 14 Apr 2015 00:48:39 +0000 Subject: [PATCH 06/10] Run config-changed hook after git-reinstall action installs from source --- actions/git_reinstall.py | 5 +++++ unit_tests/test_actions_git_reinstall.py | 15 +++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/actions/git_reinstall.py b/actions/git_reinstall.py index 2eab3a33..8f39e7ec 100755 --- a/actions/git_reinstall.py +++ b/actions/git_reinstall.py @@ -18,6 +18,10 @@ from quantum_utils import ( git_install, ) +from quantum_hooks import ( + config_changed, +) + def git_reinstall(): """Reinstall from source and restart services. @@ -38,3 +42,4 @@ def git_reinstall(): if __name__ == '__main__': git_reinstall() + config_changed() diff --git a/unit_tests/test_actions_git_reinstall.py b/unit_tests/test_actions_git_reinstall.py index e38fb6b7..db85cbf4 100644 --- a/unit_tests/test_actions_git_reinstall.py +++ b/unit_tests/test_actions_git_reinstall.py @@ -1,11 +1,22 @@ -from mock import patch +from mock import patch, MagicMock with patch('charmhelpers.core.hookenv.config') as config: config.return_value = 'neutron' import quantum_utils as utils # noqa +# Need to do some early patching to get the module loaded. +_register_configs = utils.register_configs +_restart_map = utils.restart_map + +utils.register_configs = MagicMock() +utils.restart_map = MagicMock() + import git_reinstall +# Unpatch it now that its loaded. +utils.register_configs = _register_configs +utils.restart_map = _restart_map + from test_utils import ( CharmTestCase ) @@ -70,7 +81,7 @@ class TestNeutronAPIActions(CharmTestCase): git_install.side_effect = e traceback = ( "Traceback (most recent call last):\n" - " File \"actions/git_reinstall.py\", line 33, in git_reinstall\n" + " File \"actions/git_reinstall.py\", line 37, in git_reinstall\n" " git_install(config(\'openstack-origin-git\'))\n" " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 964, in __call__\n" # noqa " return _mock_self._mock_call(*args, **kwargs)\n" From 4a24f92738d72941a3a123cb116728083a118860 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Wed, 15 Apr 2015 15:01:55 +0000 Subject: [PATCH 07/10] Fixup test_git_reinstall_exception() --- unit_tests/test_actions_git_reinstall.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/unit_tests/test_actions_git_reinstall.py b/unit_tests/test_actions_git_reinstall.py index db85cbf4..1fb63120 100644 --- a/unit_tests/test_actions_git_reinstall.py +++ b/unit_tests/test_actions_git_reinstall.py @@ -73,8 +73,9 @@ class TestNeutronAPIActions(CharmTestCase): @patch.object(git_reinstall, 'action_set') @patch.object(git_reinstall, 'action_fail') @patch.object(git_reinstall, 'git_install') + @patch('traceback.format_exc') @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall_exception(self, _config, git_install, + def test_git_reinstall_exception(self, _config, format_exc, git_install, action_fail, action_set): _config.return_value = openstack_origin_git e = OSError('something bad happened') @@ -88,6 +89,7 @@ class TestNeutronAPIActions(CharmTestCase): " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 1019, in _mock_call\n" # noqa " raise effect\n" "OSError: something bad happened\n") + format_exc.return_value = traceback git_reinstall.git_reinstall() From 9e705ae48e8a4d8a302b04c0442e7deb4f4ef1a8 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Wed, 15 Apr 2015 15:30:42 +0000 Subject: [PATCH 08/10] Sync charm-helpers --- .../contrib/openstack/amulet/deployment.py | 2 +- hooks/charmhelpers/contrib/openstack/context.py | 15 +++++++++++++++ hooks/charmhelpers/contrib/openstack/neutron.py | 13 +++++++++++++ .../contrib/openstack/templates/git.upstart | 2 ++ hooks/charmhelpers/core/strutils.py | 4 ++-- tests/charmhelpers/contrib/amulet/utils.py | 4 +++- .../contrib/openstack/amulet/deployment.py | 2 +- 7 files changed, 37 insertions(+), 5 deletions(-) diff --git a/hooks/charmhelpers/contrib/openstack/amulet/deployment.py b/hooks/charmhelpers/contrib/openstack/amulet/deployment.py index 0e0db566..fef96384 100644 --- a/hooks/charmhelpers/contrib/openstack/amulet/deployment.py +++ b/hooks/charmhelpers/contrib/openstack/amulet/deployment.py @@ -44,7 +44,7 @@ class OpenStackAmuletDeployment(AmuletDeployment): Determine if the local branch being tested is derived from its stable or next (dev) branch, and based on this, use the corresonding stable or next branches for the other_services.""" - base_charms = ['mysql', 'mongodb', 'rabbitmq-server'] + base_charms = ['mysql', 'mongodb'] if self.stable: for svc in other_services: diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index dd51bfbb..c9914d0d 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -808,6 +808,19 @@ class NeutronContext(OSContextGenerator): return ovs_ctxt + def nuage_ctxt(self): + driver = neutron_plugin_attribute(self.plugin, 'driver', + self.network_manager) + config = neutron_plugin_attribute(self.plugin, 'config', + self.network_manager) + nuage_ctxt = {'core_plugin': driver, + 'neutron_plugin': 'vsp', + 'neutron_security_groups': self.neutron_security_groups, + 'local_ip': unit_private_ip(), + 'config': config} + + return nuage_ctxt + def nvp_ctxt(self): driver = neutron_plugin_attribute(self.plugin, 'driver', self.network_manager) @@ -891,6 +904,8 @@ class NeutronContext(OSContextGenerator): ctxt.update(self.n1kv_ctxt()) elif self.plugin == 'Calico': ctxt.update(self.calico_ctxt()) + elif self.plugin == 'vsp': + ctxt.update(self.nuage_ctxt()) alchemy_flags = config('neutron-alchemy-flags') if alchemy_flags: diff --git a/hooks/charmhelpers/contrib/openstack/neutron.py b/hooks/charmhelpers/contrib/openstack/neutron.py index f8851050..02c92e9c 100644 --- a/hooks/charmhelpers/contrib/openstack/neutron.py +++ b/hooks/charmhelpers/contrib/openstack/neutron.py @@ -180,6 +180,19 @@ def neutron_plugins(): 'nova-api-metadata']], 'server_packages': ['neutron-server', 'calico-control'], 'server_services': ['neutron-server'] + }, + 'vsp': { + 'config': '/etc/neutron/plugins/nuage/nuage_plugin.ini', + 'driver': 'neutron.plugins.nuage.plugin.NuagePlugin', + 'contexts': [ + context.SharedDBContext(user=config('neutron-database-user'), + database=config('neutron-database'), + relation_prefix='neutron', + ssl_dir=NEUTRON_CONF_DIR)], + 'services': [], + 'packages': [], + 'server_packages': ['neutron-server', 'neutron-plugin-nuage'], + 'server_services': ['neutron-server'] } } if release >= 'icehouse': diff --git a/hooks/charmhelpers/contrib/openstack/templates/git.upstart b/hooks/charmhelpers/contrib/openstack/templates/git.upstart index 62af9204..4bed404b 100644 --- a/hooks/charmhelpers/contrib/openstack/templates/git.upstart +++ b/hooks/charmhelpers/contrib/openstack/templates/git.upstart @@ -12,4 +12,6 @@ exec start-stop-daemon --start --chuid {{ user_name }} \ {% for config_file in config_files -%} --config-file={{ config_file }} \ {% endfor -%} + {% if log_file -%} --log-file={{ log_file }} + {% endif -%} diff --git a/hooks/charmhelpers/core/strutils.py b/hooks/charmhelpers/core/strutils.py index efc4402e..a2a784aa 100644 --- a/hooks/charmhelpers/core/strutils.py +++ b/hooks/charmhelpers/core/strutils.py @@ -33,9 +33,9 @@ def bool_from_string(value): value = value.strip().lower() - if value in ['y', 'yes', 'true', 't']: + if value in ['y', 'yes', 'true', 't', 'on']: return True - elif value in ['n', 'no', 'false', 'f']: + elif value in ['n', 'no', 'false', 'f', 'off']: return False msg = "Unable to interpret string value '%s' as boolean" % (value) diff --git a/tests/charmhelpers/contrib/amulet/utils.py b/tests/charmhelpers/contrib/amulet/utils.py index 65219d33..5088b1d1 100644 --- a/tests/charmhelpers/contrib/amulet/utils.py +++ b/tests/charmhelpers/contrib/amulet/utils.py @@ -118,6 +118,9 @@ class AmuletUtils(object): longs, or can be a function that evaluate a variable and returns a bool. """ + self.log.debug('actual: {}'.format(repr(actual))) + self.log.debug('expected: {}'.format(repr(expected))) + for k, v in six.iteritems(expected): if k in actual: if (isinstance(v, six.string_types) or @@ -134,7 +137,6 @@ class AmuletUtils(object): def validate_relation_data(self, sentry_unit, relation, expected): """Validate actual relation data based on expected relation data.""" actual = sentry_unit.relation(relation[0], relation[1]) - self.log.debug('actual: {}'.format(repr(actual))) return self._validate_dict_data(expected, actual) def _validate_list_data(self, expected, actual): diff --git a/tests/charmhelpers/contrib/openstack/amulet/deployment.py b/tests/charmhelpers/contrib/openstack/amulet/deployment.py index 0e0db566..fef96384 100644 --- a/tests/charmhelpers/contrib/openstack/amulet/deployment.py +++ b/tests/charmhelpers/contrib/openstack/amulet/deployment.py @@ -44,7 +44,7 @@ class OpenStackAmuletDeployment(AmuletDeployment): Determine if the local branch being tested is derived from its stable or next (dev) branch, and based on this, use the corresonding stable or next branches for the other_services.""" - base_charms = ['mysql', 'mongodb', 'rabbitmq-server'] + base_charms = ['mysql', 'mongodb'] if self.stable: for svc in other_services: From 6f41aa84bcc845192f4950024420bf8a57d7912e Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Wed, 15 Apr 2015 16:46:22 +0000 Subject: [PATCH 09/10] Move config_changed into try block --- actions/git_reinstall.py | 2 +- unit_tests/test_actions_git_reinstall.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/actions/git_reinstall.py b/actions/git_reinstall.py index 8f39e7ec..3feb17f7 100755 --- a/actions/git_reinstall.py +++ b/actions/git_reinstall.py @@ -35,6 +35,7 @@ def git_reinstall(): try: git_install(config('openstack-origin-git')) + config_changed() except: action_set({'traceback': traceback.format_exc()}) action_fail('git-reinstall resulted in an unexpected error') @@ -42,4 +43,3 @@ def git_reinstall(): if __name__ == '__main__': git_reinstall() - config_changed() diff --git a/unit_tests/test_actions_git_reinstall.py b/unit_tests/test_actions_git_reinstall.py index 1fb63120..7a5fab70 100644 --- a/unit_tests/test_actions_git_reinstall.py +++ b/unit_tests/test_actions_git_reinstall.py @@ -45,22 +45,27 @@ class TestNeutronAPIActions(CharmTestCase): @patch.object(git_reinstall, 'action_set') @patch.object(git_reinstall, 'action_fail') @patch.object(git_reinstall, 'git_install') - def test_git_reinstall(self, git_install, action_fail, action_set): + @patch.object(git_reinstall, 'config_changed') + def test_git_reinstall(self, config_changed, git_install, action_fail, + action_set): self.test_config.set('openstack-origin-git', openstack_origin_git) git_reinstall.git_reinstall() git_install.assert_called_with(openstack_origin_git) self.assertTrue(git_install.called) + self.assertTrue(config_changed.called) self.assertFalse(action_set.called) self.assertFalse(action_fail.called) @patch.object(git_reinstall, 'action_set') @patch.object(git_reinstall, 'action_fail') @patch.object(git_reinstall, 'git_install') + @patch.object(git_reinstall, 'config_changed') @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall_not_configured(self, _config, git_install, - action_fail, action_set): + def test_git_reinstall_not_configured(self, _config, config_changed, + git_install, action_fail, + action_set): _config.return_value = None git_reinstall.git_reinstall() @@ -73,10 +78,12 @@ class TestNeutronAPIActions(CharmTestCase): @patch.object(git_reinstall, 'action_set') @patch.object(git_reinstall, 'action_fail') @patch.object(git_reinstall, 'git_install') + @patch.object(git_reinstall, 'config_changed') @patch('traceback.format_exc') @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall_exception(self, _config, format_exc, git_install, - action_fail, action_set): + def test_git_reinstall_exception(self, _config, format_exc, + config_changed, git_install, action_fail, + action_set): _config.return_value = openstack_origin_git e = OSError('something bad happened') git_install.side_effect = e From c59f1cb949e458dccd8ee0871f293b6a9ff25cb8 Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Thu, 16 Apr 2015 14:48:25 +0000 Subject: [PATCH 10/10] Sync charm-helpers --- hooks/charmhelpers/contrib/openstack/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index 5a12c9d6..f90a0289 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -524,9 +524,10 @@ def git_clone_and_install(projects_yaml, core_project): projects = yaml.load(projects_yaml) _git_validate_projects_yaml(projects, core_project) + old_environ = dict(os.environ) + if 'http_proxy' in projects.keys(): os.environ['http_proxy'] = projects['http_proxy'] - if 'https_proxy' in projects.keys(): os.environ['https_proxy'] = projects['https_proxy'] @@ -544,6 +545,8 @@ def git_clone_and_install(projects_yaml, core_project): repo_dir = _git_clone_and_install_single(repo, branch, parent_dir, update_requirements=True) + os.environ = old_environ + def _git_validate_projects_yaml(projects, core_project): """