diff options
-rw-r--r-- | nova/compute/api.py | 12 | ||||
-rw-r--r-- | nova/tests/unit/compute/test_compute_api.py | 25 |
2 files changed, 36 insertions, 1 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index 972405214e..d2cfeaaf4b 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -27,6 +27,7 @@ import string import uuid from oslo_log import log as logging +from oslo_messaging import exceptions as oslo_exceptions from oslo_serialization import jsonutils from oslo_utils import excutils from oslo_utils import strutils @@ -3365,10 +3366,19 @@ class API(base.Base): # Some old instances can still have no RequestSpec object attached # to them, we need to support the old way request_spec = None - self.compute_task_api.live_migrate_instance(context, instance, + try: + self.compute_task_api.live_migrate_instance(context, instance, host_name, block_migration=block_migration, disk_over_commit=disk_over_commit, request_spec=request_spec) + except oslo_exceptions.MessagingTimeout as messaging_timeout: + with excutils.save_and_reraise_exception(): + # NOTE(pkoniszewski): It is possible that MessagingTimeout + # occurs, but LM will still be in progress, so write + # instance fault to database + compute_utils.add_instance_fault_from_exc(context, + instance, + messaging_timeout) @check_instance_lock @check_instance_cell diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py index 2735d30ebf..3afd9e959d 100644 --- a/nova/tests/unit/compute/test_compute_api.py +++ b/nova/tests/unit/compute/test_compute_api.py @@ -19,6 +19,7 @@ import datetime import iso8601 import mock from mox3 import mox +from oslo_messaging import exceptions as oslo_exceptions from oslo_policy import policy as oslo_policy from oslo_serialization import jsonutils from oslo_utils import fixture as utils_fixture @@ -1872,6 +1873,30 @@ class _ComputeAPIUnitTestMixIn(object): instance = self._create_instance_obj(params=paused_state) self._live_migrate_instance(instance) + @mock.patch.object(compute_utils, 'add_instance_fault_from_exc') + @mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid') + @mock.patch.object(objects.InstanceAction, 'action_start') + @mock.patch.object(objects.Instance, 'save') + def test_live_migrate_messaging_timeout(self, _save, _action, get_spec, + add_instance_fault_from_exc): + instance = self._create_instance_obj() + if self.cell_type == 'api': + api = self.compute_api.cells_rpcapi + else: + api = conductor.api.ComputeTaskAPI + + with mock.patch.object(api, 'live_migrate_instance', + side_effect=oslo_exceptions.MessagingTimeout): + self.assertRaises(oslo_exceptions.MessagingTimeout, + self.compute_api.live_migrate, + self.context, instance, + host_name='fake_dest_host', + block_migration=True, disk_over_commit=True) + add_instance_fault_from_exc.assert_called_once_with( + self.context, + instance, + mock.ANY) + @mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid') @mock.patch.object(objects.Instance, 'save') @mock.patch.object(objects.InstanceAction, 'action_start') |