Fix 500 from image-import on queued images

If you run image-import api on any image which is in queued state having
valid container-format and disk-format set will return 500 error as it
raises IOError: [Errno 2] No such file or directory:
'/tmp/staging/567bfb61-d9f7-47e5-aa1a-90b7797e70be'. The reason is image
does not have data stored in staging area.

Restricted transition from queued to importing state and returned HTTP 409
conflict error to the user.

Change-Id: I3d3ab283fd0faf4b63365ff2dbeb714913f02b27
Closes-Bug: #1733813
This commit is contained in:
Abhishek Kekane 2017-11-24 04:08:13 +00:00
parent d88bd2ca8e
commit a19fdb0e5f
3 changed files with 16 additions and 1 deletions

View File

@ -107,6 +107,8 @@ class ImagesController(object):
except exception.Forbidden as e:
LOG.debug("User not permitted to create image import task.")
raise webob.exc.HTTPForbidden(explanation=e.msg)
except exception.Conflict as e:
raise webob.exc.HTTPConflict(explanation=e.msg)
return image_id

View File

@ -194,7 +194,7 @@ class _ImportToStore(task.Task):
# implementation
image = self.image_repo.get(self.image_id)
image.status = 'importing'
self.image_repo.save(image)
self.image_repo.save(image, from_state='uploading')
# NOTE(flaper87): Let's dance... and fall
#

View File

@ -14,6 +14,7 @@
# under the License.
import datetime
import eventlet
import uuid
import glance_store as store
@ -599,6 +600,18 @@ class TestImagesController(base.IsolatedUnitTest):
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show, request, UUID4)
def test_image_import_raises_conflict(self):
request = unit_test_utils.get_fake_request()
# NOTE(abhishekk): Due to
# https://bugs.launchpad.net/glance/+bug/1712463 taskflow is not
# executing. Once it is fixed instead of mocking spawn_n method
# we should mock execute method of _ImportToStore task.
with mock.patch.object(eventlet.GreenPool, 'spawn_n',
side_effect=exception.Conflict):
self.assertRaises(webob.exc.HTTPConflict,
self.controller.import_image, request, UUID4,
{})
def test_create(self):
request = unit_test_utils.get_fake_request()
image = {'name': 'image-1'}