diff --git a/ironic_inspector/plugins/standard.py b/ironic_inspector/plugins/standard.py index 8c79ba06d..1b80a1f23 100644 --- a/ironic_inspector/plugins/standard.py +++ b/ironic_inspector/plugins/standard.py @@ -15,6 +15,7 @@ import sys +from ironic_lib import utils as il_utils import netaddr from oslo_config import cfg from oslo_utils import netutils @@ -47,41 +48,27 @@ class RootDiskSelectionHook(base.ProcessingHook): node_info=node_info, data=introspection_data) return - if 'size' in hints: - # Special case to match IPA behaviour - try: - hints['size'] = int(hints['size']) - except (TypeError, ValueError): - raise utils.Error(_('Invalid root device size hint, expected ' - 'an integer, got %s') % hints['size'], - node_info=node_info, data=introspection_data) - inventory = utils.get_inventory(introspection_data, node_info=node_info) - for disk in inventory['disks']: - properties = disk.copy() - # Root device hints are in GiB, data from IPA is in bytes - properties['size'] //= units.Gi + try: + device = il_utils.match_root_device_hints(inventory['disks'], + hints) + except (TypeError, ValueError) as e: + raise utils.Error( + _('No disks could be found using the root device hints ' + '%(hints)s because they failed to validate. ' + 'Error: %(error)s') % {'hints': hints, 'error': e}, + node_info=node_info, data=introspection_data) - for name, value in hints.items(): - actual = properties.get(name) - if actual != value: - LOG.debug('Disk %(disk)s does not satisfy hint ' - '%(name)s=%(value)s, actual value is %(actual)s', - {'disk': disk.get('name'), 'name': name, - 'value': value, 'actual': actual}, + if not device: + raise utils.Error(_('No disks satisfied root device hints'), node_info=node_info, data=introspection_data) - break - else: - LOG.debug('Disk %(disk)s of size %(size)s satisfies ' - 'root device hints', - {'disk': disk.get('name'), 'size': disk['size']}, - node_info=node_info, data=introspection_data) - introspection_data['root_disk'] = disk - return - raise utils.Error(_('No disks satisfied root device hints'), - node_info=node_info, data=introspection_data) + LOG.debug('Disk %(disk)s of size %(size)s satisfies ' + 'root device hints', + {'disk': device.get('name'), 'size': device['size']}, + node_info=node_info, data=introspection_data) + introspection_data['root_disk'] = device class SchedulerHook(base.ProcessingHook): diff --git a/ironic_inspector/test/unit/test_plugins_standard.py b/ironic_inspector/test/unit/test_plugins_standard.py index 2a32760c1..9e648db36 100644 --- a/ironic_inspector/test/unit/test_plugins_standard.py +++ b/ironic_inspector/test/unit/test_plugins_standard.py @@ -307,7 +307,7 @@ class TestRootDiskSelection(test_base.NodeTest): for bad_size in ('foo', None, {}): self.node.properties['root_device'] = {'size': bad_size} self.assertRaisesRegex(utils.Error, - 'Invalid root device size hint', + 'No disks could be found', self.hook.before_update, self.data, self.node_info) diff --git a/releasenotes/notes/ironic-lib-hints-20412a1c7fa796e0.yaml b/releasenotes/notes/ironic-lib-hints-20412a1c7fa796e0.yaml new file mode 100644 index 000000000..c94c94114 --- /dev/null +++ b/releasenotes/notes/ironic-lib-hints-20412a1c7fa796e0.yaml @@ -0,0 +1,6 @@ +--- +features: + - Adds support for using operators with the root device hints mechanism. + The supported operators are ``=``, ``==``, ``!=``, ``>=``, + ``<=``, ``>``, ``<``, ``s==``, ``s!=``, ``s>=``, ``s>``, + ``s<=``, ``s<``, ````, ```` and ````. diff --git a/requirements.txt b/requirements.txt index ec6df772a..ce7ac577b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,6 +7,7 @@ Babel>=2.3.4 # BSD eventlet!=0.18.3,>=0.18.2 # MIT Flask!=0.11,<1.0,>=0.10 # BSD futurist!=0.15.0,>=0.11.0 # Apache-2.0 +ironic-lib>=2.2.0 # Apache-2.0 jsonpath-rw<2.0,>=1.2.0 # Apache-2.0 jsonschema!=2.5.0,<3.0.0,>=2.0.0 # MIT keystoneauth1>=2.16.0 # Apache-2.0