Merge "Scheduler: throw exception if no configured affinity filter"

This commit is contained in:
Jenkins
2014-07-28 19:38:34 +00:00
committed by Gerrit Code Review
4 changed files with 76 additions and 11 deletions
+15 -2
View File
@@ -61,6 +61,10 @@ class FilterScheduler(driver.Scheduler):
self.options = scheduler_options.SchedulerOptions()
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
self.notifier = rpc.get_notifier('scheduler')
self._supports_affinity = scheduler_utils.validate_filter(
'ServerGroupAffinityFilter')
self._supports_anti_affinity = scheduler_utils.validate_filter(
'ServerGroupAntiAffinityFilter')
# NOTE(alaski): Remove this method when the scheduler rpc interface is
# bumped to 4.x as it is no longer used.
@@ -202,8 +206,7 @@ class FilterScheduler(driver.Scheduler):
if pci_requests:
filter_properties['pci_requests'] = pci_requests
@staticmethod
def _setup_instance_group(context, filter_properties):
def _setup_instance_group(self, context, filter_properties):
update_group_hosts = False
scheduler_hints = filter_properties.get('scheduler_hints') or {}
group_hint = scheduler_hints.get('group', None)
@@ -211,6 +214,16 @@ class FilterScheduler(driver.Scheduler):
group = objects.InstanceGroup.get_by_hint(context, group_hint)
policies = set(('anti-affinity', 'affinity'))
if any((policy in policies) for policy in group.policies):
if ('affinity' in group.policies and
not self._supports_affinity):
msg = _("ServerGroupAffinityFilter not configured")
LOG.error(msg)
raise exception.NoValidHost(reason=msg)
if ('anti-affinity' in group.policies and
not self._supports_anti_affinity):
msg = _("ServerGroupAntiAffinityFilter not configured")
LOG.error(msg)
raise exception.NoValidHost(reason=msg)
update_group_hosts = True
filter_properties.setdefault('group_hosts', set())
user_hosts = set(filter_properties['group_hosts'])
+5
View File
@@ -235,3 +235,8 @@ def parse_options(opts, sep='=', converter=str, name=""):
{'name': name,
'options': ", ".join(bad)})
return good
def validate_filter(filter):
"""Validates that the filter is configured in the default filters."""
return filter in CONF.scheduler_default_filters
+50 -9
View File
@@ -371,7 +371,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
self.assertEqual({'vcpus': 5}, host_state.limits)
def _create_server_group(self):
def _create_server_group(self, policy='anti-affinity'):
instance = fake_instance.fake_instance_obj(self.context,
params={'host': 'hostA'})
@@ -379,10 +379,11 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
group.name = 'pele'
group.uuid = str(uuid.uuid4())
group.members = [instance.uuid]
group.policies = ['anti-affinity']
group.policies = [policy]
return group
def _test_group_details_in_filter_properties(self, group, func, hint):
def _group_details_in_filter_properties(self, group, func='get_by_uuid',
hint=None, policy=None):
sched = fakes.FakeFilterScheduler()
filter_properties = {
@@ -397,23 +398,63 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
mock.patch.object(objects.InstanceGroup, 'get_hosts',
return_value=['hostA']),
) as (get_group, get_hosts):
sched._supports_anti_affinity = True
update_group_hosts = sched._setup_instance_group(self.context,
filter_properties)
self.assertTrue(update_group_hosts)
self.assertEqual(set(['hostA', 'hostB']),
filter_properties['group_hosts'])
self.assertEqual(['anti-affinity'],
filter_properties['group_policies'])
self.assertEqual([policy], filter_properties['group_policies'])
def test_group_details_in_filter_properties(self):
for policy in ['affinity', 'anti-affinity']:
group = self._create_server_group(policy)
self._group_details_in_filter_properties(group, func='get_by_uuid',
hint=group.uuid,
policy=policy)
def _group_filter_with_filter_not_configured(self, policy):
self.flags(scheduler_default_filters=['f1', 'f2'])
sched = fakes.FakeFilterScheduler()
instance = fake_instance.fake_instance_obj(self.context,
params={'host': 'hostA'})
group = objects.InstanceGroup()
group.uuid = str(uuid.uuid4())
group.members = [instance.uuid]
group.policies = [policy]
filter_properties = {
'scheduler_hints': {
'group': group.uuid,
},
}
with contextlib.nested(
mock.patch.object(objects.InstanceGroup, 'get_by_uuid',
return_value=group),
mock.patch.object(objects.InstanceGroup, 'get_hosts',
return_value=['hostA']),
) as (get_group, get_hosts):
self.assertRaises(exception.NoValidHost,
sched._setup_instance_group, self.context,
filter_properties)
def test_group_filter_with_filter_not_configured(self):
policies = ['anti-affinity', 'affinity']
for policy in policies:
self._group_filter_with_filter_not_configured(policy)
def test_group_uuid_details_in_filter_properties(self):
group = self._create_server_group()
self._test_group_details_in_filter_properties(group, 'get_by_uuid',
group.uuid)
self._group_details_in_filter_properties(group, 'get_by_uuid',
group.uuid, 'anti-affinity')
def test_group_name_details_in_filter_properties(self):
group = self._create_server_group()
self._test_group_details_in_filter_properties(group, 'get_by_name',
group.name)
self._group_details_in_filter_properties(group, 'get_by_name',
group.name, 'anti-affinity')
def test_schedule_host_pool(self):
"""Make sure the scheduler_host_subset_size property works properly."""
@@ -215,3 +215,9 @@ class SchedulerUtilsTestCase(test.NoDBTestCase):
'=',
float,
[('bar', -2.1)])
def test_validate_filters_configured(self):
self.flags(scheduler_default_filters='FakeFilter1,FakeFilter2')
self.assertTrue(scheduler_utils.validate_filter('FakeFilter1'))
self.assertTrue(scheduler_utils.validate_filter('FakeFilter2'))
self.assertFalse(scheduler_utils.validate_filter('FakeFilter3'))