Add setting ``max_objects`` quota and retrieving erasure code profile
Also fix a few missing redirects of STDERR Change-Id: I243328af5db202f092c53b4d48e0d293378d2ca0
This commit is contained in:
parent
03685ca4a6
commit
203840bd69
|
@ -369,7 +369,8 @@ def handle_erasure_pool(request, service):
|
|||
"""
|
||||
pool_name = request.get('name')
|
||||
erasure_profile = request.get('erasure-profile')
|
||||
quota = request.get('max-bytes')
|
||||
max_bytes = request.get('max-bytes')
|
||||
max_objects = request.get('max-objects')
|
||||
weight = request.get('weight')
|
||||
group_name = request.get('group')
|
||||
|
||||
|
@ -409,8 +410,9 @@ def handle_erasure_pool(request, service):
|
|||
pool.create()
|
||||
|
||||
# Set a quota if requested
|
||||
if quota is not None:
|
||||
set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
|
||||
if max_bytes or max_objects:
|
||||
set_pool_quota(service=service, pool_name=pool_name,
|
||||
max_bytes=max_bytes, max_objects=max_objects)
|
||||
|
||||
|
||||
def handle_replicated_pool(request, service):
|
||||
|
@ -422,7 +424,8 @@ def handle_replicated_pool(request, service):
|
|||
"""
|
||||
pool_name = request.get('name')
|
||||
replicas = request.get('replicas')
|
||||
quota = request.get('max-bytes')
|
||||
max_bytes = request.get('max-bytes')
|
||||
max_objects = request.get('max-objects')
|
||||
weight = request.get('weight')
|
||||
group_name = request.get('group')
|
||||
|
||||
|
@ -469,8 +472,9 @@ def handle_replicated_pool(request, service):
|
|||
level=DEBUG)
|
||||
|
||||
# Set a quota if requested
|
||||
if quota is not None:
|
||||
set_pool_quota(service=service, pool_name=pool_name, max_bytes=quota)
|
||||
if max_bytes or max_objects:
|
||||
set_pool_quota(service=service, pool_name=pool_name,
|
||||
max_bytes=max_bytes, max_objects=max_objects)
|
||||
|
||||
|
||||
def handle_create_cache_tier(request, service):
|
||||
|
|
|
@ -2533,7 +2533,8 @@ def list_pools(client='admin'):
|
|||
try:
|
||||
pool_list = []
|
||||
pools = subprocess.check_output(['rados', '--id', client, 'lspools'],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
for pool in pools.splitlines():
|
||||
pool_list.append(pool)
|
||||
return pool_list
|
||||
|
@ -2558,8 +2559,8 @@ def get_pool_param(pool, param, client='admin'):
|
|||
"""
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
['ceph', '--id', client, 'osd', 'pool', 'get',
|
||||
pool, param], universal_newlines=True)
|
||||
['ceph', '--id', client, 'osd', 'pool', 'get', pool, param],
|
||||
universal_newlines=True, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cp:
|
||||
if cp.returncode == 2 and 'ENOENT: option' in cp.output:
|
||||
return None
|
||||
|
@ -2568,6 +2569,27 @@ def get_pool_param(pool, param, client='admin'):
|
|||
return output.split(':')[1].lstrip().rstrip()
|
||||
|
||||
|
||||
def get_pool_erasure_profile(pool, client='admin'):
|
||||
"""Get erasure code profile for pool.
|
||||
|
||||
:param pool: Name of pool to get variable from
|
||||
:type pool: str
|
||||
:param client: (Optional) client id for ceph key to use
|
||||
Defaults to ``admin``
|
||||
:type cilent: str
|
||||
:returns: Erasure code profile of pool or None
|
||||
:rtype: str or None
|
||||
:raises: subprocess.CalledProcessError
|
||||
"""
|
||||
try:
|
||||
return get_pool_param(pool, 'erasure_code_profile', client=client)
|
||||
except subprocess.CalledProcessError as cp:
|
||||
if cp.returncode == 13 and 'EACCES: pool' in cp.output:
|
||||
# Not a Erasure coded pool
|
||||
return None
|
||||
raise
|
||||
|
||||
|
||||
def get_pool_quota(pool, client='admin'):
|
||||
"""Get pool quota.
|
||||
|
||||
|
@ -2582,7 +2604,7 @@ def get_pool_quota(pool, client='admin'):
|
|||
"""
|
||||
output = subprocess.check_output(
|
||||
['ceph', '--id', client, 'osd', 'pool', 'get-quota', pool],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True, stderr=subprocess.STDOUT)
|
||||
rc = re.compile(r'\s+max\s+(\S+)\s*:\s+(\d+)')
|
||||
result = {}
|
||||
for line in output.splitlines():
|
||||
|
@ -2610,7 +2632,9 @@ def get_pool_applications(pool='', client='admin'):
|
|||
if pool:
|
||||
cmd.append(pool)
|
||||
try:
|
||||
output = subprocess.check_output(cmd, universal_newlines=True)
|
||||
output = subprocess.check_output(cmd,
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as cp:
|
||||
if cp.returncode == 2 and 'ENOENT' in cp.output:
|
||||
return {}
|
||||
|
@ -2646,6 +2670,10 @@ def list_pools_detail():
|
|||
for param in get_params:
|
||||
result[pool]['parameters'].update({
|
||||
param: get_pool_param(pool, param)})
|
||||
erasure_profile = get_pool_erasure_profile(pool)
|
||||
if erasure_profile:
|
||||
result[pool]['parameters'].update({
|
||||
'erasure_code_profile': erasure_profile})
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import collections
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
from mock import (
|
||||
|
@ -821,15 +822,18 @@ class CephTestCase(unittest.TestCase):
|
|||
_check_output.return_value = 'poola\npoolb\n'
|
||||
self.assertEqual(utils.list_pools('someuser'), ['poola', 'poolb'])
|
||||
_check_output.assert_called_with(['rados', '--id', 'someuser',
|
||||
'lspools'], universal_newlines=True)
|
||||
'lspools'], universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
self.assertEqual(utils.list_pools(client='someotheruser'),
|
||||
['poola', 'poolb'])
|
||||
_check_output.assert_called_with(['rados', '--id', 'someotheruser',
|
||||
'lspools'], universal_newlines=True)
|
||||
'lspools'], universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
self.assertEqual(utils.list_pools(),
|
||||
['poola', 'poolb'])
|
||||
_check_output.assert_called_with(['rados', '--id', 'admin',
|
||||
'lspools'], universal_newlines=True)
|
||||
'lspools'], universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
@patch.object(utils.subprocess, 'check_output')
|
||||
def test_get_pool_param(self, _check_output):
|
||||
|
@ -837,7 +841,22 @@ class CephTestCase(unittest.TestCase):
|
|||
self.assertEqual(utils.get_pool_param('rbd', 'size'), '3')
|
||||
_check_output.assert_called_with(['ceph', '--id', 'admin', 'osd',
|
||||
'pool', 'get', 'rbd', 'size'],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
@patch.object(utils, 'get_pool_param')
|
||||
def test_get_pool_erasure_profile(self, _get_pool_param):
|
||||
_get_pool_param.side_effect = subprocess.CalledProcessError(
|
||||
13, [], 'EACCES: pool')
|
||||
self.assertEqual(utils.get_pool_erasure_profile('cinder-ceph'), None)
|
||||
_get_pool_param.side_effect = subprocess.CalledProcessError(
|
||||
22, [], 'EINVAL: invalid')
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
utils.get_pool_erasure_profile('cinder-ceph')
|
||||
_get_pool_param.side_effect = None
|
||||
_get_pool_param.return_value = 'my-ec-profile'
|
||||
self.assertEqual(utils.get_pool_erasure_profile('cinder-ceph'),
|
||||
'my-ec-profile')
|
||||
|
||||
@patch.object(utils.subprocess, 'check_output')
|
||||
def test_get_pool_quota(self, _check_output):
|
||||
|
@ -849,7 +868,8 @@ class CephTestCase(unittest.TestCase):
|
|||
{})
|
||||
_check_output.assert_called_with(['ceph', '--id', 'admin', 'osd',
|
||||
'pool', 'get-quota', 'rbd'],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
_check_output.return_value = (
|
||||
"quotas for pool 'rbd':\n"
|
||||
" max objects: 10\n"
|
||||
|
@ -879,38 +899,46 @@ class CephTestCase(unittest.TestCase):
|
|||
{'pool': {'application': {}}})
|
||||
_check_output.assert_called_with(['ceph', '--id', 'admin', 'osd',
|
||||
'pool', 'application', 'get'],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
utils.get_pool_applications('42')
|
||||
_check_output.assert_called_with(['ceph', '--id', 'admin', 'osd',
|
||||
'pool', 'application', 'get', '42'],
|
||||
universal_newlines=True)
|
||||
universal_newlines=True,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
@patch.object(utils, 'get_pool_erasure_profile')
|
||||
@patch.object(utils, 'get_pool_param')
|
||||
@patch.object(utils, 'get_pool_quota')
|
||||
@patch.object(utils, 'list_pools')
|
||||
@patch.object(utils, 'get_pool_applications')
|
||||
def test_list_pools_detail(self, _get_pool_applications, _list_pools,
|
||||
_get_pool_quota, _get_pool_param):
|
||||
_get_pool_quota, _get_pool_param,
|
||||
_get_pool_erasure_profile):
|
||||
self.assertEqual(utils.list_pools_detail(), {})
|
||||
_get_pool_applications.return_value = {'pool': {'application': {}}}
|
||||
_list_pools.return_value = ['pool', 'pool2']
|
||||
_get_pool_quota.return_value = {'max_objects': '10',
|
||||
'max_bytes': '1000'}
|
||||
_get_pool_param.return_value = '42'
|
||||
self.assertEqual(utils.list_pools_detail(),
|
||||
{'pool': {'applications': {'application': {}},
|
||||
'parameters': {'pg_num': '42',
|
||||
'size': '42'},
|
||||
'quota': {'max_bytes': '1000',
|
||||
'max_objects': '10'},
|
||||
},
|
||||
'pool2': {'applications': {},
|
||||
'parameters': {'pg_num': '42',
|
||||
'size': '42'},
|
||||
'quota': {'max_bytes': '1000',
|
||||
'max_objects': '10'},
|
||||
},
|
||||
})
|
||||
_get_pool_erasure_profile.return_value = 'my-ec-profile'
|
||||
self.assertEqual(
|
||||
utils.list_pools_detail(),
|
||||
{'pool': {'applications': {'application': {}},
|
||||
'parameters': {'pg_num': '42',
|
||||
'size': '42',
|
||||
'erasure_code_profile': 'my-ec-profile'},
|
||||
'quota': {'max_bytes': '1000',
|
||||
'max_objects': '10'},
|
||||
},
|
||||
'pool2': {'applications': {},
|
||||
'parameters': {'pg_num': '42',
|
||||
'size': '42',
|
||||
'erasure_code_profile': 'my-ec-profile'},
|
||||
'quota': {'max_bytes': '1000',
|
||||
'max_objects': '10'},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
class CephVolumeSizeCalculatorTestCase(unittest.TestCase):
|
||||
|
|
Loading…
Reference in New Issue