From aefc28dd481354edd0f3b5aec18db006680b2ffe Mon Sep 17 00:00:00 2001 From: Ryan Moore Date: Mon, 20 May 2013 14:56:55 +0100 Subject: 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 --- nova/scheduler/filter_scheduler.py | 7 ++++++- nova/tests/scheduler/test_filter_scheduler.py | 17 +++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/nova/scheduler/filter_scheduler.py b/nova/scheduler/filter_scheduler.py index 566b7846d..186cecc14 100644 --- a/nova/scheduler/filter_scheduler.py +++ b/nova/scheduler/filter_scheduler.py @@ -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) diff --git a/nova/tests/scheduler/test_filter_scheduler.py b/nova/tests/scheduler/test_filter_scheduler.py index c8c04dc77..80680dda8 100644 --- a/nova/tests/scheduler/test_filter_scheduler.py +++ b/nova/tests/scheduler/test_filter_scheduler.py @@ -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=[]) -- cgit