Fix 500 from duplicate stage call

1. When user calls stage command again then it fails with 500 internal
server error. This is because after stage call image status changes
to 'uploading' and for second call it again tries to set status to
'uploading' and fails with 'InvalidImageStatusTransition: Image
status transition from uploading to uploading is not allowed'
exception which is not caught at the controller side.

2. If image upload (/file call) is in progress image is in saving
state at that time. If user tries to make a /stage call on same image
then it returns 500 internal server error as Image transition from
saving to uploading is not allowed.

Caught 'InvalidImageStatusTransition' and return 409 HTTPConflict
resonse status.

Change-Id: Ie66d3e3474b38b2f6c8d31f5c1fb252d45cbd3c9
Closes-Bug: #1733274
Closes-Bug: #1733512
This commit is contained in:
Abhishek Kekane 2017-11-20 07:38:29 +00:00 committed by Brian Rosmaita
parent d8bcf8ba13
commit 7d005079f3
2 changed files with 20 additions and 0 deletions

View File

@ -341,6 +341,11 @@ class ImageDataController(object):
raise webob.exc.HTTPServiceUnavailable(explanation=msg,
request=req)
except exception.InvalidImageStatusTransition as e:
msg = encodeutils.exception_to_unicode(e)
LOG.debug(msg)
raise webob.exc.HTTPConflict(explanation=e.msg, request=req)
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.exception(_LE("Failed to stage image data due to "

View File

@ -491,6 +491,21 @@ class TestImagesController(base.StoreClearingUnitTest):
self.controller.stage,
request, image_id, 'YYYYYYY', 7)
@mock.patch.object(filesystem.Store, 'add')
def test_image_stage_invalid_image_transition(self, mock_store_add):
image_id = str(uuid.uuid4())
request = unit_test_utils.get_fake_request()
image = FakeImage(image_id=image_id)
self.image_repo.result = image
self.controller.stage(request, image_id, 'YYYY', 4)
self.assertEqual('uploading', image.status)
self.assertEqual(0, image.size)
# try staging again
mock_store_add.side_effect = exception.InvalidImageStatusTransition(
cur_status='uploading', new_status='uploading')
self.assertRaises(webob.exc.HTTPConflict, self.controller.stage,
request, image_id, 'YYYY', 4)
class TestImageDataDeserializer(test_utils.BaseTestCase):