Add LXD support for ceph-access relation
The nova-lxd driver is growing support for ceph storage backends, but as this is a host based integration, it relies on keyrings being placed in /etc/ceph for cephx authentication, rather than using some other secret storage mechanism as done for libvirt. Tweak the ceph-access-relation-changed handling to deal with this and ensure that the ceph-common package is installed with relations of this type are joined. Change-Id: I887e0be007c5606614e00c6a374416368d675c4d
This commit is contained in:
parent
0360a476a0
commit
5363696a01
1
hooks/ceph-access-relation-joined
Symbolic link
1
hooks/ceph-access-relation-joined
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nova_compute_hooks.py
|
@ -239,6 +239,16 @@ def format_ipv6_addr(address):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def is_ipv6_disabled():
|
||||||
|
try:
|
||||||
|
result = subprocess.check_output(
|
||||||
|
['sysctl', 'net.ipv6.conf.all.disable_ipv6'],
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
return "net.ipv6.conf.all.disable_ipv6 = 1" in result
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
|
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
|
||||||
fatal=True, exc_list=None):
|
fatal=True, exc_list=None):
|
||||||
"""Return the assigned IP address for a given interface, if any.
|
"""Return the assigned IP address for a given interface, if any.
|
||||||
@ -544,31 +554,38 @@ def assert_charm_supports_ipv6():
|
|||||||
"versions less than Trusty 14.04")
|
"versions less than Trusty 14.04")
|
||||||
|
|
||||||
|
|
||||||
def get_relation_ip(interface, config_override=None):
|
def get_relation_ip(interface, cidr_network=None):
|
||||||
"""Return this unit's IP for the given relation.
|
"""Return this unit's IP for the given interface.
|
||||||
|
|
||||||
Allow for an arbitrary interface to use with network-get to select an IP.
|
Allow for an arbitrary interface to use with network-get to select an IP.
|
||||||
Handle all address selection options including configuration parameter
|
Handle all address selection options including passed cidr network and
|
||||||
override and IPv6.
|
IPv6.
|
||||||
|
|
||||||
Usage: get_relation_ip('amqp', config_override='access-network')
|
Usage: get_relation_ip('amqp', cidr_network='10.0.0.0/8')
|
||||||
|
|
||||||
@param interface: string name of the relation.
|
@param interface: string name of the relation.
|
||||||
@param config_override: string name of the config option for network
|
@param cidr_network: string CIDR Network to select an address from.
|
||||||
override. Supports legacy network override configuration parameters.
|
|
||||||
@raises Exception if prefer-ipv6 is configured but IPv6 unsupported.
|
@raises Exception if prefer-ipv6 is configured but IPv6 unsupported.
|
||||||
@returns IPv6 or IPv4 address
|
@returns IPv6 or IPv4 address
|
||||||
"""
|
"""
|
||||||
|
# Select the interface address first
|
||||||
|
# For possible use as a fallback bellow with get_address_in_network
|
||||||
|
try:
|
||||||
|
# Get the interface specific IP
|
||||||
|
address = network_get_primary_address(interface)
|
||||||
|
except NotImplementedError:
|
||||||
|
# If network-get is not available
|
||||||
|
address = get_host_ip(unit_get('private-address'))
|
||||||
|
|
||||||
fallback = get_host_ip(unit_get('private-address'))
|
|
||||||
if config('prefer-ipv6'):
|
if config('prefer-ipv6'):
|
||||||
|
# Currently IPv6 has priority, eventually we want IPv6 to just be
|
||||||
|
# another network space.
|
||||||
assert_charm_supports_ipv6()
|
assert_charm_supports_ipv6()
|
||||||
return get_ipv6_addr()[0]
|
return get_ipv6_addr()[0]
|
||||||
elif config_override and config(config_override):
|
elif cidr_network:
|
||||||
return get_address_in_network(config(config_override),
|
# If a specific CIDR network is passed get the address from that
|
||||||
fallback)
|
# network.
|
||||||
else:
|
return get_address_in_network(cidr_network, address)
|
||||||
try:
|
|
||||||
return network_get_primary_address(interface)
|
# Return the interface address
|
||||||
except NotImplementedError:
|
return address
|
||||||
return fallback
|
|
||||||
|
@ -547,7 +547,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||||||
"""Create the specified instance."""
|
"""Create the specified instance."""
|
||||||
self.log.debug('Creating instance '
|
self.log.debug('Creating instance '
|
||||||
'({}|{}|{})'.format(instance_name, image_name, flavor))
|
'({}|{}|{})'.format(instance_name, image_name, flavor))
|
||||||
image = nova.images.find(name=image_name)
|
image = nova.glance.find_image(image_name)
|
||||||
flavor = nova.flavors.find(name=flavor)
|
flavor = nova.flavors.find(name=flavor)
|
||||||
instance = nova.servers.create(name=instance_name, image=image,
|
instance = nova.servers.create(name=instance_name, image=image,
|
||||||
flavor=flavor)
|
flavor=flavor)
|
||||||
|
@ -89,6 +89,7 @@ from charmhelpers.contrib.network.ip import (
|
|||||||
format_ipv6_addr,
|
format_ipv6_addr,
|
||||||
is_address_in_network,
|
is_address_in_network,
|
||||||
is_bridge_member,
|
is_bridge_member,
|
||||||
|
is_ipv6_disabled,
|
||||||
)
|
)
|
||||||
from charmhelpers.contrib.openstack.utils import (
|
from charmhelpers.contrib.openstack.utils import (
|
||||||
config_flags_parser,
|
config_flags_parser,
|
||||||
@ -110,6 +111,7 @@ except ImportError:
|
|||||||
|
|
||||||
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
|
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
|
||||||
ADDRESS_TYPES = ['admin', 'internal', 'public']
|
ADDRESS_TYPES = ['admin', 'internal', 'public']
|
||||||
|
HAPROXY_RUN_DIR = '/var/run/haproxy/'
|
||||||
|
|
||||||
|
|
||||||
def ensure_packages(packages):
|
def ensure_packages(packages):
|
||||||
@ -535,6 +537,8 @@ class HAProxyContext(OSContextGenerator):
|
|||||||
"""Provides half a context for the haproxy template, which describes
|
"""Provides half a context for the haproxy template, which describes
|
||||||
all peers to be included in the cluster. Each charm needs to include
|
all peers to be included in the cluster. Each charm needs to include
|
||||||
its own context generator that describes the port mapping.
|
its own context generator that describes the port mapping.
|
||||||
|
|
||||||
|
:side effect: mkdir is called on HAPROXY_RUN_DIR
|
||||||
"""
|
"""
|
||||||
interfaces = ['cluster']
|
interfaces = ['cluster']
|
||||||
|
|
||||||
@ -542,6 +546,8 @@ class HAProxyContext(OSContextGenerator):
|
|||||||
self.singlenode_mode = singlenode_mode
|
self.singlenode_mode = singlenode_mode
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
|
if not os.path.isdir(HAPROXY_RUN_DIR):
|
||||||
|
mkdir(path=HAPROXY_RUN_DIR)
|
||||||
if not relation_ids('cluster') and not self.singlenode_mode:
|
if not relation_ids('cluster') and not self.singlenode_mode:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
@ -1226,19 +1232,19 @@ MAX_DEFAULT_WORKERS = 4
|
|||||||
DEFAULT_MULTIPLIER = 2
|
DEFAULT_MULTIPLIER = 2
|
||||||
|
|
||||||
|
|
||||||
class WorkerConfigContext(OSContextGenerator):
|
def _calculate_workers():
|
||||||
|
'''
|
||||||
|
Determine the number of worker processes based on the CPU
|
||||||
|
count of the unit containing the application.
|
||||||
|
|
||||||
@property
|
Workers will be limited to MAX_DEFAULT_WORKERS in
|
||||||
def num_cpus(self):
|
container environments where no worker-multipler configuration
|
||||||
# NOTE: use cpu_count if present (16.04 support)
|
option been set.
|
||||||
if hasattr(psutil, 'cpu_count'):
|
|
||||||
return psutil.cpu_count()
|
|
||||||
else:
|
|
||||||
return psutil.NUM_CPUS
|
|
||||||
|
|
||||||
def __call__(self):
|
@returns int: number of worker processes to use
|
||||||
|
'''
|
||||||
multiplier = config('worker-multiplier') or DEFAULT_MULTIPLIER
|
multiplier = config('worker-multiplier') or DEFAULT_MULTIPLIER
|
||||||
count = int(self.num_cpus * multiplier)
|
count = int(_num_cpus() * multiplier)
|
||||||
if multiplier > 0 and count == 0:
|
if multiplier > 0 and count == 0:
|
||||||
count = 1
|
count = 1
|
||||||
|
|
||||||
@ -1250,7 +1256,26 @@ class WorkerConfigContext(OSContextGenerator):
|
|||||||
# Reference: https://pad.lv/1665270
|
# Reference: https://pad.lv/1665270
|
||||||
count = min(count, MAX_DEFAULT_WORKERS)
|
count = min(count, MAX_DEFAULT_WORKERS)
|
||||||
|
|
||||||
ctxt = {"workers": count}
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
def _num_cpus():
|
||||||
|
'''
|
||||||
|
Compatibility wrapper for calculating the number of CPU's
|
||||||
|
a unit has.
|
||||||
|
|
||||||
|
@returns: int: number of CPU cores detected
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return psutil.cpu_count()
|
||||||
|
except AttributeError:
|
||||||
|
return psutil.NUM_CPUS
|
||||||
|
|
||||||
|
|
||||||
|
class WorkerConfigContext(OSContextGenerator):
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
ctxt = {"workers": _calculate_workers()}
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
@ -1258,7 +1283,7 @@ class WSGIWorkerConfigContext(WorkerConfigContext):
|
|||||||
|
|
||||||
def __init__(self, name=None, script=None, admin_script=None,
|
def __init__(self, name=None, script=None, admin_script=None,
|
||||||
public_script=None, process_weight=1.00,
|
public_script=None, process_weight=1.00,
|
||||||
admin_process_weight=0.75, public_process_weight=0.25):
|
admin_process_weight=0.25, public_process_weight=0.75):
|
||||||
self.service_name = name
|
self.service_name = name
|
||||||
self.user = name
|
self.user = name
|
||||||
self.group = name
|
self.group = name
|
||||||
@ -1270,8 +1295,7 @@ class WSGIWorkerConfigContext(WorkerConfigContext):
|
|||||||
self.public_process_weight = public_process_weight
|
self.public_process_weight = public_process_weight
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
multiplier = config('worker-multiplier') or 1
|
total_processes = _calculate_workers()
|
||||||
total_processes = self.num_cpus * multiplier
|
|
||||||
ctxt = {
|
ctxt = {
|
||||||
"service_name": self.service_name,
|
"service_name": self.service_name,
|
||||||
"user": self.user,
|
"user": self.user,
|
||||||
@ -1602,7 +1626,7 @@ class MemcacheContext(OSContextGenerator):
|
|||||||
"""Memcache context
|
"""Memcache context
|
||||||
|
|
||||||
This context provides options for configuring a local memcache client and
|
This context provides options for configuring a local memcache client and
|
||||||
server
|
server for both IPv4 and IPv6
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, package=None):
|
def __init__(self, package=None):
|
||||||
@ -1620,6 +1644,17 @@ class MemcacheContext(OSContextGenerator):
|
|||||||
# Trusty version of memcached does not support ::1 as a listen
|
# Trusty version of memcached does not support ::1 as a listen
|
||||||
# address so use host file entry instead
|
# address so use host file entry instead
|
||||||
release = lsb_release()['DISTRIB_CODENAME'].lower()
|
release = lsb_release()['DISTRIB_CODENAME'].lower()
|
||||||
|
if is_ipv6_disabled():
|
||||||
|
if CompareHostReleases(release) > 'trusty':
|
||||||
|
ctxt['memcache_server'] = '127.0.0.1'
|
||||||
|
else:
|
||||||
|
ctxt['memcache_server'] = 'localhost'
|
||||||
|
ctxt['memcache_server_formatted'] = '127.0.0.1'
|
||||||
|
ctxt['memcache_port'] = '11211'
|
||||||
|
ctxt['memcache_url'] = '{}:{}'.format(
|
||||||
|
ctxt['memcache_server_formatted'],
|
||||||
|
ctxt['memcache_port'])
|
||||||
|
else:
|
||||||
if CompareHostReleases(release) > 'trusty':
|
if CompareHostReleases(release) > 'trusty':
|
||||||
ctxt['memcache_server'] = '::1'
|
ctxt['memcache_server'] = '::1'
|
||||||
else:
|
else:
|
||||||
|
@ -191,7 +191,7 @@ def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d",
|
|||||||
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
||||||
sysv_file = os.path.join(initd_dir, service_name)
|
sysv_file = os.path.join(initd_dir, service_name)
|
||||||
if init_is_systemd():
|
if init_is_systemd():
|
||||||
service('disable', service_name)
|
service('mask', service_name)
|
||||||
elif os.path.exists(upstart_file):
|
elif os.path.exists(upstart_file):
|
||||||
override_path = os.path.join(
|
override_path = os.path.join(
|
||||||
init_dir, '{}.override'.format(service_name))
|
init_dir, '{}.override'.format(service_name))
|
||||||
@ -224,7 +224,7 @@ def service_resume(service_name, init_dir="/etc/init",
|
|||||||
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
||||||
sysv_file = os.path.join(initd_dir, service_name)
|
sysv_file = os.path.join(initd_dir, service_name)
|
||||||
if init_is_systemd():
|
if init_is_systemd():
|
||||||
service('enable', service_name)
|
service('unmask', service_name)
|
||||||
elif os.path.exists(upstart_file):
|
elif os.path.exists(upstart_file):
|
||||||
override_path = os.path.join(
|
override_path = os.path.join(
|
||||||
init_dir, '{}.override'.format(service_name))
|
init_dir, '{}.override'.format(service_name))
|
||||||
|
@ -97,6 +97,7 @@ from nova_compute_utils import (
|
|||||||
destroy_libvirt_network,
|
destroy_libvirt_network,
|
||||||
network_manager,
|
network_manager,
|
||||||
libvirt_daemon,
|
libvirt_daemon,
|
||||||
|
LIBVIRT_TYPES,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.network.ip import (
|
from charmhelpers.contrib.network.ip import (
|
||||||
@ -206,10 +207,14 @@ def config_changed():
|
|||||||
set_ppc64_cpu_smt_state('off')
|
set_ppc64_cpu_smt_state('off')
|
||||||
|
|
||||||
# NOTE(jamespage): trigger any configuration related changes
|
# NOTE(jamespage): trigger any configuration related changes
|
||||||
# for cephx permissions restrictions
|
# for cephx permissions restrictions and
|
||||||
|
# keys on disk for ceph-access backends
|
||||||
for rid in relation_ids('ceph'):
|
for rid in relation_ids('ceph'):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
ceph_changed(rid=rid, unit=unit)
|
ceph_changed(rid=rid, unit=unit)
|
||||||
|
for rid in relation_ids('ceph-access'):
|
||||||
|
for unit in related_units(rid):
|
||||||
|
ceph_access(rid=rid, unit=unit)
|
||||||
|
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
|
|
||||||
@ -334,13 +339,16 @@ def compute_changed():
|
|||||||
import_keystone_ca_cert()
|
import_keystone_ca_cert()
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.hook('ceph-access-relation-joined')
|
||||||
@hooks.hook('ceph-relation-joined')
|
@hooks.hook('ceph-relation-joined')
|
||||||
@restart_on_change(restart_map())
|
@restart_on_change(restart_map())
|
||||||
def ceph_joined():
|
def ceph_joined():
|
||||||
status_set('maintenance', 'Installing apt packages')
|
pkgs = filter_installed_packages(['ceph-common'])
|
||||||
apt_install(filter_installed_packages(['ceph-common']), fatal=True)
|
if pkgs:
|
||||||
|
status_set('maintenance', 'Installing ceph-common package')
|
||||||
|
apt_install(pkgs, fatal=True)
|
||||||
# Bug 1427660
|
# Bug 1427660
|
||||||
if not is_unit_paused_set():
|
if not is_unit_paused_set() and config('virt-type') in LIBVIRT_TYPES:
|
||||||
service_restart(libvirt_daemon())
|
service_restart(libvirt_daemon())
|
||||||
|
|
||||||
|
|
||||||
@ -538,16 +546,21 @@ def ceph_access(rid=None, unit=None):
|
|||||||
'''Setup libvirt secret for specific ceph backend access'''
|
'''Setup libvirt secret for specific ceph backend access'''
|
||||||
key = relation_get('key', unit, rid)
|
key = relation_get('key', unit, rid)
|
||||||
uuid = relation_get('secret-uuid', unit, rid)
|
uuid = relation_get('secret-uuid', unit, rid)
|
||||||
if config('virt-type') in ['kvm', 'qemu', 'lxc'] and key and uuid:
|
if key and uuid:
|
||||||
secrets_filename = CEPH_BACKEND_SECRET.format(
|
remote_service = remote_service_name(rid)
|
||||||
remote_service_name(rid)
|
if config('virt-type') in LIBVIRT_TYPES:
|
||||||
)
|
secrets_filename = CEPH_BACKEND_SECRET.format(remote_service)
|
||||||
render(os.path.basename(CEPH_SECRET), secrets_filename,
|
render(os.path.basename(CEPH_SECRET), secrets_filename,
|
||||||
context={'ceph_secret_uuid': uuid,
|
context={'ceph_secret_uuid': uuid,
|
||||||
'service_name': remote_service_name(rid)})
|
'service_name': remote_service})
|
||||||
create_libvirt_secret(secret_file=secrets_filename,
|
create_libvirt_secret(secret_file=secrets_filename,
|
||||||
secret_uuid=uuid,
|
secret_uuid=uuid,
|
||||||
key=key)
|
key=key)
|
||||||
|
# NOTE(jamespage): LXD ceph integration via host rbd mapping, so
|
||||||
|
# install keyring for rbd commands to use
|
||||||
|
ensure_ceph_keyring(service=remote_service,
|
||||||
|
user='nova', group='nova',
|
||||||
|
key=key)
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('update-status')
|
@hooks.hook('update-status')
|
||||||
|
@ -199,6 +199,7 @@ NOVA_COMPUTE_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
|||||||
NOVA_NETWORK_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
NOVA_NETWORK_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'
|
||||||
''.format(NOVA_NETWORK_AA_PROFILE))
|
''.format(NOVA_NETWORK_AA_PROFILE))
|
||||||
|
|
||||||
|
LIBVIRT_TYPES = ['kvm', 'qemu', 'lxc']
|
||||||
|
|
||||||
BASE_RESOURCE_MAP = {
|
BASE_RESOURCE_MAP = {
|
||||||
NOVA_CONF: {
|
NOVA_CONF: {
|
||||||
|
@ -239,6 +239,16 @@ def format_ipv6_addr(address):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def is_ipv6_disabled():
|
||||||
|
try:
|
||||||
|
result = subprocess.check_output(
|
||||||
|
['sysctl', 'net.ipv6.conf.all.disable_ipv6'],
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
return "net.ipv6.conf.all.disable_ipv6 = 1" in result
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
|
def get_iface_addr(iface='eth0', inet_type='AF_INET', inc_aliases=False,
|
||||||
fatal=True, exc_list=None):
|
fatal=True, exc_list=None):
|
||||||
"""Return the assigned IP address for a given interface, if any.
|
"""Return the assigned IP address for a given interface, if any.
|
||||||
@ -544,31 +554,38 @@ def assert_charm_supports_ipv6():
|
|||||||
"versions less than Trusty 14.04")
|
"versions less than Trusty 14.04")
|
||||||
|
|
||||||
|
|
||||||
def get_relation_ip(interface, config_override=None):
|
def get_relation_ip(interface, cidr_network=None):
|
||||||
"""Return this unit's IP for the given relation.
|
"""Return this unit's IP for the given interface.
|
||||||
|
|
||||||
Allow for an arbitrary interface to use with network-get to select an IP.
|
Allow for an arbitrary interface to use with network-get to select an IP.
|
||||||
Handle all address selection options including configuration parameter
|
Handle all address selection options including passed cidr network and
|
||||||
override and IPv6.
|
IPv6.
|
||||||
|
|
||||||
Usage: get_relation_ip('amqp', config_override='access-network')
|
Usage: get_relation_ip('amqp', cidr_network='10.0.0.0/8')
|
||||||
|
|
||||||
@param interface: string name of the relation.
|
@param interface: string name of the relation.
|
||||||
@param config_override: string name of the config option for network
|
@param cidr_network: string CIDR Network to select an address from.
|
||||||
override. Supports legacy network override configuration parameters.
|
|
||||||
@raises Exception if prefer-ipv6 is configured but IPv6 unsupported.
|
@raises Exception if prefer-ipv6 is configured but IPv6 unsupported.
|
||||||
@returns IPv6 or IPv4 address
|
@returns IPv6 or IPv4 address
|
||||||
"""
|
"""
|
||||||
|
# Select the interface address first
|
||||||
|
# For possible use as a fallback bellow with get_address_in_network
|
||||||
|
try:
|
||||||
|
# Get the interface specific IP
|
||||||
|
address = network_get_primary_address(interface)
|
||||||
|
except NotImplementedError:
|
||||||
|
# If network-get is not available
|
||||||
|
address = get_host_ip(unit_get('private-address'))
|
||||||
|
|
||||||
fallback = get_host_ip(unit_get('private-address'))
|
|
||||||
if config('prefer-ipv6'):
|
if config('prefer-ipv6'):
|
||||||
|
# Currently IPv6 has priority, eventually we want IPv6 to just be
|
||||||
|
# another network space.
|
||||||
assert_charm_supports_ipv6()
|
assert_charm_supports_ipv6()
|
||||||
return get_ipv6_addr()[0]
|
return get_ipv6_addr()[0]
|
||||||
elif config_override and config(config_override):
|
elif cidr_network:
|
||||||
return get_address_in_network(config(config_override),
|
# If a specific CIDR network is passed get the address from that
|
||||||
fallback)
|
# network.
|
||||||
else:
|
return get_address_in_network(cidr_network, address)
|
||||||
try:
|
|
||||||
return network_get_primary_address(interface)
|
# Return the interface address
|
||||||
except NotImplementedError:
|
return address
|
||||||
return fallback
|
|
||||||
|
@ -547,7 +547,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
|||||||
"""Create the specified instance."""
|
"""Create the specified instance."""
|
||||||
self.log.debug('Creating instance '
|
self.log.debug('Creating instance '
|
||||||
'({}|{}|{})'.format(instance_name, image_name, flavor))
|
'({}|{}|{})'.format(instance_name, image_name, flavor))
|
||||||
image = nova.images.find(name=image_name)
|
image = nova.glance.find_image(image_name)
|
||||||
flavor = nova.flavors.find(name=flavor)
|
flavor = nova.flavors.find(name=flavor)
|
||||||
instance = nova.servers.create(name=instance_name, image=image,
|
instance = nova.servers.create(name=instance_name, image=image,
|
||||||
flavor=flavor)
|
flavor=flavor)
|
||||||
|
@ -191,7 +191,7 @@ def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d",
|
|||||||
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
||||||
sysv_file = os.path.join(initd_dir, service_name)
|
sysv_file = os.path.join(initd_dir, service_name)
|
||||||
if init_is_systemd():
|
if init_is_systemd():
|
||||||
service('disable', service_name)
|
service('mask', service_name)
|
||||||
elif os.path.exists(upstart_file):
|
elif os.path.exists(upstart_file):
|
||||||
override_path = os.path.join(
|
override_path = os.path.join(
|
||||||
init_dir, '{}.override'.format(service_name))
|
init_dir, '{}.override'.format(service_name))
|
||||||
@ -224,7 +224,7 @@ def service_resume(service_name, init_dir="/etc/init",
|
|||||||
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
|
||||||
sysv_file = os.path.join(initd_dir, service_name)
|
sysv_file = os.path.join(initd_dir, service_name)
|
||||||
if init_is_systemd():
|
if init_is_systemd():
|
||||||
service('enable', service_name)
|
service('unmask', service_name)
|
||||||
elif os.path.exists(upstart_file):
|
elif os.path.exists(upstart_file):
|
||||||
override_path = os.path.join(
|
override_path = os.path.join(
|
||||||
init_dir, '{}.override'.format(service_name))
|
init_dir, '{}.override'.format(service_name))
|
||||||
|
@ -756,6 +756,7 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
|
|
||||||
def test_ceph_access_lxd(self):
|
def test_ceph_access_lxd(self):
|
||||||
self.relation_get.side_effect = ['mykey', 'uuid2']
|
self.relation_get.side_effect = ['mykey', 'uuid2']
|
||||||
|
self.remote_service_name.return_value = 'cinder-ceph'
|
||||||
self.test_config.set('virt-type', 'lxd')
|
self.test_config.set('virt-type', 'lxd')
|
||||||
hooks.ceph_access()
|
hooks.ceph_access()
|
||||||
self.relation_get.assert_has_calls([
|
self.relation_get.assert_has_calls([
|
||||||
@ -764,6 +765,12 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
])
|
])
|
||||||
self.render.assert_not_called()
|
self.render.assert_not_called()
|
||||||
self.create_libvirt_secret.assert_not_called()
|
self.create_libvirt_secret.assert_not_called()
|
||||||
|
self.ensure_ceph_keyring.assert_called_with(
|
||||||
|
service='cinder-ceph',
|
||||||
|
user='nova',
|
||||||
|
group='nova',
|
||||||
|
key='mykey'
|
||||||
|
)
|
||||||
|
|
||||||
def test_ceph_access_complete(self):
|
def test_ceph_access_complete(self):
|
||||||
self.relation_get.side_effect = ['mykey', 'uuid2']
|
self.relation_get.side_effect = ['mykey', 'uuid2']
|
||||||
@ -785,3 +792,9 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
secret_uuid='uuid2',
|
secret_uuid='uuid2',
|
||||||
key='mykey',
|
key='mykey',
|
||||||
)
|
)
|
||||||
|
self.ensure_ceph_keyring.assert_called_with(
|
||||||
|
service='cinder-ceph',
|
||||||
|
user='nova',
|
||||||
|
group='nova',
|
||||||
|
key='mykey'
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user