summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhangbailin <zhangbailin@inspur.com>2020-03-12 18:44:36 +0800
committerzhangbailin <zhangbailin@inspur.com>2020-04-09 08:52:05 +0800
commit4d6c70d25df99a4f28f263cd3160c74ccf1343e3 (patch)
tree64ab8962905dee361f94d2b417081d1e77e5971b
parentea092b29880e71f0ba2d8e1eb93a9cf73edee2a2 (diff)
downloadpython-novaclient-4d6c70d25df99a4f28f263cd3160c74ccf1343e3.tar.gz
Microversion 2.85: Change volume-update CLI
This commit add a new CLI ``nova volume-update [--[no-]delete-on-termination] <server> <src_volume> <dest_volume>`` to update 'delete_on_termination' for an attached volume, that the user can decide whether to delete attached volumes when destroying the server. Depends-On: https://review.opendev.org/#/c/711194/ Change-Id: I1fc64fb6e6611c92c6b72265e1bf4b32e9c45f0a Blueprint: destroy-instance-with-datavolume
-rw-r--r--doc/source/cli/nova.rst29
-rw-r--r--novaclient/__init__.py2
-rw-r--r--novaclient/tests/unit/v2/test_shell.py36
-rw-r--r--novaclient/tests/unit/v2/test_volumes.py23
-rw-r--r--novaclient/v2/shell.py34
-rw-r--r--novaclient/v2/volumes.py30
-rw-r--r--releasenotes/notes/microversion-v2_85-230931f88c4f1d52.yaml16
7 files changed, 153 insertions, 17 deletions
diff --git a/doc/source/cli/nova.rst b/doc/source/cli/nova.rst
index 26c2ce2a..6db1cd0c 100644
--- a/doc/source/cli/nova.rst
+++ b/doc/source/cli/nova.rst
@@ -558,10 +558,12 @@ nova usage
Detach a volume from a server.
``volume-update``
- Update the attachment on the server. Migrates
- the data from an attached volume to the
- specified available volume and swaps out the
- active attachment to the new volume.
+ Update the attachment on the server. Migrates the data from an
+ attached volume to the specified available volume and swaps out
+ the active attachment to the new volume.
+ Since microversion 2.85, support for updating the
+ ``delete_on_termination`` delete flag, which allows changing the
+ behavior of volume deletion on instance deletion.
``x509-create-cert``
**DEPRECATED** Create x509 cert for a user in
@@ -3896,7 +3898,7 @@ Attach a volume to a server.
Tag for the attached volume. (Supported by API versions '2.49' - '2.latest')
``--delete-on-termination``
- Specify if the attached volume sholud be deleted when the server is
+ Specify if the attached volume should be deleted when the server is
destroyed. By default the attached volume is not deleted when the server is
destroyed. (Supported by API versions '2.79' - '2.latest')
@@ -3942,7 +3944,8 @@ nova volume-update
.. code-block:: console
- usage: nova volume-update <server> <src_volid> <dest_volid>
+ usage: nova volume-update [--[no-]delete-on-termination]
+ <server> <src_volume> <dest_volume>
Update the attachment on the server. Migrates the data from an attached volume
to the specified available volume and swaps out the active attachment to the
@@ -3953,12 +3956,22 @@ new volume.
``<server>``
Name or ID of server.
-``<src_volid>``
+``<src_volume>``
ID of the source (original) volume.
-``<dest_volid>``
+``<dest_volume>``
ID of the destination volume.
+**Optional arguments:**
+
+``--delete-on-termination``
+ Specify that the volume should be deleted when the server is destroyed.
+ (Supported by API versions '2.85' - '2.latest')
+
+``--no-delete-on-termination``
+ Specify that the attached volume should not be deleted when
+ the server is destroyed. (Supported by API versions '2.85' - '2.latest')
+
.. _nova_bash-completion:
nova bash-completion
diff --git a/novaclient/__init__.py b/novaclient/__init__.py
index adcb85dd..5e3e7701 100644
--- a/novaclient/__init__.py
+++ b/novaclient/__init__.py
@@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
# when client supported the max version, and bumped sequentially, otherwise
# the client may break due to server side new version may include some
# backward incompatible change.
-API_MAX_VERSION = api_versions.APIVersion("2.84")
+API_MAX_VERSION = api_versions.APIVersion("2.85")
diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py
index 18badc0b..d21252bd 100644
--- a/novaclient/tests/unit/v2/test_shell.py
+++ b/novaclient/tests/unit/v2/test_shell.py
@@ -3992,11 +3992,43 @@ class ShellTest(utils.TestCase):
{'volumeAttachment':
{'volumeId': 'Work'}})
- def test_volume_update(self):
- self.run_command('volume-update sample-server Work Work')
+ def test_volume_update_pre_v285(self):
+ """Before microversion 2.85, we should keep the original behavior"""
+ self.run_command('volume-update sample-server Work Work',
+ api_version='2.84')
self.assert_called('PUT', '/servers/1234/os-volume_attachments/Work',
{'volumeAttachment': {'volumeId': 'Work'}})
+ def test_volume_update_swap_v285(self):
+ """Microversion 2.85, we should also keep the original behavior."""
+ self.run_command('volume-update sample-server Work Work',
+ api_version='2.85')
+ self.assert_called('PUT', '/servers/1234/os-volume_attachments/Work',
+ {'volumeAttachment': {'volumeId': 'Work'}})
+
+ def test_volume_update_v285(self):
+ self.run_command('volume-update sample-server --delete-on-termination '
+ 'Work Work', api_version='2.85')
+ body = {'volumeAttachment':
+ {'volumeId': 'Work', 'delete_on_termination': True}}
+ self.assert_called('PUT', '/servers/1234/os-volume_attachments/Work',
+ body)
+
+ self.run_command('volume-update sample-server '
+ '--no-delete-on-termination '
+ 'Work Work', api_version='2.85')
+ body = {'volumeAttachment':
+ {'volumeId': 'Work', 'delete_on_termination': False}}
+ self.assert_called('PUT', '/servers/1234/os-volume_attachments/Work',
+ body)
+
+ def test_volume_update_v285_conflicting(self):
+ self.assertRaises(
+ SystemExit, self.run_command,
+ 'volume-update sample-server --delete-on-termination '
+ '--no-delete-on-termination Work Work',
+ api_version='2.85')
+
def test_volume_detach(self):
self.run_command('volume-detach sample-server Work')
self.assert_called('DELETE',
diff --git a/novaclient/tests/unit/v2/test_volumes.py b/novaclient/tests/unit/v2/test_volumes.py
index d18f8466..93ea1c96 100644
--- a/novaclient/tests/unit/v2/test_volumes.py
+++ b/novaclient/tests/unit/v2/test_volumes.py
@@ -156,3 +156,26 @@ class VolumesV279Test(VolumesV249Test):
volume_id='15e59938-07d5-11e1-90e3-e3dffe0c5983',
delete_on_termination=True)
self.assertIn('delete_on_termination', str(ex))
+
+
+class VolumesV285Test(VolumesV279Test):
+ api_version = "2.85"
+
+ def test_volume_update_server_volume(self):
+ v = self.cs.volumes.update_server_volume(
+ server_id=1234,
+ src_volid='Work',
+ dest_volid='Work',
+ delete_on_termination=True
+ )
+ self.assert_request_id(v, fakes.FAKE_REQUEST_ID_LIST)
+ self.cs.assert_called('PUT',
+ '/servers/1234/os-volume_attachments/Work')
+ self.assertIsInstance(v, volumes.Volume)
+
+ def test_volume_update_server_volume_pre_v285(self):
+ self.cs.api_version = api_versions.APIVersion('2.84')
+ ex = self.assertRaises(
+ TypeError, self.cs.volumes.update_server_volume, "1234",
+ 'Work', 'Work', delete_on_termination=True)
+ self.assertIn('delete_on_termination', str(ex))
diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py
index ac6c5ea1..e0498df8 100644
--- a/novaclient/v2/shell.py
+++ b/novaclient/v2/shell.py
@@ -2730,22 +2730,44 @@ def do_volume_attach(cs, args):
help=_('Name or ID of server.'))
@utils.arg(
'src_volume',
- metavar='<src_volid>',
+ metavar='<src_volume>',
help=_('ID of the source (original) volume.'))
@utils.arg(
'dest_volume',
- metavar='<dest_volid>',
+ metavar='<dest_volume>',
help=_('ID of the destination volume.'))
+@utils.arg(
+ '--delete-on-termination',
+ default=None,
+ group='delete_on_termination',
+ action='store_true',
+ help=_('Specify that the volume should be deleted '
+ 'when the server is destroyed.'),
+ start_version='2.85')
+@utils.arg(
+ '--no-delete-on-termination',
+ group='delete_on_termination',
+ action='store_false',
+ help=_('Specify that the volume should not be deleted '
+ 'when the server is destroyed.'),
+ start_version='2.85')
def do_volume_update(cs, args):
"""Update the attachment on the server.
- Migrates the data from an attached volume to the
- specified available volume and swaps out the active
- attachment to the new volume.
+ If dest_volume is the same as the src_volume then the command migrates
+ the data from the attached volume to the specified available volume
+ and swaps out the active attachment to the new volume. Otherwise it
+ only updates the parameters of the existing attachment.
"""
+ kwargs = dict()
+ if (cs.api_version >= api_versions.APIVersion('2.85') and
+ args.delete_on_termination is not None):
+ kwargs['delete_on_termination'] = args.delete_on_termination
+
cs.volumes.update_server_volume(_find_server(cs, args.server).id,
args.src_volume,
- args.dest_volume)
+ args.dest_volume,
+ **kwargs)
@utils.arg(
diff --git a/novaclient/v2/volumes.py b/novaclient/v2/volumes.py
index 8fc75565..7153c835 100644
--- a/novaclient/v2/volumes.py
+++ b/novaclient/v2/volumes.py
@@ -103,6 +103,7 @@ class VolumeManager(base.Manager):
return self._create("/servers/%s/os-volume_attachments" % server_id,
body, "volumeAttachment")
+ @api_versions.wraps("2.0", "2.84")
def update_server_volume(self, server_id, src_volid, dest_volid):
"""
Swaps the existing volume attachment to point to a new volume.
@@ -124,6 +125,35 @@ class VolumeManager(base.Manager):
(server_id, src_volid,),
body, "volumeAttachment")
+ @api_versions.wraps("2.85")
+ def update_server_volume(self, server_id, src_volid, dest_volid,
+ delete_on_termination=None):
+ """
+ Swaps the existing volume attachment to point to a new volume.
+
+ Takes a server, a source (attached) volume and a destination volume and
+ performs a hypervisor assisted data migration from src to dest volume,
+ detaches the original (source) volume and attaches the new destination
+ volume. Note that not all backing hypervisor drivers support this
+ operation and it may be disabled via policy.
+
+
+ :param server_id: The ID of the server
+ :param source_volume: The ID of the src volume
+ :param dest_volume: The ID of the destination volume
+ :param delete_on_termination: Marked whether to delete the attached
+ volume when the server is deleted
+ (optional).
+ :rtype: :class:`Volume`
+ """
+ body = {'volumeAttachment': {'volumeId': dest_volid}}
+ if delete_on_termination is not None:
+ body['volumeAttachment']['delete_on_termination'] = (
+ delete_on_termination)
+ return self._update("/servers/%s/os-volume_attachments/%s" %
+ (server_id, src_volid),
+ body, "volumeAttachment")
+
def get_server_volume(self, server_id, volume_id=None, attachment_id=None):
"""
Get the volume identified by the volume ID, that is attached to
diff --git a/releasenotes/notes/microversion-v2_85-230931f88c4f1d52.yaml b/releasenotes/notes/microversion-v2_85-230931f88c4f1d52.yaml
new file mode 100644
index 00000000..859534c4
--- /dev/null
+++ b/releasenotes/notes/microversion-v2_85-230931f88c4f1d52.yaml
@@ -0,0 +1,16 @@
+---
+features:
+ - |
+ Support is added for compute API `microversion 2.85`_. This adds the
+ ability to update an attached volume with a ``delete_on_termination``,
+ which specify if the attached volume should be deleted when the server
+ is destroyed.
+
+ - The ``--delete-on-termination`` and ``--no-delete-on-termination``
+ options are added to the ``nova volume-update`` CLI.
+ - New kwarg called ``delete_on_termination`` added to the python API
+ binding:
+
+ - ``novaclient.v2.volumes.VolumeManager.update_server_volume()``
+
+ .. _microversion 2.85: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id78