set ERROR state when scheduler hits max attempts

Presently when scheduler raises NoValidHost due to max attempts
being reached, the instance remains in a build state.
Exception handler for NoValidHost in manager.run_instance() needs
request_spec[instance_uuids] to know which host to put into an
error state in _set_vm_state_and_notify().
schedule_run_instances() was popping instance_uuids from the
request_spec prior to a call to _schedule().
Changed pop of instance_uuids prior to call to _schedule() to be a get.
Added pop of instance_uuids to beneath call to _schedule() as
individual creates do not need them.

Change-Id: I9654820e01d5611763e9e673f15f46b947d09e6d
Fixes: bug #1182056
This commit is contained in:
Ryan Moore 2013-05-20 14:56:55 +01:00
parent eebcd6f205
commit aefc28dd48
2 changed files with 19 additions and 5 deletions

View File

@ -69,7 +69,7 @@ class FilterScheduler(driver.Scheduler):
notifier.notify(context, notifier.publisher_id("scheduler"),
'scheduler.run_instance.start', notifier.INFO, payload)
instance_uuids = request_spec.pop('instance_uuids')
instance_uuids = request_spec.get('instance_uuids')
LOG.info(_("Attempting to build %(num_instances)d instance(s) "
"uuids: %(instance_uuids)s"),
{'num_instances': len(instance_uuids),
@ -79,6 +79,11 @@ class FilterScheduler(driver.Scheduler):
weighed_hosts = self._schedule(context, request_spec,
filter_properties, instance_uuids)
# NOTE: Pop instance_uuids as individual creates do not need the
# set of uuids. Do not pop before here as the upper exception
# handler fo NoValidHost needs the uuid to set error state
instance_uuids = request_spec.pop('instance_uuids')
# NOTE(comstud): Make sure we do not pass this through. It
# contains an instance of RpcContext that cannot be serialized.
filter_properties.pop('context', None)

View File

@ -279,18 +279,27 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase):
self.assertEqual(2, num_attempts)
def test_retry_exceeded_max_attempts(self):
# Test for necessary explosion when max retries is exceeded.
# Test for necessary explosion when max retries is exceeded and that
# the information needed in request_spec is still present for error
# handling
self.flags(scheduler_max_attempts=2)
sched = fakes.FakeFilterScheduler()
instance_properties = {'project_id': '12345', 'os_type': 'Linux'}
request_spec = dict(instance_properties=instance_properties)
instance_uuids = ['fake-id']
request_spec = dict(instance_properties=instance_properties,
instance_uuids=instance_uuids)
retry = dict(num_attempts=2)
filter_properties = dict(retry=retry)
self.assertRaises(exception.NoValidHost, sched._schedule, self.context,
request_spec, filter_properties=filter_properties)
self.assertRaises(exception.NoValidHost, sched.schedule_run_instance,
self.context, request_spec, admin_password=None,
injected_files=None, requested_networks=None,
is_first_time=False,
filter_properties=filter_properties)
uuids = request_spec.get('instance_uuids')
self.assertEqual(uuids, instance_uuids)
def test_add_retry_host(self):
retry = dict(num_attempts=1, hosts=[])