summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranaliD <pdeore@redhat.com>2018-03-12 05:38:34 -0400
committerErno Kuvaja <jokke@usr.fi>2018-03-22 12:06:58 +0000
commit75775a133d22d377522ba6c1093b751dad7efd3c (patch)
treec97913de2ee6f16d263aebc9b2b9c02fa5c7ea53
parentbb5465636880af6aec4926fb32fc3dd1c8e80be5 (diff)
downloadpython-glanceclient-75775a133d22d377522ba6c1093b751dad7efd3c.tar.gz
Add support for web-download import method
This change adds support for 'web-download' import method to 'image-import' and 'create-image-via-import' call. To use this 'web-download' import method, user needs to pass --uri option 'a valid uri to external image to import in glance' to 'image-import' and 'create-image-via-imaport' calls. Co-authored-by: Pranali Deore <pdeore@redhat.com> Co-authored-by: Erno Kuvaja <jokke@usr.fi> Closes-Bug: #1758039 Change-Id: I0e1d18844f64723608288de473e97710798eb602 (cherry picked from commit aedabec9e46e80266cdefb315f112a30927e216a)
-rw-r--r--glanceclient/tests/unit/v2/base.py4
-rw-r--r--glanceclient/tests/unit/v2/test_images.py13
-rw-r--r--glanceclient/tests/unit/v2/test_shell_v2.py38
-rw-r--r--glanceclient/v2/images.py8
-rw-r--r--glanceclient/v2/shell.py26
5 files changed, 83 insertions, 6 deletions
diff --git a/glanceclient/tests/unit/v2/base.py b/glanceclient/tests/unit/v2/base.py
index 7391595..d6f5cc5 100644
--- a/glanceclient/tests/unit/v2/base.py
+++ b/glanceclient/tests/unit/v2/base.py
@@ -106,6 +106,10 @@ class BaseController(testtools.TestCase):
resp = self.controller.deassociate(*args)
self._assertRequestId(resp)
+ def image_import(self, *args):
+ resp = self.controller.image_import(*args)
+ self._assertRequestId(resp)
+
class BaseResourceTypeController(BaseController):
def __init__(self, api, schema_api, controller_class):
diff --git a/glanceclient/tests/unit/v2/test_images.py b/glanceclient/tests/unit/v2/test_images.py
index 579392b..23cbb43 100644
--- a/glanceclient/tests/unit/v2/test_images.py
+++ b/glanceclient/tests/unit/v2/test_images.py
@@ -215,6 +215,9 @@ data_fixtures = {
'/v2/images/87b634c1-f893-33c9-28a9-e5673c99239a/actions/deactivate': {
'POST': ({}, None)
},
+ '/v2/images/606b0e88-7c5a-4d54-b5bb-046105d4de6f/import': {
+ 'POST': ({}, None)
+ },
'/v2/images?limit=%d&visibility=public' % images.DEFAULT_PAGE_SIZE: {
'GET': (
{},
@@ -867,6 +870,16 @@ class TestController(testtools.TestCase):
body = ''.join([b for b in body])
self.assertEqual('CCC', body)
+ def test_image_import(self):
+ uri = 'http://example.com/image.qcow'
+ data = [('method', {'name': 'web-download',
+ 'uri': uri})]
+ image_id = '606b0e88-7c5a-4d54-b5bb-046105d4de6f'
+ self.controller.image_import(image_id, 'web-download', uri)
+ expect = [('POST', '/v2/images/%s/import' % image_id, {},
+ data)]
+ self.assertEqual(expect, self.api.calls)
+
def test_download_no_data(self):
resp = utils.FakeResponse(headers={}, status_code=204)
self.controller.controller.http_client.get = mock.Mock(
diff --git a/glanceclient/tests/unit/v2/test_shell_v2.py b/glanceclient/tests/unit/v2/test_shell_v2.py
index d75613f..10bf215 100644
--- a/glanceclient/tests/unit/v2/test_shell_v2.py
+++ b/glanceclient/tests/unit/v2/test_shell_v2.py
@@ -447,6 +447,33 @@ class ShellV2Test(testtools.TestCase):
utils.print_dict.assert_called_once_with({
'id': 'pass', 'name': 'IMG-01', 'myprop': 'myval'})
+ def test_do_image_create_via_import_with_web_download(self):
+ temp_args = {'name': 'IMG-01',
+ 'disk_format': 'vhd',
+ 'container_format': 'bare',
+ 'uri': 'http://example.com/image.qcow',
+ 'import_method': 'web-download',
+ '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_via_import(self.gc, args)
+
+ mocked_create.assert_called_once_with(**temp_args)
+ mocked_get.assert_called_with('pass')
+ utils.print_dict.assert_called_with({
+ 'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd',
+ 'container_format': 'bare'})
+
def test_do_image_update_no_user_props(self):
args = self._make_args({'id': 'pass', 'name': 'IMG-01',
'disk_format': 'vhd',
@@ -577,6 +604,17 @@ class ShellV2Test(testtools.TestCase):
test_shell.do_image_upload(self.gc, args)
mocked_upload.assert_called_once_with('IMG-01', 'testfile', 1024)
+ def test_image_import(self):
+ args = self._make_args(
+ {'id': 'IMG-01', 'uri': 'http://example.com/image.qcow',
+ 'import_method': 'web-download', 'from_create': True})
+
+ with mock.patch.object(self.gc.images, 'image_import') as mock_import:
+ mock_import.return_value = None
+ test_shell.do_image_import(self.gc, args)
+ mock_import.assert_called_once_with(
+ 'IMG-01', 'web-download', 'http://example.com/image.qcow')
+
def test_image_download(self):
args = self._make_args(
{'id': 'IMG-01', 'file': 'test', 'progress': True})
diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py
index 29abc30..89aa912 100644
--- a/glanceclient/v2/images.py
+++ b/glanceclient/v2/images.py
@@ -254,10 +254,16 @@ class Controller(object):
return body, resp
@utils.add_req_id_to_object()
- def image_import(self, image_id, method='glance-direct'):
+ def image_import(self, image_id, method='glance-direct', uri=None):
"""Import Image via method."""
url = '/v2/images/%s/import' % image_id
data = {'method': {'name': method}}
+ if uri:
+ if method == 'web-download':
+ data['method']['uri'] = uri
+ else:
+ raise exc.HTTPBadRequest('URI is only supported with method: '
+ '"web-download"')
resp, body = self.http_client.post(url, data=data)
return body, resp
diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py
index c9f1fe1..2b83304 100644
--- a/glanceclient/v2/shell.py
+++ b/glanceclient/v2/shell.py
@@ -105,6 +105,8 @@ def do_image_create(gc, args):
@utils.arg('--import-method', metavar='<METHOD>', default='glance-direct',
help=_('Import method used for Image Import workflow. '
'Valid values can be retrieved with import-info command.'))
+@utils.arg('--uri', metavar='<IMAGE_URL>', default=None,
+ help=_('URI to download the external image.'))
@utils.on_data_require_fields(DATA_FIELDS)
def do_image_create_via_import(gc, args):
"""EXPERIMENTAL: Create a new image via image import."""
@@ -129,15 +131,22 @@ def do_image_create_via_import(gc, args):
'glance-direct' not in import_methods.get('value')):
utils.exit("No suitable import method available for direct upload, "
"please use image-create instead.")
+ if args.import_method == 'web-download' and not args.uri:
+ utils.exit("URI is required for web-download import method. "
+ "Please use '--uri <uri>'.")
+ if args.uri and args.import_method != 'web-download':
+ utils.exit("Import method should be 'web-download' if URI is "
+ "provided.")
+
image = gc.images.create(**fields)
try:
+ args.id = image['id']
if utils.get_data_file(args) is not None:
- args.id = image['id']
args.size = None
do_image_stage(gc, args)
- args.from_create = True
- do_image_import(gc, args)
- image = gc.images.get(args.id)
+ args.from_create = True
+ do_image_import(gc, args)
+ image = gc.images.get(args.id)
finally:
utils.print_image(image)
@@ -418,12 +427,19 @@ def do_image_stage(gc, args):
'Valid values can be retrieved with import-info command '
'and the default "glance-direct" is used with '
'"image-stage".'))
+@utils.arg('--uri', metavar='<IMAGE_URL>', default=None,
+ help=_('URI to download the external image.'))
@utils.arg('id', metavar='<IMAGE_ID>',
help=_('ID of image to import.'))
def do_image_import(gc, args):
"""Initiate the image import taskflow."""
try:
- gc.images.image_import(args.id, args.import_method)
+ if args.import_method == 'web-download' and not args.uri:
+ utils.exit("Provide URI for web-download import method.")
+ if args.uri and args.import_method != 'web-download':
+ utils.exit("Import method should be 'web-download' if URI is "
+ "provided.")
+ gc.images.image_import(args.id, args.import_method, args.uri)
except exc.HTTPNotFound:
utils.exit('Target Glance does not support Image Import workflow')
else: