Add "--type" and "--retype-policy" options to "volume set" command

Add "--type" and "--retype-policy" options to
"volume set" command in volume v2 (v2 only) to
support changing the volume type for a volume

Change-Id: I0153abdb967aee790586a57cef31930e32005c1b
Implements: bp cinder-command-support
This commit is contained in:
Huanxuan Ao 2016-10-18 14:59:28 +08:00
parent 0b5655fae8
commit 4b14f3d0cb
4 changed files with 122 additions and 0 deletions

View File

@ -254,6 +254,8 @@ Set volume properties
[--property <key=value> [...] ]
[--image-property <key=value> [...] ]
[--state <state>]
[--type <volume-type>]
[--retype-policy <retype-policy>]
[--bootable | --non-bootable]
[--read-only | --read-write]
<volume>
@ -274,6 +276,20 @@ Set volume properties
Set a property on this volume (repeat option to set multiple properties)
.. option:: --type <volume-type>
New volume type (name or ID)
*Volume version 2 only*
.. option:: --retype-policy <retype-policy>
Migration policy while re-typing volume
("never" or "on-demand", default is "never" )
(available only when "--type" option is specified)
*Volume version 2 only*
.. option:: --bootable
Mark volume as bootable

View File

@ -46,6 +46,9 @@ class TestVolume(volume_fakes.TestVolume):
self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
self.snapshots_mock.reset_mock()
self.types_mock = self.app.client_manager.volume.volume_types
self.types_mock.reset_mock()
self.consistencygroups_mock = (
self.app.client_manager.volume.consistencygroups)
self.consistencygroups_mock.reset_mock()
@ -1088,11 +1091,14 @@ class TestVolumeMigrate(TestVolume):
class TestVolumeSet(TestVolume):
volume_type = volume_fakes.FakeType.create_one_type()
def setUp(self):
super(TestVolumeSet, self).setUp()
self.new_volume = volume_fakes.FakeVolume.create_one_volume()
self.volumes_mock.get.return_value = self.new_volume
self.types_mock.get.return_value = self.volume_type
# Get the command object to test
self.cmd = volume.SetVolume(self.app, None)
@ -1221,6 +1227,66 @@ class TestVolumeSet(TestVolume):
False)
self.assertIsNone(result)
def test_volume_set_type(self):
arglist = [
'--type', self.volume_type.id,
self.new_volume.id
]
verifylist = [
('retype_policy', None),
('type', self.volume_type.id),
('volume', self.new_volume.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.volumes_mock.retype.assert_called_once_with(
self.new_volume.id,
self.volume_type.id,
'never')
self.assertIsNone(result)
def test_volume_set_type_with_policy(self):
arglist = [
'--retype-policy', 'on-demand',
'--type', self.volume_type.id,
self.new_volume.id
]
verifylist = [
('retype_policy', 'on-demand'),
('type', self.volume_type.id),
('volume', self.new_volume.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.volumes_mock.retype.assert_called_once_with(
self.new_volume.id,
self.volume_type.id,
'on-demand')
self.assertIsNone(result)
@mock.patch.object(volume.LOG, 'warning')
def test_volume_set_with_only_retype_policy(self, mock_warning):
arglist = [
'--retype-policy', 'on-demand',
self.new_volume.id
]
verifylist = [
('retype_policy', 'on-demand'),
('volume', self.new_volume.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.volumes_mock.retype.assert_not_called()
mock_warning.assert_called_with("'--retype-policy' option will "
"not work without '--type' option")
self.assertIsNone(result)
class TestVolumeShow(TestVolume):

View File

@ -509,6 +509,19 @@ class SetVolume(command.Command):
'in the database with no regard to actual status, '
'exercise caution when using)'),
)
parser.add_argument(
'--type',
metavar='<volume-type>',
help=_('New volume type (name or ID)'),
)
parser.add_argument(
'--retype-policy',
metavar='<retype-policy>',
choices=['never', 'on-demand'],
help=_('Migration policy while re-typing volume '
'("never" or "on-demand", default is "never" ) '
'(available only when "--type" option is specified)'),
)
bootable_group = parser.add_mutually_exclusive_group()
bootable_group.add_argument(
"--bootable",
@ -590,6 +603,28 @@ class SetVolume(command.Command):
LOG.error(_("Failed to set volume read-only access "
"mode flag: %s"), e)
result += 1
if parsed_args.type:
# get the migration policy
migration_policy = 'never'
if parsed_args.retype_policy:
migration_policy = parsed_args.retype_policy
try:
# find the volume type
volume_type = utils.find_resource(
volume_client.volume_types,
parsed_args.type)
# reset to the new volume type
volume_client.volumes.retype(
volume.id,
volume_type.id,
migration_policy)
except Exception as e:
LOG.error(_("Failed to set volume type: %s"), e)
result += 1
elif parsed_args.retype_policy:
# If the "--retype-policy" is specified without "--type"
LOG.warning(_("'--retype-policy' option will not work "
"without '--type' option"))
kwargs = {}
if parsed_args.name:

View File

@ -0,0 +1,5 @@
---
features:
- |
Add ``--type`` and ``--retype-policy`` options to ``volume set`` command.
[Blueprint `cinder-command-support <https://blueprints.launchpad.net/python-openstackclient/+spec/cinder-command-support>`_]