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:
parent
eaee74bba2
commit
20ae54045c
@ -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>
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
6
releasenotes/notes/bug-1535213-c91133586e07d71c.yaml
Normal file
6
releasenotes/notes/bug-1535213-c91133586e07d71c.yaml
Normal 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>`_]
|
Loading…
Reference in New Issue
Block a user