Public Network Support

Add public network support to CephFS.  This patch also
adds in support for ipv6 and juju network spaces.

Closes-Bug: 1659338
Change-Id: Ibfb6377f5831f26da302308818c093c9d7e715dc
This commit is contained in:
Chris Holcombe 2017-02-06 10:44:34 -08:00 committed by James Page
parent caff36e33d
commit 2353ff93ff
4 changed files with 108 additions and 5 deletions

View File

@ -30,3 +30,23 @@ options:
default: False
description: |
If set to True, supporting services will log to syslog.
ceph-public-network:
type: string
default:
description: |
The IP address and netmask of the public (front-side) network (e.g.,
192.168.0.0/24).
If multiple networks are to be used, a space-delimited list of a.b.c.d/x
can be provided.
prefer-ipv6:
type: boolean
default: False
description: |
If True enables IPv6 support. The charm will expect network interfaces
to be configured with an IPv6 address. If set to False (default) IPv4
is expected.
NOTE: these charms do not currently support IPv6 privacy extension. In
order for this charm to function correctly, the privacy extension must be
disabled and a non-temporary address must be configured/available on
your network interface.

View File

@ -16,3 +16,5 @@ subordinate: false
requires:
ceph-mds:
interface: ceph-mds
extra-bindings:
public:

View File

@ -18,19 +18,27 @@ import subprocess
from charms.reactive import when, when_not, set_state
from charmhelpers.core.hookenv import (
application_version_set, config, log, ERROR)
application_version_set, config, log, ERROR, cached, DEBUG, unit_get,
network_get_primary_address,
status_set)
from charmhelpers.core.host import service_restart
from charmhelpers.contrib.network.ip import (
get_address_in_network
)
get_address_in_network,
get_ipv6_addr)
from charmhelpers.fetch import (
get_upstream_version,
)
apt_install, filter_installed_packages)
import jinja2
from charms.apt import queue_install
try:
import dns.resolver
except ImportError:
apt_install(filter_installed_packages(['python-dnspython']),
fatal=True)
import dns.resolver
TEMPLATES_DIR = 'templates'
VERSION_PACKAGE = 'ceph-common'
@ -76,6 +84,7 @@ def config_changed(ceph_client):
os.makedirs(key_path)
cephx_key = os.path.join(key_path,
'keyring')
ceph_context = {
'fsid': ceph_client.fsid(),
'auth_supported': ceph_client.auth(),
@ -86,6 +95,15 @@ def config_changed(ceph_client):
'mds_name': socket.gethostname(),
}
networks = get_networks('ceph-public-network')
if networks:
ceph_context['ceph_public_network'] = ', '.join(networks)
elif config('prefer-ipv6'):
dynamic_ipv6_address = get_ipv6_addr()[0]
ceph_context['public_addr'] = dynamic_ipv6_address
else:
ceph_context['public_addr'] = get_public_addr()
try:
with open(charm_ceph_conf, 'w') as ceph_conf:
ceph_conf.write(render_template('ceph.conf', ceph_context))
@ -115,3 +133,59 @@ def get_networks(config_opt='ceph-public-network'):
return [n for n in networks if get_address_in_network(n)]
return []
@cached
def get_public_addr():
if config('ceph-public-network'):
return get_network_addrs('ceph-public-network')[0]
try:
return network_get_primary_address('public')
except NotImplementedError:
log("network-get not supported", DEBUG)
return get_host_ip()
@cached
def get_host_ip(hostname=None):
if config('prefer-ipv6'):
return get_ipv6_addr()[0]
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 get_network_addrs(config_opt):
"""Get all configured public networks addresses.
If public network(s) are provided, go through them and return the
addresses we have configured on any of those networks.
"""
addrs = []
networks = config(config_opt)
if networks:
networks = networks.split()
addrs = [get_address_in_network(n) for n in networks]
addrs = [a for a in addrs if a]
if not addrs:
if networks:
msg = ("Could not find an address on any of '%s' - resolve this "
"error to retry" % networks)
status_set('blocked', msg)
raise Exception(msg)
else:
return [get_host_ip()]
return addrs

View File

@ -14,6 +14,13 @@ mon cluster log to syslog = {{ use_syslog }}
debug mon = {{ loglevel }}/5
debug osd = {{ loglevel }}/5
{% if ceph_public_network %}
public network = {{ ceph_public_network }}
{%- endif %}
{%- if public_addr %}
public addr = {{ public_addr }}
{%- endif %}
[client]
log file = /var/log/ceph.log