From 8e02b2a64145719dd2bcd870983be53dc4330e30 Mon Sep 17 00:00:00 2001 From: Erno Kuvaja Date: Tue, 14 Oct 2014 16:23:45 +0000 Subject: [PATCH] Allow --file in image-create with v2 Image API Allows passing --file and --progress to glance image-create with Image API v2. if --file is present the image-create effectively calls image-upload with the newly created image's id and the '--file' + '--progress' paramaters. The image metadata will be printed after the upload call instead of after creation. In a case argumented file does not exist the image will not be created and error will be printed instead. DocImpact Closes-Bug: #1324067 Change-Id: I5d41fb2bbeb4e56213ae8696b84bf96b749414f8 --- glanceclient/v2/shell.py | 19 ++++++++++++++++- tests/v2/test_shell_v2.py | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index 238fcd3e..4da2d990 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -41,6 +41,12 @@ def get_image_schema(): @utils.arg('--property', metavar="", action='append', default=[], help=('Arbitrary property to associate with image.' ' May be used multiple times.')) +@utils.arg('--file', metavar='', + help='Local file to save downloaded image data to. ' + 'If this is not specified the image data will be ' + 'written to stdout.') +@utils.arg('--progress', action='store_true', default=False, + help='Show upload progress bar.') def do_image_create(gc, args): """Create a new image.""" schema = gc.schemas.get("image") @@ -55,8 +61,19 @@ def do_image_create(gc, args): key, value = datum.split('=', 1) fields[key] = value + file_name = fields.pop('file', None) + if file_name is not None and os.access(file_name, os.R_OK) is False: + utils.exit("File %s does not exist or user does not have read " + "privileges to it" % file_name) image = gc.images.create(**fields) - utils.print_image(image) + try: + if file_name is not None: + args.id = image['id'] + args.size = None + do_image_upload(gc, args) + image = gc.images.get(args.id) + finally: + utils.print_image(image) @utils.arg('id', metavar='', help='ID of image to update.') diff --git a/tests/v2/test_shell_v2.py b/tests/v2/test_shell_v2.py index 0dd4fc33..23894eab 100644 --- a/tests/v2/test_shell_v2.py +++ b/tests/v2/test_shell_v2.py @@ -15,6 +15,8 @@ # under the License. import json import mock +import os +import tempfile import testtools from glanceclient.common import utils @@ -150,6 +152,47 @@ class ShellV2Test(testtools.TestCase): 'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd', 'container_format': 'bare'}) + def test_do_image_create_with_file(self): + try: + file_name = None + with open(tempfile.mktemp(), 'w+') as f: + f.write('Some data here') + f.flush() + f.seek(0) + file_name = f.name + temp_args = {'name': 'IMG-01', + 'disk_format': 'vhd', + 'container_format': 'bare', + 'file': file_name, + 'progress': False} + args = self._make_args(temp_args) + with mock.patch.object(self.gc.images, 'create') as mocked_create: + with mock.patch.object(self.gc.images, 'get') as mocked_get: + + ignore_fields = ['self', 'access', 'schema'] + expect_image = dict([(field, field) for field in + ignore_fields]) + expect_image['id'] = 'pass' + expect_image['name'] = 'IMG-01' + expect_image['disk_format'] = 'vhd' + expect_image['container_format'] = 'bare' + mocked_create.return_value = expect_image + mocked_get.return_value = expect_image + + test_shell.do_image_create(self.gc, args) + + temp_args.pop('file', None) + mocked_create.assert_called_once_with(**temp_args) + mocked_get.assert_called_once_with('pass') + utils.print_dict.assert_called_once_with({ + 'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd', + 'container_format': 'bare'}) + finally: + try: + os.remove(f.name) + except Exception: + pass + def test_do_image_create_with_user_props(self): args = self._make_args({'name': 'IMG-01', 'property': ['myprop=myval']})