Deploy from source

This commit is contained in:
Corey Bryant 2015-04-10 14:22:04 +00:00
parent 9f5fd4b55a
commit 5d267c3f36
30 changed files with 1567 additions and 153 deletions

View File

@ -1,2 +1,3 @@
bin
.coverage
tags

View File

@ -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

View File

@ -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
----

2
actions.yaml Normal file
View File

@ -0,0 +1,2 @@
git-reinstall:
description: Reinstall quantum-gateway from the openstack-origin-git repositories.

1
actions/git-reinstall Symbolic link
View File

@ -0,0 +1 @@
git_reinstall.py

40
actions/git_reinstall.py Executable file
View File

@ -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()

View File

@ -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

View File

@ -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')

View File

@ -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 }}

View File

@ -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']

View File

@ -20,11 +20,13 @@
# Authors:
# Charm Helpers Developers <juju@lists.ubuntu.com>
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):

View File

@ -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()

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,4 @@
Defaults:neutron !requiretty
neutron ALL = (root) NOPASSWD: /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *

View File

@ -0,0 +1,25 @@
description "{{ service_description }}"
author "Juju {{ service_name }} Charm <juju@localhost>"
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 }}

View File

@ -0,0 +1,13 @@
description "{{ service_description }}"
author "Juju {{ service_name }} Charm <juju@localhost>"
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

View File

@ -0,0 +1,22 @@
description "{{ service_description }}"
author "Juju {{ service_name }} Charm <juju@localhost>"
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

View File

@ -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()

View File

@ -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()

View File

@ -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()

11
tests/17-basic-trusty-juno Executable file
View File

@ -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()

12
tests/18-basic-trusty-juno-git Executable file
View File

@ -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()

View File

@ -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

View File

@ -1,2 +1,4 @@
import sys
sys.path.append('actions')
sys.path.append('hooks')

View File

@ -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',
]