diff --git a/config.yaml b/config.yaml index e63d36d5..50f14e6d 100644 --- a/config.yaml +++ b/config.yaml @@ -103,3 +103,6 @@ options: description: | The IP address and netmask of the cluster (back-side) network (e.g., 192.168.0.0/24) + prefer-ipv6: + type: boolean + default: False \ No newline at end of file diff --git a/hooks/hooks.py b/hooks/hooks.py index 6379fcb7..c7d79f2d 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -15,14 +15,17 @@ import sys import ceph from charmhelpers.core.hookenv import ( log, + WARNING, ERROR, config, relation_ids, related_units, relation_get, + relation_set, Hooks, UnregisteredHookError, - service_name + service_name, + unit_get ) from charmhelpers.core.host import ( umount, @@ -38,11 +41,14 @@ from charmhelpers.fetch import ( from utils import ( render_template, - get_host_ip, + setup_ipv6 ) from charmhelpers.contrib.openstack.alternatives import install_alternative -from charmhelpers.contrib.network.ip import is_ipv6 +from charmhelpers.contrib.network.ip import ( + is_ipv6, + get_ipv6_addr +) hooks = Hooks() @@ -58,6 +64,10 @@ def install_upstart_scripts(): def install(): add_source(config('source'), config('key')) apt_update(fatal=True) + + if config('prefer-ipv6'): + setup_ipv6() + apt_install(packages=ceph.PACKAGES, fatal=True) install_upstart_scripts() @@ -76,6 +86,14 @@ def emit_cephconf(): 'ceph_public_network': config('ceph-public-network'), 'ceph_cluster_network': config('ceph-cluster-network'), } + + if config('prefer-ipv6'): + host_ip = get_ipv6_addr() + if host_ip: + cephcontext['host_ip'] = host_ip + else: + log("Unable to obtain host address", level=WARNING) + # Install ceph.conf as an alternative to support # co-existence with other charms that write this file charm_ceph_conf = "/var/lib/charm/{}/ceph.conf".format(service_name()) @@ -95,6 +113,9 @@ def config_changed(): log('Invalid OSD disk format configuration specified', level=ERROR) sys.exit(1) + if config('prefer-ipv6'): + setup_ipv6() + e_mountpoint = config('ephemeral-unmount') if (e_mountpoint and ceph.filesystem_mounted(e_mountpoint)): umount(e_mountpoint) @@ -120,8 +141,12 @@ def get_mon_hosts(): hosts = [] for relid in relation_ids('mon'): for unit in related_units(relid): - addr = relation_get('ceph-public-address', unit, relid) or \ - get_host_ip(relation_get('private-address', unit, relid)) + if config('prefer-ipv6'): + addr = relation_get('ceph-public-address', unit, relid) or \ + get_ipv6_addr() + else: + addr = relation_get('private-address', unit, relid) + if addr is not None: if is_ipv6(addr): hosts.append('[{}]:6789'.format(addr)) @@ -166,6 +191,17 @@ def get_devices(): @hooks.hook('mon-relation-changed', 'mon-relation-departed') def mon_relation(): + if config('prefer-ipv6'): + host = get_ipv6_addr() + else: + host = unit_get('private-address') + + if host: + relation_data = {'private-address': host} + relation_set(**relation_data) + else: + log("Unable to obtain host address", level=WARNING) + bootstrap_key = relation_get('osd_bootstrap_key') if get_fsid() and get_auth() and bootstrap_key: log('mon has provided conf- scanning disks') diff --git a/hooks/utils.py b/hooks/utils.py index c1044a45..d4bbd38f 100644 --- a/hooks/utils.py +++ b/hooks/utils.py @@ -10,7 +10,6 @@ import socket import re from charmhelpers.core.hookenv import ( - unit_get, cached ) from charmhelpers.fetch import ( @@ -18,6 +17,10 @@ from charmhelpers.fetch import ( filter_installed_packages ) +from charmhelpers.core.host import ( + lsb_release +) + TEMPLATES_DIR = 'templates' try: @@ -27,13 +30,6 @@ except ImportError: fatal=True) import jinja2 -try: - import dns.resolver -except ImportError: - apt_install(filter_installed_packages(['python-dnspython']), - fatal=True) - import dns.resolver - def render_template(template_name, context, template_dir=TEMPLATES_DIR): templates = jinja2.Environment( @@ -59,16 +55,8 @@ def get_unit_hostname(): return socket.gethostname() -@cached -def get_host_ip(hostname=None): - hostname = hostname or unit_get('private-address') - try: - # 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 setup_ipv6(): + ubuntu_rel = float(lsb_release()['DISTRIB_RELEASE']) + if ubuntu_rel < 14.04: + raise Exception("IPv6 is not supported for Ubuntu " + "versions less than Trusty 14.04") diff --git a/templates/ceph.conf b/templates/ceph.conf index def993c3..44336ca0 100644 --- a/templates/ceph.conf +++ b/templates/ceph.conf @@ -32,3 +32,6 @@ osd journal size = {{ osd_journal_size }} filestore xattr use omap = true + host = {{ hostname }} + public addr = {{ host_ip }} + cluster addr = {{ host_ip }} \ No newline at end of file