Merge "Backups: allow name to be specified during restore"
This commit is contained in:
commit
8e8f7f8016
|
@ -287,6 +287,7 @@ class BackupsController(wsgi.Controller):
|
|||
context = req.environ['cinder.context']
|
||||
restore = body['restore']
|
||||
volume_id = restore.get('volume_id', None)
|
||||
name = restore.get('name', None)
|
||||
|
||||
LOG.info(_LI("Restoring backup %(backup_id)s to volume %(volume_id)s"),
|
||||
{'backup_id': id, 'volume_id': volume_id},
|
||||
|
@ -295,7 +296,8 @@ class BackupsController(wsgi.Controller):
|
|||
try:
|
||||
new_restore = self.backup_api.restore(context,
|
||||
backup_id=id,
|
||||
volume_id=volume_id)
|
||||
volume_id=volume_id,
|
||||
name=name)
|
||||
except exception.InvalidInput as error:
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.InvalidVolume as error:
|
||||
|
|
|
@ -251,7 +251,7 @@ class API(base.Base):
|
|||
|
||||
return backup
|
||||
|
||||
def restore(self, context, backup_id, volume_id=None):
|
||||
def restore(self, context, backup_id, volume_id=None, name=None):
|
||||
"""Make the RPC call to restore a volume backup."""
|
||||
check_policy(context, 'restore')
|
||||
backup = self.get(context, backup_id)
|
||||
|
@ -267,11 +267,13 @@ class API(base.Base):
|
|||
# Create a volume if none specified. If a volume is specified check
|
||||
# it is large enough for the backup
|
||||
if volume_id is None:
|
||||
if name is None:
|
||||
name = 'restore_backup_%s' % backup_id
|
||||
|
||||
description = 'auto-created_from_restore_from_backup'
|
||||
|
||||
LOG.info(_LI("Creating volume of %(size)s GB for restore of "
|
||||
"backup %(backup_id)s"),
|
||||
"backup %(backup_id)s."),
|
||||
{'size': size, 'backup_id': backup_id},
|
||||
context=context)
|
||||
volume = self.volume_api.create(context, size, name, description)
|
||||
|
|
|
@ -993,6 +993,64 @@ class BackupsAPITestCase(test.TestCase):
|
|||
self.assertEqual(res.status_int, 202)
|
||||
self.assertEqual(res_dict['restore']['backup_id'], backup_id)
|
||||
|
||||
@mock.patch('cinder.volume.API.create')
|
||||
def test_restore_backup_name_specified(self,
|
||||
_mock_volume_api_create):
|
||||
|
||||
# Intercept volume creation to ensure created volume
|
||||
# has status of available
|
||||
def fake_volume_api_create(context, size, name, description):
|
||||
volume_id = utils.create_volume(self.context, size=size,
|
||||
display_name=name)['id']
|
||||
return db.volume_get(context, volume_id)
|
||||
|
||||
_mock_volume_api_create.side_effect = fake_volume_api_create
|
||||
|
||||
backup_id = self._create_backup(size=5, status='available')
|
||||
|
||||
body = {"restore": {'name': 'vol-01'}}
|
||||
req = webob.Request.blank('/v2/fake/backups/%s/restore' %
|
||||
backup_id)
|
||||
req.method = 'POST'
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.body = json.dumps(body)
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
res_dict = json.loads(res.body)
|
||||
|
||||
description = 'auto-created_from_restore_from_backup'
|
||||
# Assert that we have indeed passed on the name parameter
|
||||
_mock_volume_api_create.assert_called_once_with(
|
||||
mock.ANY,
|
||||
5,
|
||||
body['restore']['name'],
|
||||
description)
|
||||
|
||||
self.assertEqual(202, res.status_int)
|
||||
self.assertEqual(backup_id, res_dict['restore']['backup_id'])
|
||||
|
||||
def test_restore_backup_name_volume_id_specified(self):
|
||||
|
||||
backup_id = self._create_backup(size=5, status='available')
|
||||
orig_vol_name = "vol-00"
|
||||
volume_id = utils.create_volume(self.context, size=5,
|
||||
display_name=orig_vol_name)['id']
|
||||
body = {"restore": {'name': 'vol-01', 'volume_id': volume_id}}
|
||||
req = webob.Request.blank('/v2/fake/backups/%s/restore' %
|
||||
backup_id)
|
||||
req.method = 'POST'
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.body = json.dumps(body)
|
||||
res = req.get_response(fakes.wsgi_app())
|
||||
res_dict = json.loads(res.body)
|
||||
|
||||
self.assertEqual(202, res.status_int)
|
||||
self.assertEqual(backup_id, res_dict['restore']['backup_id'])
|
||||
self.assertEqual(volume_id, res_dict['restore']['volume_id'])
|
||||
restored_vol = db.volume_get(self.context,
|
||||
res_dict['restore']['volume_id'])
|
||||
# Ensure that the original volume name wasn't overridden
|
||||
self.assertEqual(orig_vol_name, restored_vol['display_name'])
|
||||
|
||||
@mock.patch('cinder.backup.API.restore')
|
||||
def test_restore_backup_with_InvalidInput(self,
|
||||
_mock_volume_api_restore):
|
||||
|
|
Loading…
Reference in New Issue