diff --git a/nova/cells/filters/target_cell.py b/nova/cells/filters/target_cell.py index 772765c6e4a..ac5fad252d3 100644 --- a/nova/cells/filters/target_cell.py +++ b/nova/cells/filters/target_cell.py @@ -63,7 +63,12 @@ def filter_all(self, cells, filter_properties): if cell_name == filter_properties['routing_path']: return [scheduler.state_manager.get_my_state()] ctxt = filter_properties['context'] - scheduler.msg_runner.schedule_run_instance(ctxt, cell_name, - filter_properties['host_sched_kwargs']) + + # NOTE(belliott) Remove after deprecated schedule_run_instance + # code goes away: + schedule = filter_properties['cell_scheduler_method'] + schedule = getattr(scheduler.msg_runner, schedule) + schedule(ctxt, cell_name, filter_properties['host_sched_kwargs']) + # Returning None means to skip further scheduling, because we # handled it. diff --git a/nova/cells/scheduler.py b/nova/cells/scheduler.py index a3201cb57e5..fa3ec2fc6bc 100644 --- a/nova/cells/scheduler.py +++ b/nova/cells/scheduler.py @@ -246,6 +246,10 @@ def build_instances(self, message, build_inst_kwargs): 'routing_path': message.routing_path, 'host_sched_kwargs': build_inst_kwargs, 'request_spec': request_spec}) + # NOTE(belliott) remove when deprecated schedule_run_instance + # code gets removed. + filter_properties['cell_scheduler_method'] = 'build_instances' + self._schedule_build_to_cells(message, instance_uuids, filter_properties, self._build_instances, build_inst_kwargs) @@ -258,6 +262,10 @@ def run_instance(self, message, host_sched_kwargs): 'routing_path': message.routing_path, 'host_sched_kwargs': host_sched_kwargs, 'request_spec': request_spec}) + # NOTE(belliott) remove when deprecated schedule_run_instance + # code gets removed. + filter_properties['cell_scheduler_method'] = 'schedule_run_instance' + self._schedule_build_to_cells(message, instance_uuids, filter_properties, self._run_instance, host_sched_kwargs) @@ -268,6 +276,10 @@ def _schedule_build_to_cells(self, message, instance_uuids, for i in xrange(max(0, CONF.cells.scheduler_retries) + 1): try: target_cells = self._grab_target_cells(filter_properties) + if target_cells is None: + # a filter took care of scheduling. skip. + return + return method(message, target_cells, instance_uuids, method_kwargs) except exception.NoCellsAvailable: diff --git a/nova/tests/cells/test_cells_filters.py b/nova/tests/cells/test_cells_filters.py index 44e74f24172..44b4fdf45a3 100644 --- a/nova/tests/cells/test_cells_filters.py +++ b/nova/tests/cells/test_cells_filters.py @@ -154,10 +154,10 @@ def _fake_sched_run_instance(ctxt, cell, sched_kwargs): 'routing_path': current_cell, 'scheduler': self.scheduler, 'context': self.context, - 'host_sched_kwargs': 'meow'} + 'host_sched_kwargs': 'meow', + 'cell_scheduler_method': 'schedule_run_instance'} # None is returned to bypass further scheduling. - self.assertEqual(None, - self._filter_cells(cells, filter_props)) + self.assertEqual(None, self._filter_cells(cells, filter_props)) # The filter should have re-scheduled to the child cell itself. expected_info = {'ctxt': self.context, 'cell': 'fake!cell!path', diff --git a/nova/tests/cells/test_cells_scheduler.py b/nova/tests/cells/test_cells_scheduler.py index 32378afe3a3..77757edac62 100644 --- a/nova/tests/cells/test_cells_scheduler.py +++ b/nova/tests/cells/test_cells_scheduler.py @@ -422,6 +422,23 @@ def fake_build_request_spec(ctxt, image, instances): self.assertEqual(self.instance_uuids, call_info['errored_uuids1']) self.assertEqual(self.instance_uuids, call_info['errored_uuids2']) + def test_filter_schedule_skipping(self): + # if a filter handles scheduling, short circuit + + def _grab(filter_properties): + return None + + self.stubs.Set(self.scheduler, '_grab_target_cells', _grab) + + def _test(self, *args): + raise test.TestingException("shouldn't be called") + + try: + self.scheduler._schedule_build_to_cells(None, None, None, _test, + None) + except test.TestingException: + self.fail("Scheduling did not properly short circuit") + def test_cells_filter_args_correct(self): # Re-init our fakes with some filters. our_path = 'nova.tests.cells.test_cells_scheduler' @@ -488,7 +505,9 @@ def fake_get_filtered_objs(filter_classes, cells, filt_properties): 'scheduler': self.scheduler, 'routing_path': self.my_cell_state.name, 'host_sched_kwargs': host_sched_kwargs, - 'request_spec': self.request_spec} + 'request_spec': self.request_spec, + 'cell_scheduler_method': + 'schedule_run_instance'} self.assertEqual(expected_filt_props, call_info['filt_props']) self.assertEqual([FakeFilterClass1, FakeFilterClass2], call_info['filt_classes']) @@ -593,7 +612,9 @@ def fake_get_weighed_objs(weight_classes, cells, filt_properties): 'scheduler': self.scheduler, 'routing_path': self.my_cell_state.name, 'host_sched_kwargs': host_sched_kwargs, - 'request_spec': self.request_spec} + 'request_spec': self.request_spec, + 'cell_scheduler_method': + 'schedule_run_instance'} self.assertEqual(expected_filt_props, call_info['weight_props']) self.assertEqual([FakeWeightClass1, FakeWeightClass2], call_info['weight_classes'])