Merge "Make ComputeFilter verify compute-related instance properties"

This commit is contained in:
Jenkins
2012-08-16 00:47:57 +00:00
committed by Gerrit Code Review
2 changed files with 155 additions and 2 deletions

View File

@@ -22,10 +22,59 @@ LOG = logging.getLogger(__name__)
class ComputeFilter(filters.BaseHostFilter):
"""Filter on active Compute nodes"""
"""Filter on active Compute nodes that satisfy the instance properties"""
def _instance_supported(self, capabilities, instance_meta):
"""Check if the instance is supported by the hypervisor.
The instance may specify an architecture, hypervisor, and
vm_mode, e.g. (x86_64, kvm, hvm).
"""
inst_arch = instance_meta.get('image_architecture', None)
inst_h_type = instance_meta.get('image_hypervisor_type', None)
inst_vm_mode = instance_meta.get('image_vm_mode', None)
inst_props_req = (inst_arch, inst_h_type, inst_vm_mode)
# Supported if no compute-related instance properties are specified
if not any(inst_props_req):
return True
supp_instances = capabilities.get('supported_instances', None)
# Not supported if an instance property is requested but nothing
# advertised by the host.
if not supp_instances:
LOG.debug(_("Instance contains properties %(instance_meta)s, "
"but no corresponding capabilities are advertised "
"by the compute node"), locals())
return False
def _compare_props(props, other_props):
for i in props:
if i and i not in other_props:
return False
return True
for supp_inst in supp_instances:
if _compare_props(inst_props_req, supp_inst):
LOG.debug(_("Instance properties %(instance_meta)s "
"are satisfied by compute host capabilities "
"%(capabilities)s"), locals())
return True
LOG.debug(_("Instance contains properties %(instance_meta)s "
"that are not provided by the compute node "
"capabilities %(capabilities)s"), locals())
return False
def host_passes(self, host_state, filter_properties):
"""Returns True for only active compute nodes"""
"""Check if host passes instance compute properties.
Returns True for active compute nodes that satisfy
the compute properties specified in the instance.
"""
spec = filter_properties.get('request_spec', {})
instance_props = spec.get('instance_properties', {})
instance_meta = instance_props.get('system_metadata', {})
instance_type = filter_properties.get('instance_type')
if host_state.topic != 'compute' or not instance_type:
return True
@@ -40,4 +89,8 @@ class ComputeFilter(filters.BaseHostFilter):
LOG.debug(_("%(host_state)s is disabled via capabilities"),
locals())
return False
if not self._instance_supported(capabilities, instance_meta):
LOG.debug(_("%(host_state)s does not support requested "
"instance_properties"), locals())
return False
return True

View File

@@ -394,6 +394,106 @@ class HostFiltersTestCase(test.TestCase):
'service': service})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_passes_same_inst_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
inst_meta = {'system_metadata': {'image_architecture': 'x86_64',
'image_hypervisor_type': 'kvm',
'image_vm_mode': 'hvm'}}
req_spec = {'instance_properties': inst_meta}
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': req_spec}
capabilities = {'enabled': True,
'supported_instances': [
('x86_64', 'kvm', 'hvm')]}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_fails_different_inst_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
inst_meta = {'system_metadata': {'image_architecture': 'arm',
'image_hypervisor_type': 'qemu',
'image_vm_mode': 'hvm'}}
req_spec = {'instance_properties': inst_meta}
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': req_spec}
capabilities = {'enabled': True,
'supported_instances': [
('x86_64', 'kvm', 'hvm')]}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_passes_partial_inst_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
inst_meta = {'system_metadata': {'image_architecture': 'x86_64',
'image_vm_mode': 'hvm'}}
req_spec = {'instance_properties': inst_meta}
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': req_spec}
capabilities = {'enabled': True,
'supported_instances': [
('x86_64', 'kvm', 'hvm')]}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_fails_partial_inst_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
inst_meta = {'system_metadata': {'image_architecture': 'x86_64',
'image_vm_mode': 'hvm'}}
req_spec = {'instance_properties': inst_meta}
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': req_spec}
capabilities = {'enabled': True,
'supported_instances': [
('x86_64', 'xen', 'xen')]}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_passes_without_inst_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': {}}
capabilities = {'enabled': True,
'supported_instances': [
('x86_64', 'kvm', 'hvm')]}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertTrue(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_fails_without_host_props(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeFilter']()
inst_meta = {'system_metadata': {'image_architecture': 'x86_64',
'image_hypervisor_type': 'kvm',
'image_vm_mode': 'hvm'}}
req_spec = {'instance_properties': inst_meta}
filter_properties = {'instance_type': {'memory_mb': 1024},
'request_spec': req_spec}
capabilities = {'enabled': True}
service = {'disabled': False}
host = fakes.FakeHostState('host1', 'compute',
{'free_ram_mb': 1024, 'capabilities': capabilities,
'service': service})
self.assertFalse(filt_cls.host_passes(host, filter_properties))
def test_compute_filter_passes_extra_specs_noop(self):
self._stub_service_is_up(True)
filt_cls = self.class_map['ComputeCapabilitiesFilter']()