[coreycb,r=james-page] Add deploy from source support.

This commit is contained in:
james.page@ubuntu.com 2015-04-16 21:02:01 +01:00
commit b25249f051
22 changed files with 655 additions and 16 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:
@ -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

View File

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

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

1
actions/git-reinstall Symbolic link
View File

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

45
actions/git_reinstall.py Executable file
View 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()

View File

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

View File

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

View File

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

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

View File

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

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

View File

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

View File

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

View 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})

View File

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

View File

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

View File

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