Merge "Add Ceph BlueStore Compression support"
This commit is contained in:
commit
b398e40165
66
config.yaml
66
config.yaml
@ -690,3 +690,69 @@ options:
|
|||||||
.
|
.
|
||||||
This option doesn't have any effect on clouds running
|
This option doesn't have any effect on clouds running
|
||||||
a release < Ocata.
|
a release < Ocata.
|
||||||
|
bluestore-compression-algorithm:
|
||||||
|
type: string
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Compressor to use (if any) for pools requested by this charm.
|
||||||
|
.
|
||||||
|
NOTE: The ceph-osd charm sets a global default for this value (defaults
|
||||||
|
to 'lz4' unless configured by the end user) which will be used unless
|
||||||
|
specified for individual pools.
|
||||||
|
bluestore-compression-mode:
|
||||||
|
type: string
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Policy for using compression on pools requested by this charm.
|
||||||
|
.
|
||||||
|
'none' means never use compression.
|
||||||
|
'passive' means use compression when clients hint that data is
|
||||||
|
compressible.
|
||||||
|
'aggressive' means use compression unless clients hint that
|
||||||
|
data is not compressible.
|
||||||
|
'force' means use compression under all circumstances even if the clients
|
||||||
|
hint that the data is not compressible.
|
||||||
|
bluestore-compression-required-ratio:
|
||||||
|
type: float
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
The ratio of the size of the data chunk after compression relative to the
|
||||||
|
original size must be at least this small in order to store the
|
||||||
|
compressed version on pools requested by this charm.
|
||||||
|
bluestore-compression-min-blob-size:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Chunks smaller than this are never compressed on pools requested by
|
||||||
|
this charm.
|
||||||
|
bluestore-compression-min-blob-size-hdd:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Value of bluestore compression min blob size for rotational media on
|
||||||
|
pools requested by this charm.
|
||||||
|
bluestore-compression-min-blob-size-ssd:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Value of bluestore compression min blob size for solid state media on
|
||||||
|
pools requested by this charm.
|
||||||
|
bluestore-compression-max-blob-size:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Chunks larger than this are broken into smaller blobs sizing bluestore
|
||||||
|
compression max blob size before being compressed on pools requested by
|
||||||
|
this charm.
|
||||||
|
bluestore-compression-max-blob-size-hdd:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Value of bluestore compression max blob size for rotational media on
|
||||||
|
pools requested by this charm.
|
||||||
|
bluestore-compression-max-blob-size-ssd:
|
||||||
|
type: int
|
||||||
|
default:
|
||||||
|
description: |
|
||||||
|
Value of bluestore compression max blob size for solid state media on
|
||||||
|
pools requested by this charm.
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
''' Helpers for interacting with OpenvSwitch '''
|
''' Helpers for interacting with OpenvSwitch '''
|
||||||
|
import collections
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@ -20,9 +21,9 @@ import six
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from charmhelpers import deprecate
|
from charmhelpers import deprecate
|
||||||
|
from charmhelpers.contrib.network.ovs import ovsdb as ch_ovsdb
|
||||||
from charmhelpers.fetch import apt_install
|
from charmhelpers.fetch import apt_install
|
||||||
|
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
log, WARNING, INFO, DEBUG
|
log, WARNING, INFO, DEBUG
|
||||||
)
|
)
|
||||||
@ -592,3 +593,76 @@ def ovs_appctl(target, args):
|
|||||||
cmd = ['ovs-appctl', '-t', target]
|
cmd = ['ovs-appctl', '-t', target]
|
||||||
cmd.extend(args)
|
cmd.extend(args)
|
||||||
return subprocess.check_output(cmd, universal_newlines=True)
|
return subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
|
|
||||||
|
def uuid_for_port(port_name):
|
||||||
|
"""Get UUID of named port.
|
||||||
|
|
||||||
|
:param port_name: Name of port.
|
||||||
|
:type port_name: str
|
||||||
|
:returns: Port UUID.
|
||||||
|
:rtype: Optional[uuid.UUID]
|
||||||
|
"""
|
||||||
|
for port in ch_ovsdb.SimpleOVSDB(
|
||||||
|
'ovs-vsctl').port.find('name={}'.format(port_name)):
|
||||||
|
return port['_uuid']
|
||||||
|
|
||||||
|
|
||||||
|
def bridge_for_port(port_uuid):
|
||||||
|
"""Find which bridge a port is on.
|
||||||
|
|
||||||
|
:param port_uuid: UUID of port.
|
||||||
|
:type port_uuid: uuid.UUID
|
||||||
|
:returns: Name of bridge or None.
|
||||||
|
:rtype: Optional[str]
|
||||||
|
"""
|
||||||
|
for bridge in ch_ovsdb.SimpleOVSDB(
|
||||||
|
'ovs-vsctl').bridge:
|
||||||
|
# If there is a single port on a bridge the ports property will not be
|
||||||
|
# a list. ref: juju/charm-helpers#510
|
||||||
|
if (isinstance(bridge['ports'], list) and
|
||||||
|
port_uuid in bridge['ports'] or
|
||||||
|
port_uuid == bridge['ports']):
|
||||||
|
return bridge['name']
|
||||||
|
|
||||||
|
|
||||||
|
PatchPort = collections.namedtuple('PatchPort', ('bridge', 'port'))
|
||||||
|
Patch = collections.namedtuple('Patch', ('this_end', 'other_end'))
|
||||||
|
|
||||||
|
|
||||||
|
def patch_ports_on_bridge(bridge):
|
||||||
|
"""Find patch ports on a bridge.
|
||||||
|
|
||||||
|
:param bridge: Name of bridge
|
||||||
|
:type bridge: str
|
||||||
|
:returns: Iterator with bridge and port name for both ends of a patch.
|
||||||
|
:rtype: Iterator[Patch[PatchPort[str,str],PatchPort[str,str]]]
|
||||||
|
:raises: ValueError
|
||||||
|
"""
|
||||||
|
# On any given vSwitch there will be a small number of patch ports, so we
|
||||||
|
# start by iterating over ports with type `patch` then look up which bridge
|
||||||
|
# they belong to and act on any ports that match the criteria.
|
||||||
|
for interface in ch_ovsdb.SimpleOVSDB(
|
||||||
|
'ovs-vsctl').interface.find('type=patch'):
|
||||||
|
for port in ch_ovsdb.SimpleOVSDB(
|
||||||
|
'ovs-vsctl').port.find('name={}'.format(interface['name'])):
|
||||||
|
if bridge_for_port(port['_uuid']) == bridge:
|
||||||
|
this_end = PatchPort(bridge, port['name'])
|
||||||
|
other_end = PatchPort(bridge_for_port(
|
||||||
|
uuid_for_port(
|
||||||
|
interface['options']['peer'])),
|
||||||
|
interface['options']['peer'])
|
||||||
|
yield(Patch(this_end, other_end))
|
||||||
|
# We expect one result and it is ok if it turns out to be a port
|
||||||
|
# for a different bridge. However we need a break here to satisfy
|
||||||
|
# the for/else check which is in place to detect interface refering
|
||||||
|
# to non-existent port.
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError('Port for interface named "{}" does unexpectedly '
|
||||||
|
'not exist.'.format(interface['name']))
|
||||||
|
else:
|
||||||
|
# Allow our caller to handle no patch ports found gracefully, in
|
||||||
|
# reference to PEP479 just doing a return will provide a emtpy iterator
|
||||||
|
# and not None.
|
||||||
|
return
|
||||||
|
@ -36,6 +36,11 @@ class SimpleOVSDB(object):
|
|||||||
for br in ovsdb.bridge:
|
for br in ovsdb.bridge:
|
||||||
if br['name'] == 'br-test':
|
if br['name'] == 'br-test':
|
||||||
ovsdb.bridge.set(br['uuid'], 'external_ids:charm', 'managed')
|
ovsdb.bridge.set(br['uuid'], 'external_ids:charm', 'managed')
|
||||||
|
|
||||||
|
WARNING: If a list type field only have one item `ovs-vsctl` will present
|
||||||
|
it as a single item. Since we do not know the schema we have no way of
|
||||||
|
knowing what fields should be de-serialized as lists so the caller has
|
||||||
|
to be careful of checking the type of values returned from this library.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# For validation we keep a complete map of currently known good tool and
|
# For validation we keep a complete map of currently known good tool and
|
||||||
@ -157,6 +162,51 @@ class SimpleOVSDB(object):
|
|||||||
self._tool = tool
|
self._tool = tool
|
||||||
self._table = table
|
self._table = table
|
||||||
|
|
||||||
|
def _deserialize_ovsdb(self, data):
|
||||||
|
"""Deserialize OVSDB RFC7047 section 5.1 data.
|
||||||
|
|
||||||
|
:param data: Multidimensional list where first row contains RFC7047
|
||||||
|
type information
|
||||||
|
:type data: List[str,any]
|
||||||
|
:returns: Deserialized data.
|
||||||
|
:rtype: any
|
||||||
|
"""
|
||||||
|
# When using json formatted output to OVS commands Internal OVSDB
|
||||||
|
# notation may occur that require further deserializing.
|
||||||
|
# Reference: https://tools.ietf.org/html/rfc7047#section-5.1
|
||||||
|
ovs_type_cb_map = {
|
||||||
|
'uuid': uuid.UUID,
|
||||||
|
# NOTE: OVSDB sets have overloaded type
|
||||||
|
# see special handling below
|
||||||
|
'set': list,
|
||||||
|
'map': dict,
|
||||||
|
}
|
||||||
|
assert len(data) > 1, ('Invalid data provided, expecting list '
|
||||||
|
'with at least two elements.')
|
||||||
|
if data[0] == 'set':
|
||||||
|
# special handling for set
|
||||||
|
#
|
||||||
|
# it is either a list of strings or a list of typed lists.
|
||||||
|
# taste first element to see which it is
|
||||||
|
for el in data[1]:
|
||||||
|
# NOTE: We lock this handling down to the `uuid` type as
|
||||||
|
# that is the only one we have a practical example of.
|
||||||
|
# We could potentially just handle this generally based on
|
||||||
|
# the types listed in `ovs_type_cb_map` but let's open for
|
||||||
|
# that as soon as we have a concrete example to validate on
|
||||||
|
if isinstance(
|
||||||
|
el, list) and len(el) and el[0] == 'uuid':
|
||||||
|
decoded_set = []
|
||||||
|
for el in data[1]:
|
||||||
|
decoded_set.append(self._deserialize_ovsdb(el))
|
||||||
|
return(decoded_set)
|
||||||
|
# fall back to normal processing below
|
||||||
|
break
|
||||||
|
|
||||||
|
# Use map to deserialize data with fallback to `str`
|
||||||
|
f = ovs_type_cb_map.get(data[0], str)
|
||||||
|
return f(data[1])
|
||||||
|
|
||||||
def _find_tbl(self, condition=None):
|
def _find_tbl(self, condition=None):
|
||||||
"""Run and parse output of OVSDB `find` command.
|
"""Run and parse output of OVSDB `find` command.
|
||||||
|
|
||||||
@ -165,15 +215,6 @@ class SimpleOVSDB(object):
|
|||||||
:returns: Dictionary with data
|
:returns: Dictionary with data
|
||||||
:rtype: Dict[str, any]
|
:rtype: Dict[str, any]
|
||||||
"""
|
"""
|
||||||
# When using json formatted output to OVS commands Internal OVSDB
|
|
||||||
# notation may occur that require further deserializing.
|
|
||||||
# Reference: https://tools.ietf.org/html/rfc7047#section-5.1
|
|
||||||
ovs_type_cb_map = {
|
|
||||||
'uuid': uuid.UUID,
|
|
||||||
# FIXME sets also appear to sometimes contain type/value tuples
|
|
||||||
'set': list,
|
|
||||||
'map': dict,
|
|
||||||
}
|
|
||||||
cmd = [self._tool, '-f', 'json', 'find', self._table]
|
cmd = [self._tool, '-f', 'json', 'find', self._table]
|
||||||
if condition:
|
if condition:
|
||||||
cmd.append(condition)
|
cmd.append(condition)
|
||||||
@ -182,9 +223,8 @@ class SimpleOVSDB(object):
|
|||||||
for row in data['data']:
|
for row in data['data']:
|
||||||
values = []
|
values = []
|
||||||
for col in row:
|
for col in row:
|
||||||
if isinstance(col, list):
|
if isinstance(col, list) and len(col) > 1:
|
||||||
f = ovs_type_cb_map.get(col[0], str)
|
values.append(self._deserialize_ovsdb(col))
|
||||||
values.append(f(col[1]))
|
|
||||||
else:
|
else:
|
||||||
values.append(col)
|
values.append(col)
|
||||||
yield dict(zip(data['headings'], values))
|
yield dict(zip(data['headings'], values))
|
||||||
|
@ -3245,6 +3245,18 @@ class CephBlueStoreCompressionContext(OSContextGenerator):
|
|||||||
"""
|
"""
|
||||||
return self.op
|
return self.op
|
||||||
|
|
||||||
|
def get_kwargs(self):
|
||||||
|
"""Get values for use as keyword arguments.
|
||||||
|
|
||||||
|
:returns: Context values with key suitable for use as kwargs to
|
||||||
|
CephBrokerRq add_op_create_*_pool methods.
|
||||||
|
:rtype: Dict[str,any]
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
k.replace('-', '_'): v
|
||||||
|
for k, v in self.op.items()
|
||||||
|
}
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
"""Validate options.
|
"""Validate options.
|
||||||
|
|
||||||
|
@ -705,11 +705,11 @@ class ErasurePool(BasePool):
|
|||||||
# from different handling of this in the `charms.ceph` library.
|
# from different handling of this in the `charms.ceph` library.
|
||||||
self.erasure_code_profile = op.get('erasure-profile',
|
self.erasure_code_profile = op.get('erasure-profile',
|
||||||
'default-canonical')
|
'default-canonical')
|
||||||
|
self.allow_ec_overwrites = op.get('allow-ec-overwrites')
|
||||||
else:
|
else:
|
||||||
# We keep the class default when initialized from keyword arguments
|
# We keep the class default when initialized from keyword arguments
|
||||||
# to not break the API for any other consumers.
|
# to not break the API for any other consumers.
|
||||||
self.erasure_code_profile = erasure_code_profile or 'default'
|
self.erasure_code_profile = erasure_code_profile or 'default'
|
||||||
|
|
||||||
self.allow_ec_overwrites = allow_ec_overwrites
|
self.allow_ec_overwrites = allow_ec_overwrites
|
||||||
|
|
||||||
def _create(self):
|
def _create(self):
|
||||||
@ -1972,12 +1972,14 @@ class CephBrokerRq(object):
|
|||||||
'request-id': self.request_id})
|
'request-id': self.request_id})
|
||||||
|
|
||||||
def _ops_equal(self, other):
|
def _ops_equal(self, other):
|
||||||
|
keys_to_compare = [
|
||||||
|
'replicas', 'name', 'op', 'pg_num', 'group-permission',
|
||||||
|
'object-prefix-permissions',
|
||||||
|
]
|
||||||
|
keys_to_compare += list(self._partial_build_common_op_create().keys())
|
||||||
if len(self.ops) == len(other.ops):
|
if len(self.ops) == len(other.ops):
|
||||||
for req_no in range(0, len(self.ops)):
|
for req_no in range(0, len(self.ops)):
|
||||||
for key in [
|
for key in keys_to_compare:
|
||||||
'replicas', 'name', 'op', 'pg_num', 'weight',
|
|
||||||
'group', 'group-namespace', 'group-permission',
|
|
||||||
'object-prefix-permissions']:
|
|
||||||
if self.ops[req_no].get(key) != other.ops[req_no].get(key):
|
if self.ops[req_no].get(key) != other.ops[req_no].get(key):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -61,6 +61,8 @@ from charmhelpers.fetch import (
|
|||||||
filter_installed_packages,
|
filter_installed_packages,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import charmhelpers.contrib.openstack.context as ch_context
|
||||||
|
|
||||||
from charmhelpers.contrib.openstack.utils import (
|
from charmhelpers.contrib.openstack.utils import (
|
||||||
CompareOpenStackReleases,
|
CompareOpenStackReleases,
|
||||||
configure_installation_source,
|
configure_installation_source,
|
||||||
@ -390,6 +392,7 @@ def get_ceph_request():
|
|||||||
pool_name = config('rbd-pool')
|
pool_name = config('rbd-pool')
|
||||||
replicas = config('ceph-osd-replication-count')
|
replicas = config('ceph-osd-replication-count')
|
||||||
weight = config('ceph-pool-weight')
|
weight = config('ceph-pool-weight')
|
||||||
|
bluestore_compression = ch_context.CephBlueStoreCompressionContext()
|
||||||
|
|
||||||
if config('pool-type') == 'erasure-coded':
|
if config('pool-type') == 'erasure-coded':
|
||||||
# General EC plugin config
|
# General EC plugin config
|
||||||
@ -442,18 +445,31 @@ def get_ceph_request():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Create EC data pool
|
# Create EC data pool
|
||||||
rq.add_op_create_erasure_pool(
|
|
||||||
name=pool_name,
|
# NOTE(fnordahl): once we deprecate Python 3.5 support we can do
|
||||||
erasure_profile=profile_name,
|
# the unpacking of the BlueStore compression arguments as part of
|
||||||
weight=weight,
|
# the function arguments. Until then we need to build the dict
|
||||||
group="vms",
|
# prior to the function call.
|
||||||
app_name="rbd",
|
kwargs = {
|
||||||
allow_ec_overwrites=True
|
'name': pool_name,
|
||||||
)
|
'erasure_profile': profile_name,
|
||||||
|
'weight': weight,
|
||||||
|
'group': "vms",
|
||||||
|
'app_name': "rbd",
|
||||||
|
'allow_ec_overwrites': True
|
||||||
|
}
|
||||||
|
kwargs.update(bluestore_compression.get_kwargs())
|
||||||
|
rq.add_op_create_erasure_pool(**kwargs)
|
||||||
else:
|
else:
|
||||||
rq.add_op_create_pool(name=pool_name, replica_count=replicas,
|
kwargs = {
|
||||||
weight=weight,
|
'name': pool_name,
|
||||||
group='vms', app_name='rbd')
|
'replica_count': replicas,
|
||||||
|
'weight': weight,
|
||||||
|
'group': 'vms',
|
||||||
|
'app_name': 'rbd',
|
||||||
|
}
|
||||||
|
kwargs.update(bluestore_compression.get_kwargs())
|
||||||
|
rq.add_op_create_replicated_pool(**kwargs)
|
||||||
|
|
||||||
if config('restrict-ceph-pools'):
|
if config('restrict-ceph-pools'):
|
||||||
rq.add_op_request_access_to_group(
|
rq.add_op_request_access_to_group(
|
||||||
@ -494,7 +510,16 @@ def ceph_changed(rid=None, unit=None):
|
|||||||
create_libvirt_secret(secret_file=CEPH_SECRET,
|
create_libvirt_secret(secret_file=CEPH_SECRET,
|
||||||
secret_uuid=CEPH_SECRET_UUID, key=key)
|
secret_uuid=CEPH_SECRET_UUID, key=key)
|
||||||
|
|
||||||
|
try:
|
||||||
_handle_ceph_request()
|
_handle_ceph_request()
|
||||||
|
except ValueError as e:
|
||||||
|
# The end user has most likely provided a invalid value for a
|
||||||
|
# configuration option. Just log the traceback here, the end
|
||||||
|
# user will be notified by assess_status() called at the end of
|
||||||
|
# the hook execution.
|
||||||
|
log('Caught ValueError, invalid value provided for '
|
||||||
|
'configuration?: "{}"'.format(str(e)),
|
||||||
|
level=DEBUG)
|
||||||
|
|
||||||
|
|
||||||
# TODO: Refactor this method moving part of this logic to charmhelpers,
|
# TODO: Refactor this method moving part of this logic to charmhelpers,
|
||||||
|
@ -929,6 +929,33 @@ def assess_status(configs):
|
|||||||
os_application_version_set(VERSION_PACKAGE)
|
os_application_version_set(VERSION_PACKAGE)
|
||||||
|
|
||||||
|
|
||||||
|
def check_optional_config_and_relations(configs):
|
||||||
|
"""Validate optional configuration and relations when present.
|
||||||
|
|
||||||
|
This function is called from assess_status/set_os_workload_status as the
|
||||||
|
charm_func and needs to return either None, None if there is no problem or
|
||||||
|
the status, message if there is a problem.
|
||||||
|
|
||||||
|
:param configs: an OSConfigRender() instance.
|
||||||
|
:return 2-tuple: (string, string) = (status, message)
|
||||||
|
"""
|
||||||
|
if relation_ids('ceph'):
|
||||||
|
# Check that provided Ceph BlueStoe configuration is valid.
|
||||||
|
try:
|
||||||
|
bluestore_compression = context.CephBlueStoreCompressionContext()
|
||||||
|
bluestore_compression.validate()
|
||||||
|
except AttributeError:
|
||||||
|
# The charm does late installation of the `ceph-common` package and
|
||||||
|
# the class initializer above will throw an exception until it is.
|
||||||
|
pass
|
||||||
|
except ValueError as e:
|
||||||
|
return ('blocked', 'Invalid configuration: {}'.format(str(e)))
|
||||||
|
|
||||||
|
# return 'unknown' as the lowest priority to not clobber an existing
|
||||||
|
# status.
|
||||||
|
return "unknown", ""
|
||||||
|
|
||||||
|
|
||||||
def assess_status_func(configs, services_=None):
|
def assess_status_func(configs, services_=None):
|
||||||
"""Helper function to create the function that will assess_status() for
|
"""Helper function to create the function that will assess_status() for
|
||||||
the unit.
|
the unit.
|
||||||
@ -957,6 +984,7 @@ def assess_status_func(configs, services_=None):
|
|||||||
required_interfaces.update(optional_relations)
|
required_interfaces.update(optional_relations)
|
||||||
return make_assess_status_func(
|
return make_assess_status_func(
|
||||||
configs, required_interfaces,
|
configs, required_interfaces,
|
||||||
|
charm_func=check_optional_config_and_relations,
|
||||||
services=services_ or services(), ports=None)
|
services=services_ or services(), ports=None)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,247 +0,0 @@
|
|||||||
variables:
|
|
||||||
openstack-origin: &openstack-origin distro
|
|
||||||
|
|
||||||
series: focal
|
|
||||||
|
|
||||||
comment:
|
|
||||||
- 'machines section to decide order of deployment. database sooner = faster'
|
|
||||||
machines:
|
|
||||||
'0':
|
|
||||||
constraints: mem=3072M
|
|
||||||
'1':
|
|
||||||
constraints: mem=3072M
|
|
||||||
'2':
|
|
||||||
constraints: mem=3072M
|
|
||||||
'3':
|
|
||||||
'4':
|
|
||||||
'5':
|
|
||||||
'6':
|
|
||||||
'7':
|
|
||||||
'8':
|
|
||||||
'9':
|
|
||||||
'10':
|
|
||||||
constraints: mem=4096M cores=4
|
|
||||||
'11':
|
|
||||||
'12':
|
|
||||||
'13':
|
|
||||||
'14':
|
|
||||||
'15':
|
|
||||||
'16':
|
|
||||||
'17':
|
|
||||||
'18':
|
|
||||||
'19':
|
|
||||||
|
|
||||||
applications:
|
|
||||||
|
|
||||||
nova-cloud-controller-mysql-router:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-router
|
|
||||||
keystone-mysql-router:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-router
|
|
||||||
glance-mysql-router:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-router
|
|
||||||
neutron-api-mysql-router:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-router
|
|
||||||
placement-mysql-router:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-router
|
|
||||||
|
|
||||||
mysql-innodb-cluster:
|
|
||||||
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
|
||||||
num_units: 3
|
|
||||||
options:
|
|
||||||
source: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '0'
|
|
||||||
- '1'
|
|
||||||
- '2'
|
|
||||||
|
|
||||||
ceph-osd:
|
|
||||||
charm: cs:~openstack-charmers-next/ceph-osd
|
|
||||||
num_units: 6
|
|
||||||
storage:
|
|
||||||
osd-devices: '10G'
|
|
||||||
options:
|
|
||||||
source: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '11'
|
|
||||||
- '12'
|
|
||||||
- '13'
|
|
||||||
- '14'
|
|
||||||
- '15'
|
|
||||||
- '16'
|
|
||||||
|
|
||||||
ceph-mon:
|
|
||||||
charm: cs:~openstack-charmers-next/ceph-mon
|
|
||||||
num_units: 3
|
|
||||||
options:
|
|
||||||
source: *openstack-origin
|
|
||||||
monitor-count: '3'
|
|
||||||
to:
|
|
||||||
- '17'
|
|
||||||
- '18'
|
|
||||||
- '19'
|
|
||||||
|
|
||||||
rabbitmq-server:
|
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
source: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '3'
|
|
||||||
|
|
||||||
nova-cloud-controller:
|
|
||||||
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
network-manager: Neutron
|
|
||||||
debug: true
|
|
||||||
to:
|
|
||||||
- '4'
|
|
||||||
|
|
||||||
neutron-api:
|
|
||||||
charm: cs:~openstack-charmers-next/neutron-api
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
manage-neutron-plugin-legacy-mode: true
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
flat-network-providers: physnet1
|
|
||||||
neutron-security-groups: true
|
|
||||||
to:
|
|
||||||
- '5'
|
|
||||||
|
|
||||||
keystone:
|
|
||||||
charm: cs:~openstack-charmers-next/keystone
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '6'
|
|
||||||
|
|
||||||
neutron-gateway:
|
|
||||||
charm: cs:~openstack-charmers-next/neutron-gateway
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
bridge-mappings: physnet1:br-ex
|
|
||||||
to:
|
|
||||||
- '7'
|
|
||||||
|
|
||||||
glance:
|
|
||||||
charm: cs:~openstack-charmers-next/glance
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '8'
|
|
||||||
|
|
||||||
neutron-openvswitch:
|
|
||||||
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
|
||||||
|
|
||||||
placement:
|
|
||||||
charm: cs:~openstack-charmers-next/placement
|
|
||||||
num_units: 1
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
to:
|
|
||||||
- '9'
|
|
||||||
|
|
||||||
nova-compute:
|
|
||||||
charm: ../../../nova-compute
|
|
||||||
num_units: 1
|
|
||||||
storage:
|
|
||||||
ephemeral-device: '40G'
|
|
||||||
options:
|
|
||||||
openstack-origin: *openstack-origin
|
|
||||||
config-flags: auto_assign_floating_ip=False
|
|
||||||
enable-live-migration: false
|
|
||||||
aa-profile-mode: enforce
|
|
||||||
debug: true
|
|
||||||
pool-type: erasure-coded
|
|
||||||
ec-profile-k: 4
|
|
||||||
ec-profile-m: 2
|
|
||||||
libvirt-image-backend: rbd
|
|
||||||
to:
|
|
||||||
- '10'
|
|
||||||
|
|
||||||
relations:
|
|
||||||
- - 'ceph-osd:mon'
|
|
||||||
- 'ceph-mon:osd'
|
|
||||||
|
|
||||||
- - 'nova-compute:ceph'
|
|
||||||
- 'ceph-mon:client'
|
|
||||||
|
|
||||||
- - 'nova-compute:image-service'
|
|
||||||
- 'glance:image-service'
|
|
||||||
|
|
||||||
- - 'nova-compute:amqp'
|
|
||||||
- 'rabbitmq-server:amqp'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:shared-db'
|
|
||||||
- 'nova-cloud-controller-mysql-router:shared-db'
|
|
||||||
- - 'nova-cloud-controller-mysql-router:db-router'
|
|
||||||
- 'mysql-innodb-cluster:db-router'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:identity-service'
|
|
||||||
- 'keystone:identity-service'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:amqp'
|
|
||||||
- 'rabbitmq-server:amqp'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:cloud-compute'
|
|
||||||
- 'nova-compute:cloud-compute'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:image-service'
|
|
||||||
- 'glance:image-service'
|
|
||||||
|
|
||||||
- - 'keystone:shared-db'
|
|
||||||
- 'keystone-mysql-router:shared-db'
|
|
||||||
- - 'keystone-mysql-router:db-router'
|
|
||||||
- 'mysql-innodb-cluster:db-router'
|
|
||||||
|
|
||||||
- - 'glance:identity-service'
|
|
||||||
- 'keystone:identity-service'
|
|
||||||
|
|
||||||
- - 'glance:shared-db'
|
|
||||||
- 'glance-mysql-router:shared-db'
|
|
||||||
- - 'glance-mysql-router:db-router'
|
|
||||||
- 'mysql-innodb-cluster:db-router'
|
|
||||||
|
|
||||||
- - 'glance:amqp'
|
|
||||||
- 'rabbitmq-server:amqp'
|
|
||||||
|
|
||||||
- - 'neutron-gateway:amqp'
|
|
||||||
- 'rabbitmq-server:amqp'
|
|
||||||
|
|
||||||
- - 'nova-cloud-controller:quantum-network-service'
|
|
||||||
- 'neutron-gateway:quantum-network-service'
|
|
||||||
|
|
||||||
- - 'neutron-api:shared-db'
|
|
||||||
- 'neutron-api-mysql-router:shared-db'
|
|
||||||
- - 'neutron-api-mysql-router:db-router'
|
|
||||||
- 'mysql-innodb-cluster:db-router'
|
|
||||||
|
|
||||||
- - 'neutron-api:amqp'
|
|
||||||
- 'rabbitmq-server:amqp'
|
|
||||||
|
|
||||||
- - 'neutron-api:neutron-api'
|
|
||||||
- 'nova-cloud-controller:neutron-api'
|
|
||||||
|
|
||||||
- - 'neutron-api:identity-service'
|
|
||||||
- 'keystone:identity-service'
|
|
||||||
|
|
||||||
- - 'nova-compute:neutron-plugin'
|
|
||||||
- 'neutron-openvswitch:neutron-plugin'
|
|
||||||
|
|
||||||
- - 'rabbitmq-server:amqp'
|
|
||||||
- 'neutron-openvswitch:amqp'
|
|
||||||
|
|
||||||
- - 'placement:shared-db'
|
|
||||||
- 'placement-mysql-router:shared-db'
|
|
||||||
- - 'placement-mysql-router:db-router'
|
|
||||||
- 'mysql-innodb-cluster:db-router'
|
|
||||||
|
|
||||||
- - 'placement:identity-service'
|
|
||||||
- 'keystone:identity-service'
|
|
||||||
|
|
||||||
- - 'placement:placement'
|
|
||||||
- 'nova-cloud-controller:placement'
|
|
@ -21,6 +21,15 @@ machines:
|
|||||||
'9':
|
'9':
|
||||||
'10':
|
'10':
|
||||||
constraints: mem=4096M cores=4
|
constraints: mem=4096M cores=4
|
||||||
|
'11':
|
||||||
|
'12':
|
||||||
|
'13':
|
||||||
|
'14':
|
||||||
|
'15':
|
||||||
|
'16':
|
||||||
|
'17':
|
||||||
|
'18':
|
||||||
|
'19':
|
||||||
|
|
||||||
applications:
|
applications:
|
||||||
|
|
||||||
@ -45,6 +54,32 @@ applications:
|
|||||||
- '1'
|
- '1'
|
||||||
- '2'
|
- '2'
|
||||||
|
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 6
|
||||||
|
storage:
|
||||||
|
osd-devices: '10G'
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
to:
|
||||||
|
- '11'
|
||||||
|
- '12'
|
||||||
|
- '13'
|
||||||
|
- '14'
|
||||||
|
- '15'
|
||||||
|
- '16'
|
||||||
|
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
monitor-count: '3'
|
||||||
|
to:
|
||||||
|
- '17'
|
||||||
|
- '18'
|
||||||
|
- '19'
|
||||||
|
|
||||||
rabbitmq-server:
|
rabbitmq-server:
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||||
num_units: 1
|
num_units: 1
|
||||||
@ -121,10 +156,20 @@ applications:
|
|||||||
enable-live-migration: false
|
enable-live-migration: false
|
||||||
aa-profile-mode: enforce
|
aa-profile-mode: enforce
|
||||||
debug: true
|
debug: true
|
||||||
|
pool-type: erasure-coded
|
||||||
|
ec-profile-k: 4
|
||||||
|
ec-profile-m: 2
|
||||||
|
libvirt-image-backend: rbd
|
||||||
to:
|
to:
|
||||||
- '10'
|
- '10'
|
||||||
|
|
||||||
relations:
|
relations:
|
||||||
|
- - 'ceph-osd:mon'
|
||||||
|
- 'ceph-mon:osd'
|
||||||
|
|
||||||
|
- - 'nova-compute:ceph'
|
||||||
|
- 'ceph-mon:client'
|
||||||
|
|
||||||
- - 'nova-compute:image-service'
|
- - 'nova-compute:image-service'
|
||||||
- 'glance:image-service'
|
- 'glance:image-service'
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@ machines:
|
|||||||
'9':
|
'9':
|
||||||
'10':
|
'10':
|
||||||
constraints: mem=4096M cores=4
|
constraints: mem=4096M cores=4
|
||||||
|
'11':
|
||||||
|
'12':
|
||||||
|
'13':
|
||||||
|
'14':
|
||||||
|
'15':
|
||||||
|
'16':
|
||||||
|
'17':
|
||||||
|
'18':
|
||||||
|
'19':
|
||||||
|
|
||||||
applications:
|
applications:
|
||||||
|
|
||||||
@ -45,6 +54,32 @@ applications:
|
|||||||
- '1'
|
- '1'
|
||||||
- '2'
|
- '2'
|
||||||
|
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 6
|
||||||
|
storage:
|
||||||
|
osd-devices: '10G'
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
to:
|
||||||
|
- '11'
|
||||||
|
- '12'
|
||||||
|
- '13'
|
||||||
|
- '14'
|
||||||
|
- '15'
|
||||||
|
- '16'
|
||||||
|
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
monitor-count: '3'
|
||||||
|
to:
|
||||||
|
- '17'
|
||||||
|
- '18'
|
||||||
|
- '19'
|
||||||
|
|
||||||
rabbitmq-server:
|
rabbitmq-server:
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||||
num_units: 1
|
num_units: 1
|
||||||
@ -121,10 +156,20 @@ applications:
|
|||||||
enable-live-migration: false
|
enable-live-migration: false
|
||||||
aa-profile-mode: enforce
|
aa-profile-mode: enforce
|
||||||
debug: true
|
debug: true
|
||||||
|
pool-type: erasure-coded
|
||||||
|
ec-profile-k: 4
|
||||||
|
ec-profile-m: 2
|
||||||
|
libvirt-image-backend: rbd
|
||||||
to:
|
to:
|
||||||
- '10'
|
- '10'
|
||||||
|
|
||||||
relations:
|
relations:
|
||||||
|
- - 'ceph-osd:mon'
|
||||||
|
- 'ceph-mon:osd'
|
||||||
|
|
||||||
|
- - 'nova-compute:ceph'
|
||||||
|
- 'ceph-mon:client'
|
||||||
|
|
||||||
- - 'nova-compute:image-service'
|
- - 'nova-compute:image-service'
|
||||||
- 'glance:image-service'
|
- 'glance:image-service'
|
||||||
|
|
||||||
|
@ -21,6 +21,15 @@ machines:
|
|||||||
'9':
|
'9':
|
||||||
'10':
|
'10':
|
||||||
constraints: mem=4096M cores=4
|
constraints: mem=4096M cores=4
|
||||||
|
'11':
|
||||||
|
'12':
|
||||||
|
'13':
|
||||||
|
'14':
|
||||||
|
'15':
|
||||||
|
'16':
|
||||||
|
'17':
|
||||||
|
'18':
|
||||||
|
'19':
|
||||||
|
|
||||||
applications:
|
applications:
|
||||||
|
|
||||||
@ -45,6 +54,32 @@ applications:
|
|||||||
- '1'
|
- '1'
|
||||||
- '2'
|
- '2'
|
||||||
|
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-osd
|
||||||
|
num_units: 6
|
||||||
|
storage:
|
||||||
|
osd-devices: '10G'
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
to:
|
||||||
|
- '11'
|
||||||
|
- '12'
|
||||||
|
- '13'
|
||||||
|
- '14'
|
||||||
|
- '15'
|
||||||
|
- '16'
|
||||||
|
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
monitor-count: '3'
|
||||||
|
to:
|
||||||
|
- '17'
|
||||||
|
- '18'
|
||||||
|
- '19'
|
||||||
|
|
||||||
rabbitmq-server:
|
rabbitmq-server:
|
||||||
charm: cs:~openstack-charmers-next/rabbitmq-server
|
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||||
num_units: 1
|
num_units: 1
|
||||||
@ -121,10 +156,20 @@ applications:
|
|||||||
enable-live-migration: false
|
enable-live-migration: false
|
||||||
aa-profile-mode: enforce
|
aa-profile-mode: enforce
|
||||||
debug: true
|
debug: true
|
||||||
|
pool-type: erasure-coded
|
||||||
|
ec-profile-k: 4
|
||||||
|
ec-profile-m: 2
|
||||||
|
libvirt-image-backend: rbd
|
||||||
to:
|
to:
|
||||||
- '10'
|
- '10'
|
||||||
|
|
||||||
relations:
|
relations:
|
||||||
|
- - 'ceph-osd:mon'
|
||||||
|
- 'ceph-mon:osd'
|
||||||
|
|
||||||
|
- - 'nova-compute:ceph'
|
||||||
|
- 'ceph-mon:client'
|
||||||
|
|
||||||
- - 'nova-compute:image-service'
|
- - 'nova-compute:image-service'
|
||||||
- 'glance:image-service'
|
- 'glance:image-service'
|
||||||
|
|
||||||
|
@ -4,9 +4,8 @@ smoke_bundles:
|
|||||||
- bionic-train
|
- bionic-train
|
||||||
|
|
||||||
gate_bundles:
|
gate_bundles:
|
||||||
- erasure-coded: focal-ussuri-ec
|
- ceph: focal-ussuri
|
||||||
- focal-victoria
|
- ceph: focal-victoria
|
||||||
- focal-ussuri
|
|
||||||
- bionic-ussuri
|
- bionic-ussuri
|
||||||
- bionic-train
|
- bionic-train
|
||||||
- bionic-stein
|
- bionic-stein
|
||||||
@ -19,10 +18,10 @@ gate_bundles:
|
|||||||
- trusty-mitaka
|
- trusty-mitaka
|
||||||
|
|
||||||
dev_bundles:
|
dev_bundles:
|
||||||
- groovy-victoria
|
- ceph: groovy-victoria
|
||||||
|
|
||||||
configure:
|
configure:
|
||||||
- erasure-coded:
|
- ceph:
|
||||||
- zaza.openstack.charm_tests.glance.setup.add_cirros_image
|
- zaza.openstack.charm_tests.glance.setup.add_cirros_image
|
||||||
- zaza.openstack.charm_tests.glance.setup.add_lts_image
|
- zaza.openstack.charm_tests.glance.setup.add_lts_image
|
||||||
- zaza.openstack.charm_tests.keystone.setup.add_demo_user
|
- zaza.openstack.charm_tests.keystone.setup.add_demo_user
|
||||||
@ -37,12 +36,13 @@ configure:
|
|||||||
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
|
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
- erasure-coded:
|
- ceph:
|
||||||
- zaza.openstack.charm_tests.nova.tests.CirrosGuestCreateTest
|
- zaza.openstack.charm_tests.nova.tests.CirrosGuestCreateTest
|
||||||
- zaza.openstack.charm_tests.nova.tests.LTSGuestCreateTest
|
- zaza.openstack.charm_tests.nova.tests.LTSGuestCreateTest
|
||||||
- zaza.openstack.charm_tests.nova.tests.NovaCompute
|
- zaza.openstack.charm_tests.nova.tests.NovaCompute
|
||||||
- zaza.openstack.charm_tests.nova.tests.SecurityTests
|
- zaza.openstack.charm_tests.nova.tests.SecurityTests
|
||||||
- zaza.openstack.charm_tests.ceph.tests.CheckPoolTypes
|
- zaza.openstack.charm_tests.ceph.tests.CheckPoolTypes
|
||||||
|
- zaza.openstack.charm_tests.ceph.tests.BlueStoreCompressionCharmOperation
|
||||||
- zaza.openstack.charm_tests.nova.tests.CirrosGuestCreateTest
|
- zaza.openstack.charm_tests.nova.tests.CirrosGuestCreateTest
|
||||||
- zaza.openstack.charm_tests.nova.tests.LTSGuestCreateTest
|
- zaza.openstack.charm_tests.nova.tests.LTSGuestCreateTest
|
||||||
- zaza.openstack.charm_tests.nova.tests.NovaCompute
|
- zaza.openstack.charm_tests.nova.tests.NovaCompute
|
||||||
|
@ -496,6 +496,10 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
create_libvirt_secret.assert_called_once_with(
|
create_libvirt_secret.assert_called_once_with(
|
||||||
secret_file='/etc/ceph/secret.xml', key=key,
|
secret_file='/etc/ceph/secret.xml', key=key,
|
||||||
secret_uuid=hooks.CEPH_SECRET_UUID)
|
secret_uuid=hooks.CEPH_SECRET_UUID)
|
||||||
|
# confirm exception is caught
|
||||||
|
_handle_ceph_request.side_effect = ValueError
|
||||||
|
hooks.ceph_changed()
|
||||||
|
self.log.assert_called_once()
|
||||||
|
|
||||||
@patch.object(hooks, 'get_ceph_request')
|
@patch.object(hooks, 'get_ceph_request')
|
||||||
@patch.object(hooks, 'get_request_states')
|
@patch.object(hooks, 'get_request_states')
|
||||||
@ -644,13 +648,15 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
self.assertIsNone(unit)
|
self.assertIsNone(unit)
|
||||||
self.assertIsNone(rid)
|
self.assertIsNone(rid)
|
||||||
|
|
||||||
|
@patch.object(hooks.ch_context, 'CephBlueStoreCompressionContext')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_request_access_to_group')
|
'.add_op_request_access_to_group')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_create_pool')
|
'.add_op_create_pool')
|
||||||
@patch('uuid.uuid1')
|
@patch('uuid.uuid1')
|
||||||
def test_get_ceph_request(self, uuid1, mock_create_pool,
|
def test_get_ceph_request(self, uuid1, mock_create_pool,
|
||||||
mock_request_access):
|
mock_request_access,
|
||||||
|
mock_bluestore_compression):
|
||||||
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
||||||
self.test_config.set('rbd-pool', 'nova')
|
self.test_config.set('rbd-pool', 'nova')
|
||||||
self.test_config.set('ceph-osd-replication-count', 3)
|
self.test_config.set('ceph-osd-replication-count', 3)
|
||||||
@ -662,13 +668,15 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
mock_request_access.assert_not_called()
|
mock_request_access.assert_not_called()
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
|
@patch.object(hooks.ch_context, 'CephBlueStoreCompressionContext')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_request_access_to_group')
|
'.add_op_request_access_to_group')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_create_pool')
|
'.add_op_create_replicated_pool')
|
||||||
@patch('uuid.uuid1')
|
@patch('uuid.uuid1')
|
||||||
def test_get_ceph_request_rbd(self, uuid1, mock_create_pool,
|
def test_get_ceph_request_rbd(self, uuid1, mock_create_pool,
|
||||||
mock_request_access):
|
mock_request_access,
|
||||||
|
mock_bluestore_compression):
|
||||||
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
||||||
self.test_config.set('rbd-pool', 'nova')
|
self.test_config.set('rbd-pool', 'nova')
|
||||||
self.test_config.set('ceph-osd-replication-count', 3)
|
self.test_config.set('ceph-osd-replication-count', 3)
|
||||||
@ -682,7 +690,18 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
group='vms', app_name='rbd')
|
group='vms', app_name='rbd')
|
||||||
mock_request_access.assert_not_called()
|
mock_request_access.assert_not_called()
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
# confirm operation with bluestore compression
|
||||||
|
mock_create_pool.reset_mock()
|
||||||
|
mock_bluestore_compression().get_kwargs.return_value = {
|
||||||
|
'compression_mode': 'fake',
|
||||||
|
}
|
||||||
|
hooks.get_ceph_request()
|
||||||
|
mock_create_pool.assert_called_once_with(name='nova', replica_count=3,
|
||||||
|
weight=28, group='vms',
|
||||||
|
app_name='rbd',
|
||||||
|
compression_mode='fake')
|
||||||
|
|
||||||
|
@patch.object(hooks.ch_context, 'CephBlueStoreCompressionContext')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_create_erasure_pool')
|
'.add_op_create_erasure_pool')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
@ -695,7 +714,8 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
def test_get_ceph_request_rbd_ec(self, uuid1, mock_create_pool,
|
def test_get_ceph_request_rbd_ec(self, uuid1, mock_create_pool,
|
||||||
mock_request_access,
|
mock_request_access,
|
||||||
mock_create_erasure_profile,
|
mock_create_erasure_profile,
|
||||||
mock_create_erasure_pool):
|
mock_create_erasure_pool,
|
||||||
|
mock_bluestore_compression):
|
||||||
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
||||||
self.test_config.set('rbd-pool', 'nova')
|
self.test_config.set('rbd-pool', 'nova')
|
||||||
self.test_config.set('ceph-osd-replication-count', 3)
|
self.test_config.set('ceph-osd-replication-count', 3)
|
||||||
@ -738,14 +758,31 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
)
|
)
|
||||||
mock_request_access.assert_not_called()
|
mock_request_access.assert_not_called()
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
# confirm operation with bluestore compression
|
||||||
|
mock_create_erasure_pool.reset_mock()
|
||||||
|
mock_bluestore_compression().get_kwargs.return_value = {
|
||||||
|
'compression_mode': 'fake',
|
||||||
|
}
|
||||||
|
hooks.get_ceph_request()
|
||||||
|
mock_create_erasure_pool.assert_called_with(
|
||||||
|
name='nova',
|
||||||
|
erasure_profile='nova-profile',
|
||||||
|
weight=27.72,
|
||||||
|
group='vms',
|
||||||
|
app_name='rbd',
|
||||||
|
allow_ec_overwrites=True,
|
||||||
|
compression_mode='fake',
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch.object(hooks.ch_context, 'CephBlueStoreCompressionContext')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_request_access_to_group')
|
'.add_op_request_access_to_group')
|
||||||
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
@patch('charmhelpers.contrib.storage.linux.ceph.CephBrokerRq'
|
||||||
'.add_op_create_pool')
|
'.add_op_create_replicated_pool')
|
||||||
@patch('uuid.uuid1')
|
@patch('uuid.uuid1')
|
||||||
def test_get_ceph_request_perms(self, uuid1, mock_create_pool,
|
def test_get_ceph_request_perms(self, uuid1, mock_create_pool,
|
||||||
mock_request_access):
|
mock_request_access,
|
||||||
|
mock_bluestore_compression):
|
||||||
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
self.assert_libvirt_rbd_imagebackend_allowed.return_value = True
|
||||||
self.test_config.set('rbd-pool', 'nova')
|
self.test_config.set('rbd-pool', 'nova')
|
||||||
self.test_config.set('ceph-osd-replication-count', 3)
|
self.test_config.set('ceph-osd-replication-count', 3)
|
||||||
@ -770,6 +807,16 @@ class NovaComputeRelationsTests(CharmTestCase):
|
|||||||
permission='rwx'),
|
permission='rwx'),
|
||||||
])
|
])
|
||||||
self.assertEqual(expected, result)
|
self.assertEqual(expected, result)
|
||||||
|
# confirm operation with bluestore compression
|
||||||
|
mock_create_pool.reset_mock()
|
||||||
|
mock_bluestore_compression().get_kwargs.return_value = {
|
||||||
|
'compression_mode': 'fake',
|
||||||
|
}
|
||||||
|
hooks.get_ceph_request()
|
||||||
|
mock_create_pool.assert_called_once_with(name='nova', replica_count=3,
|
||||||
|
weight=28, group='vms',
|
||||||
|
app_name='rbd',
|
||||||
|
compression_mode='fake')
|
||||||
|
|
||||||
@patch.object(hooks, 'service_restart_handler')
|
@patch.object(hooks, 'service_restart_handler')
|
||||||
@patch.object(hooks, 'CONFIGS')
|
@patch.object(hooks, 'CONFIGS')
|
||||||
|
@ -899,7 +899,9 @@ class NovaComputeUtilsTests(CharmTestCase):
|
|||||||
utils.assess_status_func('test-config')
|
utils.assess_status_func('test-config')
|
||||||
# ports=None whilst port checks are disabled.
|
# ports=None whilst port checks are disabled.
|
||||||
make_assess_status_func.assert_called_once_with(
|
make_assess_status_func.assert_called_once_with(
|
||||||
'test-config', test_interfaces, services=['s1'], ports=None)
|
'test-config', test_interfaces,
|
||||||
|
charm_func=utils.check_optional_config_and_relations,
|
||||||
|
services=['s1'], ports=None)
|
||||||
|
|
||||||
def test_pause_unit_helper(self):
|
def test_pause_unit_helper(self):
|
||||||
with patch.object(utils, '_pause_resume_helper') as prh:
|
with patch.object(utils, '_pause_resume_helper') as prh:
|
||||||
|
Loading…
Reference in New Issue
Block a user