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 <stuart.mclaren@hp.com>
Change-Id: I5d3d02d6aa7c8dd054cd2933e15b4a26e91afea1
This commit is contained in:
Long Quan Sha
2015-07-08 09:29:53 +08:00
committed by Stuart McLaren
parent deff84dadf
commit 44d0b02c67
3 changed files with 16 additions and 2 deletions

View File

@@ -14,7 +14,7 @@
# under the License. # under the License.
import errno import errno
import mock
import testtools import testtools
from glanceclient import exc from glanceclient import exc
@@ -866,6 +866,12 @@ class TestController(testtools.TestCase):
body = ''.join([b for b in body]) body = ''.join([b for b in body])
self.assertEqual('CCC', 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): def test_update_replace_prop(self):
image_id = '3a4560a1-e585-443e-9b39-553b46ec92d1' image_id = '3a4560a1-e585-443e-9b39-553b46ec92d1'
params = {'name': 'pong'} params = {'name': 'pong'}

View File

@@ -14,8 +14,8 @@
# under the License. # under the License.
import json import json
from oslo_utils import encodeutils from oslo_utils import encodeutils
from requests import codes
import six import six
from six.moves.urllib import parse from six.moves.urllib import parse
import warlock import warlock
@@ -189,9 +189,13 @@ class Controller(object):
:param image_id: ID of the image to download. :param image_id: ID of the image to download.
:param do_checksum: Enable/disable checksum validation. :param do_checksum: Enable/disable checksum validation.
:returns: An interable body or None
""" """
url = '/v2/images/%s/file' % image_id url = '/v2/images/%s/file' % image_id
resp, body = self.http_client.get(url) resp, body = self.http_client.get(url)
if resp.status_code == codes.no_content:
return None
checksum = resp.headers.get('content-md5', None) checksum = resp.headers.get('content-md5', None)
content_length = int(resp.headers.get('content-length', 0)) content_length = int(resp.headers.get('content-length', 0))

View File

@@ -276,6 +276,10 @@ def do_explain(gc, args):
def do_image_download(gc, args): def do_image_download(gc, args):
"""Download a specific image.""" """Download a specific image."""
body = gc.images.data(args.id) body = gc.images.data(args.id)
if body is None:
msg = ('Image %s has no data.' % args.id)
utils.exit(msg)
if args.progress: if args.progress:
body = progressbar.VerboseIteratorWrapper(body, len(body)) body = progressbar.VerboseIteratorWrapper(body, len(body))
if not (sys.stdout.isatty() and args.file is None): if not (sys.stdout.isatty() and args.file is None):