Merged trunk in + LE charmhelper sync
This commit is contained in:
3
Makefile
3
Makefile
@@ -15,8 +15,7 @@ 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 1200 \
|
@juju test -v -p AMULET_HTTP_PROXY,AMULET_OS_VIP --timeout 2700
|
||||||
00-setup 14-basic-precise-icehouse 15-basic-trusty-icehouse
|
|
||||||
|
|
||||||
bin/charm_helpers_sync.py:
|
bin/charm_helpers_sync.py:
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
|
|||||||
15
config.yaml
15
config.yaml
@@ -79,6 +79,12 @@ options:
|
|||||||
default:
|
default:
|
||||||
description: |
|
description: |
|
||||||
Base64 encoded SSL key to use with certificate specified as ssl_cert.
|
Base64 encoded SSL key to use with certificate specified as ssl_cert.
|
||||||
|
ssl_ca:
|
||||||
|
type: string
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Base64 encoded SSL CA to use with the certificate and key provided - only
|
||||||
|
required if you are providing a privately signed ssl_cert and ssl_key.
|
||||||
# General Swift Proxy configuration
|
# General Swift Proxy configuration
|
||||||
bind-port:
|
bind-port:
|
||||||
default: 8080
|
default: 8080
|
||||||
@@ -116,6 +122,15 @@ options:
|
|||||||
Timeouts from these requests can be recovered from so setting this to
|
Timeouts from these requests can be recovered from so setting this to
|
||||||
something lower than node-timeout would provide quicker error recovery
|
something lower than node-timeout would provide quicker error recovery
|
||||||
while allowing for a longer timeout for non-recoverable requests (PUTs).
|
while allowing for a longer timeout for non-recoverable requests (PUTs).
|
||||||
|
# Logging configuration
|
||||||
|
debug:
|
||||||
|
default: False
|
||||||
|
type: boolean
|
||||||
|
description: Enable debug level logging.
|
||||||
|
log-headers:
|
||||||
|
default: False
|
||||||
|
type: boolean
|
||||||
|
description: Enable logging of all request headers.
|
||||||
# Manual Keystone configuration.
|
# Manual Keystone configuration.
|
||||||
keystone-auth-host:
|
keystone-auth-host:
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
@@ -247,7 +247,9 @@ class NRPE(object):
|
|||||||
|
|
||||||
service('restart', 'nagios-nrpe-server')
|
service('restart', 'nagios-nrpe-server')
|
||||||
|
|
||||||
for rid in relation_ids("local-monitors"):
|
monitor_ids = relation_ids("local-monitors") + \
|
||||||
|
relation_ids("nrpe-external-master")
|
||||||
|
for rid in monitor_ids:
|
||||||
relation_set(relation_id=rid, monitors=yaml.dump(monitors))
|
relation_set(relation_id=rid, monitors=yaml.dump(monitors))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,17 +44,24 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
Determine if the local branch being tested is derived from its
|
Determine if the local branch being tested is derived from its
|
||||||
stable or next (dev) branch, and based on this, use the corresonding
|
stable or next (dev) branch, and based on this, use the corresonding
|
||||||
stable or next branches for the other_services."""
|
stable or next branches for the other_services."""
|
||||||
base_charms = ['mysql', 'mongodb', 'rabbitmq-server']
|
base_charms = ['mysql', 'mongodb']
|
||||||
|
|
||||||
|
if self.series in ['precise', 'trusty']:
|
||||||
|
base_series = self.series
|
||||||
|
else:
|
||||||
|
base_series = self.current_next
|
||||||
|
|
||||||
if self.stable:
|
if self.stable:
|
||||||
for svc in other_services:
|
for svc in other_services:
|
||||||
temp = 'lp:charms/{}'
|
temp = 'lp:charms/{}/{}'
|
||||||
svc['location'] = temp.format(svc['name'])
|
svc['location'] = temp.format(base_series,
|
||||||
|
svc['name'])
|
||||||
else:
|
else:
|
||||||
for svc in other_services:
|
for svc in other_services:
|
||||||
if svc['name'] in base_charms:
|
if svc['name'] in base_charms:
|
||||||
temp = 'lp:charms/{}'
|
temp = 'lp:charms/{}/{}'
|
||||||
svc['location'] = temp.format(svc['name'])
|
svc['location'] = temp.format(base_series,
|
||||||
|
svc['name'])
|
||||||
else:
|
else:
|
||||||
temp = 'lp:~openstack-charmers/charms/{}/{}/next'
|
temp = 'lp:~openstack-charmers/charms/{}/{}/next'
|
||||||
svc['location'] = temp.format(self.current_next,
|
svc['location'] = temp.format(self.current_next,
|
||||||
@@ -99,9 +106,12 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
Return an integer representing the enum value of the openstack
|
Return an integer representing the enum value of the openstack
|
||||||
release.
|
release.
|
||||||
"""
|
"""
|
||||||
|
# Must be ordered by OpenStack release (not by Ubuntu release):
|
||||||
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
|
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
|
||||||
self.precise_havana, self.precise_icehouse,
|
self.precise_havana, self.precise_icehouse,
|
||||||
self.trusty_icehouse, self.trusty_juno, self.trusty_kilo) = range(8)
|
self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
|
||||||
|
self.trusty_kilo, self.vivid_kilo) = range(10)
|
||||||
|
|
||||||
releases = {
|
releases = {
|
||||||
('precise', None): self.precise_essex,
|
('precise', None): self.precise_essex,
|
||||||
('precise', 'cloud:precise-folsom'): self.precise_folsom,
|
('precise', 'cloud:precise-folsom'): self.precise_folsom,
|
||||||
@@ -110,7 +120,9 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
|
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
|
||||||
('trusty', None): self.trusty_icehouse,
|
('trusty', None): self.trusty_icehouse,
|
||||||
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
||||||
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo}
|
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
|
||||||
|
('utopic', None): self.utopic_juno,
|
||||||
|
('vivid', None): self.vivid_kilo}
|
||||||
return releases[(self.series, self.openstack)]
|
return releases[(self.series, self.openstack)]
|
||||||
|
|
||||||
def _get_openstack_release_string(self):
|
def _get_openstack_release_string(self):
|
||||||
|
|||||||
@@ -459,6 +459,11 @@ class AMQPContext(OSContextGenerator):
|
|||||||
|
|
||||||
ctxt['rabbitmq_hosts'] = ','.join(sorted(rabbitmq_hosts))
|
ctxt['rabbitmq_hosts'] = ','.join(sorted(rabbitmq_hosts))
|
||||||
|
|
||||||
|
oslo_messaging_flags = conf.get('oslo-messaging-flags', None)
|
||||||
|
if oslo_messaging_flags:
|
||||||
|
ctxt['oslo_messaging_flags'] = config_flags_parser(
|
||||||
|
oslo_messaging_flags)
|
||||||
|
|
||||||
if not context_complete(ctxt):
|
if not context_complete(ctxt):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@@ -808,6 +813,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)
|
||||||
@@ -891,6 +909,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,13 @@ 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)
|
||||||
|
|
||||||
|
old_environ = dict(os.environ)
|
||||||
|
|
||||||
|
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']
|
||||||
|
|
||||||
@@ -536,6 +545,8 @@ def git_clone_and_install(projects_yaml, core_project):
|
|||||||
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
||||||
update_requirements=True)
|
update_requirements=True)
|
||||||
|
|
||||||
|
os.environ = old_environ
|
||||||
|
|
||||||
|
|
||||||
def _git_validate_projects_yaml(projects, core_project):
|
def _git_validate_projects_yaml(projects, core_project):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -175,6 +175,8 @@ def peer_retrieve_by_prefix(prefix, relation_name='cluster', delimiter='_',
|
|||||||
exc_list = exc_list if exc_list else []
|
exc_list = exc_list if exc_list else []
|
||||||
peerdb_settings = peer_retrieve('-', relation_name=relation_name)
|
peerdb_settings = peer_retrieve('-', relation_name=relation_name)
|
||||||
matched = {}
|
matched = {}
|
||||||
|
if peerdb_settings is None:
|
||||||
|
return matched
|
||||||
for k, v in peerdb_settings.items():
|
for k, v in peerdb_settings.items():
|
||||||
full_prefix = prefix + delimiter
|
full_prefix = prefix + delimiter
|
||||||
if k.startswith(full_prefix):
|
if k.startswith(full_prefix):
|
||||||
|
|||||||
@@ -20,11 +20,14 @@
|
|||||||
# Authors:
|
# Authors:
|
||||||
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from functools import wraps
|
||||||
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
|
||||||
@@ -56,12 +59,14 @@ def cached(func):
|
|||||||
|
|
||||||
will cache the result of unit_get + 'test' for future calls.
|
will cache the result of unit_get + 'test' for future calls.
|
||||||
"""
|
"""
|
||||||
|
@wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
global cache
|
global cache
|
||||||
key = str((func, args, kwargs))
|
key = str((func, args, kwargs))
|
||||||
try:
|
try:
|
||||||
return cache[key]
|
return cache[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
pass # Drop out of the exception handler scope.
|
||||||
res = func(*args, **kwargs)
|
res = func(*args, **kwargs)
|
||||||
cache[key] = res
|
cache[key] = res
|
||||||
return res
|
return res
|
||||||
@@ -87,7 +92,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]
|
||||||
|
# Missing juju-log should not cause failures in unit tests
|
||||||
|
# Send log output to stderr
|
||||||
|
try:
|
||||||
subprocess.call(command)
|
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):
|
||||||
@@ -165,7 +181,7 @@ def local_unit():
|
|||||||
|
|
||||||
def remote_unit():
|
def remote_unit():
|
||||||
"""The remote unit for the current relation hook"""
|
"""The remote unit for the current relation hook"""
|
||||||
return os.environ['JUJU_REMOTE_UNIT']
|
return os.environ.get('JUJU_REMOTE_UNIT', None)
|
||||||
|
|
||||||
|
|
||||||
def service_name():
|
def service_name():
|
||||||
@@ -237,6 +253,12 @@ class Config(dict):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
return (self._prev_dict or {})[key]
|
return (self._prev_dict or {})[key]
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
try:
|
||||||
|
return self[key]
|
||||||
|
except KeyError:
|
||||||
|
return default
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
prev_keys = []
|
prev_keys = []
|
||||||
if self._prev_dict is not None:
|
if self._prev_dict is not None:
|
||||||
@@ -507,6 +529,11 @@ def unit_get(attribute):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def unit_public_ip():
|
||||||
|
"""Get this unit's public IP address"""
|
||||||
|
return unit_get('public-address')
|
||||||
|
|
||||||
|
|
||||||
def unit_private_ip():
|
def unit_private_ip():
|
||||||
"""Get this unit's private IP address"""
|
"""Get this unit's private IP address"""
|
||||||
return unit_get('private-address')
|
return unit_get('private-address')
|
||||||
@@ -664,3 +691,49 @@ def action_fail(message):
|
|||||||
|
|
||||||
The results set by action_set are preserved."""
|
The results set by action_set are preserved."""
|
||||||
subprocess.check_call(['action-fail', message])
|
subprocess.check_call(['action-fail', message])
|
||||||
|
|
||||||
|
|
||||||
|
def status_set(workload_state, message):
|
||||||
|
"""Set the workload state with a message
|
||||||
|
|
||||||
|
Use status-set to set the workload state with a message which is visible
|
||||||
|
to the user via juju status. If the status-set command is not found then
|
||||||
|
assume this is juju < 1.23 and juju-log the message unstead.
|
||||||
|
|
||||||
|
workload_state -- valid juju workload state.
|
||||||
|
message -- status update message
|
||||||
|
"""
|
||||||
|
valid_states = ['maintenance', 'blocked', 'waiting', 'active']
|
||||||
|
if workload_state not in valid_states:
|
||||||
|
raise ValueError(
|
||||||
|
'{!r} is not a valid workload state'.format(workload_state)
|
||||||
|
)
|
||||||
|
cmd = ['status-set', workload_state, message]
|
||||||
|
try:
|
||||||
|
ret = subprocess.call(cmd)
|
||||||
|
if ret == 0:
|
||||||
|
return
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno != errno.ENOENT:
|
||||||
|
raise
|
||||||
|
log_message = 'status-set failed: {} {}'.format(workload_state,
|
||||||
|
message)
|
||||||
|
log(log_message, level='INFO')
|
||||||
|
|
||||||
|
|
||||||
|
def status_get():
|
||||||
|
"""Retrieve the previously set juju workload state
|
||||||
|
|
||||||
|
If the status-set command is not found then assume this is juju < 1.23 and
|
||||||
|
return 'unknown'
|
||||||
|
"""
|
||||||
|
cmd = ['status-get']
|
||||||
|
try:
|
||||||
|
raw_status = subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
status = raw_status.rstrip()
|
||||||
|
return status
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
return 'unknown'
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ def service_available(service_name):
|
|||||||
['service', service_name, 'status'],
|
['service', service_name, 'status'],
|
||||||
stderr=subprocess.STDOUT).decode('UTF-8')
|
stderr=subprocess.STDOUT).decode('UTF-8')
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
return 'unrecognized service' not in e.output
|
return b'unrecognized service' not in e.output
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
from collections import Iterable
|
from collections import Iterable, OrderedDict
|
||||||
|
|
||||||
from charmhelpers.core import host
|
from charmhelpers.core import host
|
||||||
from charmhelpers.core import hookenv
|
from charmhelpers.core import hookenv
|
||||||
@@ -119,7 +119,7 @@ class ServiceManager(object):
|
|||||||
"""
|
"""
|
||||||
self._ready_file = os.path.join(hookenv.charm_dir(), 'READY-SERVICES.json')
|
self._ready_file = os.path.join(hookenv.charm_dir(), 'READY-SERVICES.json')
|
||||||
self._ready = None
|
self._ready = None
|
||||||
self.services = {}
|
self.services = OrderedDict()
|
||||||
for service in services or []:
|
for service in services or []:
|
||||||
service_name = service['service']
|
service_name = service['service']
|
||||||
self.services[service_name] = service
|
self.services[service_name] = service
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ def filter_installed_packages(packages):
|
|||||||
|
|
||||||
def apt_cache(in_memory=True):
|
def apt_cache(in_memory=True):
|
||||||
"""Build and return an apt cache"""
|
"""Build and return an apt cache"""
|
||||||
import apt_pkg
|
from apt import apt_pkg
|
||||||
apt_pkg.init()
|
apt_pkg.init()
|
||||||
if in_memory:
|
if in_memory:
|
||||||
apt_pkg.config.set("Dir::Cache::pkgcache", "")
|
apt_pkg.config.set("Dir::Cache::pkgcache", "")
|
||||||
|
|||||||
@@ -100,8 +100,14 @@ class SwiftIdentityContext(OSContextGenerator):
|
|||||||
'delay_auth_decision': config('delay-auth-decision'),
|
'delay_auth_decision': config('delay-auth-decision'),
|
||||||
'node_timeout': config('node-timeout'),
|
'node_timeout': config('node-timeout'),
|
||||||
'recoverable_node_timeout': config('recoverable-node-timeout'),
|
'recoverable_node_timeout': config('recoverable-node-timeout'),
|
||||||
|
'log_headers': config('log-headers')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config('debug'):
|
||||||
|
ctxt['log_level'] = 'DEBUG'
|
||||||
|
else:
|
||||||
|
ctxt['log_level'] = 'INFO'
|
||||||
|
|
||||||
# Instead of duplicating code lets use charm-helpers to set signing_dir
|
# Instead of duplicating code lets use charm-helpers to set signing_dir
|
||||||
# TODO(hopem): refactor this context handler to use charm-helpers
|
# TODO(hopem): refactor this context handler to use charm-helpers
|
||||||
# code.
|
# code.
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ from charmhelpers.contrib.network.ip import (
|
|||||||
format_ipv6_addr,
|
format_ipv6_addr,
|
||||||
)
|
)
|
||||||
from charmhelpers.contrib.openstack.context import ADDRESS_TYPES
|
from charmhelpers.contrib.openstack.context import ADDRESS_TYPES
|
||||||
|
|
||||||
from charmhelpers.contrib.charmsupport import nrpe
|
from charmhelpers.contrib.charmsupport import nrpe
|
||||||
|
|
||||||
extra_pkgs = [
|
extra_pkgs = [
|
||||||
@@ -147,22 +146,18 @@ def config_changed():
|
|||||||
|
|
||||||
@hooks.hook('identity-service-relation-joined')
|
@hooks.hook('identity-service-relation-joined')
|
||||||
def keystone_joined(relid=None):
|
def keystone_joined(relid=None):
|
||||||
if not is_elected_leader(SWIFT_HA_RES):
|
|
||||||
return
|
|
||||||
|
|
||||||
port = config('bind-port')
|
port = config('bind-port')
|
||||||
admin_url = '%s:%s' % (canonical_url(CONFIGS, ADMIN), port)
|
admin_url = '%s:%s' % (canonical_url(CONFIGS, ADMIN), port)
|
||||||
internal_url = '%s:%s/v1/AUTH_$(tenant_id)s' % \
|
internal_url = ('%s:%s/v1/AUTH_$(tenant_id)s' %
|
||||||
(canonical_url(CONFIGS, INTERNAL), port)
|
(canonical_url(CONFIGS, INTERNAL), port))
|
||||||
public_url = '%s:%s/v1/AUTH_$(tenant_id)s' % \
|
public_url = ('%s:%s/v1/AUTH_$(tenant_id)s' %
|
||||||
(canonical_url(CONFIGS, PUBLIC), port)
|
(canonical_url(CONFIGS, PUBLIC), port))
|
||||||
relation_set(service='swift',
|
region = config('region')
|
||||||
region=config('region'),
|
roles = config('operator-roles')
|
||||||
public_url=public_url,
|
|
||||||
internal_url=internal_url,
|
relation_set(service='swift', region=region, public_url=public_url,
|
||||||
admin_url=admin_url,
|
internal_url=internal_url, admin_url=admin_url,
|
||||||
requested_roles=config('operator-roles'),
|
requested_roles=roles, relation_id=relid)
|
||||||
relation_id=relid)
|
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('identity-service-relation-changed')
|
@hooks.hook('identity-service-relation-changed')
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ bind_port = {{ bind_port }}
|
|||||||
workers = {{ workers }}
|
workers = {{ workers }}
|
||||||
user = swift
|
user = swift
|
||||||
bind_ip = {{ bind_host }}
|
bind_ip = {{ bind_host }}
|
||||||
|
log_name = swift
|
||||||
|
log_facility = LOG_LOCAL0
|
||||||
|
log_level = {{ log_level }}
|
||||||
|
log_address = /dev/log
|
||||||
|
log_headers = {{ log_headers }}
|
||||||
|
|
||||||
{% if ssl %}
|
{% if ssl %}
|
||||||
cert_file = {{ ssl_cert }}
|
cert_file = {{ ssl_cert }}
|
||||||
key_file = {{ ssl_key }}
|
key_file = {{ ssl_key }}
|
||||||
@@ -10,10 +16,10 @@ key_file = {{ ssl_key }}
|
|||||||
|
|
||||||
{% if auth_type == 'keystone' %}
|
{% if auth_type == 'keystone' %}
|
||||||
[pipeline:main]
|
[pipeline:main]
|
||||||
pipeline = gatekeeper healthcheck cache swift3 s3token container_sync bulk tempurl slo dlo formpost authtoken keystoneauth staticweb container-quotas account-quotas proxy-server
|
pipeline = gatekeeper healthcheck proxy-logging cache swift3 s3token container_sync bulk tempurl slo dlo formpost authtoken keystoneauth staticweb container-quotas account-quotas proxy-logging proxy-server
|
||||||
{% else %}
|
{% else %}
|
||||||
[pipeline:main]
|
[pipeline:main]
|
||||||
pipeline = gatekeeper healthcheck cache container_sync bulk tempurl slo dlo formpost tempauth staticweb container-quotas account-quotas proxy-server
|
pipeline = gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl slo dlo formpost tempauth staticweb container-quotas account-quotas proxy-logging proxy-server
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[app:proxy-server]
|
[app:proxy-server]
|
||||||
@@ -40,6 +46,9 @@ use = egg:swift#account_quotas
|
|||||||
[filter:container-quotas]
|
[filter:container-quotas]
|
||||||
use = egg:swift#container_quotas
|
use = egg:swift#container_quotas
|
||||||
|
|
||||||
|
[filter:proxy-logging]
|
||||||
|
use = egg:swift#proxy_logging
|
||||||
|
|
||||||
[filter:staticweb]
|
[filter:staticweb]
|
||||||
use = egg:swift#staticweb
|
use = egg:swift#staticweb
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ bind_port = {{ bind_port }}
|
|||||||
workers = {{ workers }}
|
workers = {{ workers }}
|
||||||
user = swift
|
user = swift
|
||||||
bind_ip = {{ bind_host }}
|
bind_ip = {{ bind_host }}
|
||||||
|
log_name = swift
|
||||||
|
log_facility = LOG_LOCAL0
|
||||||
|
log_level = {{ log_level }}
|
||||||
|
log_address = /dev/log
|
||||||
|
log_headers = {{ log_headers }}
|
||||||
|
|
||||||
{% if ssl %}
|
{% if ssl %}
|
||||||
cert_file = {{ ssl_cert }}
|
cert_file = {{ ssl_cert }}
|
||||||
key_file = {{ ssl_key }}
|
key_file = {{ ssl_key }}
|
||||||
@@ -10,10 +16,10 @@ key_file = {{ ssl_key }}
|
|||||||
|
|
||||||
{% if auth_type == 'keystone' %}
|
{% if auth_type == 'keystone' %}
|
||||||
[pipeline:main]
|
[pipeline:main]
|
||||||
pipeline = gatekeeper healthcheck cache swift3 s3token container_sync bulk tempurl slo dlo formpost authtoken keystoneauth staticweb container-quotas account-quotas proxy-server
|
pipeline = gatekeeper healthcheck proxy-logging cache swift3 s3token container_sync bulk tempurl slo dlo formpost authtoken keystoneauth staticweb container-quotas account-quotas proxy-logging proxy-server
|
||||||
{% else %}
|
{% else %}
|
||||||
[pipeline:main]
|
[pipeline:main]
|
||||||
pipeline = gatekeeper healthcheck cache container_sync bulk tempurl slo dlo formpost tempauth staticweb container-quotas account-quotas proxy-server
|
pipeline = gatekeeper healthcheck proxy-logging cache container_sync bulk tempurl slo dlo formpost tempauth staticweb container-quotas account-quotas proxy-logging proxy-server
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
[app:proxy-server]
|
[app:proxy-server]
|
||||||
@@ -40,6 +46,9 @@ use = egg:swift#account_quotas
|
|||||||
[filter:container-quotas]
|
[filter:container-quotas]
|
||||||
use = egg:swift#container_quotas
|
use = egg:swift#container_quotas
|
||||||
|
|
||||||
|
[filter:proxy-logging]
|
||||||
|
use = egg:swift#proxy_logging
|
||||||
|
|
||||||
[filter:staticweb]
|
[filter:staticweb]
|
||||||
use = egg:swift#staticweb
|
use = egg:swift#staticweb
|
||||||
|
|
||||||
|
|||||||
11
tests/016-basic-trusty-juno
Executable file
11
tests/016-basic-trusty-juno
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic swift-proxy deployment on trusty-juno."""
|
||||||
|
|
||||||
|
from basic_deployment import SwiftProxyBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = SwiftProxyBasicDeployment(series='trusty',
|
||||||
|
openstack='cloud:trusty-juno',
|
||||||
|
source='cloud:trusty-updates/juno')
|
||||||
|
deployment.run_tests()
|
||||||
11
tests/017-basic-trusty-kilo
Normal file
11
tests/017-basic-trusty-kilo
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic swift-proxy deployment on trusty-kilo."""
|
||||||
|
|
||||||
|
from basic_deployment import SwiftProxyBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = SwiftProxyBasicDeployment(series='trusty',
|
||||||
|
openstack='cloud:trusty-kilo',
|
||||||
|
source='cloud:trusty-updates/kilo')
|
||||||
|
deployment.run_tests()
|
||||||
9
tests/018-basic-utopic-juno
Executable file
9
tests/018-basic-utopic-juno
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic swift-proxy deployment on utopic-juno."""
|
||||||
|
|
||||||
|
from basic_deployment import SwiftProxyBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = SwiftProxyBasicDeployment(series='utopic')
|
||||||
|
deployment.run_tests()
|
||||||
9
tests/019-basic-vivid-kilo
Normal file
9
tests/019-basic-vivid-kilo
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"""Amulet tests on a basic swift-proxy deployment on vivid-kilo."""
|
||||||
|
|
||||||
|
from basic_deployment import SwiftProxyBasicDeployment
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
deployment = SwiftProxyBasicDeployment(series='vivid')
|
||||||
|
deployment.run_tests()
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
"""Amulet tests on a basic swift-proxy deployment on precise-folsom."""
|
|
||||||
|
|
||||||
from basic_deployment import SwiftProxyBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = SwiftProxyBasicDeployment(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 swift-proxy deployment on precise-grizzly."""
|
|
||||||
|
|
||||||
from basic_deployment import SwiftProxyBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = SwiftProxyBasicDeployment(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 swift-proxy deployment on precise-havana."""
|
|
||||||
|
|
||||||
from basic_deployment import SwiftProxyBasicDeployment
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
deployment = SwiftProxyBasicDeployment(series='precise',
|
|
||||||
openstack='cloud:precise-havana',
|
|
||||||
source='cloud:precise-updates/havana')
|
|
||||||
deployment.run_tests()
|
|
||||||
@@ -14,7 +14,7 @@ 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 SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
||||||
@@ -368,13 +368,19 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
expected = {
|
expected = {
|
||||||
'DEFAULT': {
|
'DEFAULT': {
|
||||||
'bind_port': '8070',
|
'bind_port': '8070',
|
||||||
'user': 'swift'
|
'user': 'swift',
|
||||||
|
'log_name': 'swift',
|
||||||
|
'log_facility': 'LOG_LOCAL0',
|
||||||
|
'log_level': 'INFO',
|
||||||
|
'log_headers': 'False',
|
||||||
|
'log_address': '/dev/log'
|
||||||
},
|
},
|
||||||
'pipeline:main': {
|
'pipeline:main': {
|
||||||
'pipeline': 'gatekeeper healthcheck cache swift3 s3token '
|
'pipeline': 'gatekeeper healthcheck proxy-logging cache swift3 '
|
||||||
'container_sync bulk tempurl slo dlo formpost '
|
's3token container_sync bulk tempurl slo dlo '
|
||||||
'authtoken keystoneauth staticweb '
|
'formpost authtoken keystoneauth staticweb '
|
||||||
'container-quotas account-quotas proxy-server'
|
'container-quotas account-quotas proxy-logging '
|
||||||
|
'proxy-server'
|
||||||
},
|
},
|
||||||
'app:proxy-server': {
|
'app:proxy-server': {
|
||||||
'use': 'egg:swift#proxy',
|
'use': 'egg:swift#proxy',
|
||||||
@@ -395,6 +401,7 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
|
|||||||
},
|
},
|
||||||
'filter:account-quotas': {'use': 'egg:swift#account_quotas'},
|
'filter:account-quotas': {'use': 'egg:swift#account_quotas'},
|
||||||
'filter:container-quotas': {'use': 'egg:swift#container_quotas'},
|
'filter:container-quotas': {'use': 'egg:swift#container_quotas'},
|
||||||
|
'filter:proxy-logging': {'use': 'egg:swift#proxy_logging'},
|
||||||
'filter:staticweb': {'use': 'egg:swift#staticweb'},
|
'filter:staticweb': {'use': 'egg:swift#staticweb'},
|
||||||
'filter:bulk': {'use': 'egg:swift#bulk'},
|
'filter:bulk': {'use': 'egg:swift#bulk'},
|
||||||
'filter:slo': {'use': 'egg:swift#slo'},
|
'filter:slo': {'use': 'egg:swift#slo'},
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ class AmuletUtils(object):
|
|||||||
for k, v in six.iteritems(commands):
|
for k, v in six.iteritems(commands):
|
||||||
for cmd in v:
|
for cmd in v:
|
||||||
output, code = k.run(cmd)
|
output, code = k.run(cmd)
|
||||||
|
self.log.debug('{} `{}` returned '
|
||||||
|
'{}'.format(k.info['unit_name'],
|
||||||
|
cmd, code))
|
||||||
if code != 0:
|
if code != 0:
|
||||||
return "command `{}` returned {}".format(cmd, str(code))
|
return "command `{}` returned {}".format(cmd, str(code))
|
||||||
return None
|
return None
|
||||||
@@ -86,7 +89,11 @@ class AmuletUtils(object):
|
|||||||
def _get_config(self, unit, filename):
|
def _get_config(self, unit, filename):
|
||||||
"""Get a ConfigParser object for parsing a unit's config file."""
|
"""Get a ConfigParser object for parsing a unit's config file."""
|
||||||
file_contents = unit.file_contents(filename)
|
file_contents = unit.file_contents(filename)
|
||||||
config = ConfigParser.ConfigParser()
|
|
||||||
|
# NOTE(beisner): by default, ConfigParser does not handle options
|
||||||
|
# with no value, such as the flags used in the mysql my.cnf file.
|
||||||
|
# https://bugs.python.org/issue7005
|
||||||
|
config = ConfigParser.ConfigParser(allow_no_value=True)
|
||||||
config.readfp(io.StringIO(file_contents))
|
config.readfp(io.StringIO(file_contents))
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@@ -118,6 +125,9 @@ class AmuletUtils(object):
|
|||||||
longs, or can be a function that evaluate a variable and returns a
|
longs, or can be a function that evaluate a variable and returns a
|
||||||
bool.
|
bool.
|
||||||
"""
|
"""
|
||||||
|
self.log.debug('actual: {}'.format(repr(actual)))
|
||||||
|
self.log.debug('expected: {}'.format(repr(expected)))
|
||||||
|
|
||||||
for k, v in six.iteritems(expected):
|
for k, v in six.iteritems(expected):
|
||||||
if k in actual:
|
if k in actual:
|
||||||
if (isinstance(v, six.string_types) or
|
if (isinstance(v, six.string_types) or
|
||||||
@@ -134,7 +144,6 @@ class AmuletUtils(object):
|
|||||||
def validate_relation_data(self, sentry_unit, relation, expected):
|
def validate_relation_data(self, sentry_unit, relation, expected):
|
||||||
"""Validate actual relation data based on expected relation data."""
|
"""Validate actual relation data based on expected relation data."""
|
||||||
actual = sentry_unit.relation(relation[0], relation[1])
|
actual = sentry_unit.relation(relation[0], relation[1])
|
||||||
self.log.debug('actual: {}'.format(repr(actual)))
|
|
||||||
return self._validate_dict_data(expected, actual)
|
return self._validate_dict_data(expected, actual)
|
||||||
|
|
||||||
def _validate_list_data(self, expected, actual):
|
def _validate_list_data(self, expected, actual):
|
||||||
|
|||||||
@@ -44,17 +44,24 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
Determine if the local branch being tested is derived from its
|
Determine if the local branch being tested is derived from its
|
||||||
stable or next (dev) branch, and based on this, use the corresonding
|
stable or next (dev) branch, and based on this, use the corresonding
|
||||||
stable or next branches for the other_services."""
|
stable or next branches for the other_services."""
|
||||||
base_charms = ['mysql', 'mongodb', 'rabbitmq-server']
|
base_charms = ['mysql', 'mongodb']
|
||||||
|
|
||||||
|
if self.series in ['precise', 'trusty']:
|
||||||
|
base_series = self.series
|
||||||
|
else:
|
||||||
|
base_series = self.current_next
|
||||||
|
|
||||||
if self.stable:
|
if self.stable:
|
||||||
for svc in other_services:
|
for svc in other_services:
|
||||||
temp = 'lp:charms/{}'
|
temp = 'lp:charms/{}/{}'
|
||||||
svc['location'] = temp.format(svc['name'])
|
svc['location'] = temp.format(base_series,
|
||||||
|
svc['name'])
|
||||||
else:
|
else:
|
||||||
for svc in other_services:
|
for svc in other_services:
|
||||||
if svc['name'] in base_charms:
|
if svc['name'] in base_charms:
|
||||||
temp = 'lp:charms/{}'
|
temp = 'lp:charms/{}/{}'
|
||||||
svc['location'] = temp.format(svc['name'])
|
svc['location'] = temp.format(base_series,
|
||||||
|
svc['name'])
|
||||||
else:
|
else:
|
||||||
temp = 'lp:~openstack-charmers/charms/{}/{}/next'
|
temp = 'lp:~openstack-charmers/charms/{}/{}/next'
|
||||||
svc['location'] = temp.format(self.current_next,
|
svc['location'] = temp.format(self.current_next,
|
||||||
@@ -99,9 +106,12 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
Return an integer representing the enum value of the openstack
|
Return an integer representing the enum value of the openstack
|
||||||
release.
|
release.
|
||||||
"""
|
"""
|
||||||
|
# Must be ordered by OpenStack release (not by Ubuntu release):
|
||||||
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
|
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
|
||||||
self.precise_havana, self.precise_icehouse,
|
self.precise_havana, self.precise_icehouse,
|
||||||
self.trusty_icehouse, self.trusty_juno, self.trusty_kilo) = range(8)
|
self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
|
||||||
|
self.trusty_kilo, self.vivid_kilo) = range(10)
|
||||||
|
|
||||||
releases = {
|
releases = {
|
||||||
('precise', None): self.precise_essex,
|
('precise', None): self.precise_essex,
|
||||||
('precise', 'cloud:precise-folsom'): self.precise_folsom,
|
('precise', 'cloud:precise-folsom'): self.precise_folsom,
|
||||||
@@ -110,7 +120,9 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
|
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
|
||||||
('trusty', None): self.trusty_icehouse,
|
('trusty', None): self.trusty_icehouse,
|
||||||
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
||||||
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo}
|
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
|
||||||
|
('utopic', None): self.utopic_juno,
|
||||||
|
('vivid', None): self.vivid_kilo}
|
||||||
return releases[(self.series, self.openstack)]
|
return releases[(self.series, self.openstack)]
|
||||||
|
|
||||||
def _get_openstack_release_string(self):
|
def _get_openstack_release_string(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user