openstack team mailing list archive
-
openstack team
-
Mailing list archive
-
Message #13652
[nova] RFC - filtering compute nodes in a mixed environment
In a previous thread [1], I mentioned two possibilities for controlling
the scheduling of instances to an appropriate compute node in a mixed
node (Xen, KVM) environment. The first approach uses availability
zones, the second uses the existing vm_mode image property. Folks
seemed to agree on the latter, and the attached patch adds a check to
the compute filter to ensure the compute node can accommodate the
instance type.
The compute filter seems like the right place to add this check, but
posting as a RFC since I'm not sure if this would be agreeable to
everyone as compared to a custom filter for example.
Regards,
Jim
[1]
http://openstack.markmail.org/search/?q=improve%20xen#query:improve%20xen+page:1+mid:knmnylknf2imnruy+state:results
>From bb8777a415d5db22b83971357882261fbef092a9 Mon Sep 17 00:00:00 2001
From: Jim Fehlig <jfehlig@xxxxxxxx>
Date: Mon, 25 Jun 2012 15:54:43 -0600
Subject: [PATCH] Add check for vm_mode in compute filter
Add a check in the scheduler compute filter to see if the compute service
supports the vm_mode specified in the instance properties.
As mentioned in a previous thread [1], there needs to be a way to control
scheduling of instances to an appropriate node in a mixed compute node
environment. The existing vm_mode property, in conjuction with the
additional_compute_capabilities flag, provides a mechanism to filter
appropriate nodes.
[1] http://openstack.markmail.org/search/?q=improve%20xen#query:improve%20xen+page:1+mid:knmnylknf2imnruy+state:results
---
nova/scheduler/filters/compute_filter.py | 20 +++++++++++++++++++-
nova/tests/scheduler/test_host_filters.py | 26 ++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/nova/scheduler/filters/compute_filter.py b/nova/scheduler/filters/compute_filter.py
index 5409d3d..5187c39 100644
--- a/nova/scheduler/filters/compute_filter.py
+++ b/nova/scheduler/filters/compute_filter.py
@@ -22,7 +22,8 @@ LOG = logging.getLogger(__name__)
class ComputeFilter(filters.BaseHostFilter):
- """HostFilter hard-coded to work with InstanceType records."""
+ """HostFilter hard-coded to work with InstanceType and
+ InstanceProperties records."""
def _satisfies_extra_specs(self, capabilities, instance_type):
"""Check that the capabilities provided by the compute service
@@ -38,8 +39,21 @@ class ComputeFilter(filters.BaseHostFilter):
return False
return True
+ def _satisfies_capabilities(self, capabilities, instance_props):
+ """Check that the capabilities provided by the compute service
+ satisfies properties defined in the instance."""
+ vm_mode = instance_props.get('vm_mode')
+ if not vm_mode:
+ return True
+ if capabilities.get(vm_mode, None):
+ return True
+ else:
+ return False
+
def host_passes(self, host_state, filter_properties):
"""Return a list of hosts that can create instance_type."""
+ spec = filter_properties.get('request_spec', {})
+ instance_props = spec.get('instance_properties', {})
instance_type = filter_properties.get('instance_type')
if host_state.topic != 'compute' or not instance_type:
return True
@@ -57,4 +71,8 @@ class ComputeFilter(filters.BaseHostFilter):
LOG.debug(_("%(host_state)s fails instance_type extra_specs "
"requirements"), locals())
return False
+ if not self._satisfies_capabilities(capabilities, instance_props):
+ LOG.debug(_("%(host_state)s fails instance_properties "
+ "requirements"), locals())
+ return False
return True
diff --git a/nova/tests/scheduler/test_host_filters.py b/nova/tests/scheduler/test_host_filters.py
index 80da5ac..3a99292 100644
--- a/nova/tests/scheduler/test_host_filters.py
+++ b/nova/tests/scheduler/test_host_filters.py
@@ -349,6 +349,32 @@ class HostFiltersTestCase(test.TestCase):
self.assertFalse(filt_cls.host_passes(host, filter_properties))
+ def test_compute_filter_passes_additional_caps(self):
+ self._stub_service_is_up(True)
+ filt_cls = self.class_map['ComputeFilter']()
+ req_spec = {'instance_properties': {'vm_mode': 'pv'}}
+ capabilities = {'enabled': True, 'pv': True, 'hvm': True}
+ service = {'disabled': False}
+ filter_properties = {'instance_type': {'memory_mb': 1024},
+ 'request_spec' : req_spec}
+ 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_additional_caps(self):
+ self._stub_service_is_up(True)
+ filt_cls = self.class_map['ComputeFilter']()
+ req_spec = {'instance_properties': {'vm_mode': 'pv'}}
+ capabilities = {'enabled': True}
+ service = {'disabled': False}
+ filter_properties = {'instance_type': {'memory_mb': 1024},
+ 'request_spec': req_spec}
+ host = fakes.FakeHostState('host1', 'compute',
+ {'free_ram_mb': 1024, 'capabilities': capabilities,
+ 'service': service})
+ self.assertFalse(filt_cls.host_passes(host, filter_properties))
+
def test_isolated_hosts_fails_isolated_on_non_isolated(self):
self.flags(isolated_images=['isolated'], isolated_hosts=['isolated'])
filt_cls = self.class_map['IsolatedHostsFilter']()
--
1.7.9.2