Merge "Ironic: Parse and validate Node's properties"

This commit is contained in:
Jenkins 2015-06-09 20:15:23 +00:00 committed by Gerrit Code Review
commit 2b401636c4
2 changed files with 93 additions and 9 deletions

View File

@ -70,7 +70,8 @@ def _get_properties():
return {'cpus': 2,
'memory_mb': 512,
'local_gb': 10,
'cpu_arch': 'x86_64'}
'cpu_arch': 'x86_64',
'capabilities': None}
def _get_stats():
@ -377,6 +378,65 @@ class IronicDriverTestCase(test.NoDBTestCase):
self.assertEqual(node_uuid, result['hypervisor_hostname'])
self.assertEqual(stats, jsonutils.loads(result['stats']))
@mock.patch.object(ironic_driver.LOG, 'warning')
def test__parse_node_properties(self, mock_warning):
props = _get_properties()
node = ironic_utils.get_test_node(
uuid=uuidutils.generate_uuid(),
properties=props)
# raw_cpu_arch is included because extra_specs filters do not
# canonicalized the arch
props['raw_cpu_arch'] = props['cpu_arch']
parsed = self.driver._parse_node_properties(node)
self.assertEqual(props, parsed)
# Assert we didn't log any warning since all properties are
# correct
self.assertFalse(mock_warning.called)
@mock.patch.object(ironic_driver.LOG, 'warning')
def test__parse_node_properties_bad_values(self, mock_warning):
props = _get_properties()
props['cpus'] = 'bad-value'
props['memory_mb'] = 'bad-value'
props['local_gb'] = 'bad-value'
props['cpu_arch'] = 'bad-value'
node = ironic_utils.get_test_node(
uuid=uuidutils.generate_uuid(),
properties=props)
# raw_cpu_arch is included because extra_specs filters do not
# canonicalized the arch
props['raw_cpu_arch'] = props['cpu_arch']
parsed = self.driver._parse_node_properties(node)
expected_props = props.copy()
expected_props['cpus'] = 0
expected_props['memory_mb'] = 0
expected_props['local_gb'] = 0
expected_props['cpu_arch'] = None
self.assertEqual(expected_props, parsed)
self.assertEqual(4, mock_warning.call_count)
@mock.patch.object(ironic_driver.LOG, 'warning')
def test__parse_node_properties_canonicalize_cpu_arch(self, mock_warning):
props = _get_properties()
props['cpu_arch'] = 'amd64'
node = ironic_utils.get_test_node(
uuid=uuidutils.generate_uuid(),
properties=props)
# raw_cpu_arch is included because extra_specs filters do not
# canonicalized the arch
props['raw_cpu_arch'] = props['cpu_arch']
parsed = self.driver._parse_node_properties(node)
expected_props = props.copy()
# Make sure it cpu_arch was canonicalized
expected_props['cpu_arch'] = 'x86_64'
self.assertEqual(expected_props, parsed)
# Assert we didn't log any warning since all properties are
# correct
self.assertFalse(mock_warning.called)
@mock.patch.object(firewall.NoopFirewallDriver, 'prepare_instance_filter',
create=True)
@mock.patch.object(firewall.NoopFirewallDriver, 'setup_basic_filtering',

View File

@ -230,11 +230,19 @@ class IronicDriver(virt_driver.ComputeDriver):
"""
return node_obj.instance_uuid is not None
def _node_resource(self, node):
"""Helper method to create resource dict from node stats."""
vcpus = int(node.properties.get('cpus', 0))
memory_mb = int(node.properties.get('memory_mb', 0))
local_gb = int(node.properties.get('local_gb', 0))
def _parse_node_properties(self, node):
"""Helper method to parse the node's properties."""
properties = {}
for prop in ('cpus', 'memory_mb', 'local_gb'):
try:
properties[prop] = int(node.properties.get(prop, 0))
except (TypeError, ValueError):
LOG.warning(_LW('Node %(uuid)s has a malformed "%(prop)s". '
'It should be an integer.'),
{'uuid': node.uuid, 'prop': prop})
properties[prop] = 0
raw_cpu_arch = node.properties.get('cpu_arch', None)
try:
cpu_arch = arch.canonicalize(raw_cpu_arch)
@ -243,6 +251,21 @@ class IronicDriver(virt_driver.ComputeDriver):
if not cpu_arch:
LOG.warning(_LW("cpu_arch not defined for node '%s'"), node.uuid)
properties['cpu_arch'] = cpu_arch
properties['raw_cpu_arch'] = raw_cpu_arch
properties['capabilities'] = node.properties.get('capabilities')
return properties
def _node_resource(self, node):
"""Helper method to create resource dict from node stats."""
properties = self._parse_node_properties(node)
vcpus = properties['cpus']
memory_mb = properties['memory_mb']
local_gb = properties['local_gb']
raw_cpu_arch = properties['raw_cpu_arch']
cpu_arch = properties['cpu_arch']
nodes_extra_specs = {}
# NOTE(deva): In Havana and Icehouse, the flavor was required to link
@ -262,7 +285,7 @@ class IronicDriver(virt_driver.ComputeDriver):
# to be of the form "k1:v1,k2:v2,etc.." which we add directly as
# key/value pairs into the node_extra_specs to be used by the
# ComputeCapabilitiesFilter
capabilities = node.properties.get('capabilities')
capabilities = properties['capabilities']
if capabilities:
for capability in str(capabilities).split(','):
parts = capability.split(':')
@ -562,14 +585,15 @@ class IronicDriver(virt_driver.ComputeDriver):
return hardware.InstanceInfo(
state=map_power_state(ironic_states.NOSTATE))
memory_kib = int(node.properties.get('memory_mb', 0)) * 1024
properties = self._parse_node_properties(node)
memory_kib = properties['memory_mb'] * 1024
if memory_kib == 0:
LOG.warning(_LW("Warning, memory usage is 0 for "
"%(instance)s on baremetal node %(node)s."),
{'instance': instance.uuid,
'node': instance.node})
num_cpu = node.properties.get('cpus', 0)
num_cpu = properties['cpus']
if num_cpu == 0:
LOG.warning(_LW("Warning, number of cpus is 0 for "
"%(instance)s on baremetal node %(node)s."),