components/openstack/nova/patches/12-launchpad-1397153.patch
branchs11u3-sru
changeset 5413 bca6b9853ab7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openstack/nova/patches/12-launchpad-1397153.patch	Tue Dec 15 00:08:40 2015 -0800
@@ -0,0 +1,103 @@
+commit 40a37269c52977a718e91012cfd4580b2e31ec65
+Author: He Jie Xu <[email protected]>
+Date:   Fri Nov 7 23:29:18 2014 +0800
+
+    Set vm state error when raising unexpected exception in live migrate
+    
+    The instance stuck at migrating task_state when unexpected exception.
+    This is confuse for user, this patch set the vm_state to error.
+    
+    Change-Id: Ib1b97452bc5e777c66c4d368f71156dbe1e116b7
+    Partial-Bug: 1397153
+
+--- nova-2014.2.2/nova/conductor/manager.py.~2~	2015-12-01 04:57:58.583807338 -0800
++++ nova-2014.2.2/nova/conductor/manager.py	2015-12-01 05:00:43.319845439 -0800
+@@ -558,6 +558,19 @@ class ComputeTaskManager(base.Base):
+     def _live_migrate(self, context, instance, scheduler_hint,
+                       block_migration, disk_over_commit):
+         destination = scheduler_hint.get("host")
++
++        def _set_vm_state(context, instance, ex, vm_state=None,
++                          task_state=None):
++            request_spec = {'instance_properties': {
++                'uuid': instance['uuid'], },
++            }
++            scheduler_utils.set_vm_state_and_notify(context,
++                'compute_task', 'migrate_server',
++                dict(vm_state=vm_state,
++                     task_state=task_state,
++                     expected_task_state=task_states.MIGRATING,),
++                ex, request_spec, self.db)
++
+         try:
+             live_migrate.execute(context, instance, destination,
+                              block_migration, disk_over_commit)
+@@ -575,20 +588,14 @@ class ComputeTaskManager(base.Base):
+                 exception.LiveMigrationWithOldNovaNotSafe) as ex:
+             with excutils.save_and_reraise_exception():
+                 # TODO(johngarbutt) - eventually need instance actions here
+-                request_spec = {'instance_properties': {
+-                    'uuid': instance['uuid'], },
+-                }
+-                scheduler_utils.set_vm_state_and_notify(context,
+-                        'compute_task', 'migrate_server',
+-                        dict(vm_state=instance['vm_state'],
+-                             task_state=None,
+-                             expected_task_state=task_states.MIGRATING,),
+-                        ex, request_spec, self.db)
++                _set_vm_state(context, instance, ex, instance['vm_state'])
+         except Exception as ex:
+             LOG.error(_('Migration of instance %(instance_id)s to host'
+                        ' %(dest)s unexpectedly failed.'),
+                        {'instance_id': instance['uuid'], 'dest': destination},
+                        exc_info=True)
++            _set_vm_state(context, instance, ex, vm_states.ERROR,
++                          instance['task_state'])
+             raise exception.MigrationError(reason=six.text_type(ex))
+ 
+     def build_instances(self, context, instances, image, filter_properties,
+--- nova-2014.2.2/nova/tests/conductor/test_conductor.py.~2~	2015-12-01 04:57:58.599204982 -0800
++++ nova-2014.2.2/nova/tests/conductor/test_conductor.py	2015-12-01 05:04:39.416251458 -0800
+@@ -1704,27 +1704,28 @@ class ConductorTaskTestCase(_BaseTaskTes
+         ex = exc.LiveMigrationWithOldNovaNotSafe(server='dummy')
+         self._test_migrate_server_deals_with_expected_exceptions(ex)
+ 
+-    def test_migrate_server_deals_with_unexpected_exceptions(self):
++    @mock.patch.object(scheduler_utils, 'set_vm_state_and_notify')
++    @mock.patch.object(live_migrate, 'execute')
++    def test_migrate_server_deals_with_unexpected_exceptions(self,
++            mock_live_migrate, mock_set_state):
++        expected_ex = IOError('fake error')
++        mock_live_migrate.side_effect = expected_ex
+         instance = fake_instance.fake_db_instance()
+         inst_obj = objects.Instance._from_db_object(
+             self.context, objects.Instance(), instance, [])
+-        self.mox.StubOutWithMock(live_migrate, 'execute')
+-        self.mox.StubOutWithMock(scheduler_utils,
+-                'set_vm_state_and_notify')
+-
+-        expected_ex = IOError('fake error')
+-        live_migrate.execute(self.context, mox.IsA(objects.Instance),
+-                             'destination', 'block_migration',
+-                             'disk_over_commit').AndRaise(expected_ex)
+-        self.mox.ReplayAll()
+-
+-        self.conductor = utils.ExceptionHelper(self.conductor)
+-
+         ex = self.assertRaises(exc.MigrationError,
+             self.conductor.migrate_server, self.context, inst_obj,
+             {'host': 'destination'}, True, False, None, 'block_migration',
+             'disk_over_commit')
+-        self.assertEqual(ex.kwargs['reason'], six.text_type(expected_ex))
++        request_spec = {'instance_properties': {
++                'uuid': instance['uuid'], },
++        }
++        mock_set_state.assert_called_once_with(self.context,
++                        'compute_task', 'migrate_server',
++                        dict(vm_state=vm_states.ERROR,
++                             task_state=inst_obj.task_state,
++                             expected_task_state=task_states.MIGRATING,),
++                        expected_ex, request_spec, self.conductor.db)
+ 
+     def test_set_vm_state_and_notify(self):
+         self.mox.StubOutWithMock(scheduler_utils,