Add parse_root_device_hints to utils.py
This patch is adding a function called parse_root_device_hints to the utils.py module. This function is responsible for parsing the root device hints dictionary from the node's properties attribute. Both Ironic and Ironic Python Agent project have similar functions so adding it to ironic-lib would make it easier to share code between both projects and fix bugs in only one place. Change-Id: Ida6d20d1fdb40e50fe33ffec1c953286d4cbc2b7 Partial-Bug: #1605631
This commit is contained in:
parent
64dc8b64c7
commit
7aac631fbc
|
@ -279,3 +279,52 @@ class IsHttpUrlTestCase(test_base.BaseTestCase):
|
|||
self.assertTrue(utils.is_http_url('HTTPS://127.3.2.1'))
|
||||
self.assertFalse(utils.is_http_url('Zm9vYmFy'))
|
||||
self.assertFalse(utils.is_http_url('11111111'))
|
||||
|
||||
|
||||
class ParseRootDeviceTestCase(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ParseRootDeviceTestCase, self).setUp()
|
||||
self.root_device = {
|
||||
'wwn': '123456', 'model': 'foo-model', 'size': 12345,
|
||||
'serial': 'foo-serial', 'vendor': 'foo-vendor', 'name': '/dev/sda',
|
||||
'wwn_with_extension': '123456111', 'wwn_vendor_extension': '111',
|
||||
'rotational': True}
|
||||
|
||||
def test_parse_root_device_hints(self):
|
||||
result = utils.parse_root_device_hints(self.root_device)
|
||||
self.assertEqual(self.root_device, result)
|
||||
|
||||
def test_parse_root_device_hints_no_hints(self):
|
||||
result = utils.parse_root_device_hints({})
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_parse_root_device_hints_convert_size(self):
|
||||
result = utils.parse_root_device_hints({'size': '12345'})
|
||||
self.assertEqual({'size': 12345}, result)
|
||||
|
||||
def test_parse_root_device_hints_invalid_size(self):
|
||||
for value in ('not-int', -123, 0):
|
||||
self.assertRaises(ValueError, utils.parse_root_device_hints,
|
||||
{'size': value})
|
||||
|
||||
def _parse_root_device_hints_convert_rotational(self, values,
|
||||
expected_value):
|
||||
for value in values:
|
||||
result = utils.parse_root_device_hints({'rotational': value})
|
||||
self.assertEqual({'rotational': expected_value}, result)
|
||||
|
||||
def test_parse_root_device_hints_convert_rotational(self):
|
||||
self._parse_root_device_hints_convert_rotational(
|
||||
(True, 'true', 'on', 'y', 'yes'), True)
|
||||
|
||||
self._parse_root_device_hints_convert_rotational(
|
||||
(False, 'false', 'off', 'n', 'no'), False)
|
||||
|
||||
def test_parse_root_device_hints_invalid_rotational(self):
|
||||
self.assertRaises(ValueError, utils.parse_root_device_hints,
|
||||
{'rotational': 'not-bool'})
|
||||
|
||||
def test_parse_root_device_hints_non_existent_hint(self):
|
||||
self.assertRaises(ValueError, utils.parse_root_device_hints,
|
||||
{'non-existent': 'foo'})
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
"""Utilities and helper functions."""
|
||||
|
||||
import copy
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
|
@ -25,7 +26,9 @@ import os
|
|||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import strutils
|
||||
|
||||
from ironic_lib.common.i18n import _
|
||||
from ironic_lib.common.i18n import _LE
|
||||
from ironic_lib.common.i18n import _LW
|
||||
from ironic_lib import exception
|
||||
|
@ -43,6 +46,11 @@ CONF.register_opts(utils_opts, group='ironic_lib')
|
|||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
VALID_ROOT_DEVICE_HINTS = set(('size', 'model', 'wwn', 'serial', 'vendor',
|
||||
'wwn_with_extension', 'wwn_vendor_extension',
|
||||
'name', 'rotational'))
|
||||
|
||||
|
||||
def execute(*cmd, **kwargs):
|
||||
"""Convenience wrapper around oslo's execute() method.
|
||||
|
||||
|
@ -159,3 +167,57 @@ def is_http_url(url):
|
|||
def list_opts():
|
||||
"""Entry point for oslo-config-generator."""
|
||||
return [('ironic_lib', utils_opts)]
|
||||
|
||||
|
||||
def parse_root_device_hints(root_device):
|
||||
"""Parse the root_device property of a node.
|
||||
|
||||
Parses and validates the root_device property of a node. These are
|
||||
hints for how a node's root device is created. The 'size' hint
|
||||
should be a positive integer. The 'rotational' hint should be a
|
||||
Boolean value.
|
||||
|
||||
:param root_device: the root_device dictionary from the node's property.
|
||||
:returns: a dictionary with the root device hints parsed or
|
||||
None if there are no hints.
|
||||
:raises: ValueError, if some information is invalid.
|
||||
|
||||
"""
|
||||
if not root_device:
|
||||
return
|
||||
|
||||
root_device = copy.deepcopy(root_device)
|
||||
|
||||
invalid_hints = set(root_device) - VALID_ROOT_DEVICE_HINTS
|
||||
if invalid_hints:
|
||||
raise ValueError(
|
||||
_('The hints "%(invalid_hints)s" are invalid. '
|
||||
'Valid hints are: "%(valid_hints)s"') %
|
||||
{'invalid_hints': ', '.join(invalid_hints),
|
||||
'valid_hints': ', '.join(VALID_ROOT_DEVICE_HINTS)})
|
||||
|
||||
if 'size' in root_device:
|
||||
try:
|
||||
size = int(root_device['size'])
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
_('Root device hint "size" is not an integer value. '
|
||||
'Current value: %s') % root_device['size'])
|
||||
|
||||
if size <= 0:
|
||||
raise ValueError(
|
||||
_('Root device hint "size" should be a positive integer. '
|
||||
'Current value: %d') % size)
|
||||
|
||||
root_device['size'] = size
|
||||
|
||||
if 'rotational' in root_device:
|
||||
try:
|
||||
root_device['rotational'] = strutils.bool_from_string(
|
||||
root_device['rotational'], strict=True)
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
_('Root device hint "rotational" is not a Boolean value. '
|
||||
'Current value: %s') % root_device['rotational'])
|
||||
|
||||
return root_device
|
||||
|
|
Loading…
Reference in New Issue