From 44d0b02c67ce7926f40377d9367a0f61124ed26d Mon Sep 17 00:00:00 2001 From: Long Quan Sha Date: Wed, 8 Jul 2015 09:29:53 +0800 Subject: [PATCH] Fix the download error when the image locations are blank When the image locations are blank, glance client will get a http response with no content, glance client should show user no data could be found, instead of processing the blank response body that will lead to exception. Glance client will also get a 204 response when an image is in a queued state (this is true for 'master' and liberty/kilo/juno based servers). Closes-Bug: #1472449 Co-Authored-by: Stuart McLaren Change-Id: I5d3d02d6aa7c8dd054cd2933e15b4a26e91afea1 --- glanceclient/tests/unit/v2/test_images.py | 8 +++++++- glanceclient/v2/images.py | 6 +++++- glanceclient/v2/shell.py | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/glanceclient/tests/unit/v2/test_images.py b/glanceclient/tests/unit/v2/test_images.py index 6fda7ae3..15732280 100644 --- a/glanceclient/tests/unit/v2/test_images.py +++ b/glanceclient/tests/unit/v2/test_images.py @@ -14,7 +14,7 @@ # under the License. import errno - +import mock import testtools from glanceclient import exc @@ -866,6 +866,12 @@ class TestController(testtools.TestCase): body = ''.join([b for b in body]) self.assertEqual('CCC', body) + def test_download_no_data(self): + resp = utils.FakeResponse(headers={}, status_code=204) + self.controller.http_client.get = mock.Mock(return_value=(resp, None)) + body = self.controller.data('image_id') + self.assertEqual(None, body) + def test_update_replace_prop(self): image_id = '3a4560a1-e585-443e-9b39-553b46ec92d1' params = {'name': 'pong'} diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py index 4fdcea2d..053cc641 100644 --- a/glanceclient/v2/images.py +++ b/glanceclient/v2/images.py @@ -14,8 +14,8 @@ # under the License. import json - from oslo_utils import encodeutils +from requests import codes import six from six.moves.urllib import parse import warlock @@ -189,9 +189,13 @@ class Controller(object): :param image_id: ID of the image to download. :param do_checksum: Enable/disable checksum validation. + :returns: An interable body or None """ url = '/v2/images/%s/file' % image_id resp, body = self.http_client.get(url) + if resp.status_code == codes.no_content: + return None + checksum = resp.headers.get('content-md5', None) content_length = int(resp.headers.get('content-length', 0)) diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index 7be90ae9..99ca3974 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -276,6 +276,10 @@ def do_explain(gc, args): def do_image_download(gc, args): """Download a specific image.""" body = gc.images.data(args.id) + if body is None: + msg = ('Image %s has no data.' % args.id) + utils.exit(msg) + if args.progress: body = progressbar.VerboseIteratorWrapper(body, len(body)) if not (sys.stdout.isatty() and args.file is None):