summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2011-11-03 20:25:06 +0000
committerGerrit Code Review <review@openstack.org>2011-11-03 20:25:06 +0000
commit03b366d434eb23f15391801099e7e307b17e979f (patch)
treec73b32806f176d9b8fed3fdfca9bf33212769c9c
parentfec3c19c492ee16096fdcd369b0adee6ddf43fb8 (diff)
parentca6295e5dd238a88b731c3bf3e337007d12b6c1c (diff)
downloadnova-03b366d434eb23f15391801099e7e307b17e979f.tar.gz
nova-03b366d434eb23f15391801099e7e307b17e979f.tar.xz
nova-03b366d434eb23f15391801099e7e307b17e979f.zip
Merge "Gracefully handle Xen resize failure"
-rw-r--r--nova/compute/manager.py12
-rw-r--r--nova/tests/test_compute.py24
-rw-r--r--nova/tests/test_xenapi.py13
-rw-r--r--nova/virt/xenapi/vmops.py12
4 files changed, 56 insertions, 5 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index ddd878664..f16b72a57 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -1070,8 +1070,16 @@ class ComputeManager(manager.SchedulerDependentManager):
migration_id,
{'status': 'migrating'})
- disk_info = self.driver.migrate_disk_and_power_off(
- context, instance_ref, migration_ref['dest_host'])
+ try:
+ disk_info = self.driver.migrate_disk_and_power_off(
+ context, instance_ref, migration_ref['dest_host'])
+ except exception.MigrationError, error:
+ LOG.error(_('%s. Setting instance vm_state to ERROR') % (error,))
+ self._instance_update(context,
+ instance_id,
+ vm_state=vm_states.ERROR)
+ return
+
self.db.migration_update(context,
migration_id,
{'status': 'post-migrating'})
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 7295c9f1f..b235bcade 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -746,6 +746,30 @@ class ComputeTestCase(test.TestCase):
self.context, inst_ref['uuid'], 1)
self.compute.terminate_instance(self.context, instance_id)
+ def test_resize_instance_handles_migration_error(self):
+ """Ensure vm_state is ERROR when MigrationError occurs"""
+ def raise_migration_failure(*args):
+ raise exception.MigrationError(reason='test failure')
+ self.stubs.Set(self.compute.driver,
+ 'migrate_disk_and_power_off',
+ raise_migration_failure)
+
+ instance_id = self._create_instance()
+ context = self.context.elevated()
+ inst_ref = db.instance_get(context, instance_id)
+
+ self.compute.run_instance(self.context, instance_id)
+ db.instance_update(self.context, inst_ref['uuid'], {'host': 'foo'})
+ self.compute.prep_resize(context, inst_ref['uuid'], 1)
+ migration_ref = db.migration_get_by_instance_and_status(context,
+ inst_ref['uuid'], 'pre-migrating')
+ self.compute.resize_instance(context,
+ inst_ref['uuid'],
+ migration_ref['id'])
+ inst_ref = db.instance_get(context, instance_id)
+ self.assertEqual(inst_ref['vm_state'], vm_states.ERROR)
+ self.compute.terminate_instance(context, instance_id)
+
def test_migrate(self):
context = self.context.elevated()
instance_id = self._create_instance()
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 08a7686b5..6587bedd1 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -791,6 +791,19 @@ class XenAPIMigrateInstance(test.TestCase):
conn = xenapi_conn.get_connection(False)
conn.migrate_disk_and_power_off(self.context, instance, '127.0.0.1')
+ def test_migrate_disk_and_power_off_passes_exceptions(self):
+ instance = db.instance_create(self.context, self.instance_values)
+ stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
+
+ def fake_raise(*args, **kwargs):
+ raise exception.MigrationError(reason='test failure')
+ self.stubs.Set(vmops.VMOps, "_migrate_vhd", fake_raise)
+
+ conn = xenapi_conn.get_connection(False)
+ self.assertRaises(exception.MigrationError,
+ conn.migrate_disk_and_power_off,
+ self.context, instance, '127.0.0.1')
+
def test_revert_migrate(self):
instance = db.instance_create(self.context, self.instance_values)
self.called = False
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index f6c4ce429..2da5706b6 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -620,9 +620,15 @@ class VMOps(object):
'instance_id': instance_id,
'sr_path': sr_path}
- task = self._session.async_call_plugin('migration', 'transfer_vhd',
- {'params': pickle.dumps(params)})
- self._session.wait_for_task(task, instance_id)
+ try:
+ _params = {'params': pickle.dumps(params)}
+ task = self._session.async_call_plugin('migration',
+ 'transfer_vhd',
+ _params)
+ self._session.wait_for_task(task, instance_id)
+ except self.XenAPI.Failure:
+ msg = _("Failed to transfer vhd to new host")
+ raise exception.MigrationError(reason=msg)
def _get_orig_vm_name_label(self, instance):
return instance.name + '-orig'