summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cinderclient/tests/unit/utils.py5
-rw-r--r--cinderclient/tests/unit/v2/test_shell.py26
-rw-r--r--cinderclient/tests/unit/v3/test_shell.py25
-rw-r--r--cinderclient/v2/shell.py43
-rw-r--r--cinderclient/v2/volumes.py28
-rw-r--r--cinderclient/v3/volumes.py4
6 files changed, 104 insertions, 27 deletions
diff --git a/cinderclient/tests/unit/utils.py b/cinderclient/tests/unit/utils.py
index ddf8972..def38bd 100644
--- a/cinderclient/tests/unit/utils.py
+++ b/cinderclient/tests/unit/utils.py
@@ -44,6 +44,11 @@ class TestCase(testtools.TestCase):
self.assertTrue(hasattr(obj, 'request_ids'))
self.assertEqual(REQUEST_ID, obj.request_ids)
+ def assert_called_anytime(self, method, url, body=None,
+ partial_body=None):
+ return self.shell.cs.assert_called_anytime(method, url, body,
+ partial_body)
+
class FixturedTestCase(TestCase):
diff --git a/cinderclient/tests/unit/v2/test_shell.py b/cinderclient/tests/unit/v2/test_shell.py
index d94c302..88c447f 100644
--- a/cinderclient/tests/unit/v2/test_shell.py
+++ b/cinderclient/tests/unit/v2/test_shell.py
@@ -71,11 +71,6 @@ class ShellTest(utils.TestCase):
return self.shell.cs.assert_called(method, url, body,
partial_body, **kwargs)
- def assert_called_anytime(self, method, url, body=None,
- partial_body=None):
- return self.shell.cs.assert_called_anytime(method, url, body,
- partial_body)
-
def test_list(self):
self.run_command('list')
# NOTE(jdg): we default to detail currently
@@ -359,9 +354,7 @@ class ShellTest(utils.TestCase):
expected = {'os-volume_upload_image': {'force': False,
'container_format': 'bare',
'disk_format': 'raw',
- 'image_name': 'test-image',
- 'protected': False,
- 'visibility': 'private'}}
+ 'image_name': 'test-image'}}
self.run_command('upload-to-image 1234 test-image')
self.assert_called_anytime('GET', '/volumes/1234')
self.assert_called_anytime('POST', '/volumes/1234/action',
@@ -371,27 +364,12 @@ class ShellTest(utils.TestCase):
expected = {'os-volume_upload_image': {'force': 'True',
'container_format': 'bare',
'disk_format': 'raw',
- 'image_name': 'test-image',
- 'protected': False,
- 'visibility': 'private'}}
+ 'image_name': 'test-image'}}
self.run_command('upload-to-image --force=True 1234 test-image')
self.assert_called_anytime('GET', '/volumes/1234')
self.assert_called_anytime('POST', '/volumes/1234/action',
body=expected)
- def test_upload_to_image_public_protected(self):
- expected = {'os-volume_upload_image': {'force': False,
- 'container_format': 'bare',
- 'disk_format': 'raw',
- 'image_name': 'test-image',
- 'protected': 'True',
- 'visibility': 'public'}}
- self.run_command('upload-to-image --visibility=public '
- '--protected=True 1234 test-image')
- self.assert_called_anytime('GET', '/volumes/1234')
- self.assert_called_anytime('POST', '/volumes/1234/action',
- body=expected)
-
def test_create_size_required_if_not_snapshot_or_clone(self):
self.assertRaises(SystemExit, self.run_command, 'create')
diff --git a/cinderclient/tests/unit/v3/test_shell.py b/cinderclient/tests/unit/v3/test_shell.py
index e18f647..35e205d 100644
--- a/cinderclient/tests/unit/v3/test_shell.py
+++ b/cinderclient/tests/unit/v3/test_shell.py
@@ -68,3 +68,28 @@ class ShellTest(utils.TestCase):
def test_list_availability_zone(self):
self.run_command('availability-zone-list')
self.assert_called('GET', '/os-availability-zone')
+
+ def test_upload_to_image(self):
+ expected = {'os-volume_upload_image': {'force': False,
+ 'container_format': 'bare',
+ 'disk_format': 'raw',
+ 'image_name': 'test-image',
+ 'protected': False,
+ 'visibility': 'private'}}
+ self.run_command('upload-to-image 1234 test-image')
+ self.assert_called_anytime('GET', '/volumes/1234')
+ self.assert_called_anytime('POST', '/volumes/1234/action',
+ body=expected)
+
+ def test_upload_to_image_public_protected(self):
+ expected = {'os-volume_upload_image': {'force': False,
+ 'container_format': 'bare',
+ 'disk_format': 'raw',
+ 'image_name': 'test-image',
+ 'protected': 'True',
+ 'visibility': 'public'}}
+ self.run_command('upload-to-image --visibility=public '
+ '--protected=True 1234 test-image')
+ self.assert_called_anytime('GET', '/volumes/1234')
+ self.assert_called_anytime('POST', '/volumes/1234/action',
+ body=expected)
diff --git a/cinderclient/v2/shell.py b/cinderclient/v2/shell.py
index 1e0ddb3..95db39d 100644
--- a/cinderclient/v2/shell.py
+++ b/cinderclient/v2/shell.py
@@ -64,3 +64,46 @@ def _treeizeAvailabilityZone(zone):
return result
+# TODO(e0ne): remove copy-paste of this function in a next cinderclient release
+def _print_volume_image(image):
+ utils.print_dict(image[1]['os-volume_upload_image'])
+
+
+@utils.arg('volume',
+ metavar='<volume>',
+ help='Name or ID of volume to snapshot.')
+@utils.arg('--force',
+ metavar='<True|False>',
+ const=True,
+ nargs='?',
+ default=False,
+ help='Enables or disables upload of '
+ 'a volume that is attached to an instance. '
+ 'Default=False.')
+@utils.arg('--container-format',
+ metavar='<container-format>',
+ default='bare',
+ help='Container format type. '
+ 'Default is bare.')
+@utils.arg('--container_format',
+ help=argparse.SUPPRESS)
+@utils.arg('--disk-format',
+ metavar='<disk-format>',
+ default='raw',
+ help='Disk format type. '
+ 'Default is raw.')
+@utils.arg('--disk_format',
+ help=argparse.SUPPRESS)
+@utils.arg('image_name',
+ metavar='<image-name>',
+ help='The new image name.')
+@utils.arg('--image_name',
+ help=argparse.SUPPRESS)
+@utils.service_type('volumev2')
+def do_upload_to_image(cs, args):
+ """Uploads volume to Image Service as an image."""
+ volume = utils.find_volume(cs, args.volume)
+ _print_volume_image(volume.upload_to_image(args.force,
+ args.image_name,
+ args.container_format,
+ args.disk_format))
diff --git a/cinderclient/v2/volumes.py b/cinderclient/v2/volumes.py
index 093b911..37c87c3 100644
--- a/cinderclient/v2/volumes.py
+++ b/cinderclient/v2/volumes.py
@@ -15,5 +15,31 @@
"""Volume interface (v2 extension)."""
-from cinderclient.v3.volumes import * # flake8: noqa
+from cinderclient import api_versions
+from cinderclient.v3 import volumes
+
+class Volume(volumes.Volume):
+ def upload_to_image(self, force, image_name, container_format,
+ disk_format):
+ """Upload a volume to image service as an image."""
+ return self.manager.upload_to_image(self, force, image_name,
+ container_format, disk_format)
+
+
+class VolumeManager(volumes.VolumeManager):
+ resource_class = Volume
+
+ @api_versions.wraps("2.0")
+ def upload_to_image(self, volume, force, image_name, container_format,
+ disk_format):
+ """Upload volume to image service as image.
+
+ :param volume: The :class:`Volume` to upload.
+ """
+ return self._action('os-volume_upload_image',
+ volume,
+ {'force': force,
+ 'image_name': image_name,
+ 'container_format': container_format,
+ 'disk_format': disk_format})
diff --git a/cinderclient/v3/volumes.py b/cinderclient/v3/volumes.py
index 8d1bc25..c7654d6 100644
--- a/cinderclient/v3/volumes.py
+++ b/cinderclient/v3/volumes.py
@@ -453,9 +453,9 @@ class VolumeManager(base.ManagerWithFind):
"""
return self._action("os-show_image_metadata", volume)
- @api_versions.wraps("2.0", "3.0")
+ @api_versions.wraps("3.0")
def upload_to_image(self, volume, force, image_name, container_format,
- disk_format, visibility, protected):
+ disk_format):
"""Upload volume to image service as image.
:param volume: The :class:`Volume` to upload.