[coreycb,r=james-page] Add deploy from source support.
This commit is contained in:
commit
76cd3d7e20
@ -1,2 +1,3 @@
|
||||
bin
|
||||
.coverage
|
||||
tags
|
||||
|
7
Makefile
7
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:
|
||||
@ -15,7 +15,7 @@ bin/charm_helpers_sync.py:
|
||||
> bin/charm_helpers_sync.py
|
||||
|
||||
sync: bin/charm_helpers_sync.py
|
||||
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-sync.yaml
|
||||
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
|
||||
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-tests.yaml
|
||||
|
||||
test:
|
||||
@ -25,7 +25,8 @@ test:
|
||||
# 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 \
|
||||
16-basic-trusty-juno
|
||||
16-basic-trusty-icehouse-git 17-basic-trusty-juno \
|
||||
18-basic-trusty-juno-git
|
||||
|
||||
publish: lint unit_test
|
||||
bzr push lp:charms/neutron-openvswitch
|
||||
|
87
README.md
87
README.md
@ -41,3 +41,90 @@ This charm has a configuration option to allow users to disable any per-instance
|
||||
...
|
||||
|
||||
These compute nodes could then be accessed by cloud users via use of host aggregates with specific flavors to target instances to hypervisors with no per-instance security.
|
||||
|
||||
# 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}"
|
||||
|
2
actions.yaml
Normal file
2
actions.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
git-reinstall:
|
||||
description: Reinstall neutron-openvswitch from the openstack-origin-git repositories.
|
1
actions/git-reinstall
Symbolic link
1
actions/git-reinstall
Symbolic link
@ -0,0 +1 @@
|
||||
git_reinstall.py
|
45
actions/git_reinstall.py
Executable file
45
actions/git_reinstall.py
Executable file
@ -0,0 +1,45 @@
|
||||
#!/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 neutron_ovs_utils import (
|
||||
git_install,
|
||||
)
|
||||
|
||||
from neutron_ovs_hooks import (
|
||||
config_changed,
|
||||
)
|
||||
|
||||
|
||||
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'))
|
||||
config_changed()
|
||||
except:
|
||||
action_set({'traceback': traceback.format_exc()})
|
||||
action_fail('git-reinstall resulted in an unexpected error')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
git_reinstall()
|
17
config.yaml
17
config.yaml
@ -1,4 +1,21 @@
|
||||
options:
|
||||
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.
|
||||
|
||||
When openstack-origin-git is specified, openstack-specific
|
||||
packages will be installed from source rather than from the
|
||||
the nova-compute charm's openstack-origin repository.
|
||||
|
||||
Note that the installed config files will be determined based on
|
||||
the OpenStack release of the nova-compute charm's openstack-origin
|
||||
option.
|
||||
|
||||
For more details see README.md.
|
||||
rabbit-user:
|
||||
default: neutron
|
||||
type: string
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
import sys
|
||||
|
||||
from charmhelpers.contrib.openstack.utils import (
|
||||
config_value_changed,
|
||||
git_install_requested,
|
||||
)
|
||||
|
||||
from charmhelpers.core.hookenv import (
|
||||
Hooks,
|
||||
UnregisteredHookError,
|
||||
@ -27,6 +32,7 @@ from neutron_ovs_utils import (
|
||||
DVR_PACKAGES,
|
||||
configure_ovs,
|
||||
determine_packages,
|
||||
git_install,
|
||||
get_topics,
|
||||
determine_dvr_packages,
|
||||
get_shared_secret,
|
||||
@ -46,6 +52,8 @@ def install():
|
||||
for pkg in pkgs:
|
||||
apt_install(pkg, fatal=True)
|
||||
|
||||
git_install(config('openstack-origin-git'))
|
||||
|
||||
|
||||
@hooks.hook('neutron-plugin-relation-changed')
|
||||
@hooks.hook('config-changed')
|
||||
@ -54,6 +62,11 @@ def config_changed():
|
||||
if determine_dvr_packages():
|
||||
apt_update()
|
||||
apt_install(determine_dvr_packages(), fatal=True)
|
||||
|
||||
if git_install_requested():
|
||||
if config_value_changed('openstack-origin-git'):
|
||||
git_install(config('openstack-origin-git'))
|
||||
|
||||
configure_ovs()
|
||||
CONFIGS.write_all()
|
||||
for rid in relation_ids('zeromq-configuration'):
|
||||
|
@ -1,7 +1,15 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from charmhelpers.contrib.openstack.neutron import neutron_plugin_attribute
|
||||
from copy import deepcopy
|
||||
|
||||
from charmhelpers.contrib.openstack import context, templating
|
||||
from charmhelpers.contrib.openstack.utils import (
|
||||
git_install_requested,
|
||||
git_clone_and_install,
|
||||
git_src_dir,
|
||||
)
|
||||
from collections import OrderedDict
|
||||
from charmhelpers.contrib.openstack.utils import (
|
||||
os_release,
|
||||
@ -23,10 +31,36 @@ from charmhelpers.contrib.openstack.context import (
|
||||
DataPortContext,
|
||||
)
|
||||
from charmhelpers.core.host import (
|
||||
adduser,
|
||||
add_group,
|
||||
add_user_to_group,
|
||||
mkdir,
|
||||
service_restart,
|
||||
service_running,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from charmhelpers.core.templating import render
|
||||
|
||||
BASE_GIT_PACKAGES = [
|
||||
'libxml2-dev',
|
||||
'libxslt1-dev',
|
||||
'openvswitch-switch',
|
||||
'python-dev',
|
||||
'python-pip',
|
||||
'python-setuptools',
|
||||
'zlib1g-dev',
|
||||
]
|
||||
|
||||
# ubuntu packages that should not be installed when deploying from git
|
||||
GIT_PACKAGE_BLACKLIST = [
|
||||
'neutron-l3-agent',
|
||||
'neutron-metadata-agent',
|
||||
'neutron-server',
|
||||
'neutron-plugin-openvswitch',
|
||||
'neutron-plugin-openvswitch-agent',
|
||||
]
|
||||
|
||||
NOVA_CONF_DIR = "/etc/nova"
|
||||
NEUTRON_CONF_DIR = "/etc/neutron"
|
||||
NEUTRON_CONF = '%s/neutron.conf' % NEUTRON_CONF_DIR
|
||||
@ -83,14 +117,23 @@ DATA_BRIDGE = 'br-data'
|
||||
|
||||
|
||||
def determine_dvr_packages():
|
||||
if use_dvr():
|
||||
return DVR_PACKAGES
|
||||
if not git_install_requested():
|
||||
if use_dvr():
|
||||
return DVR_PACKAGES
|
||||
return []
|
||||
|
||||
|
||||
def determine_packages():
|
||||
pkgs = neutron_plugin_attribute('ovs', 'packages', 'neutron')
|
||||
pkgs.extend(determine_dvr_packages())
|
||||
|
||||
if git_install_requested():
|
||||
pkgs.extend(BASE_GIT_PACKAGES)
|
||||
# don't include packages that will be installed from git
|
||||
for p in GIT_PACKAGE_BLACKLIST:
|
||||
if p in pkgs:
|
||||
pkgs.remove(p)
|
||||
|
||||
return pkgs
|
||||
|
||||
|
||||
@ -169,3 +212,81 @@ def get_shared_secret():
|
||||
|
||||
def use_dvr():
|
||||
return context.NeutronAPIContext()()['enable_dvr']
|
||||
|
||||
|
||||
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 = [
|
||||
'/var/lib/neutron',
|
||||
'/var/lib/neutron/lock',
|
||||
'/var/log/neutron',
|
||||
]
|
||||
|
||||
logs = [
|
||||
'/var/log/neutron/server.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=0600)
|
||||
|
||||
|
||||
def git_post_install(projects_yaml):
|
||||
"""Perform post-install setup."""
|
||||
src_etc = os.path.join(git_src_dir(projects_yaml, 'neutron'), 'etc')
|
||||
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 c in configs:
|
||||
if os.path.exists(c['dest']):
|
||||
shutil.rmtree(c['dest'])
|
||||
shutil.copytree(c['src'], c['dest'])
|
||||
|
||||
render('git/neutron_sudoers', '/etc/sudoers.d/neutron_sudoers', {},
|
||||
perms=0o440)
|
||||
|
||||
neutron_ovs_agent_context = {
|
||||
'service_description': 'Neutron OpenvSwitch Plugin Agent',
|
||||
'charm_name': 'neutron-openvswitch',
|
||||
'process_name': 'neutron-openvswitch-agent',
|
||||
'cleanup_process_name': 'neutron-ovs-cleanup',
|
||||
'plugin_config': '/etc/neutron/plugins/ml2/ml2_conf.ini',
|
||||
'log_file': '/var/log/neutron/openvswitch-agent.log',
|
||||
}
|
||||
|
||||
neutron_ovs_cleanup_context = {
|
||||
'service_description': 'Neutron OpenvSwitch Cleanup',
|
||||
'charm_name': 'neutron-openvswitch',
|
||||
'process_name': 'neutron-ovs-cleanup',
|
||||
'log_file': '/var/log/neutron/ovs-cleanup.log',
|
||||
}
|
||||
|
||||
# NOTE(coreycb): Needs systemd support
|
||||
render('git/upstart/neutron-plugin-openvswitch-agent.upstart',
|
||||
'/etc/init/neutron-plugin-openvswitch-agent.conf',
|
||||
neutron_ovs_agent_context, perms=0o644)
|
||||
render('git/upstart/neutron-ovs-cleanup.upstart',
|
||||
'/etc/init/neutron-ovs-cleanup.conf',
|
||||
neutron_ovs_cleanup_context, perms=0o644)
|
||||
|
||||
service_restart('neutron-plugin-openvswitch-agent')
|
||||
|
4
templates/git/neutron_sudoers
Normal file
4
templates/git/neutron_sudoers
Normal file
@ -0,0 +1,4 @@
|
||||
Defaults:neutron !requiretty
|
||||
|
||||
neutron ALL = (root) NOPASSWD: /usr/local/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *
|
||||
|
17
templates/git/upstart/neutron-ovs-cleanup.upstart
Normal file
17
templates/git/upstart/neutron-ovs-cleanup.upstart
Normal file
@ -0,0 +1,17 @@
|
||||
description "{{ service_description }}"
|
||||
author "Juju {{ charm_name }} Charm <juju@localhost>"
|
||||
|
||||
start on started openvswitch-switch
|
||||
stop on runlevel [!2345]
|
||||
|
||||
pre-start script
|
||||
mkdir -p /var/run/neutron
|
||||
chown neutron:root /var/run/neutron
|
||||
end script
|
||||
|
||||
pre-start script
|
||||
[ ! -x /usr/bin/{{ process_name }} ] && exit 0
|
||||
start-stop-daemon --start --chuid neutron --exec /usr/local/bin/{{ process_name }} -- \
|
||||
--log-file /var/log/neutron/{{ log_file }} \
|
||||
--config-file /etc/neutron/neutron.conf --verbose
|
||||
end script
|
@ -0,0 +1,18 @@
|
||||
description "{{ service_description }}"
|
||||
author "Juju {{ charm_name }} Charm <juju@localhost>"
|
||||
|
||||
start on runlevel [2345] and started {{ cleanup_process_name}}
|
||||
stop on runlevel [!2345]
|
||||
|
||||
respawn
|
||||
|
||||
chdir /var/run
|
||||
|
||||
pre-start script
|
||||
mkdir -p /var/run/neutron
|
||||
chown neutron:root /var/run/neutron
|
||||
end script
|
||||
|
||||
exec start-stop-daemon --start --chuid neutron --exec /usr/local/bin/{{ process_name }} -- \
|
||||
--config-file=/etc/neutron/neutron.conf --config-file={{ plugin_config }} \
|
||||
--log-file={{ log_file }}
|
9
tests/16-basic-trusty-icehouse-git
Executable file
9
tests/16-basic-trusty-icehouse-git
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic neutron-openvswitch git deployment on trusty-icehouse."""
|
||||
|
||||
from basic_deployment import NeutronOVSBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = NeutronOVSBasicDeployment(series='trusty', git=True)
|
||||
deployment.run_tests()
|
12
tests/18-basic-trusty-juno-git
Executable file
12
tests/18-basic-trusty-juno-git
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Amulet tests on a basic neutron-openvswitch git deployment on trusty-juno."""
|
||||
|
||||
from basic_deployment import NeutronOVSBasicDeployment
|
||||
|
||||
if __name__ == '__main__':
|
||||
deployment = NeutronOVSBasicDeployment(series='trusty',
|
||||
openstack='cloud:trusty-juno',
|
||||
source='cloud:trusty-updates/juno',
|
||||
git=True)
|
||||
deployment.run_tests()
|
@ -1,7 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import amulet
|
||||
import os
|
||||
import time
|
||||
import yaml
|
||||
|
||||
from charmhelpers.contrib.openstack.amulet.deployment import (
|
||||
OpenStackAmuletDeployment
|
||||
@ -14,7 +16,7 @@ from charmhelpers.contrib.openstack.amulet.utils import (
|
||||
)
|
||||
|
||||
# Use DEBUG to turn on debug logging
|
||||
u = OpenStackAmuletUtils(ERROR)
|
||||
u = OpenStackAmuletUtils(DEBUG)
|
||||
|
||||
# XXX Tests inspecting relation data from the perspective of the
|
||||
# neutron-openvswitch are missing because amulet sentries aren't created for
|
||||
@ -24,10 +26,12 @@ u = OpenStackAmuletUtils(ERROR)
|
||||
class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
|
||||
"""Amulet tests on a basic neutron-openvswtich 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(NeutronOVSBasicDeployment, self).__init__(series, openstack,
|
||||
source, stable)
|
||||
self.git = git
|
||||
self._add_services()
|
||||
self._add_relations()
|
||||
self._configure_services()
|
||||
@ -61,7 +65,25 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
|
||||
|
||||
def _configure_services(self):
|
||||
"""Configure all of the services."""
|
||||
configs = {}
|
||||
neutron_ovs_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',
|
||||
'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': amulet_http_proxy,
|
||||
'https_proxy': amulet_http_proxy,
|
||||
}
|
||||
neutron_ovs_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
|
||||
configs = {'neutron-openvswitch': neutron_ovs_config}
|
||||
super(NeutronOVSBasicDeployment, self)._configure_services(configs)
|
||||
|
||||
def _initialize_tests(self):
|
||||
@ -76,7 +98,8 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
|
||||
service units."""
|
||||
|
||||
commands = {
|
||||
self.compute_sentry: ['status nova-compute'],
|
||||
self.compute_sentry: ['status nova-compute',
|
||||
'status neutron-plugin-openvswitch-agent'],
|
||||
self.rabbitmq_sentry: ['service rabbitmq-server status'],
|
||||
self.neutron_api_sentry: ['status neutron-server'],
|
||||
}
|
||||
@ -138,7 +161,7 @@ class NeutronOVSBasicDeployment(OpenStackAmuletDeployment):
|
||||
conf = "/etc/neutron/plugins/ml2/ml2_conf.ini"
|
||||
for value in vpair:
|
||||
self.d.configure(service, {charm_key: value})
|
||||
time.sleep(30)
|
||||
time.sleep(60)
|
||||
ret = u.validate_config_data(unit, conf, section,
|
||||
{config_file_key: value})
|
||||
msg = "Propagation error, expected %s=%s" % (config_file_key,
|
||||
|
@ -1,2 +1,4 @@
|
||||
import sys
|
||||
|
||||
sys.path.append('actions/')
|
||||
sys.path.append('hooks/')
|
||||
|
105
unit_tests/test_actions_git_reinstall.py
Normal file
105
unit_tests/test_actions_git_reinstall.py
Normal file
@ -0,0 +1,105 @@
|
||||
from mock import patch, MagicMock
|
||||
|
||||
with patch('charmhelpers.core.hookenv.config') as config:
|
||||
config.return_value = 'neutron'
|
||||
import neutron_ovs_utils as utils # noqa
|
||||
|
||||
# Need to do some early patching to get the module loaded.
|
||||
_reg = utils.register_configs
|
||||
_map = utils.restart_map
|
||||
|
||||
utils.register_configs = MagicMock()
|
||||
utils.restart_map = MagicMock()
|
||||
|
||||
import git_reinstall
|
||||
|
||||
# Unpatch it now that its loaded.
|
||||
utils.register_configs = _reg
|
||||
utils.restart_map = _map
|
||||
|
||||
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 TestNeutronOVSActions(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestNeutronOVSActions, 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')
|
||||
@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, config_changed,
|
||||
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.object(git_reinstall, 'config_changed')
|
||||
@patch('traceback.format_exc')
|
||||
@patch('charmhelpers.contrib.openstack.utils.config')
|
||||
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
|
||||
traceback = (
|
||||
"Traceback (most recent call last):\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"
|
||||
" 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()
|
||||
|
||||
msg = 'git-reinstall resulted in an unexpected error'
|
||||
action_fail.assert_called_with(msg)
|
||||
action_set.assert_called_with({'traceback': traceback})
|
@ -101,6 +101,7 @@ class OVSPluginContextTest(CharmTestCase):
|
||||
|
||||
return config
|
||||
|
||||
self.maxDiff = None
|
||||
self.config.side_effect = mock_config
|
||||
_npa.side_effect = mock_npa
|
||||
_unit_get.return_value = '127.0.0.13'
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
from mock import MagicMock, patch, call
|
||||
import yaml
|
||||
|
||||
from test_utils import CharmTestCase
|
||||
|
||||
with patch('charmhelpers.core.hookenv.config') as config:
|
||||
@ -26,6 +27,7 @@ TO_PATCH = [
|
||||
'determine_packages',
|
||||
'determine_dvr_packages',
|
||||
'get_shared_secret',
|
||||
'git_install',
|
||||
'log',
|
||||
'relation_ids',
|
||||
'relation_set',
|
||||
@ -49,7 +51,9 @@ class NeutronOVSHooksTests(CharmTestCase):
|
||||
hooks.hooks.execute([
|
||||
'hooks/{}'.format(hookname)])
|
||||
|
||||
def test_install_hook(self):
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
def test_install_hook(self, git_requested):
|
||||
git_requested.return_value = False
|
||||
_pkgs = ['foo', 'bar']
|
||||
self.determine_packages.return_value = [_pkgs]
|
||||
self._call_hook('install')
|
||||
@ -58,7 +62,32 @@ class NeutronOVSHooksTests(CharmTestCase):
|
||||
call(_pkgs, fatal=True),
|
||||
])
|
||||
|
||||
def test_config_changed(self):
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
def test_install_hook_git(self, git_requested):
|
||||
git_requested.return_value = True
|
||||
_pkgs = ['foo', 'bar']
|
||||
self.determine_packages.return_value = _pkgs
|
||||
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-git', projects_yaml)
|
||||
self._call_hook('install')
|
||||
self.apt_update.assert_called_with()
|
||||
self.assertTrue(self.determine_packages)
|
||||
self.git_install.assert_called_with(projects_yaml)
|
||||
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
def test_config_changed(self, git_requested):
|
||||
git_requested.return_value = False
|
||||
self.relation_ids.return_value = ['relid']
|
||||
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
|
||||
self._call_hook('config-changed')
|
||||
@ -66,7 +95,35 @@ class NeutronOVSHooksTests(CharmTestCase):
|
||||
self.assertTrue(_zmq_joined.called_with('relid'))
|
||||
self.configure_ovs.assert_called_with()
|
||||
|
||||
def test_config_changed_dvr(self):
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
@patch.object(hooks, 'config_value_changed')
|
||||
def test_config_changed_git(self, config_val_changed, git_requested):
|
||||
git_requested.return_value = True
|
||||
self.relation_ids.return_value = ['relid']
|
||||
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
|
||||
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-git', projects_yaml)
|
||||
self._call_hook('config-changed')
|
||||
self.git_install.assert_called_with(projects_yaml)
|
||||
self.assertTrue(self.CONFIGS.write_all.called)
|
||||
self.assertTrue(_zmq_joined.called_with('relid'))
|
||||
self.configure_ovs.assert_called_with()
|
||||
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
def test_config_changed_dvr(self, git_requested):
|
||||
git_requested.return_value = False
|
||||
self.determine_dvr_packages.return_value = ['dvr']
|
||||
self._call_hook('config-changed')
|
||||
self.apt_update.assert_called_with()
|
||||
@ -84,7 +141,9 @@ class NeutronOVSHooksTests(CharmTestCase):
|
||||
self.assertTrue(self.CONFIGS.write_all.called)
|
||||
_plugin_joined.assert_called_with(relation_id='rid')
|
||||
|
||||
def test_neutron_plugin_joined(self):
|
||||
@patch.object(hooks, 'git_install_requested')
|
||||
def test_neutron_plugin_joined(self, git_requested):
|
||||
git_requested.return_value = False
|
||||
self.get_shared_secret.return_value = 'secret'
|
||||
self._call_hook('neutron-plugin-relation-joined')
|
||||
rel_data = {
|
||||
|
@ -29,6 +29,15 @@ TO_PATCH = [
|
||||
|
||||
head_pkg = 'linux-headers-3.15.0-5-generic'
|
||||
|
||||
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}"""
|
||||
|
||||
|
||||
def _mock_npa(plugin, attr, net_manager=None):
|
||||
plugins = {
|
||||
@ -67,9 +76,12 @@ class TestNeutronOVSUtils(CharmTestCase):
|
||||
hookenv.cache = {}
|
||||
|
||||
@patch.object(nutils, 'use_dvr')
|
||||
@patch.object(nutils, 'git_install_requested')
|
||||
@patch.object(charmhelpers.contrib.openstack.neutron, 'os_release')
|
||||
@patch.object(charmhelpers.contrib.openstack.neutron, 'headers_package')
|
||||
def test_determine_packages(self, _head_pkgs, _os_rel, _use_dvr):
|
||||
def test_determine_packages(self, _head_pkgs, _os_rel, _git_requested,
|
||||
_use_dvr):
|
||||
_git_requested.return_value = False
|
||||
_use_dvr.return_value = False
|
||||
_os_rel.return_value = 'trusty'
|
||||
_head_pkgs.return_value = head_pkg
|
||||
@ -206,3 +218,92 @@ class TestNeutronOVSUtils(CharmTestCase):
|
||||
_dvr_secret_ctxt.return_value = \
|
||||
DummyContext(return_value={'shared_secret': 'supersecret'})
|
||||
self.assertEqual(nutils.get_shared_secret(), 'supersecret')
|
||||
|
||||
@patch.object(nutils, 'git_install_requested')
|
||||
@patch.object(nutils, 'git_clone_and_install')
|
||||
@patch.object(nutils, 'git_post_install')
|
||||
@patch.object(nutils, '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
|
||||
nutils.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(nutils, 'mkdir')
|
||||
@patch.object(nutils, 'write_file')
|
||||
@patch.object(nutils, 'add_user_to_group')
|
||||
@patch.object(nutils, 'add_group')
|
||||
@patch.object(nutils, 'adduser')
|
||||
def test_git_pre_install(self, adduser, add_group, add_user_to_group,
|
||||
write_file, mkdir):
|
||||
nutils.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('/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/server.log', '', owner='neutron',
|
||||
group='neutron', perms=0600),
|
||||
]
|
||||
self.assertEquals(write_file.call_args_list, expected)
|
||||
|
||||
@patch.object(nutils, 'git_src_dir')
|
||||
@patch.object(nutils, 'service_restart')
|
||||
@patch.object(nutils, 'render')
|
||||
@patch('os.path.join')
|
||||
@patch('os.path.exists')
|
||||
@patch('shutil.copytree')
|
||||
@patch('shutil.rmtree')
|
||||
def test_git_post_install(self, rmtree, copytree, exists, join, render,
|
||||
service_restart, git_src_dir):
|
||||
projects_yaml = openstack_origin_git
|
||||
join.return_value = 'joined-string'
|
||||
nutils.git_post_install(projects_yaml)
|
||||
expected = [
|
||||
call('joined-string', '/etc/neutron'),
|
||||
call('joined-string', '/etc/neutron/plugins'),
|
||||
call('joined-string', '/etc/neutron/rootwrap.d'),
|
||||
]
|
||||
copytree.assert_has_calls(expected)
|
||||
neutron_ovs_agent_context = {
|
||||
'service_description': 'Neutron OpenvSwitch Plugin Agent',
|
||||
'charm_name': 'neutron-openvswitch',
|
||||
'process_name': 'neutron-openvswitch-agent',
|
||||
'cleanup_process_name': 'neutron-ovs-cleanup',
|
||||
'plugin_config': '/etc/neutron/plugins/ml2/ml2_conf.ini',
|
||||
'log_file': '/var/log/neutron/openvswitch-agent.log',
|
||||
}
|
||||
neutron_ovs_cleanup_context = {
|
||||
'service_description': 'Neutron OpenvSwitch Cleanup',
|
||||
'charm_name': 'neutron-openvswitch',
|
||||
'process_name': 'neutron-ovs-cleanup',
|
||||
'log_file': '/var/log/neutron/ovs-cleanup.log',
|
||||
}
|
||||
expected = [
|
||||
call('git/neutron_sudoers', '/etc/sudoers.d/neutron_sudoers', {},
|
||||
perms=0o440),
|
||||
call('git/upstart/neutron-plugin-openvswitch-agent.upstart',
|
||||
'/etc/init/neutron-plugin-openvswitch-agent.conf',
|
||||
neutron_ovs_agent_context, perms=0o644),
|
||||
call('git/upstart/neutron-ovs-cleanup.upstart',
|
||||
'/etc/init/neutron-ovs-cleanup.conf',
|
||||
neutron_ovs_cleanup_context, perms=0o644),
|
||||
]
|
||||
self.assertEquals(render.call_args_list, expected)
|
||||
expected = [
|
||||
call('neutron-plugin-openvswitch-agent'),
|
||||
]
|
||||
self.assertEquals(service_restart.call_args_list, expected)
|
||||
|
Loading…
Reference in New Issue
Block a user