diff options
author | PranaliD <pdeore@redhat.com> | 2018-03-12 05:38:34 -0400 |
---|---|---|
committer | Erno Kuvaja <jokke@usr.fi> | 2018-03-22 12:06:58 +0000 |
commit | 75775a133d22d377522ba6c1093b751dad7efd3c (patch) | |
tree | c97913de2ee6f16d263aebc9b2b9c02fa5c7ea53 | |
parent | bb5465636880af6aec4926fb32fc3dd1c8e80be5 (diff) | |
download | python-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.py | 4 | ||||
-rw-r--r-- | glanceclient/tests/unit/v2/test_images.py | 13 | ||||
-rw-r--r-- | glanceclient/tests/unit/v2/test_shell_v2.py | 38 | ||||
-rw-r--r-- | glanceclient/v2/images.py | 8 | ||||
-rw-r--r-- | glanceclient/v2/shell.py | 26 |
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: |