Raise exception when backup volume-backed instance
This patch will be backported to Juno and Icehouse so that Nova can fail immediately to let user know that it's not supported in that release. Partial-Bug: #1313573 Change-Id: Ic84fa9e0b9c2d7b6cf49955aa4f0d44ade2b5397
This commit is contained in:
parent
20c47ea3d5
commit
2b94135865
|
@ -289,6 +289,8 @@ class AdminActionsController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'createBackup', id)
|
||||
except exception.InvalidRequest as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
resp = webob.Response(status_int=202)
|
||||
|
||||
|
|
|
@ -69,6 +69,8 @@ class CreateBackupController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'createBackup', id)
|
||||
except exception.InvalidRequest as e:
|
||||
raise webob.exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
resp = webob.Response(status_int=202)
|
||||
|
||||
|
|
|
@ -2120,8 +2120,17 @@ class API(base.Base):
|
|||
:returns: A dict containing image metadata
|
||||
"""
|
||||
props_copy = dict(extra_properties, backup_type=backup_type)
|
||||
image_meta = self._create_image(context, instance, name,
|
||||
'backup', extra_properties=props_copy)
|
||||
|
||||
if self.is_volume_backed_instance(context, instance):
|
||||
# TODO(flwang): The log level will be changed to INFO after
|
||||
# string freeze (Liberty).
|
||||
LOG.debug("It's not supported to backup volume backed instance.",
|
||||
context=context, instance=instance)
|
||||
raise exception.InvalidRequest()
|
||||
else:
|
||||
image_meta = self._create_image(context, instance,
|
||||
name, 'backup',
|
||||
extra_properties=props_copy)
|
||||
|
||||
# NOTE(comstud): Any changes to this method should also be made
|
||||
# to the backup_instance() method in nova/cells/messaging.py
|
||||
|
|
|
@ -272,6 +272,28 @@ class CreateBackupTestsV21(admin_only_action_common.CommonMixin,
|
|||
self.controller._create_backup,
|
||||
self.req, fakes.FAKE_UUID, body=body)
|
||||
|
||||
def test_backup_volume_backed_instance(self):
|
||||
body = {
|
||||
'createBackup': {
|
||||
'name': 'BackupMe',
|
||||
'backup_type': 'daily',
|
||||
'rotation': 3
|
||||
},
|
||||
}
|
||||
|
||||
common.check_img_metadata_properties_quota(self.context, {})
|
||||
instance = self._stub_instance_get()
|
||||
instance.image_ref = None
|
||||
|
||||
self.compute_api.backup(self.context, instance, 'BackupMe', 'daily', 3,
|
||||
extra_properties={}).AndRaise(exception.InvalidRequest())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller._create_backup,
|
||||
self.req, instance['uuid'], body=body)
|
||||
|
||||
|
||||
class CreateBackupTestsV2(CreateBackupTestsV21):
|
||||
create_backup = create_backup_v2
|
||||
|
|
|
@ -1742,6 +1742,13 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||
self.mox.StubOutWithMock(self.compute_api.compute_rpcapi,
|
||||
'backup_instance')
|
||||
|
||||
if not is_snapshot:
|
||||
self.mox.StubOutWithMock(self.compute_api,
|
||||
'is_volume_backed_instance')
|
||||
|
||||
self.compute_api.is_volume_backed_instance(self.context,
|
||||
instance).AndReturn(False)
|
||||
|
||||
image_type = is_snapshot and 'snapshot' or 'backup'
|
||||
|
||||
expected_sys_meta = dict(fake_sys_meta)
|
||||
|
@ -1885,6 +1892,19 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||
self._test_snapshot_and_backup(is_snapshot=False,
|
||||
with_base_ref=True)
|
||||
|
||||
def test_backup_volume_backed_instance(self):
|
||||
instance = self._create_instance_obj()
|
||||
|
||||
with mock.patch.object(self.compute_api,
|
||||
'is_volume_backed_instance',
|
||||
return_value=True) as mock_is_volume_backed:
|
||||
self.assertRaises(exception.InvalidRequest,
|
||||
self.compute_api.backup, self.context,
|
||||
instance, 'fake-name', 'weekly',
|
||||
3, extra_properties={})
|
||||
mock_is_volume_backed.assert_called_once_with(self.context,
|
||||
instance)
|
||||
|
||||
def _test_snapshot_volume_backed(self, quiesce_required, quiesce_fails,
|
||||
vm_state=vm_states.ACTIVE):
|
||||
params = dict(locked=True, vm_state=vm_state)
|
||||
|
|
Loading…
Reference in New Issue