Fix broken <range-in> in root device hints
Closes-Bug: #2117514 Change-Id: I3747230c788def8a484b7c65ab60b998b3661ae9 Signed-off-by: Dmitry Tantsur <dtantsur@protonmail.com> Signed-off-by: Riccardo Pittau <elfosardo@gmail.com>
This commit is contained in:

committed by
Riccardo Pittau

parent
77bd8c988d
commit
322a10dcfb
@@ -15,7 +15,11 @@ which disk it should pick for the deployment. The list of supported hints is:
|
|||||||
provided to the operating system which do not match or align to physical
|
provided to the operating system which do not match or align to physical
|
||||||
disks in a system.
|
disks in a system.
|
||||||
|
|
||||||
* size (INT): size of the device in GiB
|
* size (INT or range): size of the device in GiB or range boundaries in GiB
|
||||||
|
size accepts a single int value representing the size of the device in
|
||||||
|
GiB, or a range of two values representing the lower and higher acceptable
|
||||||
|
sizes in GiB for the device using the special operator <range-in>, e.g.
|
||||||
|
size: <range-in> ( 10 100 )
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
A node's 'local_gb' property is often set to a value 1 GiB less than the
|
A node's 'local_gb' property is often set to a value 1 GiB less than the
|
||||||
@@ -103,6 +107,8 @@ and ``s==`` (for string values). The supported operators are:
|
|||||||
|
|
||||||
* ``<all-in>`` all elements contained in collection
|
* ``<all-in>`` all elements contained in collection
|
||||||
* ``<or>`` find one of these
|
* ``<or>`` find one of these
|
||||||
|
* ``<range-in>`` range boundaries in GiB, boundary condition could be
|
||||||
|
inclusive \'[\' or exclusive \'(\'.
|
||||||
|
|
||||||
Examples are:
|
Examples are:
|
||||||
|
|
||||||
|
@@ -953,7 +953,12 @@ def parse_root_device_hints(root_device):
|
|||||||
|
|
||||||
for name, expression in root_device.items():
|
for name, expression in root_device.items():
|
||||||
hint_type = VALID_ROOT_DEVICE_HINTS[name]
|
hint_type = VALID_ROOT_DEVICE_HINTS[name]
|
||||||
if hint_type is str:
|
hint_info = _extract_hint_operator_and_values(expression,
|
||||||
|
name)
|
||||||
|
operator = hint_info['op']
|
||||||
|
if name == 'size' and operator == '<range-in>':
|
||||||
|
pass
|
||||||
|
elif hint_type is str:
|
||||||
if not isinstance(expression, str):
|
if not isinstance(expression, str):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
_('Root device hint "%(name)s" is not a string value. '
|
_('Root device hint "%(name)s" is not a string value. '
|
||||||
@@ -1049,6 +1054,8 @@ def find_devices_by_hints(devices, root_device_hints):
|
|||||||
# Since we don't support units yet we expect the size
|
# Since we don't support units yet we expect the size
|
||||||
# in GiB for now
|
# in GiB for now
|
||||||
device_value = device_value / units.Gi
|
device_value = device_value / units.Gi
|
||||||
|
if hint_value.startswith('<range-in>'):
|
||||||
|
device_value = str(device_value)
|
||||||
|
|
||||||
LOG.debug('Trying to match the device hint "%(hint)s" '
|
LOG.debug('Trying to match the device hint "%(hint)s" '
|
||||||
'with a value of "%(hint_value)s" against the same '
|
'with a value of "%(hint_value)s" against the same '
|
||||||
|
@@ -910,6 +910,12 @@ class ParseRootDeviceTestCase(base.TestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
expected, utils._extract_hint_operator_and_values(123, 'size'))
|
expected, utils._extract_hint_operator_and_values(123, 'size'))
|
||||||
|
|
||||||
|
def test_extract_hint_operator_and_values_range_in(self):
|
||||||
|
expected = {'op': '<range-in>', 'values': ['( 100 200 )']}
|
||||||
|
self.assertEqual(
|
||||||
|
expected, utils._extract_hint_operator_and_values(
|
||||||
|
'<range-in> ( 100 200 )', 'size'))
|
||||||
|
|
||||||
def test__append_operator_to_hints(self):
|
def test__append_operator_to_hints(self):
|
||||||
root_device = {'serial': 'foo', 'size': 12345,
|
root_device = {'serial': 'foo', 'size': 12345,
|
||||||
'model': 'foo model', 'rotational': True}
|
'model': 'foo model', 'rotational': True}
|
||||||
@@ -978,6 +984,11 @@ class MatchRootDeviceTestCase(base.TestCase):
|
|||||||
dev = utils.match_root_device_hints(self.devices, root_device_hints)
|
dev = utils.match_root_device_hints(self.devices, root_device_hints)
|
||||||
self.assertEqual('/dev/sdb', dev['name'])
|
self.assertEqual('/dev/sdb', dev['name'])
|
||||||
|
|
||||||
|
def test_match_root_device_hints_range_in(self):
|
||||||
|
root_device_hints = {'size': '<range-in> ( 10 100 )'}
|
||||||
|
dev = utils.match_root_device_hints(self.devices, root_device_hints)
|
||||||
|
self.assertEqual('/dev/sda', dev['name'])
|
||||||
|
|
||||||
def test_match_root_device_hints_rotational(self):
|
def test_match_root_device_hints_rotational(self):
|
||||||
root_device_hints = {'rotational': False}
|
root_device_hints = {'rotational': False}
|
||||||
dev = utils.match_root_device_hints(self.devices, root_device_hints)
|
dev = utils.match_root_device_hints(self.devices, root_device_hints)
|
||||||
|
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
Fixes an issue with <range in> operator in root device hint. Now it's
|
||||||
|
possible to use the range operator correctly, specifying a two values
|
||||||
|
range that includes the size of the root device in GiB.
|
Reference in New Issue
Block a user