Merge "Support cross AZ backups"

This commit is contained in:
Zuul
2018-03-27 08:10:24 +00:00
committed by Gerrit Code Review
4 changed files with 76 additions and 28 deletions

View File

@@ -1107,6 +1107,19 @@ class ShellTest(utils.TestCase):
'metadata': {'foo': 'bar'}, }}
self.assert_called('POST', '/backups', body=expected)
def test_backup_with_az(self):
self.run_command('--os-volume-api-version 3.51 backup-create '
'--availability-zone AZ2 --name 1234 1234')
expected = {'backup': {'volume_id': 1234,
'container': None,
'name': '1234',
'description': None,
'incremental': False,
'force': False,
'snapshot_id': None,
'availability_zone': 'AZ2'}}
self.assert_called('POST', '/backups', body=expected)
@mock.patch("cinderclient.utils.print_list")
def test_snapshot_list_with_userid(self, mock_print_list):
"""Ensure 3.41 provides User ID header."""

View File

@@ -2332,6 +2332,11 @@ def do_service_get_log(cs, args):
default=None,
start_version='3.43',
help='Metadata key and value pairs. Default=None.')
@utils.arg('--availability-zone',
default=None,
start_version='3.51',
help='AZ where the backup should be stored, by default it will be '
'the same as the source.')
def do_backup_create(cs, args):
"""Creates a volume backup."""
if args.display_name is not None:
@@ -2340,25 +2345,22 @@ def do_backup_create(cs, args):
if args.display_description is not None:
args.description = args.display_description
volume = utils.find_volume(cs, args.volume)
if hasattr(args, 'metadata') and args.metadata:
backup = cs.backups.create(volume.id,
args.container,
args.name,
args.description,
args.incremental,
args.force,
args.snapshot_id,
shell_utils.extract_metadata(args))
else:
backup = cs.backups.create(volume.id,
args.container,
args.name,
args.description,
args.incremental,
args.force,
args.snapshot_id)
kwargs = {}
if getattr(args, 'metadata', None):
kwargs['metadata'] = shell_utils.extract_metadata(args)
az = getattr(args, 'availability_zone', None)
if az:
kwargs['availability_zone'] = az
volume = utils.find_volume(cs, args.volume)
backup = cs.backups.create(volume.id,
args.container,
args.name,
args.description,
args.incremental,
args.force,
args.snapshot_id,
**kwargs)
info = {"volume_id": volume.id}
info.update(backup._info)

View File

@@ -57,14 +57,8 @@ class VolumeBackupManager(volume_backups.VolumeBackupManager):
the new backup will be based on the snapshot.
:rtype: :class:`VolumeBackup`
"""
body = {'backup': {'volume_id': volume_id,
'container': container,
'name': name,
'description': description,
'incremental': incremental,
'force': force,
'snapshot_id': snapshot_id, }}
return self._create('/backups', body, 'backup')
return self._create_backup(volume_id, container, name, description,
incremental, force, snapshot_id)
@api_versions.wraps("3.43") # noqa: F811
def create(self, volume_id, container=None,
@@ -87,12 +81,46 @@ class VolumeBackupManager(volume_backups.VolumeBackupManager):
:rtype: :class:`VolumeBackup`
"""
# pylint: disable=function-redefined
return self._create_backup(volume_id, container, name, description,
incremental, force, snapshot_id, metadata)
@api_versions.wraps("3.51") # noqa: F811
def create(self, volume_id, container=None, name=None, description=None,
incremental=False, force=False, snapshot_id=None, metadata=None,
availability_zone=None):
return self._create_backup(volume_id, container, name, description,
incremental, force, snapshot_id, metadata,
availability_zone)
def _create_backup(self, volume_id, container=None, name=None,
description=None, incremental=False, force=False,
snapshot_id=None, metadata=None,
availability_zone=None):
"""Creates a volume backup.
:param volume_id: The ID of the volume to backup.
:param container: The name of the backup service container.
:param name: The name of the backup.
:param description: The description of the backup.
:param incremental: Incremental backup.
:param force: If True, allows an in-use volume to be backed up.
:param metadata: Key Value pairs
:param snapshot_id: The ID of the snapshot to backup. This should
be a snapshot of the src volume, when specified,
the new backup will be based on the snapshot.
:param availability_zone: The AZ where we want the backup stored.
:rtype: :class:`VolumeBackup`
"""
# pylint: disable=function-redefined
body = {'backup': {'volume_id': volume_id,
'container': container,
'name': name,
'description': description,
'incremental': incremental,
'force': force,
'snapshot_id': snapshot_id,
'metadata': metadata, }}
'snapshot_id': snapshot_id, }}
if metadata:
body['backup']['metadata'] = metadata
if availability_zone:
body['backup']['availability_zone'] = availability_zone
return self._create('/backups', body, 'backup')

View File

@@ -0,0 +1,5 @@
---
features:
- |
Support cross AZ backup creation specifying desired backup service AZ
(added in microversion v3.51)