summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nova/cells/messaging.py6
-rw-r--r--nova/compute/api.py3
-rw-r--r--nova/compute/instance_actions.py1
-rw-r--r--nova/compute/manager.py1
-rw-r--r--nova/tests/unit/cells/test_cells_messaging.py9
-rw-r--r--nova/tests/unit/compute/test_compute.py15
-rw-r--r--nova/tests/unit/compute/test_compute_api.py6
-rw-r--r--releasenotes/notes/fill-instance-action-record-gaps-14b36eba313d6d87.yaml1
8 files changed, 34 insertions, 8 deletions
diff --git a/nova/cells/messaging.py b/nova/cells/messaging.py
index 75fb015cb7..f7e7c575fc 100644
--- a/nova/cells/messaging.py
+++ b/nova/cells/messaging.py
@@ -44,6 +44,7 @@ from six.moves import range
from nova.cells import state as cells_state
from nova.cells import utils as cells_utils
from nova import compute
+from nova.compute import instance_actions
from nova.compute import rpcapi as compute_rpcapi
from nova.compute import task_states
from nova.compute import vm_states
@@ -918,6 +919,11 @@ class _TargetedMessageMethods(_BaseMessageMethods):
instance.refresh()
instance.task_state = task_states.IMAGE_BACKUP
instance.save(expected_task_state=[None])
+
+ objects.InstanceAction.action_start(
+ message.ctxt, instance.uuid, instance_actions.BACKUP,
+ want_result=False)
+
self.compute_rpcapi.backup_instance(message.ctxt,
instance,
image_id,
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 85a4a8d429..7b1b94b37b 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -2597,6 +2597,9 @@ class API(base.Base):
instance.task_state = task_states.IMAGE_BACKUP
instance.save(expected_task_state=[None])
+ self._record_action_start(context, instance,
+ instance_actions.BACKUP)
+
self.compute_rpcapi.backup_instance(context, instance,
image_meta['id'],
backup_type,
diff --git a/nova/compute/instance_actions.py b/nova/compute/instance_actions.py
index fe5e5448f6..ec6e0e77a3 100644
--- a/nova/compute/instance_actions.py
+++ b/nova/compute/instance_actions.py
@@ -68,3 +68,4 @@ DETACH_VOLUME = 'detach_volume'
SWAP_VOLUME = 'swap_volume'
LOCK = 'lock'
UNLOCK = 'unlock'
+BACKUP = 'createBackup'
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 046e443db8..fbb19dde65 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -3215,6 +3215,7 @@ class ComputeManager(manager.Manager):
@wrap_exception()
@reverts_task_state
+ @wrap_instance_event(prefix='compute')
@wrap_instance_fault
def backup_instance(self, context, image_id, instance, backup_type,
rotation):
diff --git a/nova/tests/unit/cells/test_cells_messaging.py b/nova/tests/unit/cells/test_cells_messaging.py
index 3e3640727a..5d6d5f2cd6 100644
--- a/nova/tests/unit/cells/test_cells_messaging.py
+++ b/nova/tests/unit/cells/test_cells_messaging.py
@@ -26,6 +26,7 @@ from oslo_utils import timeutils
from nova.cells import messaging
from nova.cells import rpcapi as cells_rpcapi
from nova.cells import utils as cells_utils
+from nova.compute import instance_actions
from nova.compute import task_states
from nova.compute import vm_states
import nova.conf
@@ -1371,8 +1372,9 @@ class CellsTargetedMethodsTestCase(test.NoDBTestCase):
meth_cls.snapshot_instance(message, inst, image_id='image-id')
- def test_backup_instance(self):
- inst = objects.Instance()
+ @mock.patch.object(objects.InstanceAction, 'action_start')
+ def test_backup_instance(self, action_start):
+ inst = objects.Instance(uuid=uuids.instance)
meth_cls = self.tgt_methods_cls
self.mox.StubOutWithMock(inst, 'refresh')
@@ -1404,6 +1406,9 @@ class CellsTargetedMethodsTestCase(test.NoDBTestCase):
image_id='image-id',
backup_type='backup-type',
rotation='rotation')
+ action_start.assert_called_once_with(
+ message.ctxt, inst.uuid, instance_actions.BACKUP,
+ want_result=False)
def test_set_admin_password(self):
args = ['fake-password']
diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py
index 220a873c26..3f74ca25f6 100644
--- a/nova/tests/unit/compute/test_compute.py
+++ b/nova/tests/unit/compute/test_compute.py
@@ -3398,11 +3398,16 @@ class ComputeTestCase(BaseTestCase,
self.context, image_id='fakesnap',
instance=inst_obj)
else:
- self.assertRaises(test.TestingException,
- self.compute.backup_instance,
- self.context, image_id='fakesnap',
- instance=inst_obj, backup_type='fake',
- rotation=1)
+ with mock.patch.object(compute_utils,
+ 'EventReporter') as mock_event:
+ self.assertRaises(test.TestingException,
+ self.compute.backup_instance,
+ self.context, image_id='fakesnap',
+ instance=inst_obj, backup_type='fake',
+ rotation=1)
+ mock_event.assert_called_once_with(self.context,
+ 'compute_backup_instance',
+ inst_obj.uuid)
self.assertEqual(expected_state, self.fake_image_delete_called)
self._assert_state({'task_state': None})
diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py
index abc5ded184..8eb4aee888 100644
--- a/nova/tests/unit/compute/test_compute_api.py
+++ b/nova/tests/unit/compute/test_compute_api.py
@@ -2485,7 +2485,8 @@ class _ComputeAPIUnitTestMixIn(object):
_do_test()
- def _test_snapshot_and_backup(self, is_snapshot=True,
+ @mock.patch.object(compute_api.API, '_record_action_start')
+ def _test_snapshot_and_backup(self, mock_record, is_snapshot=True,
with_base_ref=False, min_ram=None,
min_disk=None,
create_fails=False,
@@ -2599,6 +2600,9 @@ class _ComputeAPIUnitTestMixIn(object):
'fake-backup-type',
'fake-rotation',
extra_properties=extra_props)
+ mock_record.assert_called_once_with(self.context,
+ instance,
+ instance_actions.BACKUP)
self.assertEqual(fake_image, res)
except test.TestingException:
got_exc = True
diff --git a/releasenotes/notes/fill-instance-action-record-gaps-14b36eba313d6d87.yaml b/releasenotes/notes/fill-instance-action-record-gaps-14b36eba313d6d87.yaml
index a60a723acd..817117d91e 100644
--- a/releasenotes/notes/fill-instance-action-record-gaps-14b36eba313d6d87.yaml
+++ b/releasenotes/notes/fill-instance-action-record-gaps-14b36eba313d6d87.yaml
@@ -11,3 +11,4 @@ features:
* lock
* unlock
* shelveOffload
+ * createBackup