Deploy from source
This commit is contained in:
commit
6f29a919ed
|
@ -1,2 +1,3 @@
|
||||||
bin
|
bin
|
||||||
.coverage
|
.coverage
|
||||||
|
tags
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -2,7 +2,7 @@
|
||||||
PYTHON := /usr/bin/env python
|
PYTHON := /usr/bin/env python
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@flake8 --exclude hooks/charmhelpers hooks unit_tests tests
|
@flake8 --exclude hooks/charmhelpers actions hooks unit_tests tests
|
||||||
@charm proof
|
@charm proof
|
||||||
|
|
||||||
unit_test:
|
unit_test:
|
||||||
|
@ -18,8 +18,10 @@ test:
|
||||||
# coreycb note: The -v should only be temporary until Amulet sends
|
# coreycb note: The -v should only be temporary until Amulet sends
|
||||||
# raise_status() messages to stderr:
|
# raise_status() messages to stderr:
|
||||||
# https://bugs.launchpad.net/amulet/+bug/1320357
|
# https://bugs.launchpad.net/amulet/+bug/1320357
|
||||||
@juju test -v -p AMULET_HTTP_PROXY --timeout 900 \
|
@juju test -v -p AMULET_HTTP_PROXY --timeout 1200 \
|
||||||
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
|
||||||
|
|
||||||
sync: bin/charm_helpers_sync.py
|
sync: bin/charm_helpers_sync.py
|
||||||
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
|
@$(PYTHON) bin/charm_helpers_sync.py -c charm-helpers-hooks.yaml
|
||||||
|
|
85
README.txt
85
README.txt
|
@ -23,3 +23,88 @@ juju deploy postgresql
|
||||||
|
|
||||||
juju add-relation "nova-cloud-controller:pgsql-nova-db" "postgresql:db"
|
juju add-relation "nova-cloud-controller:pgsql-nova-db" "postgresql:db"
|
||||||
juju add-relation "nova-cloud-controller:pgsql-neutron-db" "postgresql:db"
|
juju add-relation "nova-cloud-controller:pgsql-neutron-db" "postgresql:db"
|
||||||
|
|
||||||
|
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}"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
git-reinstall:
|
||||||
|
description: Reinstall nova-cloud-controller from the openstack-origin-git repositories.
|
|
@ -0,0 +1 @@
|
||||||
|
git_reinstall.py
|
|
@ -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_cc_utils import (
|
||||||
|
git_install,
|
||||||
|
)
|
||||||
|
|
||||||
|
from nova_cc_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()
|
16
config.yaml
16
config.yaml
|
@ -14,6 +14,22 @@ options:
|
||||||
Note that updating this setting to a source that is known to
|
Note that updating this setting to a source that is known to
|
||||||
provide a later version of OpenStack will trigger a software
|
provide a later version of OpenStack will trigger a software
|
||||||
upgrade.
|
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.
|
||||||
rabbit-user:
|
rabbit-user:
|
||||||
default: nova
|
default: nova
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -320,14 +320,15 @@ def db_ssl(rdata, ctxt, ssl_dir):
|
||||||
|
|
||||||
|
|
||||||
class IdentityServiceContext(OSContextGenerator):
|
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 = service
|
||||||
self.service_user = service_user
|
self.service_user = service_user
|
||||||
|
self.rel_name = rel_name
|
||||||
|
self.interfaces = [self.rel_name]
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
log('Generating template context for identity-service', level=DEBUG)
|
log('Generating template context for ' + self.rel_name, level=DEBUG)
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
|
|
||||||
if self.service and self.service_user:
|
if self.service and self.service_user:
|
||||||
|
@ -341,7 +342,7 @@ class IdentityServiceContext(OSContextGenerator):
|
||||||
|
|
||||||
ctxt['signing_dir'] = cachedir
|
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):
|
for unit in related_units(rid):
|
||||||
rdata = relation_get(rid=rid, unit=unit)
|
rdata = relation_get(rid=rid, unit=unit)
|
||||||
serv_host = rdata.get('service_host')
|
serv_host = rdata.get('service_host')
|
||||||
|
@ -807,6 +808,19 @@ class NeutronContext(OSContextGenerator):
|
||||||
|
|
||||||
return ovs_ctxt
|
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):
|
def nvp_ctxt(self):
|
||||||
driver = neutron_plugin_attribute(self.plugin, 'driver',
|
driver = neutron_plugin_attribute(self.plugin, 'driver',
|
||||||
self.network_manager)
|
self.network_manager)
|
||||||
|
@ -890,6 +904,8 @@ class NeutronContext(OSContextGenerator):
|
||||||
ctxt.update(self.n1kv_ctxt())
|
ctxt.update(self.n1kv_ctxt())
|
||||||
elif self.plugin == 'Calico':
|
elif self.plugin == 'Calico':
|
||||||
ctxt.update(self.calico_ctxt())
|
ctxt.update(self.calico_ctxt())
|
||||||
|
elif self.plugin == 'vsp':
|
||||||
|
ctxt.update(self.nuage_ctxt())
|
||||||
|
|
||||||
alchemy_flags = config('neutron-alchemy-flags')
|
alchemy_flags = config('neutron-alchemy-flags')
|
||||||
if alchemy_flags:
|
if alchemy_flags:
|
||||||
|
|
|
@ -180,6 +180,19 @@ def neutron_plugins():
|
||||||
'nova-api-metadata']],
|
'nova-api-metadata']],
|
||||||
'server_packages': ['neutron-server', 'calico-control'],
|
'server_packages': ['neutron-server', 'calico-control'],
|
||||||
'server_services': ['neutron-server']
|
'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':
|
if release >= 'icehouse':
|
||||||
|
|
|
@ -9,5 +9,9 @@ respawn
|
||||||
exec start-stop-daemon --start --chuid {{ user_name }} \
|
exec start-stop-daemon --start --chuid {{ user_name }} \
|
||||||
--chdir {{ start_dir }} --name {{ process_name }} \
|
--chdir {{ start_dir }} --name {{ process_name }} \
|
||||||
--exec {{ executable_name }} -- \
|
--exec {{ executable_name }} -- \
|
||||||
|
{% for config_file in config_files -%}
|
||||||
--config-file={{ config_file }} \
|
--config-file={{ config_file }} \
|
||||||
|
{% endfor -%}
|
||||||
|
{% if log_file -%}
|
||||||
--log-file={{ 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',
|
repository: 'git://git.openstack.org/openstack/requirements.git',
|
||||||
branch: 'stable/icehouse'}
|
branch: 'stable/icehouse'}
|
||||||
directory: /mnt/openstack-git
|
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
|
global requirements_dir
|
||||||
parent_dir = '/mnt/openstack-git'
|
parent_dir = '/mnt/openstack-git'
|
||||||
|
@ -522,6 +524,12 @@ def git_clone_and_install(projects_yaml, core_project):
|
||||||
projects = yaml.load(projects_yaml)
|
projects = yaml.load(projects_yaml)
|
||||||
_git_validate_projects_yaml(projects, core_project)
|
_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():
|
if 'directory' in projects.keys():
|
||||||
parent_dir = projects['directory']
|
parent_dir = projects['directory']
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
# Authors:
|
# Authors:
|
||||||
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import errno
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
@ -87,7 +89,18 @@ def log(message, level=None):
|
||||||
if not isinstance(message, six.string_types):
|
if not isinstance(message, six.string_types):
|
||||||
message = repr(message)
|
message = repr(message)
|
||||||
command += [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):
|
class Serializable(UserDict):
|
||||||
|
|
|
@ -33,9 +33,9 @@ def bool_from_string(value):
|
||||||
|
|
||||||
value = value.strip().lower()
|
value = value.strip().lower()
|
||||||
|
|
||||||
if value in ['y', 'yes', 'true', 't']:
|
if value in ['y', 'yes', 'true', 't', 'on']:
|
||||||
return True
|
return True
|
||||||
elif value in ['n', 'no', 'false', 'f']:
|
elif value in ['n', 'no', 'false', 'f', 'off']:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
msg = "Unable to interpret string value '%s' as boolean" % (value)
|
msg = "Unable to interpret string value '%s' as boolean" % (value)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import os
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
config,
|
config,
|
||||||
relation_ids,
|
relation_ids,
|
||||||
|
@ -329,4 +331,22 @@ class InstanceConsoleContext(context.OSContextGenerator):
|
||||||
servers = []
|
servers = []
|
||||||
|
|
||||||
ctxt['memcached_servers'] = ','.join(servers)
|
ctxt['memcached_servers'] = ','.join(servers)
|
||||||
|
|
||||||
|
# Configure nova-novncproxy https if nova-api is using https.
|
||||||
|
if https():
|
||||||
|
cn = resolve_address(endpoint_type=INTERNAL)
|
||||||
|
if cn:
|
||||||
|
cert_filename = 'cert_{}'.format(cn)
|
||||||
|
key_filename = 'key_{}'.format(cn)
|
||||||
|
else:
|
||||||
|
cert_filename = 'cert'
|
||||||
|
key_filename = 'key'
|
||||||
|
|
||||||
|
ssl_dir = '/etc/apache2/ssl/nova'
|
||||||
|
cert = os.path.join(ssl_dir, cert_filename)
|
||||||
|
key = os.path.join(ssl_dir, key_filename)
|
||||||
|
if os.path.exists(cert) and os.path.exists(key):
|
||||||
|
ctxt['ssl_cert'] = cert
|
||||||
|
ctxt['ssl_key'] = key
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
|
@ -43,7 +43,9 @@ from charmhelpers.fetch import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.openstack.utils import (
|
from charmhelpers.contrib.openstack.utils import (
|
||||||
|
config_value_changed,
|
||||||
configure_installation_source,
|
configure_installation_source,
|
||||||
|
git_install_requested,
|
||||||
openstack_upgrade_available,
|
openstack_upgrade_available,
|
||||||
os_release,
|
os_release,
|
||||||
os_requires_version,
|
os_requires_version,
|
||||||
|
@ -75,6 +77,7 @@ from nova_cc_utils import (
|
||||||
disable_services,
|
disable_services,
|
||||||
do_openstack_upgrade,
|
do_openstack_upgrade,
|
||||||
enable_services,
|
enable_services,
|
||||||
|
git_install,
|
||||||
keystone_ca_cert_b64,
|
keystone_ca_cert_b64,
|
||||||
migrate_neutron_database,
|
migrate_neutron_database,
|
||||||
migrate_nova_database,
|
migrate_nova_database,
|
||||||
|
@ -132,9 +135,12 @@ CONFIGS = register_configs()
|
||||||
def install():
|
def install():
|
||||||
execd_preinstall()
|
execd_preinstall()
|
||||||
configure_installation_source(config('openstack-origin'))
|
configure_installation_source(config('openstack-origin'))
|
||||||
|
|
||||||
apt_update()
|
apt_update()
|
||||||
apt_install(determine_packages(), fatal=True)
|
apt_install(determine_packages(), fatal=True)
|
||||||
|
|
||||||
|
git_install(config('openstack-origin-git'))
|
||||||
|
|
||||||
_files = os.path.join(charm_dir(), 'files')
|
_files = os.path.join(charm_dir(), 'files')
|
||||||
if os.path.isdir(_files):
|
if os.path.isdir(_files):
|
||||||
for f in os.listdir(_files):
|
for f in os.listdir(_files):
|
||||||
|
@ -160,16 +166,21 @@ def config_changed():
|
||||||
relation_prefix='nova')
|
relation_prefix='nova')
|
||||||
|
|
||||||
global CONFIGS
|
global CONFIGS
|
||||||
if openstack_upgrade_available('nova-common'):
|
if git_install_requested():
|
||||||
CONFIGS = do_openstack_upgrade()
|
if config_value_changed('openstack-origin-git'):
|
||||||
[neutron_api_relation_joined(rid=rid, remote_restart=True)
|
git_install(config('openstack-origin-git'))
|
||||||
for rid in relation_ids('neutron-api')]
|
else:
|
||||||
|
if openstack_upgrade_available('nova-common'):
|
||||||
|
CONFIGS = do_openstack_upgrade()
|
||||||
|
[neutron_api_relation_joined(rid=rid, remote_restart=True)
|
||||||
|
for rid in relation_ids('neutron-api')]
|
||||||
save_script_rc()
|
save_script_rc()
|
||||||
configure_https()
|
configure_https()
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
if console_attributes('protocol'):
|
if console_attributes('protocol'):
|
||||||
apt_update()
|
if not git_install_requested():
|
||||||
apt_install(console_attributes('packages'), fatal=True)
|
apt_update()
|
||||||
|
apt_install(console_attributes('packages'), fatal=True)
|
||||||
[compute_joined(rid=rid)
|
[compute_joined(rid=rid)
|
||||||
for rid in relation_ids('cloud-compute')]
|
for rid in relation_ids('cloud-compute')]
|
||||||
for r_id in relation_ids('identity-service'):
|
for r_id in relation_ids('identity-service'):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
|
@ -19,6 +20,9 @@ from charmhelpers.contrib.openstack.utils import (
|
||||||
get_host_ip,
|
get_host_ip,
|
||||||
get_hostname,
|
get_hostname,
|
||||||
get_os_codename_install_source,
|
get_os_codename_install_source,
|
||||||
|
git_install_requested,
|
||||||
|
git_clone_and_install,
|
||||||
|
git_src_dir,
|
||||||
is_ip,
|
is_ip,
|
||||||
os_release,
|
os_release,
|
||||||
save_script_rc as _save_script_rc)
|
save_script_rc as _save_script_rc)
|
||||||
|
@ -31,6 +35,7 @@ from charmhelpers.fetch import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
|
charm_dir,
|
||||||
config,
|
config,
|
||||||
log,
|
log,
|
||||||
relation_get,
|
relation_get,
|
||||||
|
@ -42,13 +47,19 @@ from charmhelpers.core.hookenv import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.core.host import (
|
from charmhelpers.core.host import (
|
||||||
|
adduser,
|
||||||
|
add_group,
|
||||||
|
add_user_to_group,
|
||||||
|
mkdir,
|
||||||
service,
|
service,
|
||||||
service_start,
|
service_start,
|
||||||
service_stop,
|
service_stop,
|
||||||
service_running,
|
service_running,
|
||||||
lsb_release
|
lsb_release,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from charmhelpers.core.templating import render
|
||||||
|
|
||||||
from charmhelpers.contrib.network.ip import (
|
from charmhelpers.contrib.network.ip import (
|
||||||
is_ipv6
|
is_ipv6
|
||||||
)
|
)
|
||||||
|
@ -72,6 +83,40 @@ BASE_PACKAGES = [
|
||||||
'python-memcache',
|
'python-memcache',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
BASE_GIT_PACKAGES = [
|
||||||
|
'libxml2-dev',
|
||||||
|
'libxslt1-dev',
|
||||||
|
'python-dev',
|
||||||
|
'python-pip',
|
||||||
|
'python-setuptools',
|
||||||
|
'zlib1g-dev',
|
||||||
|
]
|
||||||
|
|
||||||
|
LATE_GIT_PACKAGES = [
|
||||||
|
'novnc',
|
||||||
|
'spice-html5',
|
||||||
|
'websockify',
|
||||||
|
]
|
||||||
|
|
||||||
|
# ubuntu packages that should not be installed when deploying from git
|
||||||
|
GIT_PACKAGE_BLACKLIST = [
|
||||||
|
'neutron-server',
|
||||||
|
'nova-api-ec2',
|
||||||
|
'nova-api-os-compute',
|
||||||
|
'nova-api-os-volume',
|
||||||
|
'nova-cert',
|
||||||
|
'nova-conductor',
|
||||||
|
'nova-consoleauth',
|
||||||
|
'nova-novncproxy',
|
||||||
|
'nova-objectstore',
|
||||||
|
'nova-scheduler',
|
||||||
|
'nova-spiceproxy',
|
||||||
|
'nova-xvpvncproxy',
|
||||||
|
'python-keystoneclient',
|
||||||
|
'python-six',
|
||||||
|
'quantum-server',
|
||||||
|
]
|
||||||
|
|
||||||
BASE_SERVICES = [
|
BASE_SERVICES = [
|
||||||
'nova-api-ec2',
|
'nova-api-ec2',
|
||||||
'nova-api-os-compute',
|
'nova-api-os-compute',
|
||||||
|
@ -377,6 +422,15 @@ def determine_packages():
|
||||||
packages.extend(pkgs)
|
packages.extend(pkgs)
|
||||||
if console_attributes('packages'):
|
if console_attributes('packages'):
|
||||||
packages.extend(console_attributes('packages'))
|
packages.extend(console_attributes('packages'))
|
||||||
|
|
||||||
|
if git_install_requested():
|
||||||
|
packages = list(set(packages))
|
||||||
|
packages.extend(BASE_GIT_PACKAGES)
|
||||||
|
# don't include packages that will be installed from git
|
||||||
|
for p in GIT_PACKAGE_BLACKLIST:
|
||||||
|
if p in packages:
|
||||||
|
packages.remove(p)
|
||||||
|
|
||||||
return list(set(packages))
|
return list(set(packages))
|
||||||
|
|
||||||
|
|
||||||
|
@ -974,3 +1028,210 @@ def setup_ipv6():
|
||||||
' main')
|
' main')
|
||||||
apt_update()
|
apt_update()
|
||||||
apt_install('haproxy/trusty-backports', fatal=True)
|
apt_install('haproxy/trusty-backports', fatal=True)
|
||||||
|
|
||||||
|
|
||||||
|
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',
|
||||||
|
]
|
||||||
|
|
||||||
|
adduser('nova', shell='/bin/bash', system_user=True)
|
||||||
|
subprocess.check_call(['usermod', '--home', '/var/lib/nova', 'nova'])
|
||||||
|
add_group('nova', system_group=True)
|
||||||
|
add_user_to_group('nova', 'nova')
|
||||||
|
|
||||||
|
for d in dirs:
|
||||||
|
mkdir(d, owner='nova', group='nova', perms=0755, force=False)
|
||||||
|
|
||||||
|
|
||||||
|
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'])
|
||||||
|
|
||||||
|
render('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers', {}, perms=0o440)
|
||||||
|
|
||||||
|
nova_cc = 'nova-cloud-controller'
|
||||||
|
nova_user = 'nova'
|
||||||
|
start_dir = '/var/lib/nova'
|
||||||
|
nova_conf = '/etc/nova/nova.conf'
|
||||||
|
nova_ec2_api_context = {
|
||||||
|
'service_description': 'Nova EC2 API server',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-api-ec2',
|
||||||
|
'executable_name': '/usr/local/bin/nova-api-ec2',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_api_os_compute_context = {
|
||||||
|
'service_description': 'Nova OpenStack Compute API server',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-api-os-compute',
|
||||||
|
'executable_name': '/usr/local/bin/nova-api-os-compute',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_cells_context = {
|
||||||
|
'service_description': 'Nova cells',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-cells',
|
||||||
|
'executable_name': '/usr/local/bin/nova-cells',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_cert_context = {
|
||||||
|
'service_description': 'Nova cert',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-cert',
|
||||||
|
'executable_name': '/usr/local/bin/nova-cert',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_conductor_context = {
|
||||||
|
'service_description': 'Nova conductor',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-conductor',
|
||||||
|
'executable_name': '/usr/local/bin/nova-conductor',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_consoleauth_context = {
|
||||||
|
'service_description': 'Nova console auth',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-consoleauth',
|
||||||
|
'executable_name': '/usr/local/bin/nova-consoleauth',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_console_context = {
|
||||||
|
'service_description': 'Nova console',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-console',
|
||||||
|
'executable_name': '/usr/local/bin/nova-console',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_novncproxy_context = {
|
||||||
|
'service_description': 'Nova NoVNC proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-novncproxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-novncproxy',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_objectstore_context = {
|
||||||
|
'service_description': 'Nova object store',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-objectstore',
|
||||||
|
'executable_name': '/usr/local/bin/nova-objectstore',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_scheduler_context = {
|
||||||
|
'service_description': 'Nova scheduler',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-scheduler',
|
||||||
|
'executable_name': '/usr/local/bin/nova-scheduler',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_spiceproxy_context = {
|
||||||
|
'service_description': 'Nova spice proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-spicehtml5proxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-spicehtml5proxy',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_xvpvncproxy_context = {
|
||||||
|
'service_description': 'Nova XVPVNC proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-xvpvncproxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-xvpvncproxy',
|
||||||
|
'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-ec2.conf',
|
||||||
|
nova_ec2_api_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-api-os-compute.conf',
|
||||||
|
nova_api_os_compute_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-cells.conf',
|
||||||
|
nova_cells_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-cert.conf',
|
||||||
|
nova_cert_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-conductor.conf',
|
||||||
|
nova_conductor_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-consoleauth.conf',
|
||||||
|
nova_consoleauth_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-console.conf',
|
||||||
|
nova_console_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-novncproxy.conf',
|
||||||
|
nova_novncproxy_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-objectstore.conf',
|
||||||
|
nova_objectstore_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-scheduler.conf',
|
||||||
|
nova_scheduler_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-spiceproxy.conf',
|
||||||
|
nova_spiceproxy_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
render('git.upstart', '/etc/init/nova-xvpvncproxy.conf',
|
||||||
|
nova_xvpvncproxy_context, perms=0o644,
|
||||||
|
templates_dir=templates_dir)
|
||||||
|
|
||||||
|
apt_update()
|
||||||
|
apt_install(LATE_GIT_PACKAGES, fatal=True)
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Defaults:nova !requiretty
|
||||||
|
|
||||||
|
nova ALL = (root) NOPASSWD: /usr/local/bin/nova-rootwrap /etc/nova/rootwrap.conf *
|
||||||
|
|
|
@ -42,6 +42,8 @@ my_ip = {{ host_ip }}
|
||||||
memcached_servers = {{ memcached_servers }}
|
memcached_servers = {{ memcached_servers }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "parts/novnc" %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -70,6 +72,10 @@ default_floating_pool = {{ external_network }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
|
||||||
|
neutron_ovs_bridge = alubr0
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
||||||
security_group_api = neutron
|
security_group_api = neutron
|
||||||
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||||
|
|
|
@ -42,6 +42,8 @@ my_ip = {{ host_ip }}
|
||||||
memcached_servers = {{ memcached_servers }}
|
memcached_servers = {{ memcached_servers }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "parts/novnc" %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -70,6 +72,10 @@ default_floating_pool = {{ external_network }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
|
||||||
|
neutron_ovs_bridge = alubr0
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
||||||
security_group_api = neutron
|
security_group_api = neutron
|
||||||
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||||
|
|
|
@ -41,6 +41,8 @@ my_ip = {{ host_ip }}
|
||||||
memcached_servers = {{ memcached_servers }}
|
memcached_servers = {{ memcached_servers }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "parts/novnc" %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -63,6 +65,10 @@ default_floating_pool = {{ external_network }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
|
||||||
|
{% if neutron_plugin and neutron_plugin == 'vsp' -%}
|
||||||
|
neutron_ovs_bridge = alubr0
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
{% if neutron_plugin and neutron_plugin == 'nvp' -%}
|
||||||
security_group_api = neutron
|
security_group_api = neutron
|
||||||
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
nova_firewall_driver = nova.virt.firewall.NoopFirewallDriver
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
{%- if ssl_only -%}
|
||||||
|
ssl_only=true
|
||||||
|
{% endif -%}
|
||||||
|
{% if ssl_cert -%}
|
||||||
|
cert={{ ssl_cert }}
|
||||||
|
{% endif -%}
|
||||||
|
{% if ssl_key -%}
|
||||||
|
key={{ ssl_key }}
|
||||||
|
{% endif %}
|
|
@ -1,10 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""Amulet tests on a basic nova cloud controller deployment on
|
|
||||||
precise-essex."""
|
|
||||||
|
|
||||||
from basic_deployment import NovaCCBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = NovaCCBasicDeployment(series='precise')
|
|
||||||
deployment.run_tests()
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""Amulet tests on a basic nova cloud controller deployment on
|
|
||||||
precise-folsom."""
|
|
||||||
|
|
||||||
import amulet
|
|
||||||
from basic_deployment import NovaCCBasicDeployment
|
|
||||||
|
|
||||||
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 = NovaCCBasicDeployment(series='precise',
|
|
||||||
openstack='cloud:precise-folsom',
|
|
||||||
source='cloud:precise-updates/folsom')
|
|
||||||
deployment.run_tests()
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""Amulet tests on a basic nova cloud controller deployment on
|
|
||||||
precise-grizzly."""
|
|
||||||
|
|
||||||
from basic_deployment import NovaCCBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = NovaCCBasicDeployment(series='precise',
|
|
||||||
openstack='cloud:precise-grizzly',
|
|
||||||
source='cloud:precise-updates/grizzly')
|
|
||||||
deployment.run_tests()
|
|
|
@ -1,12 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""Amulet tests on a basic nova cloud controller deployment on
|
|
||||||
precise-havana."""
|
|
||||||
|
|
||||||
from basic_deployment import NovaCCBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = NovaCCBasicDeployment(series='precise',
|
|
||||||
openstack='cloud:precise-havana',
|
|
||||||
source='cloud:precise-updates/havana')
|
|
||||||
deployment.run_tests()
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic nova cloud controller git deployment on
|
||||||
|
trusty-icehouse."""
|
||||||
|
|
||||||
|
from basic_deployment import NovaCCBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = NovaCCBasicDeployment(series='trusty', git=True)
|
||||||
|
deployment.run_tests()
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic nova cloud controller deployment on
|
||||||
|
trusty-juno."""
|
||||||
|
|
||||||
|
from basic_deployment import NovaCCBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = NovaCCBasicDeployment(series='trusty',
|
||||||
|
openstack='cloud:trusty-juno',
|
||||||
|
source='cloud:trusty-updates/juno')
|
||||||
|
deployment.run_tests()
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic nova cloud controller git deployment on
|
||||||
|
trusty-juno."""
|
||||||
|
|
||||||
|
from basic_deployment import NovaCCBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = NovaCCBasicDeployment(series='trusty',
|
||||||
|
openstack='cloud:trusty-juno',
|
||||||
|
source='cloud:trusty-updates/juno',
|
||||||
|
git=True)
|
||||||
|
deployment.run_tests()
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
import amulet
|
import amulet
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
from charmhelpers.contrib.openstack.amulet.deployment import (
|
from charmhelpers.contrib.openstack.amulet.deployment import (
|
||||||
OpenStackAmuletDeployment
|
OpenStackAmuletDeployment
|
||||||
|
@ -13,15 +15,17 @@ from charmhelpers.contrib.openstack.amulet.utils import (
|
||||||
)
|
)
|
||||||
|
|
||||||
# Use DEBUG to turn on debug logging
|
# Use DEBUG to turn on debug logging
|
||||||
u = OpenStackAmuletUtils(ERROR)
|
u = OpenStackAmuletUtils(DEBUG)
|
||||||
|
|
||||||
|
|
||||||
class NovaCCBasicDeployment(OpenStackAmuletDeployment):
|
class NovaCCBasicDeployment(OpenStackAmuletDeployment):
|
||||||
"""Amulet tests on a basic nova cloud controller deployment."""
|
"""Amulet tests on a basic nova cloud controller deployment."""
|
||||||
|
|
||||||
def __init__(self, series=None, openstack=None, source=None, stable=True):
|
def __init__(self, series=None, openstack=None, source=None, git=False,
|
||||||
|
stable=False):
|
||||||
"""Deploy the entire test environment."""
|
"""Deploy the entire test environment."""
|
||||||
super(NovaCCBasicDeployment, self).__init__(series, openstack, source, stable)
|
super(NovaCCBasicDeployment, self).__init__(series, openstack, source, stable)
|
||||||
|
self.git = git
|
||||||
self._add_services()
|
self._add_services()
|
||||||
self._add_relations()
|
self._add_relations()
|
||||||
self._configure_services()
|
self._configure_services()
|
||||||
|
@ -62,9 +66,28 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
|
||||||
|
|
||||||
def _configure_services(self):
|
def _configure_services(self):
|
||||||
"""Configure all of the services."""
|
"""Configure all of the services."""
|
||||||
|
nova_cc_config = {}
|
||||||
|
if self.git:
|
||||||
|
branch = 'stable/' + self._get_openstack_release_string()
|
||||||
|
amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY')
|
||||||
|
openstack_origin_git = {
|
||||||
|
'repositories': [
|
||||||
|
{'name': 'requirements',
|
||||||
|
'repository': 'git://git.openstack.org/openstack/requirements',
|
||||||
|
'branch': branch},
|
||||||
|
{'name': '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_cc_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
|
||||||
keystone_config = {'admin-password': 'openstack',
|
keystone_config = {'admin-password': 'openstack',
|
||||||
'admin-token': 'ubuntutesting'}
|
'admin-token': 'ubuntutesting'}
|
||||||
configs = {'keystone': keystone_config}
|
configs = {'nova-cloud-controller': nova_cc_config,
|
||||||
|
'keystone': keystone_config}
|
||||||
super(NovaCCBasicDeployment, self)._configure_services(configs)
|
super(NovaCCBasicDeployment, self)._configure_services(configs)
|
||||||
|
|
||||||
def _initialize_tests(self):
|
def _initialize_tests(self):
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
sys.path.append('actions/')
|
||||||
sys.path.append('hooks/')
|
sys.path.append('hooks/')
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
from mock import patch, MagicMock
|
||||||
|
|
||||||
|
with patch('charmhelpers.core.hookenv.config') as config:
|
||||||
|
config.return_value = 'nova'
|
||||||
|
import nova_cc_utils as utils # noqa
|
||||||
|
|
||||||
|
_reg = utils.register_configs
|
||||||
|
_map = utils.restart_map
|
||||||
|
|
||||||
|
utils.register_configs = MagicMock()
|
||||||
|
utils.restart_map = MagicMock()
|
||||||
|
|
||||||
|
with patch('nova_cc_utils.guard_map') as gmap:
|
||||||
|
with patch('charmhelpers.core.hookenv.config') as config:
|
||||||
|
config.return_value = False
|
||||||
|
gmap.return_value = {}
|
||||||
|
import git_reinstall
|
||||||
|
|
||||||
|
utils.register_configs = _reg
|
||||||
|
utils.restart_map = _map
|
||||||
|
|
||||||
|
from test_utils import (
|
||||||
|
CharmTestCase
|
||||||
|
)
|
||||||
|
|
||||||
|
TO_PATCH = [
|
||||||
|
'config',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
openstack_origin_git = \
|
||||||
|
"""repositories:
|
||||||
|
- {name: requirements,
|
||||||
|
repository: 'git://git.openstack.org/openstack/requirements',
|
||||||
|
branch: stable/juno}
|
||||||
|
- {name: 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})
|
|
@ -9,9 +9,7 @@ import mock
|
||||||
from charmhelpers.core import hookenv
|
from charmhelpers.core import hookenv
|
||||||
_conf = hookenv.config
|
_conf = hookenv.config
|
||||||
hookenv.config = mock.MagicMock()
|
hookenv.config = mock.MagicMock()
|
||||||
import nova_cc_utils as _utils
|
import nova_cc_utils as _utils # noqa
|
||||||
# this assert is a double check + to avoid pep8 warning
|
|
||||||
assert _utils.config == hookenv.config
|
|
||||||
hookenv.config = _conf
|
hookenv.config = _conf
|
||||||
#####
|
#####
|
||||||
|
|
||||||
|
@ -47,6 +45,8 @@ class NovaComputeContextTests(CharmTestCase):
|
||||||
self.config.side_effect = self.test_config.get
|
self.config.side_effect = self.test_config.get
|
||||||
self.log.side_effect = fake_log
|
self.log.side_effect = fake_log
|
||||||
|
|
||||||
|
@mock.patch.object(context, 'resolve_address',
|
||||||
|
lambda *args, **kwargs: None)
|
||||||
@mock.patch.object(utils, 'os_release')
|
@mock.patch.object(utils, 'os_release')
|
||||||
@mock.patch('charmhelpers.contrib.network.ip.log')
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
def test_instance_console_context_without_memcache(self, os_release, log_):
|
def test_instance_console_context_without_memcache(self, os_release, log_):
|
||||||
|
@ -57,6 +57,8 @@ class NovaComputeContextTests(CharmTestCase):
|
||||||
self.assertEqual({'memcached_servers': ''},
|
self.assertEqual({'memcached_servers': ''},
|
||||||
instance_console())
|
instance_console())
|
||||||
|
|
||||||
|
@mock.patch.object(context, 'resolve_address',
|
||||||
|
lambda *args, **kwargs: None)
|
||||||
@mock.patch.object(utils, 'os_release')
|
@mock.patch.object(utils, 'os_release')
|
||||||
@mock.patch('charmhelpers.contrib.network.ip.log')
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
def test_instance_console_context_with_memcache(self, os_release, log_):
|
def test_instance_console_context_with_memcache(self, os_release, log_):
|
||||||
|
@ -64,6 +66,8 @@ class NovaComputeContextTests(CharmTestCase):
|
||||||
'127.0.1.1',
|
'127.0.1.1',
|
||||||
'127.0.1.1')
|
'127.0.1.1')
|
||||||
|
|
||||||
|
@mock.patch.object(context, 'resolve_address',
|
||||||
|
lambda *args, **kwargs: None)
|
||||||
@mock.patch.object(utils, 'os_release')
|
@mock.patch.object(utils, 'os_release')
|
||||||
@mock.patch('charmhelpers.contrib.network.ip.log')
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
def test_instance_console_context_with_memcache_ipv6(self, os_release,
|
def test_instance_console_context_with_memcache_ipv6(self, os_release,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from mock import MagicMock, patch, call
|
from mock import MagicMock, patch, call
|
||||||
from test_utils import CharmTestCase, patch_open
|
from test_utils import CharmTestCase, patch_open
|
||||||
import os
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
with patch('charmhelpers.core.hookenv.config') as config:
|
with patch('charmhelpers.core.hookenv.config') as config:
|
||||||
config.return_value = 'neutron'
|
config.return_value = 'neutron'
|
||||||
|
@ -69,6 +70,8 @@ TO_PATCH = [
|
||||||
'get_iface_for_address',
|
'get_iface_for_address',
|
||||||
'get_netmask_for_address',
|
'get_netmask_for_address',
|
||||||
'update_nrpe_config',
|
'update_nrpe_config',
|
||||||
|
'git_install',
|
||||||
|
'git_install_requested',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,18 +109,70 @@ class NovaCCHooksTests(CharmTestCase):
|
||||||
self.disable_services.assert_called()
|
self.disable_services.assert_called()
|
||||||
self.cmd_all_services.assert_called_with('stop')
|
self.cmd_all_services.assert_called_with('stop')
|
||||||
|
|
||||||
|
def test_install_hook_git(self):
|
||||||
|
self.git_install_requested.return_value = True
|
||||||
|
self.determine_packages.return_value = ['foo', 'bar']
|
||||||
|
self.determine_ports.return_value = [80, 81, 82]
|
||||||
|
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.git_install.assert_called_with(projects_yaml)
|
||||||
|
self.apt_install.assert_called_with(['foo', 'bar'], fatal=True)
|
||||||
|
self.execd_preinstall.assert_called()
|
||||||
|
self.disable_services.assert_called()
|
||||||
|
self.cmd_all_services.assert_called_with('stop')
|
||||||
|
|
||||||
@patch.object(hooks, 'configure_https')
|
@patch.object(hooks, 'configure_https')
|
||||||
def test_config_changed_no_upgrade(self, conf_https):
|
def test_config_changed_no_upgrade(self, conf_https):
|
||||||
|
self.git_install_requested.return_value = False
|
||||||
self.openstack_upgrade_available.return_value = False
|
self.openstack_upgrade_available.return_value = False
|
||||||
hooks.config_changed()
|
hooks.config_changed()
|
||||||
self.assertTrue(self.save_script_rc.called)
|
self.assertTrue(self.save_script_rc.called)
|
||||||
|
|
||||||
|
@patch.object(hooks, 'config_value_changed')
|
||||||
|
@patch.object(hooks, 'configure_https')
|
||||||
|
def test_config_changed_git(self, configure_https, 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)
|
||||||
|
|
||||||
@patch.object(hooks, 'cluster_joined')
|
@patch.object(hooks, 'cluster_joined')
|
||||||
@patch.object(hooks, 'identity_joined')
|
@patch.object(hooks, 'identity_joined')
|
||||||
@patch.object(hooks, 'neutron_api_relation_joined')
|
@patch.object(hooks, 'neutron_api_relation_joined')
|
||||||
@patch.object(hooks, 'configure_https')
|
@patch.object(hooks, 'configure_https')
|
||||||
def test_config_changed_with_upgrade(self, conf_https, neutron_api_joined,
|
def test_config_changed_with_upgrade(self, conf_https, neutron_api_joined,
|
||||||
identity_joined, cluster_joined):
|
identity_joined, cluster_joined):
|
||||||
|
self.git_install_requested.return_value = False
|
||||||
self.openstack_upgrade_available.return_value = True
|
self.openstack_upgrade_available.return_value = True
|
||||||
self.relation_ids.return_value = ['generic_rid']
|
self.relation_ids.return_value = ['generic_rid']
|
||||||
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
|
_zmq_joined = self.patch('zeromq_configuration_relation_joined')
|
||||||
|
|
|
@ -127,6 +127,15 @@ DPKG_OPTS = [
|
||||||
'--option', 'Dpkg::Options::=--force-confdef',
|
'--option', 'Dpkg::Options::=--force-confdef',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
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}"""
|
||||||
|
|
||||||
|
|
||||||
def fake_plugin_attribute(plugin, attr, net_manager):
|
def fake_plugin_attribute(plugin, attr, net_manager):
|
||||||
if plugin in PLUGIN_ATTRIBUTES:
|
if plugin in PLUGIN_ATTRIBUTES:
|
||||||
|
@ -298,26 +307,34 @@ class NovaCCUtilsTests(CharmTestCase):
|
||||||
self.assertEquals(_proxy_page, None)
|
self.assertEquals(_proxy_page, None)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_quantum(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_quantum(self, git_requested, subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self._resource_map(network_manager='quantum')
|
self._resource_map(network_manager='quantum')
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
self.assertIn('quantum-server', pkgs)
|
self.assertIn('quantum-server', pkgs)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_neutron(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_neutron(self, git_requested, subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self.is_relation_made.return_value = False
|
self.is_relation_made.return_value = False
|
||||||
self._resource_map(network_manager='neutron')
|
self._resource_map(network_manager='neutron')
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
self.assertIn('neutron-server', pkgs)
|
self.assertIn('neutron-server', pkgs)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_nova_volume(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_nova_volume(self, git_requested, subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self.relation_ids.return_value = ['nova-volume-service:0']
|
self.relation_ids.return_value = ['nova-volume-service:0']
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
self.assertIn('nova-api-os-volume', pkgs)
|
self.assertIn('nova-api-os-volume', pkgs)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_console(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_console(self, git_requested, subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self.test_config.set('console-access-protocol', 'spice')
|
self.test_config.set('console-access-protocol', 'spice')
|
||||||
self.relation_ids.return_value = []
|
self.relation_ids.return_value = []
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
|
@ -326,7 +343,9 @@ class NovaCCUtilsTests(CharmTestCase):
|
||||||
self.assertIn(console_pkg, pkgs)
|
self.assertIn(console_pkg, pkgs)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_base(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_base(self, git_requested, subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self.relation_ids.return_value = []
|
self.relation_ids.return_value = []
|
||||||
self.os_release.return_value = 'folsom'
|
self.os_release.return_value = 'folsom'
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
|
@ -334,7 +353,10 @@ class NovaCCUtilsTests(CharmTestCase):
|
||||||
self.assertEquals(ex, pkgs)
|
self.assertEquals(ex, pkgs)
|
||||||
|
|
||||||
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
|
||||||
def test_determine_packages_base_grizzly_beyond(self, subcontext):
|
@patch.object(utils, 'git_install_requested')
|
||||||
|
def test_determine_packages_base_grizzly_beyond(self, git_requested,
|
||||||
|
subcontext):
|
||||||
|
git_requested.return_value = False
|
||||||
self.relation_ids.return_value = []
|
self.relation_ids.return_value = []
|
||||||
self.os_release.return_value = 'grizzly'
|
self.os_release.return_value = 'grizzly'
|
||||||
pkgs = utils.determine_packages()
|
pkgs = utils.determine_packages()
|
||||||
|
@ -824,3 +846,237 @@ class NovaCCUtilsTests(CharmTestCase):
|
||||||
self.assertFalse(self.service_running.called)
|
self.assertFalse(self.service_running.called)
|
||||||
self.assertFalse(self.service_stop.called)
|
self.assertFalse(self.service_stop.called)
|
||||||
self.assertTrue(contexts.complete_contexts.called)
|
self.assertTrue(contexts.complete_contexts.called)
|
||||||
|
|
||||||
|
@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, 'add_user_to_group')
|
||||||
|
@patch.object(utils, 'add_group')
|
||||||
|
@patch.object(utils, 'adduser')
|
||||||
|
@patch('subprocess.check_call')
|
||||||
|
def test_git_pre_install(self, check_call, adduser, add_group,
|
||||||
|
add_user_to_group, 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'),
|
||||||
|
]
|
||||||
|
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)
|
||||||
|
|
||||||
|
@patch.object(utils, 'git_src_dir')
|
||||||
|
@patch.object(utils, 'render')
|
||||||
|
@patch('os.path.join')
|
||||||
|
@patch('os.path.exists')
|
||||||
|
@patch('shutil.copytree')
|
||||||
|
@patch('shutil.rmtree')
|
||||||
|
def test_git_post_install(self, rmtree, copytree, exists, join, render,
|
||||||
|
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)
|
||||||
|
|
||||||
|
nova_cc = 'nova-cloud-controller'
|
||||||
|
nova_user = 'nova'
|
||||||
|
start_dir = '/var/lib/nova'
|
||||||
|
nova_conf = '/etc/nova/nova.conf'
|
||||||
|
nova_ec2_api_context = {
|
||||||
|
'service_description': 'Nova EC2 API server',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-api-ec2',
|
||||||
|
'executable_name': '/usr/local/bin/nova-api-ec2',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_api_os_compute_context = {
|
||||||
|
'service_description': 'Nova OpenStack Compute API server',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-api-os-compute',
|
||||||
|
'executable_name': '/usr/local/bin/nova-api-os-compute',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_cells_context = {
|
||||||
|
'service_description': 'Nova cells',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-cells',
|
||||||
|
'executable_name': '/usr/local/bin/nova-cells',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_cert_context = {
|
||||||
|
'service_description': 'Nova cert',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-cert',
|
||||||
|
'executable_name': '/usr/local/bin/nova-cert',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_conductor_context = {
|
||||||
|
'service_description': 'Nova conductor',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-conductor',
|
||||||
|
'executable_name': '/usr/local/bin/nova-conductor',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_consoleauth_context = {
|
||||||
|
'service_description': 'Nova console auth',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-consoleauth',
|
||||||
|
'executable_name': '/usr/local/bin/nova-consoleauth',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_console_context = {
|
||||||
|
'service_description': 'Nova console',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-console',
|
||||||
|
'executable_name': '/usr/local/bin/nova-console',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_novncproxy_context = {
|
||||||
|
'service_description': 'Nova NoVNC proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-novncproxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-novncproxy',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_objectstore_context = {
|
||||||
|
'service_description': 'Nova object store',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-objectstore',
|
||||||
|
'executable_name': '/usr/local/bin/nova-objectstore',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_scheduler_context = {
|
||||||
|
'service_description': 'Nova scheduler',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-scheduler',
|
||||||
|
'executable_name': '/usr/local/bin/nova-scheduler',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_spiceproxy_context = {
|
||||||
|
'service_description': 'Nova spice proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-spicehtml5proxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-spicehtml5proxy',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
nova_xvpvncproxy_context = {
|
||||||
|
'service_description': 'Nova XVPVNC proxy',
|
||||||
|
'service_name': nova_cc,
|
||||||
|
'user_name': nova_user,
|
||||||
|
'start_dir': start_dir,
|
||||||
|
'process_name': 'nova-xvpvncproxy',
|
||||||
|
'executable_name': '/usr/local/bin/nova-xvpvncproxy',
|
||||||
|
'config_files': [nova_conf],
|
||||||
|
}
|
||||||
|
expected = [
|
||||||
|
call('git/nova_sudoers', '/etc/sudoers.d/nova_sudoers',
|
||||||
|
{}, perms=0o440),
|
||||||
|
call('git.upstart', '/etc/init/nova-api-ec2.conf',
|
||||||
|
nova_ec2_api_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-api-os-compute.conf',
|
||||||
|
nova_api_os_compute_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-cells.conf',
|
||||||
|
nova_cells_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-cert.conf',
|
||||||
|
nova_cert_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-conductor.conf',
|
||||||
|
nova_conductor_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-consoleauth.conf',
|
||||||
|
nova_consoleauth_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-console.conf',
|
||||||
|
nova_console_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-novncproxy.conf',
|
||||||
|
nova_novncproxy_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-objectstore.conf',
|
||||||
|
nova_objectstore_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-scheduler.conf',
|
||||||
|
nova_scheduler_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-spiceproxy.conf',
|
||||||
|
nova_spiceproxy_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
call('git.upstart', '/etc/init/nova-xvpvncproxy.conf',
|
||||||
|
nova_xvpvncproxy_context, perms=0o644,
|
||||||
|
templates_dir='joined-string'),
|
||||||
|
]
|
||||||
|
self.assertEquals(render.call_args_list, expected)
|
||||||
|
self.assertTrue(self.apt_update.called)
|
||||||
|
self.apt_install.assert_called_with(['novnc', 'spice-html5',
|
||||||
|
'websockify'], fatal=True)
|
||||||
|
|
Loading…
Reference in New Issue