Split ComputeFilter up.
Pull out compute capabilities to instance_type extra_specs into its own filter. ComputeFilter now only passes active compute nodes. Change-Id: If9b81bdd7b24faa8a27915a9e5de3e651f6ed0d0
This commit is contained in:
48
nova/scheduler/filters/compute_capabilities_filter.py
Normal file
48
nova/scheduler/filters/compute_capabilities_filter.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from nova.openstack.common import log as logging
|
||||
from nova.scheduler import filters
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ComputeCapabilitiesFilter(filters.BaseHostFilter):
|
||||
"""HostFilter hard-coded to work with InstanceType records."""
|
||||
|
||||
def _satisfies_extra_specs(self, capabilities, instance_type):
|
||||
"""Check that the capabilities provided by the compute service
|
||||
satisfy the extra specs associated with the instance type"""
|
||||
if 'extra_specs' not in instance_type:
|
||||
return True
|
||||
|
||||
# NOTE(lorinh): For now, we are just checking exact matching on the
|
||||
# values. Later on, we want to handle numerical
|
||||
# values so we can represent things like number of GPU cards
|
||||
for key, value in instance_type['extra_specs'].iteritems():
|
||||
if capabilities.get(key, None) != value:
|
||||
return False
|
||||
return True
|
||||
|
||||
def host_passes(self, host_state, filter_properties):
|
||||
"""Return a list of hosts that can create instance_type."""
|
||||
instance_type = filter_properties.get('instance_type')
|
||||
if not self._satisfies_extra_specs(host_state.capabilities,
|
||||
instance_type):
|
||||
LOG.debug(_("%(host_state)s fails instance_type extra_specs "
|
||||
"requirements"), locals())
|
||||
return False
|
||||
return True
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2011 OpenStack, LLC.
|
||||
# Copyright (c) 2012 OpenStack, LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
@@ -22,24 +22,10 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ComputeFilter(filters.BaseHostFilter):
|
||||
"""HostFilter hard-coded to work with InstanceType records."""
|
||||
|
||||
def _satisfies_extra_specs(self, capabilities, instance_type):
|
||||
"""Check that the capabilities provided by the compute service
|
||||
satisfy the extra specs associated with the instance type"""
|
||||
if 'extra_specs' not in instance_type:
|
||||
return True
|
||||
|
||||
# NOTE(lorinh): For now, we are just checking exact matching on the
|
||||
# values. Later on, we want to handle numerical
|
||||
# values so we can represent things like number of GPU cards
|
||||
for key, value in instance_type['extra_specs'].iteritems():
|
||||
if capabilities.get(key, None) != value:
|
||||
return False
|
||||
return True
|
||||
"""Filter on active Compute nodes"""
|
||||
|
||||
def host_passes(self, host_state, filter_properties):
|
||||
"""Return a list of hosts that can create instance_type."""
|
||||
"""Returns True for only active compute nodes"""
|
||||
instance_type = filter_properties.get('instance_type')
|
||||
if host_state.topic != 'compute' or not instance_type:
|
||||
return True
|
||||
@@ -51,10 +37,7 @@ class ComputeFilter(filters.BaseHostFilter):
|
||||
"heard from in a while"), locals())
|
||||
return False
|
||||
if not capabilities.get("enabled", True):
|
||||
LOG.debug(_("%(host_state)s is disabled via capabs"), locals())
|
||||
return False
|
||||
if not self._satisfies_extra_specs(capabilities, instance_type):
|
||||
LOG.debug(_("%(host_state)s fails instance_type extra_specs "
|
||||
"requirements"), locals())
|
||||
LOG.debug(_("%(host_state)s is disabled via capabilities"),
|
||||
locals())
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -46,7 +46,8 @@ host_manager_opts = [
|
||||
default=[
|
||||
'AvailabilityZoneFilter',
|
||||
'RamFilter',
|
||||
'ComputeFilter'
|
||||
'ComputeFilter',
|
||||
'ComputeCapabilitiesFilter'
|
||||
],
|
||||
help='Which filter class names to use for filtering hosts '
|
||||
'when not specified in the request.'),
|
||||
|
||||
@@ -338,6 +338,17 @@ class HostFiltersTestCase(test.TestCase):
|
||||
'service': service})
|
||||
self.assertFalse(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
def test_compute_filter_fails_on_capability_disabled(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['ComputeFilter']()
|
||||
filter_properties = {'instance_type': {'memory_mb': 1024}}
|
||||
capabilities = {'enabled': False}
|
||||
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_on_volume(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['ComputeFilter']()
|
||||
@@ -362,7 +373,7 @@ class HostFiltersTestCase(test.TestCase):
|
||||
|
||||
def test_compute_filter_passes_extra_specs(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['ComputeFilter']()
|
||||
filt_cls = self.class_map['ComputeCapabilitiesFilter']()
|
||||
extra_specs = {'opt1': 1, 'opt2': 2}
|
||||
capabilities = {'enabled': True, 'opt1': 1, 'opt2': 2}
|
||||
service = {'disabled': False}
|
||||
@@ -375,7 +386,7 @@ class HostFiltersTestCase(test.TestCase):
|
||||
|
||||
def test_compute_filter_fails_extra_specs(self):
|
||||
self._stub_service_is_up(True)
|
||||
filt_cls = self.class_map['ComputeFilter']()
|
||||
filt_cls = self.class_map['ComputeCapabilitiesFilter']()
|
||||
extra_specs = {'opt1': 1, 'opt2': 3}
|
||||
capabilities = {'enabled': True, 'opt1': 1, 'opt2': 2}
|
||||
service = {'disabled': False}
|
||||
@@ -555,7 +566,7 @@ class HostFiltersTestCase(test.TestCase):
|
||||
'service': service})
|
||||
self.assertTrue(filt_cls.host_passes(host, filter_properties))
|
||||
|
||||
# Failes due to caps disabled
|
||||
# Fails due to capabilities being disabled
|
||||
capabilities = {'enabled': False, 'opt1': 'match'}
|
||||
service = {'disabled': False}
|
||||
host = fakes.FakeHostState('host1', 'instance_type',
|
||||
|
||||
Reference in New Issue
Block a user