Deploy from source
This commit is contained in:
commit
6a77fa888e
@ -1,2 +1,3 @@
|
||||
bin
|
||||
.coverage
|
||||
tags
|
||||
|
6
Makefile
6
Makefile
@ -2,7 +2,7 @@
|
||||
PYTHON := /usr/bin/env python
|
||||
|
||||
lint:
|
||||
@flake8 --exclude hooks/charmhelpers hooks unit_tests tests
|
||||
@flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests
|
||||
@charm proof
|
||||
|
||||
unit_test:
|
||||
@ -24,7 +24,9 @@ test:
|
||||
# raise_status() messages to stderr:
|
||||
# https://bugs.launchpad.net/amulet/+bug/1320357
|
||||
@juju test -v -p AMULET_HTTP_PROXY --timeout 900 \
|
||||
00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse
|
||||
00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse \
|
||||
16-basic-trusty-icehouse-git 17-basic-trusty-juno \
|
||||
18-basic-trusty-juno-git
|
||||
|
||||
publish: lint unit_test
|
||||
bzr push lp:charms/nova-compute
|
||||
|
91
README.md
91
README.md
@ -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
2
actions.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
git-reinstall:
|
||||
description: Reinstall nova-compute 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 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()
|
24
config.yaml
24
config.yaml
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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':
|
||||
|
@ -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 -%}
|
||||
|
@ -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']
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -33,3 +33,6 @@ requires:
|
||||
zeromq-configuration:
|
||||
interface: zeromq-configuration
|
||||
scope: container
|
||||
peers:
|
||||
compute-peer:
|
||||
interface: nova
|
||||
|
4
templates/git/nova-compute-kvm.conf
Normal file
4
templates/git/nova-compute-kvm.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
compute_driver=libvirt.LibvirtDriver
|
||||
[libvirt]
|
||||
virt_type=kvm
|
4
templates/git/nova-compute-lxc.conf
Normal file
4
templates/git/nova-compute-lxc.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
compute_driver=libvirt.LibvirtDriver
|
||||
[libvirt]
|
||||
virt_type=lxc
|
4
templates/git/nova-compute-qemu.conf
Normal file
4
templates/git/nova-compute-qemu.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
compute_driver=libvirt.LibvirtDriver
|
||||
[libvirt]
|
||||
virt_type=qemu
|
2
templates/git/nova-compute-vmware.conf
Normal file
2
templates/git/nova-compute-vmware.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[DEFAULT]
|
||||
compute_driver=vmwareapi.VMwareVCDriver
|
4
templates/git/nova-compute-xen.conf
Normal file
4
templates/git/nova-compute-xen.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
compute_driver=libvirt.LibvirtDriver
|
||||
[libvirt]
|
||||
virt_type=xen
|
4
templates/git/nova_sudoers
Normal file
4
templates/git/nova_sudoers
Normal file
@ -0,0 +1,4 @@
|
||||
Defaults:nova !requiretty
|
||||
|
||||
nova ALL = (root) NOPASSWD: /usr/local/bin/nova-rootwrap /etc/nova/rootwrap.conf *
|
||||
|
1
templates/git/nova_tgt.conf
Normal file
1
templates/git/nova_tgt.conf
Normal file
@ -0,0 +1 @@
|
||||
include /var/lib/nova/volumes/*
|
27
templates/git/upstart/nova-compute.upstart
Executable file
27
templates/git/upstart/nova-compute.upstart
Executable 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 -%}
|
@ -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
|
||||
|
155
templates/icehouse/nova.conf
Normal file
155
templates/icehouse/nova.conf
Normal 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 -%}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
@ -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()
|
@ -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()
|
@ -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()
|
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 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
11
tests/17-basic-trusty-juno
Executable 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
12
tests/18-basic-trusty-juno-git
Executable 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()
|
@ -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:
|
||||
|
@ -1,3 +1,4 @@
|
||||
import sys
|
||||
|
||||
sys.path.append('actions/')
|
||||
sys.path.append('hooks/')
|
||||
|
87
unit_tests/test_actions_git_reinstall.py
Normal file
87
unit_tests/test_actions_git_reinstall.py
Normal 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})
|
@ -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(
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user