get rid of all mention of drivers ... it's filter only now

This commit is contained in:
Sandy Walsh
2011-05-23 10:39:50 -07:00
parent 1745a83419
commit dae711ffc7
3 changed files with 75 additions and 78 deletions

View File

@@ -465,9 +465,8 @@ class ZoneNotFound(NotFound):
message = _("Zone %(zone_id)s could not be found.") message = _("Zone %(zone_id)s could not be found.")
class SchedulerHostFilterDriverNotFound(NotFound): class SchedulerHostFilterNotFound(NotFound):
message = _("Scheduler Host Filter Driver %(driver_name)s could" message = _("Scheduler Host Filter %(filter_name)s could not be found.")
" not be found.")
class InstanceMetadataNotFound(NotFound): class InstanceMetadataNotFound(NotFound):

View File

@@ -14,8 +14,8 @@
# under the License. # under the License.
""" """
Host Filter is a driver mechanism for requesting instance resources. Host Filter is a mechanism for requesting instance resources.
Three drivers are included: AllHosts, Flavor & JSON. AllHosts just Three filters are included: AllHosts, Flavor & JSON. AllHosts just
returns the full, unfiltered list of hosts. Flavor is a hard coded returns the full, unfiltered list of hosts. Flavor is a hard coded
matching mechanism based on flavor criteria and JSON is an ad-hoc matching mechanism based on flavor criteria and JSON is an ad-hoc
filter grammar. filter grammar.
@@ -47,13 +47,13 @@ from nova.scheduler import zone_aware_scheduler
LOG = logging.getLogger('nova.scheduler.host_filter') LOG = logging.getLogger('nova.scheduler.host_filter')
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
flags.DEFINE_string('default_host_filter_driver', flags.DEFINE_string('default_host_filter',
'nova.scheduler.host_filter.AllHostsFilter', 'nova.scheduler.host_filter.AllHostsFilter',
'Which driver to use for filtering hosts.') 'Which filter to use for filtering hosts.')
class HostFilter(object): class HostFilter(object):
"""Base class for host filter drivers.""" """Base class for host filters."""
def instance_type_to_filter(self, instance_type): def instance_type_to_filter(self, instance_type):
"""Convert instance_type into a filter for most common use-case.""" """Convert instance_type into a filter for most common use-case."""
@@ -64,12 +64,12 @@ class HostFilter(object):
raise NotImplementedError() raise NotImplementedError()
def _full_name(self): def _full_name(self):
"""module.classname of the filter driver""" """module.classname of the filter."""
return "%s.%s" % (self.__module__, self.__class__.__name__) return "%s.%s" % (self.__module__, self.__class__.__name__)
class AllHostsFilter(HostFilter): class AllHostsFilter(HostFilter):
"""NOP host filter driver. Returns all hosts in ZoneManager. """NOP host filter. Returns all hosts in ZoneManager.
This essentially does what the old Scheduler+Chance used This essentially does what the old Scheduler+Chance used
to give us.""" to give us."""
@@ -85,7 +85,7 @@ class AllHostsFilter(HostFilter):
class InstanceTypeFilter(HostFilter): class InstanceTypeFilter(HostFilter):
"""HostFilter driver hard-coded to work with InstanceType records.""" """HostFilter hard-coded to work with InstanceType records."""
def instance_type_to_filter(self, instance_type): def instance_type_to_filter(self, instance_type):
"""Use instance_type to filter hosts.""" """Use instance_type to filter hosts."""
@@ -133,7 +133,7 @@ class InstanceTypeFilter(HostFilter):
class JsonFilter(HostFilter): class JsonFilter(HostFilter):
"""Host Filter driver to allow simple JSON-based grammar for """Host Filter to allow simple JSON-based grammar for
selecting hosts.""" selecting hosts."""
def _equals(self, args): def _equals(self, args):
@@ -273,43 +273,44 @@ class JsonFilter(HostFilter):
return hosts return hosts
DRIVERS = [AllHostsFilter, InstanceTypeFilter, JsonFilter] FILTERS = [AllHostsFilter, InstanceTypeFilter, JsonFilter]
def choose_driver(driver_name=None): def choose_host_filter(filter_name=None):
"""Since the caller may specify which driver to use we need """Since the caller may specify which filter to use we need
to have an authoritative list of what is permissible. This to have an authoritative list of what is permissible. This
function checks the driver name against a predefined set function checks the filter name against a predefined set
of acceptable drivers.""" of acceptable filters."""
if not driver_name: if not filter_name:
driver_name = FLAGS.default_host_filter_driver filter_name = FLAGS.default_host_filter
for driver in DRIVERS: for filter_class in FILTERS:
if "%s.%s" % (driver.__module__, driver.__name__) == driver_name: if "%s.%s" % (filter_class.__module__, filter_class.__name__) == \
return driver() filter_name:
raise exception.SchedulerHostFilterDriverNotFound(driver_name=driver_name) return filter_class()
raise exception.SchedulerHostFilterNotFound(filter_name=filter_name)
class HostFilterScheduler(zone_aware_scheduler.ZoneAwareScheduler): class HostFilterScheduler(zone_aware_scheduler.ZoneAwareScheduler):
"""The HostFilterScheduler uses the HostFilter drivers to filter """The HostFilterScheduler uses the HostFilter to filter
hosts for weighing. The particular driver used may be passed in hosts for weighing. The particular filter used may be passed in
as an argument or the default will be used. as an argument or the default will be used.
request_spec = {'filter_driver': <Filter Driver name>, request_spec = {'filter_name': <Filter name>,
'instance_type': <InstanceType dict>} 'instance_type': <InstanceType dict>}
""" """
def filter_hosts(self, num, request_spec): def filter_hosts(self, num, request_spec):
"""Filter the full host list (from the ZoneManager)""" """Filter the full host list (from the ZoneManager)"""
driver_name = request_spec.get('filter_driver', None) filter_name = request_spec.get('filter_name', None)
driver = choose_driver(driver_name) host_filter = choose_host_filter(filter_name)
# TODO(sandy): We're only using InstanceType-based specs # TODO(sandy): We're only using InstanceType-based specs
# currently. Later we'll need to snoop for more detailed # currently. Later we'll need to snoop for more detailed
# host filter requests. # host filter requests.
instance_type = request_spec['instance_type'] instance_type = request_spec['instance_type']
name, query = driver.instance_type_to_filter(instance_type) name, query = host_filter.instance_type_to_filter(instance_type)
return driver.filter_hosts(self.zone_manager, query) return host_filter.filter_hosts(self.zone_manager, query)
def weigh_hosts(self, num, request_spec, hosts): def weigh_hosts(self, num, request_spec, hosts):
"""Derived classes must override this method and return """Derived classes must override this method and return

View File

@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
""" """
Tests For Scheduler Host Filter Drivers. Tests For Scheduler Host Filters.
""" """
import json import json
@@ -31,7 +31,7 @@ class FakeZoneManager:
class HostFilterTestCase(test.TestCase): class HostFilterTestCase(test.TestCase):
"""Test case for host filter drivers.""" """Test case for host filters."""
def _host_caps(self, multiplier): def _host_caps(self, multiplier):
# Returns host capabilities in the following way: # Returns host capabilities in the following way:
@@ -57,8 +57,8 @@ class HostFilterTestCase(test.TestCase):
'host_name-label': 'xs-%s' % multiplier} 'host_name-label': 'xs-%s' % multiplier}
def setUp(self): def setUp(self):
self.old_flag = FLAGS.default_host_filter_driver self.old_flag = FLAGS.default_host_filter
FLAGS.default_host_filter_driver = \ FLAGS.default_host_filter = \
'nova.scheduler.host_filter.AllHostsFilter' 'nova.scheduler.host_filter.AllHostsFilter'
self.instance_type = dict(name='tiny', self.instance_type = dict(name='tiny',
memory_mb=50, memory_mb=50,
@@ -76,52 +76,52 @@ class HostFilterTestCase(test.TestCase):
self.zone_manager.service_states = states self.zone_manager.service_states = states
def tearDown(self): def tearDown(self):
FLAGS.default_host_filter_driver = self.old_flag FLAGS.default_host_filter = self.old_flag
def test_choose_driver(self): def test_choose_filter(self):
# Test default driver ... # Test default filter ...
driver = host_filter.choose_driver() hf = host_filter.choose_host_filter()
self.assertEquals(driver._full_name(), self.assertEquals(hf._full_name(),
'nova.scheduler.host_filter.AllHostsFilter') 'nova.scheduler.host_filter.AllHostsFilter')
# Test valid driver ... # Test valid filter ...
driver = host_filter.choose_driver( hf = host_filter.choose_host_filter(
'nova.scheduler.host_filter.InstanceTypeFilter') 'nova.scheduler.host_filter.InstanceTypeFilter')
self.assertEquals(driver._full_name(), self.assertEquals(hf._full_name(),
'nova.scheduler.host_filter.InstanceTypeFilter') 'nova.scheduler.host_filter.InstanceTypeFilter')
# Test invalid driver ... # Test invalid filter ...
try: try:
host_filter.choose_driver('does not exist') host_filter.choose_host_filter('does not exist')
self.fail("Should not find driver") self.fail("Should not find host filter.")
except exception.SchedulerHostFilterDriverNotFound: except exception.SchedulerHostFilterNotFound:
pass pass
def test_all_host_driver(self): def test_all_host_filter(self):
driver = host_filter.AllHostsFilter() hf = host_filter.AllHostsFilter()
cooked = driver.instance_type_to_filter(self.instance_type) cooked = hf.instance_type_to_filter(self.instance_type)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(10, len(hosts)) self.assertEquals(10, len(hosts))
for host, capabilities in hosts: for host, capabilities in hosts:
self.assertTrue(host.startswith('host')) self.assertTrue(host.startswith('host'))
def test_instance_type_driver(self): def test_instance_type_filter(self):
driver = host_filter.InstanceTypeFilter() hf = host_filter.InstanceTypeFilter()
# filter all hosts that can support 50 ram and 500 disk # filter all hosts that can support 50 ram and 500 disk
name, cooked = driver.instance_type_to_filter(self.instance_type) name, cooked = hf.instance_type_to_filter(self.instance_type)
self.assertEquals('nova.scheduler.host_filter.InstanceTypeFilter', self.assertEquals('nova.scheduler.host_filter.InstanceTypeFilter',
name) name)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(6, len(hosts)) self.assertEquals(6, len(hosts))
just_hosts = [host for host, caps in hosts] just_hosts = [host for host, caps in hosts]
just_hosts.sort() just_hosts.sort()
self.assertEquals('host05', just_hosts[0]) self.assertEquals('host05', just_hosts[0])
self.assertEquals('host10', just_hosts[5]) self.assertEquals('host10', just_hosts[5])
def test_json_driver(self): def test_json_filter(self):
driver = host_filter.JsonFilter() hf = host_filter.JsonFilter()
# filter all hosts that can support 50 ram and 500 disk # filter all hosts that can support 50 ram and 500 disk
name, cooked = driver.instance_type_to_filter(self.instance_type) name, cooked = hf.instance_type_to_filter(self.instance_type)
self.assertEquals('nova.scheduler.host_filter.JsonFilter', name) self.assertEquals('nova.scheduler.host_filter.JsonFilter', name)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(6, len(hosts)) self.assertEquals(6, len(hosts))
just_hosts = [host for host, caps in hosts] just_hosts = [host for host, caps in hosts]
just_hosts.sort() just_hosts.sort()
@@ -141,7 +141,7 @@ class HostFilterTestCase(test.TestCase):
] ]
] ]
cooked = json.dumps(raw) cooked = json.dumps(raw)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(5, len(hosts)) self.assertEquals(5, len(hosts))
just_hosts = [host for host, caps in hosts] just_hosts = [host for host, caps in hosts]
@@ -153,7 +153,7 @@ class HostFilterTestCase(test.TestCase):
['=', '$compute.host_memory_free', 30], ['=', '$compute.host_memory_free', 30],
] ]
cooked = json.dumps(raw) cooked = json.dumps(raw)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(9, len(hosts)) self.assertEquals(9, len(hosts))
just_hosts = [host for host, caps in hosts] just_hosts = [host for host, caps in hosts]
@@ -163,7 +163,7 @@ class HostFilterTestCase(test.TestCase):
raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100] raw = ['in', '$compute.host_memory_free', 20, 40, 60, 80, 100]
cooked = json.dumps(raw) cooked = json.dumps(raw)
hosts = driver.filter_hosts(self.zone_manager, cooked) hosts = hf.filter_hosts(self.zone_manager, cooked)
self.assertEquals(5, len(hosts)) self.assertEquals(5, len(hosts))
just_hosts = [host for host, caps in hosts] just_hosts = [host for host, caps in hosts]
@@ -175,35 +175,32 @@ class HostFilterTestCase(test.TestCase):
raw = ['unknown command', ] raw = ['unknown command', ]
cooked = json.dumps(raw) cooked = json.dumps(raw)
try: try:
driver.filter_hosts(self.zone_manager, cooked) hf.filter_hosts(self.zone_manager, cooked)
self.fail("Should give KeyError") self.fail("Should give KeyError")
except KeyError, e: except KeyError, e:
pass pass
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps([]))) self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([])))
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps({}))) self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({})))
self.assertTrue(driver.filter_hosts(self.zone_manager, json.dumps( self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps(
['not', True, False, True, False] ['not', True, False, True, False]
))) )))
try: try:
driver.filter_hosts(self.zone_manager, json.dumps( hf.filter_hosts(self.zone_manager, json.dumps(
'not', True, False, True, False 'not', True, False, True, False
)) ))
self.fail("Should give KeyError") self.fail("Should give KeyError")
except KeyError, e: except KeyError, e:
pass pass
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps( self.assertFalse(hf.filter_hosts(self.zone_manager,
['=', '$foo', 100] json.dumps(['=', '$foo', 100])))
))) self.assertFalse(hf.filter_hosts(self.zone_manager,
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps( json.dumps(['=', '$.....', 100])))
['=', '$.....', 100] self.assertFalse(hf.filter_hosts(self.zone_manager,
))) json.dumps(
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps( ['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]])))
['>', ['and', ['or', ['not', ['<', ['>=', ['<=', ['in', ]]]]]]]]
)))
self.assertFalse(driver.filter_hosts(self.zone_manager, json.dumps( self.assertFalse(hf.filter_hosts(self.zone_manager,
['=', {}, ['>', '$missing....foo']] json.dumps(['=', {}, ['>', '$missing....foo']])))
)))