Update support for Erasure Coded pools

Add support to allow 'allow_ec_overwrites' to be set on a pool,
supporting RBD and CephFS uses cases for Erasure Coding.

Add support to allow the EC technique to be provided when
creating EC profiles.

Add support for extended configuration of EC plugins.

Depends-On: https://github.com/juju/charm-helpers/pull/498
Change-Id: I2547933964849f7af1c623b2fbc014fb332839ef
This commit is contained in:
Pedro Guimaraes 2020-06-01 10:16:30 +02:00 committed by James Page
parent b688f04889
commit 89b3b8d1eb
2 changed files with 98 additions and 9 deletions

View File

@ -155,25 +155,47 @@ def handle_create_erasure_profile(request, service):
:param service: The ceph client to run the command under.
:returns: dict. exit-code and reason if not 0
"""
# "local" | "shec" or it defaults to "jerasure"
# "isa" | "lrc" | "shec" | "clay" or it defaults to "jerasure"
erasure_type = request.get('erasure-type')
# "host" | "rack" or it defaults to "host" # Any valid Ceph bucket
# dependent on erasure coding type
erasure_technique = request.get('erasure-technique')
# "host" | "rack" | ...
failure_domain = request.get('failure-domain')
name = request.get('name')
# Binary Distribution Matrix (BDM) parameters
bdm_k = request.get('k')
bdm_m = request.get('m')
# LRC parameters
bdm_l = request.get('l')
crush_locality = request.get('crush-locality')
# SHEC parameters
bdm_c = request.get('c')
# CLAY parameters
bdm_d = request.get('d')
scalar_mds = request.get('scalar-mds')
# Device Class
device_class = request.get('device-class')
if failure_domain not in CEPH_BUCKET_TYPES:
if failure_domain and failure_domain not in CEPH_BUCKET_TYPES:
msg = "failure-domain must be one of {}".format(CEPH_BUCKET_TYPES)
log(msg, level=ERROR)
return {'exit-code': 1, 'stderr': msg}
create_erasure_profile(service=service, erasure_plugin_name=erasure_type,
profile_name=name, failure_domain=failure_domain,
data_chunks=bdm_k, coding_chunks=bdm_m,
locality=bdm_l)
create_erasure_profile(service=service,
erasure_plugin_name=erasure_type,
profile_name=name,
failure_domain=failure_domain,
data_chunks=bdm_k,
coding_chunks=bdm_m,
locality=bdm_l,
durability_estimator=bdm_d,
helper_chunks=bdm_c,
scalar_mds=scalar_mds,
crush_locality=crush_locality,
device_class=device_class,
erasure_plugin_technique=erasure_technique)
return {'exit-code': 0}
def handle_add_permissions_to_key(request, service):
@ -387,6 +409,7 @@ def handle_erasure_pool(request, service):
max_objects = request.get('max-objects')
weight = request.get('weight')
group_name = request.get('group')
allow_ec_overwrites = request.get('allow-ec-overwrites')
if erasure_profile is None:
erasure_profile = "default-canonical"
@ -416,7 +439,9 @@ def handle_erasure_pool(request, service):
pool = ErasurePool(service=service, name=pool_name,
erasure_code_profile=erasure_profile,
percent_data=weight, app_name=app_name)
percent_data=weight,
app_name=app_name,
allow_ec_overwrites=allow_ec_overwrites)
# Ok make the erasure pool
if not pool_exists(service=service, name=pool_name):
log("Creating pool '{}' (erasure_profile={})"

View File

@ -15,7 +15,7 @@
import json
import unittest
from unittest.mock import patch
from unittest.mock import patch, ANY
import charms_ceph.broker
@ -703,3 +703,67 @@ class CephBrokerTestCase(unittest.TestCase):
'osd',
('allow rwx pool=glance, '
'allow class-read object_prefix rbd_children')])
@patch.object(charms_ceph.broker, 'create_erasure_profile')
def test_handle_create_erasure_profile(self,
mock_create_erasure_profile):
request = {
'erasure-type': 'jerasure',
'erasure-technique': 'reed_sol',
'name': 'newprofile',
'failure-domain': 'rack',
'k': 4,
'm': 2,
'l': 3,
'c': 5,
'd': 9,
'scalar-mds': 'isa',
'crush-locality': 'host',
'device-class': 'ssd',
}
resp = charms_ceph.broker.handle_create_erasure_profile(
request,
'testservice'
)
self.assertEqual(resp, {'exit-code': 0})
mock_create_erasure_profile.assert_called_once_with(
service='testservice',
erasure_plugin_name='jerasure',
profile_name='newprofile',
failure_domain='rack',
data_chunks=4,
coding_chunks=2,
locality=3,
durability_estimator=9,
helper_chunks=5,
scalar_mds='isa',
crush_locality='host',
device_class='ssd',
erasure_plugin_technique='reed_sol'
)
@patch.object(charms_ceph.broker, 'create_erasure_profile')
def test_handle_create_erasure_profile_bad(self,
mock_create_erasure_profile):
request = {
'erasure-type': 'jerasure',
'erasure-technique': 'reed_sol',
'name': 'newprofile',
'failure-domain': 'foobar',
'k': 4,
'm': 2,
'l': None,
}
resp = charms_ceph.broker.handle_create_erasure_profile(
request,
'testservice'
)
self.assertEqual(
resp,
{
'exit-code': 1,
'stderr': ANY,
}
)
mock_create_erasure_profile.assert_not_called()