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 <jfeh...@suse.com> 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
_______________________________________________ Mailing list: https://launchpad.net/~openstack Post to : openstack@lists.launchpad.net Unsubscribe : https://launchpad.net/~openstack More help : https://help.launchpad.net/ListHelp