Deploy from source

This commit is contained in:
Corey Bryant 2015-04-15 14:21:42 +00:00
commit 6a77fa888e
40 changed files with 1055 additions and 80 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/nova-compute

View File

@ -16,17 +16,102 @@ The following interfaces are provided:
- nrpe-external-master - Used to generate Nagios checks.
Database
--------
========
Nova compute only requires database access if using nova-network. If using
Neutron, no direct database access is required and the shared-db relation need
not be added.
Networking
----------
==========
This charm support nova-network (legacy) and Neutron networking.
Storage
-------
=======
This charm supports a number of different storage backends depending on
your hypervisor type and storage relations.
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: nova,
repository: 'git://git.openstack.org/openstack/nova',
branch: stable/juno}"
Note that there are only two 'name' values the charm knows about: 'requirements'
and 'nova'. These repositories must correspond to these 'name' values.
Additionally, the requirements repository must be specified first and the
nova 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-log,
repository: 'git://git.openstack.org/openstack/oslo.log',
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: sqlalchemy-migrate,
repository: 'git://git.openstack.org/stackforge/sqlalchemy-migrate',
branch: master}
- {name: python-cinderclient,
repository: 'git://git.openstack.org/openstack/python-cinderclient.git',
branch: master}
- {name: python-glanceclient,
repository': 'git://git.openstack.org/openstack/python-glanceclient.git',
branch: master}
- {name: python-neutronlient,
repository': 'git://git.openstack.org/openstack/python-neutronclient.git',
branch: master}
- {name: keystonemiddleware,
repository: 'git://git.openstack.org/openstack/keystonemiddleware',
branch: master}
- {name: nova,
repository: 'git://git.openstack.org/openstack/nova',
branch: master}"

2
actions.yaml Normal file
View File

@ -0,0 +1,2 @@
git-reinstall:
description: Reinstall nova-compute 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 nova_compute_utils import (
git_install,
)
from nova_compute_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'))
except:
action_set({'traceback': traceback.format_exc()})
action_fail('git-reinstall resulted in an unexpected error')
if __name__ == '__main__':
git_reinstall()
config_changed()

View File

@ -1,4 +1,12 @@
options:
debug:
default: False
type: boolean
description: "Enable debug logging"
verbose:
default: False
type: boolean
description: "Enable verbose logging"
openstack-origin:
default: distro
type: string
@ -14,6 +22,22 @@ options:
Note that updating this setting to a source that is known to
provide a later version of OpenStack will trigger a software
upgrade.
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.
nova-config:
default: /etc/nova/nova.conf
type: string

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')
@ -807,6 +808,19 @@ class NeutronContext(OSContextGenerator):
return ovs_ctxt
def nuage_ctxt(self):
driver = neutron_plugin_attribute(self.plugin, 'driver',
self.network_manager)
config = neutron_plugin_attribute(self.plugin, 'config',
self.network_manager)
nuage_ctxt = {'core_plugin': driver,
'neutron_plugin': 'vsp',
'neutron_security_groups': self.neutron_security_groups,
'local_ip': unit_private_ip(),
'config': config}
return nuage_ctxt
def nvp_ctxt(self):
driver = neutron_plugin_attribute(self.plugin, 'driver',
self.network_manager)
@ -890,6 +904,8 @@ class NeutronContext(OSContextGenerator):
ctxt.update(self.n1kv_ctxt())
elif self.plugin == 'Calico':
ctxt.update(self.calico_ctxt())
elif self.plugin == 'vsp':
ctxt.update(self.nuage_ctxt())
alchemy_flags = config('neutron-alchemy-flags')
if alchemy_flags:

View File

@ -180,6 +180,19 @@ def neutron_plugins():
'nova-api-metadata']],
'server_packages': ['neutron-server', 'calico-control'],
'server_services': ['neutron-server']
},
'vsp': {
'config': '/etc/neutron/plugins/nuage/nuage_plugin.ini',
'driver': 'neutron.plugins.nuage.plugin.NuagePlugin',
'contexts': [
context.SharedDBContext(user=config('neutron-database-user'),
database=config('neutron-database'),
relation_prefix='neutron',
ssl_dir=NEUTRON_CONF_DIR)],
'services': [],
'packages': [],
'server_packages': ['neutron-server', 'neutron-plugin-nuage'],
'server_services': ['neutron-server']
}
}
if release >= 'icehouse':

View File

@ -9,5 +9,9 @@ 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 -%}
{% if log_file -%}
--log-file={{ log_file }}
{% endif -%}

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

@ -33,9 +33,9 @@ def bool_from_string(value):
value = value.strip().lower()
if value in ['y', 'yes', 'true', 't']:
if value in ['y', 'yes', 'true', 't', 'on']:
return True
elif value in ['n', 'no', 'false', 'f']:
elif value in ['n', 'no', 'false', 'f', 'off']:
return False
msg = "Unable to interpret string value '%s' as boolean" % (value)

View File

@ -28,7 +28,9 @@ from charmhelpers.fetch import (
)
from charmhelpers.contrib.openstack.utils import (
config_value_changed,
configure_installation_source,
git_install_requested,
openstack_upgrade_available,
os_requires_version,
)
@ -43,6 +45,7 @@ from charmhelpers.payload.execd import execd_preinstall
from nova_compute_utils import (
create_libvirt_secret,
determine_packages,
git_install,
import_authorized_keys,
import_keystone_ca_cert,
initialize_ssh_keys,
@ -84,9 +87,12 @@ CONFIGS = register_configs()
def install():
execd_preinstall()
configure_installation_source(config('openstack-origin'))
apt_update()
apt_install(determine_packages(), fatal=True)
git_install(config('openstack-origin-git'))
@hooks.hook('config-changed')
@restart_on_change(restart_map())
@ -95,8 +101,12 @@ def config_changed():
assert_charm_supports_ipv6()
global CONFIGS
if openstack_upgrade_available('nova-common'):
CONFIGS = do_openstack_upgrade()
if git_install_requested():
if config_value_changed('openstack-origin-git'):
git_install(config('openstack-origin-git'))
else:
if openstack_upgrade_available('nova-common'):
CONFIGS = do_openstack_upgrade()
sysctl_dict = config('sysctl')
if sysctl_dict:

View File

@ -1,4 +1,5 @@
import os
import shutil
import pwd
from base64 import b64decode
@ -8,16 +9,21 @@ from subprocess import check_call, check_output
from charmhelpers.fetch import (
apt_update,
apt_upgrade,
apt_install
apt_install,
)
from charmhelpers.core.host import (
adduser,
add_group,
add_user_to_group,
mkdir,
service_restart,
lsb_release
lsb_release,
write_file,
)
from charmhelpers.core.hookenv import (
charm_dir,
config,
log,
related_units,
@ -27,6 +33,7 @@ from charmhelpers.core.hookenv import (
INFO,
)
from charmhelpers.core.templating import render
from charmhelpers.contrib.openstack.neutron import neutron_plugin_attribute
from charmhelpers.contrib.openstack import templating, context
from charmhelpers.contrib.openstack.alternatives import install_alternative
@ -34,6 +41,9 @@ from charmhelpers.contrib.openstack.alternatives import install_alternative
from charmhelpers.contrib.openstack.utils import (
configure_installation_source,
get_os_codename_install_source,
git_install_requested,
git_clone_and_install,
git_src_dir,
os_release
)
@ -57,9 +67,61 @@ TEMPLATES = 'templates/'
BASE_PACKAGES = [
'nova-compute',
'genisoimage', # was missing as a package dependency until raring.
'librbd1', # bug 1440953
'python-six',
]
BASE_GIT_PACKAGES = [
'libvirt-bin',
'libxml2-dev',
'libxslt1-dev',
'python-dev',
'python-pip',
'python-setuptools',
'zlib1g-dev',
]
LATE_GIT_PACKAGES = [
'bridge-utils',
'dnsmasq-base',
'dnsmasq-utils',
'ebtables',
'genisoimage',
'iptables',
'iputils-arping',
'kpartx',
'kvm',
'netcat',
'open-iscsi',
'parted',
'python-libvirt',
'qemu',
'qemu-system',
'qemu-utils',
'vlan',
'xen-system-amd64',
]
# ubuntu packages that should not be installed when deploying from git
GIT_PACKAGE_BLACKLIST = [
'neutron-plugin-openvswitch',
'neutron-plugin-openvswitch-agent',
'neutron-server',
'nova-api',
'nova-api-metadata',
'nova-compute',
'nova-compute-kvm',
'nova-compute-lxc',
'nova-compute-qemu',
'nova-compute-uml',
'nova-compute-xen',
'nova-network',
'python-six',
'quantum-plugin-openvswitch',
'quantum-plugin-openvswitch-agent',
'quantum-server',
]
NOVA_CONF_DIR = "/etc/nova"
QEMU_CONF = '/etc/libvirt/qemu.conf'
LIBVIRTD_CONF = '/etc/libvirt/libvirtd.conf'
@ -104,7 +166,8 @@ BASE_RESOURCE_MAP = {
context.ZeroMQContext(),
context.NotificationDriverContext(),
MetadataServiceContext(),
HostIPContext()],
HostIPContext(),
context.LogLevelContext()],
},
}
@ -287,6 +350,14 @@ def determine_packages():
if enable_nova_metadata():
packages.append('nova-api-metadata')
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
@ -525,3 +596,123 @@ def neutron_plugin_legacy_mode():
def manage_ovs():
return neutron_plugin_legacy_mode() and neutron_plugin() == 'ovs'
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='nova')
git_post_install(projects_yaml)
def git_pre_install():
"""Perform pre-install setup."""
dirs = [
'/var/lib/nova',
'/var/lib/nova/buckets',
'/var/lib/nova/CA',
'/var/lib/nova/CA/INTER',
'/var/lib/nova/CA/newcerts',
'/var/lib/nova/CA/private',
'/var/lib/nova/CA/reqs',
'/var/lib/nova/images',
'/var/lib/nova/instances',
'/var/lib/nova/keys',
'/var/lib/nova/networks',
'/var/lib/nova/tmp',
'/var/log/nova',
]
logs = [
'/var/log/nova/nova-api.log',
'/var/log/nova/nova-compute.log',
'/var/log/nova/nova-manage.log',
'/var/log/nova/nova-network.log',
]
adduser('nova', shell='/bin/bash', system_user=True)
check_call(['usermod', '--home', '/var/lib/nova', 'nova'])
add_group('nova', system_group=True)
add_user_to_group('nova', 'nova')
add_user_to_group('nova', 'libvirtd')
for d in dirs:
mkdir(d, owner='nova', group='nova', perms=0755, force=False)
for l in logs:
write_file(l, '', owner='nova', group='nova', perms=0644)
def git_post_install(projects_yaml):
"""Perform post-install setup."""
src_etc = os.path.join(git_src_dir(projects_yaml, 'nova'), 'etc/nova')
configs = [
{'src': src_etc,
'dest': '/etc/nova'},
]
for c in configs:
if os.path.exists(c['dest']):
shutil.rmtree(c['dest'])
shutil.copytree(c['src'], c['dest'])
virt_type = VIRT_TYPES[config('virt-type')][0]
nova_compute_conf = 'git/{}.conf'.format(virt_type)
render(nova_compute_conf, '/etc/nova/nova-compute.conf', {}, perms=0o644)
render('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers', {}, perms=0o440)
service_name = 'nova-compute'
nova_user = 'nova'
start_dir = '/var/lib/nova'
nova_conf = 'etc/nova/nova.conf'
nova_api_metadata_context = {
'service_description': 'Nova Metadata API server',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-api-metadata',
'executable_name': '/usr/local/bin/nova-api-metadata',
'config_files': [nova_conf],
}
nova_api_context = {
'service_description': 'Nova API server',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-api',
'executable_name': '/usr/local/bin/nova-api',
'config_files': [nova_conf],
}
nova_compute_context = {
'service_description': 'Nova compute worker',
'service_name': service_name,
'user_name': nova_user,
'process_name': 'nova-compute',
'executable_name': '/usr/local/bin/nova-compute',
'config_files': [nova_conf, '/etc/nova/nova-compute.conf'],
}
nova_network_context = {
'service_description': 'Nova network worker',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-network',
'executable_name': '/usr/local/bin/nova-network',
'config_files': [nova_conf],
}
# NOTE(coreycb): Needs systemd support
templates_dir = 'hooks/charmhelpers/contrib/openstack/templates'
templates_dir = os.path.join(charm_dir(), templates_dir)
render('git.upstart', '/etc/init/nova-api-metadata.conf',
nova_api_metadata_context, perms=0o644, templates_dir=templates_dir)
render('git.upstart', '/etc/init/nova-api.conf',
nova_api_context, perms=0o644, templates_dir=templates_dir)
render('git/upstart/nova-compute.upstart', '/etc/init/nova-compute.conf',
nova_compute_context, perms=0o644)
render('git.upstart', '/etc/init/nova-network.conf',
nova_network_context, perms=0o644, templates_dir=templates_dir)
apt_update()
apt_install(LATE_GIT_PACKAGES, fatal=True)

View File

@ -33,3 +33,6 @@ requires:
zeromq-configuration:
interface: zeromq-configuration
scope: container
peers:
compute-peer:
interface: nova

View File

@ -0,0 +1,4 @@
[DEFAULT]
compute_driver=libvirt.LibvirtDriver
[libvirt]
virt_type=kvm

View File

@ -0,0 +1,4 @@
[DEFAULT]
compute_driver=libvirt.LibvirtDriver
[libvirt]
virt_type=lxc

View File

@ -0,0 +1,4 @@
[DEFAULT]
compute_driver=libvirt.LibvirtDriver
[libvirt]
virt_type=qemu

View File

@ -0,0 +1,2 @@
[DEFAULT]
compute_driver=vmwareapi.VMwareVCDriver

View File

@ -0,0 +1,4 @@
[DEFAULT]
compute_driver=libvirt.LibvirtDriver
[libvirt]
virt_type=xen

View File

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

View File

@ -0,0 +1 @@
include /var/lib/nova/volumes/*

View File

@ -0,0 +1,27 @@
description "{{ service_description }}"
author "Juju {{ service_name }} Charm <juju@localhost>"
start on runlevel [2345]
stop on runlevel [!2345]
chdir /var/run
pre-start script
mkdir -p /var/run/nova
chown nova:root /var/run/nova/
mkdir -p /var/lock/nova
chown nova:root /var/lock/nova/
modprobe nbd
# If libvirt-bin is installed, always wait for it to start first
if status libvirt-bin; then
start wait-for-state WAIT_FOR=libvirt-bin WAIT_STATE=running WAITER={{ process_name }}
fi
end script
exec start-stop-daemon --start --chuid {{ user_name }} --exec {{ executable_name }} -- \
{% for config_file in config_files -%}
--config-file={{ config_file }} \
{% endfor -%}

View File

@ -7,6 +7,8 @@
{% endif -%}
###############################################################################
[DEFAULT]
verbose={{ verbose }}
debug={{ debug }}
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
logdir=/var/log/nova
@ -21,7 +23,6 @@ libvirt_disk_prefix=vd
libvirt_use_virtio_for_bridges=True
{% endif -%}
verbose=True
use_syslog = {{ use_syslog }}
ec2_private_dns_show_ip=True
api_paste_config=/etc/nova/api-paste.ini

View File

@ -0,0 +1,155 @@
# icehouse
###############################################################################
# [ WARNING ]
# Configuration file maintained by Juju. Local changes may be overwritten.
{% if restart_trigger -%}
# restart trigger: {{ restart_trigger }}
{% endif -%}
###############################################################################
[DEFAULT]
verbose={{ verbose }}
debug={{ debug }}
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
logdir=/var/log/nova
state_path=/var/lib/nova
lock_path=/var/lock/nova
force_dhcp_release=True
{% if arch == 'aarch64' -%}
libvirt_use_virtio_for_bridges=False
libvirt_disk_prefix=vd
{% else -%}
libvirt_use_virtio_for_bridges=True
{% endif -%}
use_syslog = {{ use_syslog }}
ec2_private_dns_show_ip=True
api_paste_config=/etc/nova/api-paste.ini
enabled_apis=ec2,osapi_compute,metadata
auth_strategy=keystone
compute_driver=libvirt.LibvirtDriver
my_ip = {{ host_ip }}
{% include "parts/database" %}
{% include "parts/rabbitmq" %}
{% if glance_api_servers -%}
glance_api_servers = {{ glance_api_servers }}
{% endif -%}
{% if console_vnc_type -%}
vnc_enabled = True
novnc_enabled = True
vnc_keymap = {{ console_keymap }}
vncserver_listen = 0.0.0.0
vncserver_proxyclient_address = {{ console_listen_addr }}
{% if console_access_protocol == 'novnc' or console_access_protocol == 'vnc' -%}
novncproxy_base_url = {{ novnc_proxy_address }}
{% endif -%}
{% if console_access_protocol == 'xvpvnc' or console_access_protocol == 'vnc' -%}
xvpvncproxy_port = {{ xvpvnc_proxy_port }}
xvpvncproxy_host = {{ xvpvnc_proxy_host }}
xvpvncproxy_base_url = {{ xvpvnc_proxy_address }}
{% endif -%}
{% else -%}
vnc_enabled = False
novnc_enabled = False
{% endif -%}
{% if neutron_plugin and neutron_plugin == 'ovs' -%}
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtGenericVIFDriver
{% if neutron_security_groups -%}
security_group_api = neutron
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% endif -%}
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
network_api_class=nova.network.neutronv2.api.API
libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
neutron_ovs_bridge=alubr0
security_group_api=nova
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% if neutron_plugin and (neutron_plugin == 'nvp' or neutron_plugin == 'nsx') -%}
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtOpenVswitchVirtualPortDriver
security_group_api = neutron
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% if neutron_plugin and neutron_plugin == 'Calico' -%}
security_group_api = neutron
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% if network_manager_config -%}
{% for key, value in network_manager_config.iteritems() -%}
{{ key }} = {{ value }}
{% endfor -%}
{% endif -%}
{% if network_manager == 'neutron' -%}
network_api_class = nova.network.neutronv2.api.API
{% else -%}
network_manager = nova.network.manager.FlatDHCPManager
{% endif -%}
{% if network_device_mtu -%}
network_device_mtu = {{ network_device_mtu }}
{% endif -%}
{% if volume_service -%}
volume_api_class = nova.volume.cinder.API
{% endif -%}
{% if user_config_flags -%}
{% for key, value in user_config_flags.iteritems() -%}
{{ key }} = {{ value }}
{% endfor -%}
{% endif -%}
{% if live_migration_uri -%}
live_migration_uri = {{ live_migration_uri }}
{% endif -%}
{% if instances_path -%}
instances_path = {{ instances_path }}
{% endif -%}
{% if sections and 'DEFAULT' in sections -%}
{% for key, value in sections['DEFAULT'] -%}
{{ key }} = {{ value }}
{% endfor -%}
{% endif -%}
{% if console_access_protocol == 'spice' -%}
[spice]
agent_enabled = True
enabled = True
html5proxy_base_url = {{ spice_proxy_address }}
keymap = {{ console_keymap }}
server_listen = 0.0.0.0
server_proxyclient_address = {{ console_listen_addr }}
{% endif -%}
[libvirt]
{% if libvirt_images_type -%}
images_type = {{ libvirt_images_type }}
images_rbd_pool = {{ rbd_pool }}
images_rbd_ceph_conf = {{ libvirt_rbd_images_ceph_conf }}
inject_password=false
inject_key=false
inject_partition=-2
{% endif -%}
{% if rbd_pool -%}
rbd_pool = {{ rbd_pool }}
rbd_user = {{ rbd_user }}
rbd_secret_uuid = {{ rbd_secret_uuid }}
{% endif -%}
{% if disk_cachemodes -%}
disk_cachemodes = {{ disk_cachemodes }}
{% endif -%}

View File

@ -7,6 +7,8 @@
{% endif -%}
###############################################################################
[DEFAULT]
verbose={{ verbose }}
debug={{ debug }}
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
logdir=/var/log/nova
@ -21,7 +23,6 @@ libvirt_disk_prefix=vd
libvirt_use_virtio_for_bridges=True
{% endif -%}
verbose=True
use_syslog = {{ use_syslog }}
ec2_private_dns_show_ip=True
api_paste_config=/etc/nova/api-paste.ini
@ -70,6 +71,14 @@ firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% endif -%}
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
network_api_class=nova.network.neutronv2.api.API
libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
neutron_ovs_bridge=alubr0
security_group_api=nova
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% if neutron_plugin and (neutron_plugin == 'nvp' or neutron_plugin == 'nsx') -%}
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtOpenVswitchVirtualPortDriver
security_group_api = neutron

View File

@ -7,12 +7,13 @@
{% endif -%}
###############################################################################
[DEFAULT]
verbose={{ verbose }}
debug={{ debug }}
dhcpbridge_flagfile=/etc/nova/nova.conf
dhcpbridge=/usr/bin/nova-dhcpbridge
logdir=/var/log/nova
state_path=/var/lib/nova
force_dhcp_release=True
verbose=True
use_syslog = {{ use_syslog }}
ec2_private_dns_show_ip=True
api_paste_config=/etc/nova/api-paste.ini
@ -58,6 +59,14 @@ firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% endif -%}
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
network_api_class=nova.network.neutronv2.api.API
libvirt_vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
neutron_ovs_bridge=alubr0
security_group_api=nova
firewall_driver = nova.virt.firewall.NoopFirewallDriver
{% endif -%}
{% if neutron_plugin and (neutron_plugin == 'nvp' or neutron_plugin == 'nsx') -%}
libvirt_vif_driver = nova.virt.libvirt.vif.LibvirtOpenVswitchVirtualPortDriver
security_group_api = neutron

View File

@ -1,9 +0,0 @@
#!/usr/bin/python
"""Amulet tests on a basic nova compute deployment on precise-essex."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(series='precise')
deployment.run_tests()

View File

@ -1,17 +0,0 @@
#!/usr/bin/python
"""Amulet tests on a basic nova compute deployment on precise-folsom."""
import amulet
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
# NOTE(coreycb): Skipping failing test until resolved. 'nova-manage db sync'
# fails in shared-db-relation-changed (only fails on folsom)
message = "Skipping failing test until resolved"
amulet.raise_status(amulet.SKIP, msg=message)
deployment = NovaBasicDeployment(series='precise',
openstack='cloud:precise-folsom',
source='cloud:precise-updates/folsom')
deployment.run_tests()

View File

@ -1,11 +0,0 @@
#!/usr/bin/python
"""Amulet tests on a basic nova compute deployment on precise-grizzly."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(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 nova compute deployment on precise-havana."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(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 nova compute git deployment on trusty-icehouse."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(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 nova compute deployment on trusty-juno."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(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 nova compute git deployment on trusty-juno."""
from basic_deployment import NovaBasicDeployment
if __name__ == '__main__':
deployment = NovaBasicDeployment(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,15 +16,17 @@ from charmhelpers.contrib.openstack.amulet.utils import (
)
# Use DEBUG to turn on debug logging
u = OpenStackAmuletUtils(ERROR)
u = OpenStackAmuletUtils(DEBUG)
class NovaBasicDeployment(OpenStackAmuletDeployment):
"""Amulet tests on a basic nova compute deployment."""
def __init__(self, series=None, openstack=None, source=None, stable=True):
def __init__(self, series=None, openstack=None, source=None, git=False,
stable=True):
"""Deploy the entire test environment."""
super(NovaBasicDeployment, self).__init__(series, openstack, source, stable)
self.git = git
self._add_services()
self._add_relations()
self._configure_services()
@ -65,6 +69,24 @@ class NovaBasicDeployment(OpenStackAmuletDeployment):
"""Configure all of the services."""
nova_config = {'config-flags': 'auto_assign_floating_ip=False',
'enable-live-migration': 'False'}
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': 'nova',
'repository': 'git://git.openstack.org/openstack/nova',
'branch': branch},
],
'directory': '/mnt/openstack-git',
'http_proxy': amulet_http_proxy,
'https_proxy': amulet_http_proxy,
}
nova_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
keystone_config = {'admin-password': 'openstack',
'admin-token': 'ubuntutesting'}
configs = {'nova-compute': nova_config, 'keystone': keystone_config}
@ -362,7 +384,7 @@ class NovaBasicDeployment(OpenStackAmuletDeployment):
'lock_path': '/var/lock/nova',
'force_dhcp_release': 'True',
'libvirt_use_virtio_for_bridges': 'True',
'verbose': 'True',
'verbose': 'False',
'use_syslog': 'False',
'ec2_private_dns_show_ip': 'True',
'api_paste_config': '/etc/nova/api-paste.ini',
@ -377,8 +399,7 @@ class NovaBasicDeployment(OpenStackAmuletDeployment):
'glance_api_servers': glance_relation['glance-api-server'],
'flat_interface': 'eth1',
'network_manager': 'nova.network.manager.FlatDHCPManager',
'volume_api_class': 'nova.volume.cinder.API',
'verbose': 'True'}
'volume_api_class': 'nova.volume.cinder.API'}
ret = u.validate_config_data(unit, conf, 'DEFAULT', expected)
if ret:

View File

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

View File

@ -0,0 +1,87 @@
from mock import patch
with patch('charmhelpers.core.hookenv.config') as config:
config.return_value = 'nova'
import nova_compute_utils as utils # noqa
with patch('nova_compute_utils.restart_map'):
with patch('nova_compute_utils.register_configs'):
import git_reinstall
from test_utils import (
CharmTestCase
)
TO_PATCH = [
'config',
]
openstack_origin_git = \
"""repositories:
- {name: requirements,
repository: 'git://git.openstack.org/openstack/requirements',
branch: stable/juno}
- {name: nova,
repository: 'git://git.openstack.org/openstack/nova',
branch: stable/juno}"""
class TestnovaAPIActions(CharmTestCase):
def setUp(self):
super(TestnovaAPIActions, self).setUp(git_reinstall, TO_PATCH)
self.config.side_effect = self.test_config.get
@patch.object(git_reinstall, 'action_set')
@patch.object(git_reinstall, 'action_fail')
@patch.object(git_reinstall, 'git_install')
def test_git_reinstall(self, git_install, action_fail, action_set):
self.test_config.set('openstack-origin-git', openstack_origin_git)
git_reinstall.git_reinstall()
git_install.assert_called_with(openstack_origin_git)
self.assertTrue(git_install.called)
self.assertFalse(action_set.called)
self.assertFalse(action_fail.called)
@patch.object(git_reinstall, 'action_set')
@patch.object(git_reinstall, 'action_fail')
@patch.object(git_reinstall, 'git_install')
@patch('charmhelpers.contrib.openstack.utils.config')
def test_git_reinstall_not_configured(self, _config, git_install,
action_fail, action_set):
_config.return_value = None
git_reinstall.git_reinstall()
msg = 'openstack-origin-git is not configured'
action_fail.assert_called_with(msg)
self.assertFalse(git_install.called)
self.assertFalse(action_set.called)
@patch.object(git_reinstall, 'action_set')
@patch.object(git_reinstall, 'action_fail')
@patch.object(git_reinstall, 'git_install')
@patch('charmhelpers.contrib.openstack.utils.config')
def test_git_reinstall_exception(self, _config, git_install,
action_fail, action_set):
_config.return_value = openstack_origin_git
e = OSError('something bad happened')
git_install.side_effect = e
traceback = (
"Traceback (most recent call last):\n"
" File \"actions/git_reinstall.py\", line 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")
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

@ -3,6 +3,7 @@ from mock import (
patch,
MagicMock
)
import yaml
from test_utils import CharmTestCase
@ -48,6 +49,8 @@ TO_PATCH = [
'disable_shell',
'enable_shell',
'update_nrpe_config',
'git_install',
'git_install_requested',
# misc_utils
'ensure_ceph_keyring',
'execd_preinstall',
@ -77,13 +80,40 @@ class NovaComputeRelationsTests(CharmTestCase):
self.apt_install.assert_called_with(['foo', 'bar'], fatal=True)
self.execd_preinstall.assert_called()
def test_install_hook_git(self):
self.git_install_requested.return_value = True
self.determine_packages.return_value = ['foo', 'bar']
repo = 'cloud:trusty-juno'
openstack_origin_git = {
'repositories': [
{'name': 'requirements',
'repository': 'git://git.openstack.org/openstack/requirements', # noqa
'branch': 'stable/juno'},
{'name': 'nova',
'repository': 'git://git.openstack.org/openstack/nova',
'branch': 'stable/juno'}
],
'directory': '/mnt/openstack-git',
}
projects_yaml = yaml.dump(openstack_origin_git)
self.test_config.set('openstack-origin', repo)
self.test_config.set('openstack-origin-git', projects_yaml)
hooks.install()
self.configure_installation_source.assert_called_with(repo)
self.assertTrue(self.apt_update.called)
self.apt_install.assert_called_with(['foo', 'bar'], fatal=True)
self.git_install.assert_called_with(projects_yaml)
self.execd_preinstall.assert_called()
def test_config_changed_with_upgrade(self):
self.git_install_requested.return_value = False
self.openstack_upgrade_available.return_value = True
hooks.config_changed()
self.assertTrue(self.do_openstack_upgrade.called)
@patch.object(hooks, 'compute_joined')
def test_config_changed_with_migration(self, compute_joined):
self.git_install_requested.return_value = False
self.migration_enabled.return_value = True
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
self.test_config.set('migration-auth-type', 'ssh')
@ -102,6 +132,7 @@ class NovaComputeRelationsTests(CharmTestCase):
@patch.object(hooks, 'compute_joined')
def test_config_changed_with_resize(self, compute_joined):
self.git_install_requested.return_value = False
self.test_config.set('enable-resize', True)
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
self.relation_ids.return_value = [
@ -120,6 +151,7 @@ class NovaComputeRelationsTests(CharmTestCase):
@patch.object(hooks, 'compute_joined')
def test_config_changed_without_resize(self, compute_joined):
self.git_install_requested.return_value = False
self.test_config.set('enable-resize', False)
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
self.relation_ids.return_value = [
@ -137,6 +169,7 @@ class NovaComputeRelationsTests(CharmTestCase):
@patch.object(hooks, 'compute_joined')
def test_config_changed_no_upgrade_no_migration(self, compute_joined):
self.git_install_requested.return_value = False
self.openstack_upgrade_available.return_value = False
self.migration_enabled.return_value = False
hooks.config_changed()
@ -145,10 +178,34 @@ class NovaComputeRelationsTests(CharmTestCase):
@patch.object(hooks, 'compute_joined')
def test_config_changed_with_sysctl(self, compute_joined):
self.git_install_requested.return_value = False
self.test_config.set('sysctl', '{ kernel.max_pid : "1337" }')
hooks.config_changed()
self.create_sysctl.assert_called()
@patch.object(hooks, 'config_value_changed')
def test_config_changed_git(self, config_val_changed):
self.git_install_requested.return_value = True
repo = 'cloud:trusty-juno'
openstack_origin_git = {
'repositories': [
{'name': 'requirements',
'repository':
'git://git.openstack.org/openstack/requirements',
'branch': 'stable/juno'},
{'name': 'nova',
'repository': 'git://git.openstack.org/openstack/nova',
'branch': 'stable/juno'}
],
'directory': '/mnt/openstack-git',
}
projects_yaml = yaml.dump(openstack_origin_git)
self.test_config.set('openstack-origin', repo)
self.test_config.set('openstack-origin-git', projects_yaml)
hooks.config_changed()
self.git_install.assert_called_with(projects_yaml)
self.assertFalse(self.do_openstack_upgrade.called)
def test_amqp_joined(self):
hooks.amqp_joined()
self.relation_set.assert_called_with(

View File

@ -35,6 +35,15 @@ OVS_PKGS = [
OVS_PKGS_FLAT = list(itertools.chain.from_iterable(OVS_PKGS))
openstack_origin_git = \
"""repositories:
- {name: requirements,
repository: 'git://git.openstack.org/openstack/requirements',
branch: stable/juno}
- {name: nova,
repository: 'git://git.openstack.org/openstack/nova',
branch: stable/juno}"""
class NovaComputeUtilsTests(CharmTestCase):
@ -44,7 +53,10 @@ class NovaComputeUtilsTests(CharmTestCase):
@patch.object(utils, 'enable_nova_metadata')
@patch.object(utils, 'network_manager')
def test_determine_packages_nova_network(self, net_man, en_meta):
@patch.object(utils, 'git_install_requested')
def test_determine_packages_nova_network(self, git_requested, net_man,
en_meta):
git_requested.return_value = False
en_meta.return_value = False
net_man.return_value = 'flatdhcpmanager'
self.relation_ids.return_value = []
@ -59,7 +71,10 @@ class NovaComputeUtilsTests(CharmTestCase):
@patch.object(utils, 'enable_nova_metadata')
@patch.object(utils, 'neutron_plugin')
@patch.object(utils, 'network_manager')
def test_determine_packages_quantum(self, net_man, n_plugin, en_meta):
@patch.object(utils, 'git_install_requested')
def test_determine_packages_quantum(self, git_requested, net_man, n_plugin,
en_meta):
git_requested.return_value = False
en_meta.return_value = False
self.neutron_plugin_attribute.return_value = OVS_PKGS
net_man.return_value = 'quantum'
@ -73,8 +88,11 @@ class NovaComputeUtilsTests(CharmTestCase):
@patch.object(utils, 'enable_nova_metadata')
@patch.object(utils, 'neutron_plugin')
@patch.object(utils, 'network_manager')
def test_determine_packages_quantum_legacy_off(self, net_man, n_plugin,
@patch.object(utils, 'git_install_requested')
def test_determine_packages_quantum_legacy_off(self, git_requested,
net_man, n_plugin,
en_meta, leg_mode):
git_requested.return_value = False
en_meta.return_value = False
leg_mode.return_value = False
self.neutron_plugin_attribute.return_value = OVS_PKGS
@ -89,8 +107,10 @@ class NovaComputeUtilsTests(CharmTestCase):
@patch.object(utils, 'enable_nova_metadata')
@patch.object(utils, 'neutron_plugin')
@patch.object(utils, 'network_manager')
def test_determine_packages_quantum_ceph(self, net_man, n_plugin, en_meta,
leg_mode):
@patch.object(utils, 'git_install_requested')
def test_determine_packages_quantum_ceph(self, git_requested, net_man,
n_plugin, en_meta, leg_mode):
git_requested.return_value = False
en_meta.return_value = False
leg_mode.return_value = True
self.neutron_plugin_attribute.return_value = OVS_PKGS
@ -105,7 +125,10 @@ class NovaComputeUtilsTests(CharmTestCase):
@patch.object(utils, 'enable_nova_metadata')
@patch.object(utils, 'neutron_plugin')
@patch.object(utils, 'network_manager')
def test_determine_packages_metadata(self, net_man, n_plugin, en_meta):
@patch.object(utils, 'git_install_requested')
def test_determine_packages_metadata(self, git_requested, net_man,
n_plugin, en_meta):
git_requested.return_value = False
en_meta.return_value = True
self.neutron_plugin_attribute.return_value = OVS_PKGS
net_man.return_value = 'bob'
@ -475,3 +498,163 @@ class NovaComputeUtilsTests(CharmTestCase):
_neutron_plugin_legacy_mode.return_value = True
_neutron_plugin.return_value = 'bobvs'
self.assertFalse(utils.manage_ovs())
@patch.object(utils, 'git_install_requested')
@patch.object(utils, 'git_clone_and_install')
@patch.object(utils, 'git_post_install')
@patch.object(utils, 'git_pre_install')
def test_git_install(self, git_pre, git_post, git_clone_and_install,
git_requested):
projects_yaml = openstack_origin_git
git_requested.return_value = True
utils.git_install(projects_yaml)
self.assertTrue(git_pre.called)
git_clone_and_install.assert_called_with(openstack_origin_git,
core_project='nova')
self.assertTrue(git_post.called)
@patch.object(utils, 'mkdir')
@patch.object(utils, 'write_file')
@patch.object(utils, 'add_user_to_group')
@patch.object(utils, 'add_group')
@patch.object(utils, 'adduser')
@patch.object(utils, 'check_call')
def test_git_pre_install(self, check_call, adduser, add_group,
add_user_to_group, write_file, mkdir):
utils.git_pre_install()
adduser.assert_called_with('nova', shell='/bin/bash',
system_user=True)
check_call.assert_called_with(['usermod', '--home', '/var/lib/nova',
'nova'])
add_group.assert_called_with('nova', system_group=True)
expected = [
call('nova', 'nova'),
call('nova', 'libvirtd'),
]
self.assertEquals(add_user_to_group.call_args_list, expected)
expected = [
call('/var/lib/nova', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/buckets', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/CA', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/CA/INTER', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/CA/newcerts', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/CA/private', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/CA/reqs', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/images', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/instances', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/keys', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/networks', owner='nova',
group='nova', perms=0755, force=False),
call('/var/lib/nova/tmp', owner='nova',
group='nova', perms=0755, force=False),
call('/var/log/nova', owner='nova',
group='nova', perms=0755, force=False),
]
self.assertEquals(mkdir.call_args_list, expected)
expected = [
call('/var/log/nova/nova-api.log', '', owner='nova',
group='nova', perms=0644),
call('/var/log/nova/nova-compute.log', '', owner='nova',
group='nova', perms=0644),
call('/var/log/nova/nova-manage.log', '', owner='nova',
group='nova', perms=0644),
call('/var/log/nova/nova-network.log', '', owner='nova',
group='nova', perms=0644),
]
self.assertEquals(write_file.call_args_list, expected)
@patch.object(utils, 'git_src_dir')
@patch.object(utils, 'service_restart')
@patch.object(utils, 'render')
@patch('os.path.join')
@patch('os.path.exists')
@patch('shutil.copytree')
@patch('shutil.rmtree')
@patch.object(utils, 'apt_install')
@patch.object(utils, 'apt_update')
def test_git_post_install(self, apt_update, apt_install, rmtree, copytree,
exists, join, render, service_restart,
git_src_dir):
projects_yaml = openstack_origin_git
join.return_value = 'joined-string'
utils.git_post_install(projects_yaml)
expected = [
call('joined-string', '/etc/nova'),
]
copytree.assert_has_calls(expected)
service_name = 'nova-compute'
nova_user = 'nova'
start_dir = '/var/lib/nova'
nova_conf = 'etc/nova/nova.conf'
nova_api_metadata_context = {
'service_description': 'Nova Metadata API server',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-api-metadata',
'executable_name': '/usr/local/bin/nova-api-metadata',
'config_files': [nova_conf],
}
nova_api_context = {
'service_description': 'Nova API server',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-api',
'executable_name': '/usr/local/bin/nova-api',
'config_files': [nova_conf],
}
nova_compute_context = {
'service_description': 'Nova compute worker',
'service_name': service_name,
'user_name': nova_user,
'process_name': 'nova-compute',
'executable_name': '/usr/local/bin/nova-compute',
'config_files': [nova_conf, '/etc/nova/nova-compute.conf'],
}
nova_network_context = {
'service_description': 'Nova network worker',
'service_name': service_name,
'user_name': nova_user,
'start_dir': start_dir,
'process_name': 'nova-network',
'executable_name': '/usr/local/bin/nova-network',
'config_files': [nova_conf],
}
expected = [
call('git/nova-compute-kvm.conf', '/etc/nova/nova-compute.conf',
{}, perms=0o644),
call('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers',
{}, perms=0o440),
call('git.upstart', '/etc/init/nova-api-metadata.conf',
nova_api_metadata_context, perms=0o644,
templates_dir='joined-string'),
call('git.upstart', '/etc/init/nova-api.conf',
nova_api_context, perms=0o644,
templates_dir='joined-string'),
call('git/upstart/nova-compute.upstart',
'/etc/init/nova-compute.conf',
nova_compute_context, perms=0o644),
call('git.upstart', '/etc/init/nova-network.conf',
nova_network_context, perms=0o644,
templates_dir='joined-string'),
]
self.assertEquals(render.call_args_list, expected)
self.assertTrue(apt_update.called)
apt_install.assert_called_with(
['bridge-utils', 'dnsmasq-base',
'dnsmasq-utils', 'ebtables', 'genisoimage', 'iptables',
'iputils-arping', 'kpartx', 'kvm', 'netcat', 'open-iscsi',
'parted', 'python-libvirt', 'qemu', 'qemu-system',
'qemu-utils', 'vlan', 'xen-system-amd64'], fatal=True)