# # Copyright 2012 Canonical Ltd. # # Authors: # James Page # Paul Collins # import socket import re import os import dns.resolver import jinja2 from copy import deepcopy from collections import OrderedDict from charmhelpers.core.hookenv import unit_get, relation_ids, status_get from charmhelpers.contrib.openstack import context, templating from charmhelpers.contrib.openstack.utils import set_os_workload_status from charmhelpers.contrib.hahelpers.cluster import get_hacluster_config from charmhelpers.core.host import cmp_pkgrevno from charmhelpers.fetch import filter_installed_packages import ceph_radosgw_context # The interface is said to be satisfied if anyone of the interfaces in the # list has a complete context. REQUIRED_INTERFACES = { 'mon': ['ceph-radosgw'], } CEPHRG_HA_RES = 'grp_cephrg_vips' TEMPLATES_DIR = 'templates' TEMPLATES = 'templates/' HAPROXY_CONF = '/etc/haproxy/haproxy.cfg' CEPH_CONF = '/etc/ceph/ceph.conf' BASE_RESOURCE_MAP = OrderedDict([ (HAPROXY_CONF, { 'contexts': [context.HAProxyContext(singlenode_mode=True), ceph_radosgw_context.HAProxyContext()], 'services': ['haproxy'], }), (CEPH_CONF, { 'contexts': [ceph_radosgw_context.MonContext()], 'services': ['radosgw'], }), ]) def resource_map(): ''' Dynamically generate a map of resources that will be managed for a single hook execution. ''' resource_map = deepcopy(BASE_RESOURCE_MAP) return resource_map # Hardcoded to icehouse to enable use of charmhelper templating/context tools # Ideally these function would support non-OpenStack services def register_configs(release='icehouse'): configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) CONFIGS = resource_map() pkg = 'radosgw' if not filter_installed_packages([pkg]) and cmp_pkgrevno(pkg, '0.55') >= 0: # Add keystone configuration if found CONFIGS[CEPH_CONF]['contexts'].append( ceph_radosgw_context.IdentityServiceContext() ) for cfg, rscs in CONFIGS.iteritems(): configs.register(cfg, rscs['contexts']) return configs def render_template(template_name, context, template_dir=TEMPLATES_DIR): templates = jinja2.Environment( loader=jinja2.FileSystemLoader(template_dir) ) template = templates.get_template(template_name) return template.render(context) def enable_pocket(pocket): apt_sources = "/etc/apt/sources.list" with open(apt_sources, "r") as sources: lines = sources.readlines() with open(apt_sources, "w") as sources: for line in lines: if pocket in line: sources.write(re.sub('^# deb', 'deb', line)) else: sources.write(line) def get_host_ip(hostname=None): try: if not hostname: hostname = unit_get('private-address') # Test to see if already an IPv4 address socket.inet_aton(hostname) return hostname except socket.error: # This may throw an NXDOMAIN exception; in which case # things are badly broken so just let it kill the hook answers = dns.resolver.query(hostname, 'A') if answers: return answers[0].address def is_apache_24(): if os.path.exists('/etc/apache2/conf-available'): return True else: return False 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 cmp_pkgrevno('radosgw', '0.55') >= 0 and \ relation_ids('identity-service'): required_interfaces['identity'] = ['identity-service'] if required_interfaces: set_os_workload_status(configs, required_interfaces) return status_get() else: return 'unknown', 'No optional relations'