Re-sync'd charmhelpers and merged from next.

This commit is contained in:
Alberto Donato
2015-09-30 18:01:18 +03:00
12 changed files with 127 additions and 21 deletions

View File

@@ -11,3 +11,4 @@ include:
- contrib.network.ip
- contrib.python.packages
- contrib.charmsupport
- core.kernel

View File

@@ -752,7 +752,7 @@ class OpenStackAmuletUtils(AmuletUtils):
self.log.debug('SSL is enabled @{}:{} '
'({})'.format(host, port, unit_name))
return True
elif not port and not conf_ssl:
elif not conf_ssl:
self.log.debug('SSL not enabled @{}:{} '
'({})'.format(host, port, unit_name))
return False

View File

@@ -14,6 +14,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
import glob
import json
import os
import re
@@ -1363,7 +1364,7 @@ class DataPortContext(NeutronPortContext):
normalized.update({port: port for port in resolved
if port in ports})
if resolved:
return {bridge: normalized[port] for port, bridge in
return {normalized[port]: bridge for port, bridge in
six.iteritems(portmap) if port in normalized.keys()}
return None
@@ -1374,12 +1375,22 @@ class PhyNICMTUContext(DataPortContext):
def __call__(self):
ctxt = {}
mappings = super(PhyNICMTUContext, self).__call__()
if mappings and mappings.values():
ports = mappings.values()
if mappings and mappings.keys():
ports = sorted(mappings.keys())
napi_settings = NeutronAPIContext()()
mtu = napi_settings.get('network_device_mtu')
all_ports = set()
# If any of ports is a vlan device, its underlying device must have
# mtu applied first.
for port in ports:
for lport in glob.glob("/sys/class/net/%s/lower_*" % port):
lport = os.path.basename(lport)
all_ports.add(lport.split('_')[1])
all_ports = list(all_ports)
all_ports.extend(ports)
if mtu:
ctxt["devs"] = '\\n'.join(ports)
ctxt["devs"] = '\\n'.join(all_ports)
ctxt['mtu'] = mtu
return ctxt

View File

@@ -310,10 +310,10 @@ def parse_bridge_mappings(mappings):
def parse_data_port_mappings(mappings, default_bridge='br-data'):
"""Parse data port mappings.
Mappings must be a space-delimited list of port:bridge mappings.
Mappings must be a space-delimited list of bridge:port.
Returns dict of the form {port:bridge} where port may be an mac address or
interface name.
Returns dict of the form {port:bridge} where ports may be mac addresses or
interface names.
"""
# NOTE(dosaboy): we use rvalue for key to allow multiple values to be

View File

@@ -13,3 +13,9 @@ log to syslog = {{ use_syslog }}
err to syslog = {{ use_syslog }}
clog to syslog = {{ use_syslog }}
[client]
{% if rbd_client_cache_settings -%}
{% for key, value in rbd_client_cache_settings.iteritems() -%}
{{ key }} = {{ value }}
{% endfor -%}
{%- endif %}

View File

@@ -23,7 +23,9 @@ from glance_utils import (
GLANCE_API_PASTE_INI,
HAPROXY_CONF,
ceph_config_file,
setup_ipv6
setup_ipv6,
REQUIRED_INTERFACES,
check_optional_relations,
)
from charmhelpers.core.hookenv import (
config,
@@ -38,7 +40,8 @@ from charmhelpers.core.hookenv import (
relation_ids,
service_name,
unit_get,
UnregisteredHookError
UnregisteredHookError,
status_set,
)
from charmhelpers.core.host import (
restart_on_change,
@@ -63,6 +66,7 @@ from charmhelpers.contrib.openstack.utils import (
openstack_upgrade_available,
os_release,
sync_db_with_multi_ipv6_addresses,
os_workload_status,
)
from charmhelpers.contrib.storage.linux.ceph import (
send_request_if_needed,
@@ -96,8 +100,10 @@ CONFIGS = register_configs()
@hooks.hook('install.real')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def install_hook():
juju_log('Installing glance packages')
status_set('maintenance', 'Executing pre-install')
execd_preinstall()
src = config('openstack-origin')
if (lsb_release()['DISTRIB_CODENAME'] == 'precise' and
@@ -106,9 +112,11 @@ def install_hook():
configure_installation_source(src)
status_set('maintenance', 'Installing apt packages')
apt_update(fatal=True)
apt_install(determine_packages(), fatal=True)
status_set('maintenance', 'Git install')
git_install(config('openstack-origin-git'))
for service in SERVICES:
@@ -116,6 +124,8 @@ def install_hook():
@hooks.hook('shared-db-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def db_joined():
if is_relation_made('pgsql-db'):
# error, postgresql is used
@@ -135,6 +145,8 @@ def db_joined():
@hooks.hook('pgsql-db-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def pgsql_db_joined():
if is_relation_made('shared-db'):
# raise error
@@ -147,6 +159,8 @@ def pgsql_db_joined():
@hooks.hook('shared-db-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def db_changed():
rel = os_release('glance-common')
@@ -181,6 +195,8 @@ def db_changed():
@hooks.hook('pgsql-db-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def pgsql_db_changed():
rel = os_release('glance-common')
@@ -220,6 +236,8 @@ def image_service_joined(relation_id=None):
@hooks.hook('object-store-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def object_store_joined():
@@ -236,6 +254,8 @@ def object_store_joined():
@hooks.hook('ceph-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def ceph_joined():
apt_install(['ceph-common', 'python-ceph'])
@@ -249,6 +269,8 @@ def get_ceph_request():
@hooks.hook('ceph-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def ceph_changed():
if 'ceph' not in CONFIGS.complete_contexts():
@@ -273,6 +295,8 @@ def ceph_changed():
@hooks.hook('ceph-relation-broken')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def ceph_broken():
service = service_name()
delete_keyring(service=service)
@@ -280,6 +304,8 @@ def ceph_broken():
@hooks.hook('identity-service-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def keystone_joined(relation_id=None):
public_url = '{}:9292'.format(canonical_url(CONFIGS, PUBLIC))
internal_url = '{}:9292'.format(canonical_url(CONFIGS, INTERNAL))
@@ -295,6 +321,8 @@ def keystone_joined(relation_id=None):
@hooks.hook('identity-service-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def keystone_changed():
if 'identity-service' not in CONFIGS.complete_contexts():
@@ -317,19 +345,23 @@ def keystone_changed():
@hooks.hook('config-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map(), stopstart=True)
def config_changed():
if config('prefer-ipv6'):
setup_ipv6()
status_set('maintenance', 'Sync DB')
sync_db_with_multi_ipv6_addresses(config('database'),
config('database-user'))
if git_install_requested():
if config_value_changed('openstack-origin-git'):
status_set('maintenance', 'Running Git install')
git_install(config('openstack-origin-git'))
elif not config('action-managed-upgrade'):
if openstack_upgrade_available('glance-common'):
juju_log('Upgrading OpenStack release')
status_set('maintenance', 'Upgrading OpenStack release')
do_openstack_upgrade(CONFIGS)
open_port(9292)
@@ -381,6 +413,8 @@ def upgrade_charm():
@hooks.hook('ha-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def ha_relation_joined(relation_id=None):
cluster_config = get_hacluster_config()
@@ -440,6 +474,8 @@ def ha_relation_joined(relation_id=None):
@hooks.hook('ha-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def ha_relation_changed():
clustered = relation_get('clustered')
if not clustered or clustered in [None, 'None', '']:
@@ -457,6 +493,8 @@ def ha_relation_changed():
'object-store-relation-broken',
'shared-db-relation-broken',
'pgsql-db-relation-broken')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def relation_broken():
CONFIGS.write_all()
@@ -485,12 +523,16 @@ def configure_https():
@hooks.hook('amqp-relation-joined')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
def amqp_joined():
conf = config()
relation_set(username=conf['rabbit-user'], vhost=conf['rabbit-vhost'])
@hooks.hook('amqp-relation-changed')
@os_workload_status(CONFIGS, REQUIRED_INTERFACES,
charm_func=check_optional_relations)
@restart_on_change(restart_map())
def amqp_changed():
if 'amqp' not in CONFIGS.complete_contexts():

View File

@@ -24,7 +24,10 @@ from charmhelpers.core.hookenv import (
config,
log,
relation_ids,
service_name)
service_name,
status_get,
)
from charmhelpers.core.host import (
adduser,
@@ -44,6 +47,7 @@ from charmhelpers.contrib.openstack import (
from charmhelpers.contrib.hahelpers.cluster import (
is_elected_leader,
get_hacluster_config,
)
from charmhelpers.contrib.openstack.alternatives import install_alternative
@@ -56,6 +60,7 @@ from charmhelpers.contrib.openstack.utils import (
git_pip_venv_dir,
configure_installation_source,
os_release,
set_os_workload_status,
)
from charmhelpers.core.templating import render
@@ -64,6 +69,7 @@ from charmhelpers.core.decorators import (
retry_on_exception,
)
CLUSTER_RES = "grp_glance_vips"
PACKAGES = [
@@ -115,6 +121,14 @@ CONF_DIR = "/etc/glance"
TEMPLATES = 'templates/'
# The interface is said to be satisfied if anyone of the interfaces in the
# list has a complete context.
REQUIRED_INTERFACES = {
'database': ['shared-db', 'pgsql-db'],
'message': ['amqp'],
'identity': ['identity-service'],
}
def ceph_config_file():
return CHARM_CEPH_CONF.format(service_name())
@@ -423,3 +437,24 @@ def git_post_install(projects_yaml):
service_restart('glance-api')
service_restart('glance-registry')
def check_optional_relations(configs):
required_interfaces = {}
if relation_ids('ha'):
required_interfaces['ha'] = ['cluster']
try:
get_hacluster_config()
except:
return ('blocked',
'hacluster missing configuration: '
'vip, vip_iface, vip_cidr')
if relation_ids('ceph') or relation_ids('object-store'):
required_interfaces['storage-backend'] = ['ceph', 'object-store']
if required_interfaces:
set_os_workload_status(configs, required_interfaces)
return status_get()
else:
return 'unknown', 'No optional relations'

View File

@@ -752,7 +752,7 @@ class OpenStackAmuletUtils(AmuletUtils):
self.log.debug('SSL is enabled @{}:{} '
'({})'.format(host, port, unit_name))
return True
elif not port and not conf_ssl:
elif not conf_ssl:
self.log.debug('SSL not enabled @{}:{} '
'({})'.format(host, port, unit_name))
return False

View File

@@ -81,17 +81,23 @@ class TestGlanceContexts(CharmTestCase):
'ext_ports': [9282],
'namespace': 'glance'})
@patch('charmhelpers.contrib.openstack.context.config')
@patch("subprocess.check_output")
def test_glance_ipv6_context_service_enabled(self, mock_subprocess):
def test_glance_ipv6_context_service_enabled(self, mock_subprocess,
mock_config):
self.config.return_value = True
mock_config.return_value = True
mock_subprocess.return_value = 'true'
ctxt = contexts.GlanceIPv6Context()
self.assertEquals(ctxt(), {'bind_host': '::',
'registry_host': '[::]'})
@patch('charmhelpers.contrib.openstack.context.config')
@patch("subprocess.check_output")
def test_glance_ipv6_context_service_disabled(self, mock_subprocess):
def test_glance_ipv6_context_service_disabled(self, mock_subprocess,
mock_config):
self.config.return_value = False
mock_config.return_value = False
mock_subprocess.return_value = 'false'
ctxt = contexts.GlanceIPv6Context()
self.assertEquals(ctxt(), {'bind_host': '0.0.0.0',

View File

@@ -534,14 +534,17 @@ class GlanceRelationTests(CharmTestCase):
self.open_port.assert_called_with(9292)
self.assertTrue(configure_https.called)
@patch.object(relations, 'status_set')
@patch.object(relations, 'configure_https')
@patch.object(relations, 'git_install_requested')
def test_config_changed_with_openstack_upgrade(self, git_requested,
configure_https):
configure_https,
status):
git_requested.return_value = False
self.openstack_upgrade_available.return_value = True
relations.config_changed()
self.juju_log.assert_called_with(
status.assert_called_with(
'maintenance',
'Upgrading OpenStack release'
)
self.assertTrue(self.do_openstack_upgrade.called)

View File

@@ -5,9 +5,7 @@ import os
os.environ['JUJU_UNIT_NAME'] = 'glance'
with patch('charmhelpers.core.hookenv.config') as config:
import hooks.glance_utils as utils
import hooks.glance_utils as utils
from test_utils import (
CharmTestCase,
)

View File

@@ -6,6 +6,10 @@ import yaml
from contextlib import contextmanager
from mock import patch, MagicMock
patch('hooks.charmhelpers.contrib.openstack.utils.'
'set_os_workload_status').start()
patch('hooks.charmhelpers.core.hookenv.status_set').start()
def load_config():
'''Walk backwords from __file__ looking for config.yaml,