summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwhoami-rajat <rajatdhasmana@gmail.com>2018-10-01 12:55:43 +0530
committerwhoami-rajat <rajatdhasmana@gmail.com>2022-02-24 23:13:19 +0530
commit12075cb71067563f60de929e61f79eae33b2c2ec (patch)
tree665a82bcf7e08994cbb96bdf2b0cc042d5034a4e
parentaf3bc66a5fe2a1ab37d537b6cfe1f5dfb5659002 (diff)
downloadpython-cinderclient-12075cb71067563f60de929e61f79eae33b2c2ec.tar.gz
Add volume reimage command
A new reimage API will be introduced on cinder API side with change in depends on. This patch provides the CLI support for the same by adding a reimage command. Implements: blueprint add-volume-re-image-api Change-Id: I37c254d4caf2f416e456ff6a78b5a4df4e08a176
-rw-r--r--cinderclient/api_versions.py2
-rw-r--r--cinderclient/tests/unit/v3/fakes.py2
-rw-r--r--cinderclient/tests/unit/v3/fakes_base.py2
-rw-r--r--cinderclient/tests/unit/v3/test_shell.py15
-rw-r--r--cinderclient/tests/unit/v3/test_volumes.py12
-rw-r--r--cinderclient/v3/shell.py20
-rw-r--r--cinderclient/v3/volumes.py22
-rw-r--r--releasenotes/notes/reimage-volume-fea3a1178662e65a.yaml10
8 files changed, 84 insertions, 1 deletions
diff --git a/cinderclient/api_versions.py b/cinderclient/api_versions.py
index 48e00b7..dc2a88d 100644
--- a/cinderclient/api_versions.py
+++ b/cinderclient/api_versions.py
@@ -26,7 +26,7 @@ LOG = logging.getLogger(__name__)
# key is unsupported version, value is appropriate supported alternative
REPLACEMENT_VERSIONS = {"1": "3", "2": "3"}
-MAX_VERSION = "3.66"
+MAX_VERSION = "3.68"
MIN_VERSION = "3.0"
_SUBSTITUTIONS = {}
diff --git a/cinderclient/tests/unit/v3/fakes.py b/cinderclient/tests/unit/v3/fakes.py
index d39dd4b..f21c2ab 100644
--- a/cinderclient/tests/unit/v3/fakes.py
+++ b/cinderclient/tests/unit/v3/fakes.py
@@ -453,6 +453,8 @@ class FakeHTTPClient(fakes_base.FakeHTTPClient):
'failover_replication', 'list_replication_targets',
'reset_status'):
assert action in body
+ elif action == 'os-reimage':
+ assert 'image_id' in body[action]
else:
raise AssertionError("Unexpected action: %s" % action)
return (resp, {}, {})
diff --git a/cinderclient/tests/unit/v3/fakes_base.py b/cinderclient/tests/unit/v3/fakes_base.py
index ec75ff0..b5f2728 100644
--- a/cinderclient/tests/unit/v3/fakes_base.py
+++ b/cinderclient/tests/unit/v3/fakes_base.py
@@ -550,6 +550,8 @@ class FakeHTTPClient(base_client.HTTPClient):
_body = body
elif action == 'revert':
assert 'snapshot_id' in body[action]
+ elif action == 'os-reimage':
+ assert 'image_id' in body[action]
else:
raise AssertionError("Unexpected action: %s" % action)
return (resp, {}, _body)
diff --git a/cinderclient/tests/unit/v3/test_shell.py b/cinderclient/tests/unit/v3/test_shell.py
index 8f00525..9eb6ce3 100644
--- a/cinderclient/tests/unit/v3/test_shell.py
+++ b/cinderclient/tests/unit/v3/test_shell.py
@@ -1895,3 +1895,18 @@ class ShellTest(utils.TestCase):
'volume_id': '1234',
'volume_name': volume_name,
})
+
+ def test_reimage(self):
+ self.run_command('--os-volume-api-version 3.68 reimage 1234 1')
+ expected = {'os-reimage': {'image_id': '1',
+ 'reimage_reserved': False}}
+ self.assert_called('POST', '/volumes/1234/action', body=expected)
+
+ @ddt.data('False', 'True')
+ def test_reimage_reserved(self, reimage_reserved):
+ self.run_command(
+ '--os-volume-api-version 3.68 reimage --reimage-reserved %s 1234 1'
+ % reimage_reserved)
+ expected = {'os-reimage': {'image_id': '1',
+ 'reimage_reserved': reimage_reserved}}
+ self.assert_called('POST', '/volumes/1234/action', body=expected)
diff --git a/cinderclient/tests/unit/v3/test_volumes.py b/cinderclient/tests/unit/v3/test_volumes.py
index c733a09..1c2f8a2 100644
--- a/cinderclient/tests/unit/v3/test_volumes.py
+++ b/cinderclient/tests/unit/v3/test_volumes.py
@@ -201,3 +201,15 @@ class VolumesTest(utils.TestCase):
'force_host_copy': False,
'lock_volume': False}})
self._assert_request_id(vol)
+
+ @ddt.data(False, True)
+ def test_reimage(self, reimage_reserved):
+ cs = fakes.FakeClient(api_versions.APIVersion('3.68'))
+ v = cs.volumes.get('1234')
+ self._assert_request_id(v)
+ vol = cs.volumes.reimage(v, '1', reimage_reserved)
+ cs.assert_called('POST', '/volumes/1234/action',
+ {'os-reimage': {'image_id': '1',
+ 'reimage_reserved':
+ reimage_reserved}})
+ self._assert_request_id(vol)
diff --git a/cinderclient/v3/shell.py b/cinderclient/v3/shell.py
index 27f2c7f..60239c7 100644
--- a/cinderclient/v3/shell.py
+++ b/cinderclient/v3/shell.py
@@ -2858,3 +2858,23 @@ def do_default_type_unset(cs, args):
except Exception as e:
print("Unset for default volume type for project %s failed: %s"
% (project_id, e))
+
+
+@api_versions.wraps('3.68')
+@utils.arg('volume',
+ metavar='<volume>',
+ help='Name or ID of volume to reimage')
+@utils.arg('image_id',
+ metavar='<image-id>',
+ help='The image id of the image that will be used to reimage '
+ 'the volume.')
+@utils.arg('--reimage-reserved',
+ metavar='<True|False>',
+ default=False,
+ help='Enables or disables reimage for a volume that is in '
+ 'reserved state otherwise only volumes in "available" '
+ ' or "error" status may be re-imaged. Default=False.')
+def do_reimage(cs, args):
+ """Rebuilds a volume, overwriting all content with the specified image"""
+ volume = utils.find_volume(cs, args.volume)
+ volume.reimage(args.image_id, args.reimage_reserved)
diff --git a/cinderclient/v3/volumes.py b/cinderclient/v3/volumes.py
index 42527f7..0479dc3 100644
--- a/cinderclient/v3/volumes.py
+++ b/cinderclient/v3/volumes.py
@@ -67,6 +67,10 @@ class Volume(volumes_base.Volume):
metadata=metadata, bootable=bootable,
cluster=cluster)
+ def reimage(self, image_id, reimage_reserved=False):
+ """Rebuilds the volume with the new specified image"""
+ self.manager.reimage(self, image_id, reimage_reserved)
+
class VolumeManager(volumes_base.VolumeManager):
resource_class = Volume
@@ -282,3 +286,21 @@ class VolumeManager(volumes_base.VolumeManager):
search_opts=options)
return self._get(url, None)
+
+ @api_versions.wraps('3.68')
+ def reimage(self, volume, image_id, reimage_reserved=False):
+ """Reimage a volume
+
+ .. warning:: This is a destructive action and the contents of the
+ volume will be lost.
+
+ :param volume: Volume to reimage.
+ :param reimage_reserved: Boolean to enable or disable reimage
+ of a volume that is in 'reserved' state otherwise only
+ volumes in 'available' status may be re-imaged.
+ :param image_id: The image id.
+ """
+ return self._action('os-reimage',
+ volume,
+ {'image_id': image_id,
+ 'reimage_reserved': reimage_reserved})
diff --git a/releasenotes/notes/reimage-volume-fea3a1178662e65a.yaml b/releasenotes/notes/reimage-volume-fea3a1178662e65a.yaml
new file mode 100644
index 0000000..a95fb1f
--- /dev/null
+++ b/releasenotes/notes/reimage-volume-fea3a1178662e65a.yaml
@@ -0,0 +1,10 @@
+---
+features:
+ - |
+ A new ``cinder reimage`` command and related python API binding has been
+ added which allows a user to replace the current content of a specified
+ volume with the data of a specified image supplied by the Image service
+ (Glance). (Note that this is a destructive action, that is, all data
+ currently contained in the volume is destroyed when the volume is
+ re-imaged.) This feature requires Block Storage API microversion 3.68
+ or greater.