Merge "Send traits to ironic on server boot"

This commit is contained in:
Zuul 2018-01-28 09:24:27 +00:00 committed by Gerrit Code Review
commit 717088d825
2 changed files with 52 additions and 13 deletions

View File

@ -115,6 +115,36 @@ class IronicDriverFieldsTestCase(test.NoDBTestCase):
self.instance, self.image_meta, self.flavor)
self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits(self):
node = ironic_utils.get_test_node(driver='fake')
self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'required'
expected = [{'path': '/instance_info/traits',
'value': '["CUSTOM_FOO"]',
'op': 'add'}]
expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor)
self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits_granular(self):
node = ironic_utils.get_test_node(driver='fake')
self.flavor['extra_specs']['trait1:CUSTOM_FOO'] = 'required'
expected = [{'path': '/instance_info/traits',
'value': '["CUSTOM_FOO"]',
'op': 'add'}]
expected += self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor)
self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_traits_ignores_not_required(self):
node = ironic_utils.get_test_node(driver='fake')
self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'invalid'
expected = self._expected_deploy_patch
patch = patcher.create(node).get_deploy_patch(
self.instance, self.image_meta, self.flavor)
self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_ephemeral(self):
CONF.set_override('default_ephemeral_format', 'testfmt')
node = ironic_utils.get_test_node(driver='fake')

View File

@ -86,26 +86,35 @@ class GenericDriverFields(object):
patch.append({'path': '/instance_info/preserve_ephemeral',
'op': 'add', 'value': str(preserve_ephemeral)})
capabilities = {}
# read the flavor and get the extra_specs value.
extra_specs = flavor.get('extra_specs')
# scan through the extra_specs values and ignore the keys
# not starting with keyword 'capabilities'.
# not starting with keyword 'capabilities' and 'trait'
capabilities = {}
traits = []
for key, val in extra_specs.items():
if not key.startswith('capabilities:'):
continue
# split the extra_spec key to remove the keyword
# 'capabilities' and get the actual key.
capabilities_string, capabilities_key = key.split(':', 1)
if capabilities_key:
capabilities[capabilities_key] = val
# NOTE(mgoddard): For traits we need to support granular resource
# request syntax, where the 'trait' prefix may be followed by a
# numeric suffix: trait$N. For ironic we do not care about the
# group number.
if key.startswith('capabilities:') or key.startswith('trait'):
# get the actual key.
prefix, parsed_key = key.split(':', 1)
if prefix == "capabilities":
capabilities[parsed_key] = val
else:
# NOTE(mgoddard): Currently, the value must be 'required'.
# We do not need to pass the value to ironic. When the
# value can be something other than 'required', we may need
# to filter out traits not supported by the node.
if val == 'required':
traits.append(parsed_key)
if capabilities:
patch.append({'path': '/instance_info/capabilities',
'op': 'add', 'value': jsonutils.dumps(capabilities)})
if traits:
patch.append({'path': '/instance_info/traits',
'op': 'add', 'value': jsonutils.dumps(traits)})
return patch