From 2c3169e55e533154bb24e9b1eb9aa94a3e01719a Mon Sep 17 00:00:00 2001 From: Xing Yang Date: Tue, 21 Jul 2015 15:06:39 -0400 Subject: [PATCH] CLI: Non-disruptive backup This is the CLI change required to support non-disruptive backup for volumes in 'in-use' status. A force flag is added to the create backup CLI. The force flag needs to be True when backing up an 'in-use' volume. By default it is False and it is not needed when backing up an 'available' volume. The Cinder server side change is merged: https://review.openstack.org/#/c/193937/ Partial-implements blueprint non-disruptive-backup Change-Id: I53aff3973cc6365a5b1d40c21b0885c1d8166df5 --- cinderclient/tests/unit/v2/test_shell.py | 4 ++++ cinderclient/tests/unit/v2/test_volume_backups.py | 5 +++++ cinderclient/v2/shell.py | 12 +++++++++++- cinderclient/v2/volume_backups.py | 6 ++++-- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py index ba5fcc778..766175424 100644 --- a/cinderclient/tests/unit/v2/test_shell.py +++ b/cinderclient/tests/unit/v2/test_shell.py @@ -359,6 +359,10 @@ class ShellTest(utils.TestCase): self.run_command('backup-create 1234 --incremental') self.assert_called('POST', '/backups') + def test_backup_force(self): + self.run_command('backup-create 1234 --force') + self.assert_called('POST', '/backups') + def test_restore(self): self.run_command('backup-restore 1234') self.assert_called('POST', '/backups/1234/restore') diff --git a/cinderclient/tests/unit/v2/test_volume_backups.py b/cinderclient/tests/unit/v2/test_volume_backups.py index 1b77b9ca8..9a49529b5 100644 --- a/cinderclient/tests/unit/v2/test_volume_backups.py +++ b/cinderclient/tests/unit/v2/test_volume_backups.py @@ -36,6 +36,11 @@ class VolumeBackupsTest(utils.TestCase): None, None, True) cs.assert_called('POST', '/backups') + def test_create_force(self): + cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', + None, None, False, True) + cs.assert_called('POST', '/backups') + def test_get(self): backup_id = '76a17945-3c6f-435c-975b-b5685db10b62' cs.backups.get(backup_id) diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py index acb2348bb..4046381ff 100644 --- a/cinderclient/v2/shell.py +++ b/cinderclient/v2/shell.py @@ -1193,6 +1193,15 @@ def do_retype(cs, args): action='store_true', help='Incremental backup. Default=False.', default=False) +@utils.arg('--force', + action='store_true', + help='Allows or disallows backup of a volume ' + 'when the volume is attached to an instance. ' + 'If set to True, backs up the volume whether ' + 'its status is "available" or "in-use". The backup ' + 'of an "in-use" volume means your data is crash ' + 'consistent. Default=False.', + default=False) @utils.service_type('volumev2') def do_backup_create(cs, args): """Creates a volume backup.""" @@ -1207,7 +1216,8 @@ def do_backup_create(cs, args): args.container, args.name, args.description, - args.incremental) + args.incremental, + args.force) info = {"volume_id": volume.id} info.update(backup._info) diff --git a/cinderclient/v2/volume_backups.py b/cinderclient/v2/volume_backups.py index 59f07242d..70fda6066 100644 --- a/cinderclient/v2/volume_backups.py +++ b/cinderclient/v2/volume_backups.py @@ -38,7 +38,7 @@ class VolumeBackupManager(base.ManagerWithFind): def create(self, volume_id, container=None, name=None, description=None, - incremental=False): + incremental=False, force=False): """Creates a volume backup. :param volume_id: The ID of the volume to backup. @@ -46,13 +46,15 @@ class VolumeBackupManager(base.ManagerWithFind): :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. :rtype: :class:`VolumeBackup` """ body = {'backup': {'volume_id': volume_id, 'container': container, 'name': name, 'description': description, - 'incremental': incremental}} + 'incremental': incremental, + 'force': force, }} return self._create('/backups', body, 'backup') def get(self, backup_id):