diff --git a/cinderclient/shell_utils.py b/cinderclient/shell_utils.py index 451552e3c..e05d90774 100644 --- a/cinderclient/shell_utils.py +++ b/cinderclient/shell_utils.py @@ -26,12 +26,13 @@ _quota_resources = ['volumes', 'snapshots', 'gigabytes', _quota_infos = ['Type', 'In_use', 'Reserved', 'Limit', 'Allocated'] -def print_volume_image(image): - if 'volume_type' in image[1]['os-volume_upload_image']: - volume_type_name = ( - image[1]['os-volume_upload_image']['volume_type']['name']) - image[1]['os-volume_upload_image']['volume_type'] = volume_type_name - utils.print_dict(image[1]['os-volume_upload_image']) +def print_volume_image(image_resp_tuple): + # image_resp_tuple = tuple (response, body) + image = image_resp_tuple[1] + vt = image['os-volume_upload_image'].get('volume_type') + if vt is not None: + image['os-volume_upload_image']['volume_type'] = vt.get('name') + utils.print_dict(image['os-volume_upload_image']) def poll_for_status(poll_fn, obj_id, action, final_ok_states, diff --git a/cinderclient/tests/unit/test_shell.py b/cinderclient/tests/unit/test_shell.py index b94b8b9bf..705089232 100644 --- a/cinderclient/tests/unit/test_shell.py +++ b/cinderclient/tests/unit/test_shell.py @@ -513,3 +513,31 @@ class TestLoadVersionedActions(utils.TestCase): mock_add_arg.call_args_list) self.assertIn(mock.call('--foo', help="second foo"), mock_add_arg.call_args_list) + + +class ShellUtilsTest(utils.TestCase): + + @mock.patch.object(cinderclient.utils, 'print_dict') + def test_print_volume_image(self, mock_print_dict): + response = {'os-volume_upload_image': {'name': 'myimg1'}} + image_resp_tuple = (202, response) + cinderclient.shell_utils.print_volume_image(image_resp_tuple) + + response = {'os-volume_upload_image': + {'name': 'myimg2', + 'volume_type': None}} + image_resp_tuple = (202, response) + cinderclient.shell_utils.print_volume_image(image_resp_tuple) + + response = {'os-volume_upload_image': + {'name': 'myimg3', + 'volume_type': {'id': '1234', 'name': 'sometype'}}} + image_resp_tuple = (202, response) + cinderclient.shell_utils.print_volume_image(image_resp_tuple) + + mock_print_dict.assert_has_calls( + (mock.call({'name': 'myimg1'}), + mock.call({'name': 'myimg2', + 'volume_type': None}), + mock.call({'name': 'myimg3', + 'volume_type': 'sometype'}))) diff --git a/cinderclient/v2/volumes.py b/cinderclient/v2/volumes.py index 18a6e250a..c16b3a005 100644 --- a/cinderclient/v2/volumes.py +++ b/cinderclient/v2/volumes.py @@ -352,6 +352,8 @@ class VolumeManager(base.ManagerWithFind): def _action(self, action, volume, info=None, **kwargs): """Perform a volume "action." + + :returns: tuple (response, body) """ body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) diff --git a/cinderclient/v3/shell.py b/cinderclient/v3/shell.py index fefec60e6..121fbd97d 100644 --- a/cinderclient/v3/shell.py +++ b/cinderclient/v3/shell.py @@ -964,19 +964,20 @@ def do_upload_to_image(cs, args): """Uploads volume to Image Service as an image.""" volume = utils.find_volume(cs, args.volume) if cs.api_version >= api_versions.APIVersion("3.1"): - shell_utils.print_volume_image( - volume.upload_to_image(args.force, - args.image_name, - args.container_format, - args.disk_format, - args.visibility, - args.protected)) + (resp, body) = volume.upload_to_image(args.force, + args.image_name, + args.container_format, + args.disk_format, + args.visibility, + args.protected) + + shell_utils.print_volume_image((resp, body)) else: - shell_utils.print_volume_image( - volume.upload_to_image(args.force, - args.image_name, - args.container_format, - args.disk_format)) + (resp, body) = volume.upload_to_image(args.force, + args.image_name, + args.container_format, + args.disk_format) + shell_utils.print_volume_image((resp, body)) @utils.arg('volume', metavar='<volume>', help='ID of volume to migrate.') diff --git a/cinderclient/v3/volumes.py b/cinderclient/v3/volumes.py index 33850a316..d4b9637c6 100644 --- a/cinderclient/v3/volumes.py +++ b/cinderclient/v3/volumes.py @@ -37,6 +37,7 @@ class Volume(volumes.Volume): 3.1-latest). :param protected: Boolean to decide whether prevents image from being deleted (allowed for 3.1-latest). + :returns: tuple (response, body) """ if self.manager.api_version >= api_versions.APIVersion("3.1"): visibility = 'private' if visibility is None else visibility