Skip to content

Commit

Permalink
Fix regression issues with cells target filter
Browse files Browse the repository at this point in the history
1) Skip scheduling if a cell filter already took care of it
2) Call build_instances or schedule_run_instance (deprecated) depending on
   which method the caller used.

bug 1224465

Change-Id: I391e1c4f288c9dc3e1308ee8c001a662e0f4c1b8
  • Loading branch information
Brian Elliott committed Sep 10, 2013
1 parent 4e842e3 commit 2dbea4a
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
9 changes: 7 additions & 2 deletions nova/cells/filters/target_cell.py
Expand Up @@ -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.
12 changes: 12 additions & 0 deletions nova/cells/scheduler.py
Expand Up @@ -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)

Expand All @@ -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)

Expand All @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions nova/tests/cells/test_cells_filters.py
Expand Up @@ -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',
Expand Down
25 changes: 23 additions & 2 deletions nova/tests/cells/test_cells_scheduler.py
Expand Up @@ -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'
Expand Down Expand Up @@ -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'])
Expand Down Expand Up @@ -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'])
Expand Down

0 comments on commit 2dbea4a

Please sign in to comment.