Re-sync'd charmhelpers and merged from next.
This commit is contained in:
@@ -11,3 +11,4 @@ include:
|
||||
- contrib.network.ip
|
||||
- contrib.python.packages
|
||||
- contrib.charmsupport
|
||||
- core.kernel
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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():
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user