diff --git a/nova/compute/manager.py b/nova/compute/manager.py index e6595d363a..1c77284a4c 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -310,8 +310,7 @@ def wrap_instance_fault(function): with excutils.save_and_reraise_exception(): compute_utils.add_instance_fault_from_exc(context, - self.conductor_api, kwargs['instance'], - e, sys.exc_info()) + kwargs['instance'], e, sys.exc_info()) return decorated_function @@ -1418,7 +1417,7 @@ class ComputeManager(manager.Manager): instance_uuid = instance['uuid'] rescheduled = False - compute_utils.add_instance_fault_from_exc(context, self.conductor_api, + compute_utils.add_instance_fault_from_exc(context, instance, exc_info[1], exc_info=exc_info) self._notify_about_instance_usage(context, instance, 'instance.create.error', fault=exc_info[1]) @@ -2670,7 +2669,7 @@ class ComputeManager(manager.Manager): LOG.warning(_('Reboot failed but instance is running'), context=context, instance=instance) compute_utils.add_instance_fault_from_exc(context, - self.conductor_api, instance, error, exc_info) + instance, error, exc_info) self._notify_about_instance_usage(context, instance, 'reboot.error', fault=error) ctxt.reraise = False @@ -3410,7 +3409,7 @@ class ComputeManager(manager.Manager): LOG.exception(_("Error trying to reschedule"), instance_uuid=instance_uuid) compute_utils.add_instance_fault_from_exc(context, - self.conductor_api, instance, error, + instance, error, exc_info=sys.exc_info()) self._notify_about_instance_usage(context, instance, 'resize.error', fault=error) @@ -3418,8 +3417,7 @@ class ComputeManager(manager.Manager): if rescheduled: self._log_original_error(exc_info, instance_uuid) compute_utils.add_instance_fault_from_exc(context, - self.conductor_api, instance, exc_info[1], - exc_info=exc_info) + instance, exc_info[1], exc_info=exc_info) self._notify_about_instance_usage(context, instance, 'resize.error', fault=exc_info[1]) else: diff --git a/nova/compute/utils.py b/nova/compute/utils.py index fa4fa9c694..17cb59f6a0 100644 --- a/nova/compute/utils.py +++ b/nova/compute/utils.py @@ -29,6 +29,7 @@ from nova import exception from nova.network import model as network_model from nova import notifications from nova.objects import instance as instance_obj +from nova.objects import instance_fault as instance_fault_obj from nova.openstack.common.gettextutils import _ from nova.openstack.common import log from nova.openstack.common import timeutils @@ -82,22 +83,16 @@ def _get_fault_details(exc_info, error_code): return unicode(details) -def add_instance_fault_from_exc(context, conductor, - instance, fault, exc_info=None): +def add_instance_fault_from_exc(context, instance, fault, exc_info=None): """Adds the specified fault to the database.""" - fault_dict = exception_to_dict(fault) - code = fault_dict["code"] - details = _get_fault_details(exc_info, code) - - values = { - 'instance_uuid': instance['uuid'], - 'code': code, - 'message': fault_dict["message"], - 'details': details, - 'host': CONF.host - } - conductor.instance_fault_create(context, values) + fault_obj = instance_fault_obj.InstanceFault(context=context) + fault_obj.host = CONF.host + fault_obj.instance_uuid = instance['uuid'] + fault_obj.update(exception_to_dict(fault)) + code = fault_obj.code + fault_obj.details = _get_fault_details(exc_info, code) + fault_obj.create() def pack_action_start(context, instance_uuid, action_name): diff --git a/nova/scheduler/driver.py b/nova/scheduler/driver.py index 4f8a78e625..f0533dbcbf 100644 --- a/nova/scheduler/driver.py +++ b/nova/scheduler/driver.py @@ -25,7 +25,6 @@ from oslo.config import cfg from nova.compute import utils as compute_utils from nova.compute import vm_states -from nova.conductor import api as conductor_api from nova import db from nova import exception from nova import notifications @@ -68,7 +67,6 @@ def handle_schedule_error(context, ex, instance_uuid, request_spec): notifications.send_update(context, old_ref, new_ref, service="scheduler") compute_utils.add_instance_fault_from_exc(context, - conductor_api.LocalAPI(), new_ref, ex, sys.exc_info()) properties = request_spec.get('instance_properties', {}) diff --git a/nova/scheduler/utils.py b/nova/scheduler/utils.py index ab10fcbb7d..e3250f12c8 100644 --- a/nova/scheduler/utils.py +++ b/nova/scheduler/utils.py @@ -72,8 +72,6 @@ def set_vm_state_and_notify(context, service, method, updates, ex, # be removed along with the 'if instance_uuid:' if we can # verify that uuid is always set. uuids = [properties.get('uuid')] - from nova.conductor import api as conductor_api - conductor = conductor_api.LocalAPI() notifier = rpc.get_notifier(service) for instance_uuid in request_spec.get('instance_uuids') or uuids: if instance_uuid: @@ -87,7 +85,6 @@ def set_vm_state_and_notify(context, service, method, updates, ex, notifications.send_update(context, old_ref, new_ref, service=service) compute_utils.add_instance_fault_from_exc(context, - conductor, new_ref, ex, sys.exc_info()) payload = dict(request_spec=request_spec, diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 9a3fe73af6..b3f2d2adfd 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -5506,6 +5506,16 @@ class ComputeTestCase(BaseTestCase): self.assertEqual(len(instances), 1) self.assertIsNone(instances[0]['task_state']) + def _fill_fault(self, values): + extra = dict([(x, None) for x in ['created_at', + 'deleted_at', + 'updated_at', + 'deleted']]) + extra['id'] = 1 + extra['details'] = '' + extra.update(values) + return extra + def test_add_instance_fault(self): instance = self._create_fake_instance() exc_info = None @@ -5521,6 +5531,7 @@ class ComputeTestCase(BaseTestCase): 'host': self.compute.host } self.assertEqual(expected, values) + return self._fill_fault(expected) try: raise NotImplementedError('test') @@ -5531,7 +5542,6 @@ class ComputeTestCase(BaseTestCase): ctxt = context.get_admin_context() compute_utils.add_instance_fault_from_exc(ctxt, - self.compute.conductor_api, instance, NotImplementedError('test'), exc_info) @@ -5552,6 +5562,7 @@ class ComputeTestCase(BaseTestCase): 'host': self.compute.host } self.assertEqual(expected, values) + return self._fill_fault(expected) try: raise messaging.RemoteError('test', 'My Test Message') @@ -5562,7 +5573,7 @@ class ComputeTestCase(BaseTestCase): ctxt = context.get_admin_context() compute_utils.add_instance_fault_from_exc(ctxt, - self.compute.conductor_api, instance, exc, exc_info) + instance, exc, exc_info) def test_add_instance_fault_user_error(self): instance = self._create_fake_instance() @@ -5578,6 +5589,7 @@ class ComputeTestCase(BaseTestCase): 'host': self.compute.host } self.assertEqual(expected, values) + return self._fill_fault(expected) user_exc = exception.Invalid('fake details', code=400) @@ -5590,7 +5602,7 @@ class ComputeTestCase(BaseTestCase): ctxt = context.get_admin_context() compute_utils.add_instance_fault_from_exc(ctxt, - self.compute.conductor_api, instance, user_exc, exc_info) + instance, user_exc, exc_info) def test_add_instance_fault_no_exc_info(self): instance = self._create_fake_instance() @@ -5604,12 +5616,12 @@ class ComputeTestCase(BaseTestCase): 'host': self.compute.host } self.assertEqual(expected, values) + return self._fill_fault(expected) self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() compute_utils.add_instance_fault_from_exc(ctxt, - self.compute.conductor_api, instance, NotImplementedError('test')) @@ -5627,12 +5639,12 @@ class ComputeTestCase(BaseTestCase): 'host': self.compute.host } self.assertEqual(expected, values) + return self._fill_fault(expected) self.stubs.Set(nova.db, 'instance_fault_create', fake_db_fault_create) ctxt = context.get_admin_context() compute_utils.add_instance_fault_from_exc(ctxt, - self.compute.conductor_api, instance, NotImplementedError(message)) @@ -10111,7 +10123,6 @@ class ComputeRescheduleOrErrorTestCase(BaseTestCase): exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, - self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._shutdown_instance(self.context, self.instance, mox.IgnoreArg(), @@ -10199,7 +10210,6 @@ class ComputeRescheduleOrErrorTestCase(BaseTestCase): except test.TestingException: exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, - self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._shutdown_instance(self.context, self.instance, @@ -10232,7 +10242,6 @@ class ComputeRescheduleOrErrorTestCase(BaseTestCase): exc_info = sys.exc_info() compute_utils.add_instance_fault_from_exc(self.context, - self.compute.conductor_api, self.instance, exc_info[0], exc_info=exc_info) self.compute._shutdown_instance(self.context, self.instance, mox.IgnoreArg(), diff --git a/nova/tests/compute/test_compute_mgr.py b/nova/tests/compute/test_compute_mgr.py index 621a9ac1e9..75387cd94d 100644 --- a/nova/tests/compute/test_compute_mgr.py +++ b/nova/tests/compute/test_compute_mgr.py @@ -40,6 +40,7 @@ from nova import test from nova.tests.compute import fake_resource_tracker from nova.tests import fake_block_device from nova.tests import fake_instance +from nova.tests.objects import test_instance_fault from nova.tests.objects import test_instance_info_cache @@ -936,9 +937,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase): fake_vol_migrate_volume_completion) self.stubs.Set(db, 'block_device_mapping_update', lambda *a, **k: fake_bdm) - self.stubs.Set(self.compute.conductor_api, + self.stubs.Set(db, 'instance_fault_create', - lambda x, y: None) + lambda x, y: + test_instance_fault.fake_faults['fake-uuid'][0]) # Good path self.compute.swap_volume(self.context, old_volume_id, new_volume_id, @@ -1033,10 +1035,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase): self.context, instance, dest_check_data) if do_raise: mock_meth.AndRaise(test.TestingException()) - self.mox.StubOutWithMock(self.compute.conductor_api, - 'instance_fault_create') - self.compute.conductor_api.instance_fault_create(self.context, - mox.IgnoreArg()) + self.mox.StubOutWithMock(db, 'instance_fault_create') + db.instance_fault_create( + self.context, mox.IgnoreArg()).AndReturn( + test_instance_fault.fake_faults['fake-uuid'][0]) else: mock_meth.AndReturn(mig_data) self.compute.driver.check_can_live_migrate_destination_cleanup( @@ -1866,14 +1868,15 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): 'action_event_start'), mock.patch.object(self.compute.conductor_api, 'action_event_finish'), - mock.patch.object(self.compute.conductor_api, - 'instance_fault_create'), + mock.patch.object(db, 'instance_fault_create'), mock.patch.object(self.compute, '_instance_update'), mock.patch.object(self.migration, 'save'), mock.patch.object(self.context, 'elevated', return_value=elevated_context) ) as (meth, event_start, event_finish, fault_create, instance_update, migration_save, context_elevated): + fault_create.return_value = ( + test_instance_fault.fake_faults['fake-uuid'][0]) self.assertRaises( exception.ResizeError, self.compute.finish_resize, context=self.context, disk_info=[], image=self.image, @@ -1894,8 +1897,7 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): 'action_event_start'), mock.patch.object(self.compute.conductor_api, 'action_event_finish'), - mock.patch.object(self.compute.conductor_api, - 'instance_fault_create'), + mock.patch.object(db, 'instance_fault_create'), mock.patch.object(self.compute, '_instance_update'), mock.patch.object(self.migration, 'save'), mock.patch.object(self.context, 'elevated', @@ -1913,6 +1915,8 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): ) as (meth, event_start, event_finish, fault_create, instance_update, migration_save, context_elevated, nw_info, save_inst, notify, vol_block_info, bdm): + fault_create.return_value = ( + test_instance_fault.fake_faults['fake-uuid'][0]) self.assertRaises( exception.ResizeError, self.compute.resize_instance, context=self.context, instance=self.instance, image=self.image, diff --git a/nova/tests/scheduler/test_chance_scheduler.py b/nova/tests/scheduler/test_chance_scheduler.py index a9b2333110..3f542e6b88 100644 --- a/nova/tests/scheduler/test_chance_scheduler.py +++ b/nova/tests/scheduler/test_chance_scheduler.py @@ -23,7 +23,6 @@ import mox from nova.compute import rpcapi as compute_rpcapi from nova.compute import utils as compute_utils from nova.compute import vm_states -from nova.conductor import api as conductor_api from nova import context from nova import db from nova import exception @@ -130,8 +129,7 @@ class ChanceSchedulerTestCase(test_scheduler.SchedulerTestCase): old_ref, new_ref = db.instance_update_and_get_original(ctxt, uuid, {'vm_state': vm_states.ERROR, 'task_state': None}).AndReturn(({}, {})) - compute_utils.add_instance_fault_from_exc(ctxt, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(ctxt, new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.ReplayAll() diff --git a/nova/tests/scheduler/test_filter_scheduler.py b/nova/tests/scheduler/test_filter_scheduler.py index f1132998f7..66da25508d 100644 --- a/nova/tests/scheduler/test_filter_scheduler.py +++ b/nova/tests/scheduler/test_filter_scheduler.py @@ -24,7 +24,6 @@ import mox from nova.compute import utils as compute_utils from nova.compute import vm_states -from nova.conductor import api as conductor_api from nova import context from nova import db from nova import exception @@ -88,8 +87,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): old_ref, new_ref = db.instance_update_and_get_original(fake_context, uuid, {'vm_state': vm_states.ERROR, 'task_state': None}).AndReturn(({}, {})) - compute_utils.add_instance_fault_from_exc(fake_context, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(fake_context, new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.StubOutWithMock(db, 'compute_node_get_all') @@ -124,8 +122,7 @@ class FilterSchedulerTestCase(test_scheduler.SchedulerTestCase): old_ref, new_ref = db.instance_update_and_get_original(fake_context, uuid, {'vm_state': vm_states.ERROR, 'task_state': None}).AndReturn(({}, {})) - compute_utils.add_instance_fault_from_exc(fake_context, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(fake_context, new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.ReplayAll() sched.schedule_run_instance( diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index 6f7ac59c21..d86fb45248 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -27,7 +27,6 @@ from nova.compute import api as compute_api from nova.compute import task_states from nova.compute import utils as compute_utils from nova.compute import vm_states -from nova.conductor import api as conductor_api from nova.conductor.tasks import live_migrate from nova import context from nova import db @@ -43,6 +42,7 @@ from nova.tests import fake_instance from nova.tests import fake_server_actions from nova.tests.image import fake as fake_image from nova.tests import matchers +from nova.tests.objects import test_instance_fault from nova.tests.scheduler import fakes from nova import utils @@ -152,8 +152,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): {"vm_state": vm_states.ERROR, "task_state": None}).AndReturn((inst, inst)) compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), new_ref, - mox.IsA(exception.NoValidHost), mox.IgnoreArg()) + new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.ReplayAll() self.manager.run_instance(self.context, request_spec, @@ -180,8 +179,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): "task_state": None, "expected_task_state": task_states.MIGRATING, }).AndReturn((inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), inst, + compute_utils.add_instance_fault_from_exc(self.context, inst, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) @@ -213,8 +211,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): "task_state": None, "expected_task_state": task_states.MIGRATING, }).AndReturn((inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), inst, + compute_utils.add_instance_fault_from_exc(self.context, inst, mox.IsA(exception.ComputeServiceUnavailable), mox.IgnoreArg()) @@ -254,8 +251,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): db.instance_update_and_get_original(self.context, inst["uuid"], {"vm_state": vm_states.ERROR, }).AndReturn((inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), inst, + compute_utils.add_instance_fault_from_exc(self.context, inst, mox.IsA(ValueError), mox.IgnoreArg()) @@ -295,8 +291,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): fake_instance_uuid, {"vm_state": vm_states.ACTIVE, "task_state": None}).AndReturn( (inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(self.context, new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.ReplayAll() @@ -331,8 +326,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): fake_instance_uuid, {"vm_state": vm_states.STOPPED, "task_state": None}).AndReturn( (inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(self.context, new_ref, mox.IsA(exception.NoValidHost), mox.IgnoreArg()) self.mox.ReplayAll() @@ -373,8 +367,7 @@ class SchedulerManagerTestCase(test.NoDBTestCase): fake_instance_uuid, {"vm_state": vm_states.ERROR, "task_state": None}).AndReturn((inst, inst)) - compute_utils.add_instance_fault_from_exc(self.context, - mox.IsA(conductor_api.LocalAPI), new_ref, + compute_utils.add_instance_fault_from_exc(self.context, new_ref, mox.IsA(test.TestingException), mox.IgnoreArg()) self.mox.ReplayAll() @@ -391,12 +384,12 @@ class SchedulerManagerTestCase(test.NoDBTestCase): self.mox.StubOutWithMock(db, 'instance_fault_create') self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() - rpc.get_notifier('conductor', CONF.host).AndReturn(notifier) rpc.get_notifier('scheduler').AndReturn(notifier) db.instance_update_and_get_original(self.context, 'fake-uuid', updates).AndReturn((None, fake_inst)) - db.instance_fault_create(self.context, mox.IgnoreArg()) + db.instance_fault_create(self.context, mox.IgnoreArg()).AndReturn( + test_instance_fault.fake_faults['fake-uuid'][0]) notifier.error(self.context, 'scheduler.foo', mox.IgnoreArg()) self.mox.ReplayAll() @@ -504,10 +497,10 @@ class SchedulerTestCase(test.NoDBTestCase): db.instance_update_and_get_original(self.context, instance['uuid'], mox.IgnoreArg()).AndReturn( (None, instance)) - db.instance_fault_create(self.context, mox.IgnoreArg()) + db.instance_fault_create(self.context, mox.IgnoreArg()).AndReturn( + test_instance_fault.fake_faults['fake-uuid'][0]) self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() - rpc.get_notifier('conductor', CONF.host).AndReturn(notifier) rpc.get_notifier('scheduler').AndReturn(notifier) notifier.error(self.context, 'scheduler.run_instance', mox.IgnoreArg()) self.mox.ReplayAll() diff --git a/nova/tests/scheduler/test_scheduler_utils.py b/nova/tests/scheduler/test_scheduler_utils.py index 9e2d0d3b6c..e7a391b033 100644 --- a/nova/tests/scheduler/test_scheduler_utils.py +++ b/nova/tests/scheduler/test_scheduler_utils.py @@ -21,7 +21,6 @@ from oslo.config import cfg from nova.compute import flavors from nova.compute import utils as compute_utils -from nova.conductor import api as conductor_api from nova import db from nova import notifications from nova import rpc @@ -81,7 +80,6 @@ class SchedulerUtilsTestCase(test.NoDBTestCase): self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() - rpc.get_notifier('conductor', CONF.host).AndReturn(notifier) rpc.get_notifier(service).AndReturn(notifier) old_ref = 'old_ref' @@ -94,7 +92,6 @@ class SchedulerUtilsTestCase(test.NoDBTestCase): service=service) compute_utils.add_instance_fault_from_exc( self.context, - mox.IsA(conductor_api.LocalAPI), new_ref, exc_info, mox.IsA(tuple)) payload = dict(request_spec=request_spec, diff --git a/nova/tests/virt/xenapi/test_xenapi.py b/nova/tests/virt/xenapi/test_xenapi.py index ca1257e939..926a36beb0 100644 --- a/nova/tests/virt/xenapi/test_xenapi.py +++ b/nova/tests/virt/xenapi/test_xenapi.py @@ -1176,7 +1176,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): called = {} def fake_add_instance_fault(*args, **kwargs): - called["fake_add_instance_fault"] = args[3] + called["fake_add_instance_fault"] = args[2] self.stubs.Set(compute_utils, 'add_instance_fault_from_exc', fake_add_instance_fault) diff --git a/nova/virt/xenapi/agent.py b/nova/virt/xenapi/agent.py index fa012263cd..64071c856d 100644 --- a/nova/virt/xenapi/agent.py +++ b/nova/virt/xenapi/agent.py @@ -25,7 +25,6 @@ from oslo.config import cfg from nova.api.metadata import password from nova.compute import utils as compute_utils -from nova import conductor from nova import context from nova import crypto from nova import exception @@ -186,9 +185,8 @@ class XenAPIBasedAgent(object): instance=self.instance, exc_info=True) try: ctxt = context.get_admin_context() - capi = conductor.API() compute_utils.add_instance_fault_from_exc( - ctxt, capi, self.instance, error, exc_info=exc_info) + ctxt, self.instance, error, exc_info=exc_info) except Exception: LOG.debug(_("Error setting instance fault."), exc_info=True)