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
This commit is contained in:
@@ -41,6 +41,12 @@ def get_image_schema():
|
|||||||
@utils.arg('--property', metavar="<key=value>", action='append',
|
@utils.arg('--property', metavar="<key=value>", action='append',
|
||||||
default=[], help=('Arbitrary property to associate with image.'
|
default=[], help=('Arbitrary property to associate with image.'
|
||||||
' May be used multiple times.'))
|
' May be used multiple times.'))
|
||||||
|
@utils.arg('--file', metavar='<FILE>',
|
||||||
|
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):
|
def do_image_create(gc, args):
|
||||||
"""Create a new image."""
|
"""Create a new image."""
|
||||||
schema = gc.schemas.get("image")
|
schema = gc.schemas.get("image")
|
||||||
@@ -55,7 +61,18 @@ def do_image_create(gc, args):
|
|||||||
key, value = datum.split('=', 1)
|
key, value = datum.split('=', 1)
|
||||||
fields[key] = value
|
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)
|
image = gc.images.create(**fields)
|
||||||
|
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.print_image(image)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
import json
|
import json
|
||||||
import mock
|
import mock
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from glanceclient.common import utils
|
from glanceclient.common import utils
|
||||||
@@ -150,6 +152,47 @@ class ShellV2Test(testtools.TestCase):
|
|||||||
'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd',
|
'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd',
|
||||||
'container_format': 'bare'})
|
'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):
|
def test_do_image_create_with_user_props(self):
|
||||||
args = self._make_args({'name': 'IMG-01',
|
args = self._make_args({'name': 'IMG-01',
|
||||||
'property': ['myprop=myval']})
|
'property': ['myprop=myval']})
|
||||||
|
Reference in New Issue
Block a user