Add support of setting volume's state

OSC does not support to set volume's state, this
patch is going to add this functionality.

Closes-Bug:#1535213
Change-Id: I5bc1c7e81b8ba61c37f4bfd209fc86c5857fb050
Co-Authored-By: Huanxuan Ao <huanxuan.ao@easystack.cn>
This commit is contained in:
Xi Yang 2016-01-18 15:47:23 +08:00 committed by Huanxuan Ao
parent eaee74bba2
commit 20ae54045c
5 changed files with 81 additions and 30 deletions

View File

@ -180,6 +180,7 @@ Set volume properties
[--description <description>] [--description <description>]
[--property <key=value> [...] ] [--property <key=value> [...] ]
[--image-property <key=value> [...] ] [--image-property <key=value> [...] ]
[--state <state>]
<volume> <volume>
.. option:: --name <name> .. option:: --name <name>
@ -209,6 +210,14 @@ Set volume properties
*Volume version 2 only* *Volume version 2 only*
.. option:: --state <state>
New volume state
("available", "error", "creating", "deleting", "in-use",
"attaching", "detaching", "error_deleting" or "maintenance")
*Volume version 2 only*
.. _volume_set-volume: .. _volume_set-volume:
.. describe:: <volume> .. describe:: <volume>

View File

@ -43,9 +43,16 @@ class VolumeTests(common.BaseVolumeTests):
'volume set --name ' + cls.OTHER_NAME + ' ' + cls.NAME) 'volume set --name ' + cls.OTHER_NAME + ' ' + cls.NAME)
cls.assertOutput('', raw_output) cls.assertOutput('', raw_output)
# Set volume state
cls.openstack('volume set --state error ' + cls.OTHER_NAME)
opts = cls.get_opts(["status"])
raw_output_status = cls.openstack(
'volume show ' + cls.OTHER_NAME + opts)
# Delete test volume # Delete test volume
raw_output = cls.openstack('volume delete ' + cls.OTHER_NAME) raw_output = cls.openstack('volume delete ' + cls.OTHER_NAME)
cls.assertOutput('', raw_output) cls.assertOutput('', raw_output)
cls.assertOutput('error\n', raw_output_status)
def test_volume_list(self): def test_volume_list(self):
opts = self.get_opts(self.HEADERS) opts = self.get_opts(self.HEADERS)

View File

@ -814,6 +814,53 @@ class TestVolumeList(TestVolume):
self.assertEqual(datalist, tuple(data)) self.assertEqual(datalist, tuple(data))
class TestVolumeSet(TestVolume):
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
# Get the command object to test
self.cmd = volume.SetVolume(self.app, None)
def test_volume_set_image_property(self):
arglist = [
'--image-property', 'Alpha=a',
'--image-property', 'Beta=b',
self.new_volume.id,
]
verifylist = [
('image_property', {'Alpha': 'a', 'Beta': 'b'}),
('volume', self.new_volume.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns nothing
self.cmd.take_action(parsed_args)
self.volumes_mock.set_image_metadata.assert_called_with(
self.volumes_mock.get().id, parsed_args.image_property)
def test_volume_set_state(self):
arglist = [
'--state', 'error',
self.new_volume.id
]
verifylist = [
('state', 'error'),
('volume', self.new_volume.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.volumes_mock.reset_state.assert_called_with(
self.new_volume.id, 'error')
self.assertIsNone(result)
class TestVolumeShow(TestVolume): class TestVolumeShow(TestVolume):
def setUp(self): def setUp(self):
@ -845,36 +892,6 @@ class TestVolumeShow(TestVolume):
data) data)
class TestVolumeSet(TestVolume):
def setUp(self):
super(TestVolumeSet, self).setUp()
self.new_volume = volume_fakes.FakeVolume.create_one_volume()
self.volumes_mock.create.return_value = self.new_volume
# Get the command object to test
self.cmd = volume.SetVolume(self.app, None)
def test_volume_set_image_property(self):
arglist = [
'--image-property', 'Alpha=a',
'--image-property', 'Beta=b',
self.new_volume.id,
]
verifylist = [
('image_property', {'Alpha': 'a', 'Beta': 'b'}),
('volume', self.new_volume.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns nothing
self.cmd.take_action(parsed_args)
self.volumes_mock.set_image_metadata.assert_called_with(
self.volumes_mock.get().id, parsed_args.image_property)
class TestVolumeUnset(TestVolume): class TestVolumeUnset(TestVolume):
def setUp(self): def setUp(self):

View File

@ -378,6 +378,16 @@ class SetVolume(command.Command):
help=_('Set an image property on this volume ' help=_('Set an image property on this volume '
'(repeat option to set multiple image properties)'), '(repeat option to set multiple image properties)'),
) )
parser.add_argument(
"--state",
metavar="<state>",
choices=['available', 'error', 'creating', 'deleting',
'in-use', 'attaching', 'detaching', 'error_deleting',
'maintenance'],
help=_('New volume state ("available", "error", "creating", '
'"deleting", "in-use", "attaching", "detaching", '
'"error_deleting" or "maintenance")'),
)
return parser return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -400,6 +410,8 @@ class SetVolume(command.Command):
if parsed_args.image_property: if parsed_args.image_property:
volume_client.volumes.set_image_metadata( volume_client.volumes.set_image_metadata(
volume.id, parsed_args.image_property) volume.id, parsed_args.image_property)
if parsed_args.state:
volume_client.volumes.reset_state(volume.id, parsed_args.state)
kwargs = {} kwargs = {}
if parsed_args.name: if parsed_args.name:

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Support a new ``--state`` option for ``volume set`` command that
changes the state of a volume.
[Bug `1535213 <https://bugs.launchpad.net/bugs/1535213>`_]