diff options
author | abhishekkekane <abhishek.kekane@nttdata.com> | 2014-09-24 04:36:13 -0700 |
---|---|---|
committer | Nikhil Komawar <nikhilskomawar@gmail.com> | 2014-10-09 09:46:44 -0400 |
commit | ace6197bbaaba7d53c05ff6eb2c39a642cfc463d (patch) | |
tree | 0f3dff2e46b3939d333d6e38eea9796fae54f521 | |
parent | 9eff67b8fff812acdbf787f2dc119761f3cf3153 (diff) | |
download | glance-ace6197bbaaba7d53c05ff6eb2c39a642cfc463d.tar.gz |
g-api raises 500 error while uploading image
If both filesystem_store_datadirs and filesystem_store_datadir parameters
specified in glance-api.conf file then while creating new image 500
internal server error is raised.
Caught StoreAddDisabled exception for v1 and v2 api while uploading
image and raised HTTPGone exception to return HTTP 410 response to
user.
Closes-Bug: #1372888
Change-Id: Iccbf5b88634d3c956d41e8d8a0126648c64b34eb
-rw-r--r-- | glance/api/v1/upload_utils.py | 9 | ||||
-rw-r--r-- | glance/api/v2/image_data.py | 8 | ||||
-rw-r--r-- | glance/tests/unit/v1/test_api.py | 39 | ||||
-rw-r--r-- | glance/tests/unit/v1/test_upload_utils.py | 7 | ||||
-rw-r--r-- | glance/tests/unit/v2/test_image_data_resource.py | 10 |
5 files changed, 73 insertions, 0 deletions
diff --git a/glance/api/v1/upload_utils.py b/glance/api/v1/upload_utils.py index 2e22dae3d..763d6cb9d 100644 --- a/glance/api/v1/upload_utils.py +++ b/glance/api/v1/upload_utils.py @@ -173,6 +173,15 @@ def upload_data_to_store(req, image_meta, image_data, store, notifier): request=req, content_type='text/plain') + except store_api.StoreAddDisabled: + msg = _("Error in store configuration. Adding images to store " + "is disabled.") + LOG.exception(msg) + safe_kill(req, image_id, 'saving') + notifier.error('image.upload', msg) + raise webob.exc.HTTPGone(explanation=msg, request=req, + content_type='text/plain') + except exception.Duplicate as e: msg = u"Attempt to upload duplicate image: %s" % e LOG.debug(msg) diff --git a/glance/api/v2/image_data.py b/glance/api/v2/image_data.py index 04cfe3481..dc38ffcea 100644 --- a/glance/api/v2/image_data.py +++ b/glance/api/v2/image_data.py @@ -98,6 +98,14 @@ class ImageDataController(object): raise webob.exc.HTTPBadRequest(explanation= utils.exception_to_str(e)) + except glance_store.StoreAddDisabled: + msg = _("Error in store configuration. Adding images to store " + "is disabled.") + LOG.exception(msg) + self._restore(image_repo, image) + raise webob.exc.HTTPGone(explanation=msg, request=req, + content_type='text/plain') + except exception.InvalidImageStatusTransition as e: msg = utils.exception_to_str(e) LOG.debug(msg) diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py index f5c59a1fc..f000ee141 100644 --- a/glance/tests/unit/v1/test_api.py +++ b/glance/tests/unit/v1/test_api.py @@ -1500,6 +1500,45 @@ class TestGlanceAPI(base.IsolatedUnitTest): "Got headers: %r" % res.headers) self.assertEqual("active", res.headers['x-image-meta-status']) + def test_upload_image_raises_store_disabled(self): + """Test that uploading an image file returns HTTTP 410 response""" + # create image + fs = store.get_store_from_scheme('file') + fixture_headers = {'x-image-meta-store': 'file', + 'x-image-meta-disk-format': 'vhd', + 'x-image-meta-container-format': 'ovf', + 'x-image-meta-name': 'fake image #3', + 'x-image-meta-property-key1': 'value1'} + + req = webob.Request.blank("/images") + req.method = 'POST' + for k, v in six.iteritems(fixture_headers): + req.headers[k] = v + + res = req.get_response(self.api) + self.assertEqual(201, res.status_int) + res_body = jsonutils.loads(res.body)['image'] + + self.assertIn('id', res_body) + + image_id = res_body['id'] + self.assertIn('/images/%s' % image_id, res.headers['location']) + + # Verify the status is queued + self.assertIn('status', res_body) + self.assertEqual('queued', res_body['status']) + + # Now upload the image file + with mock.patch.object(fs, 'add') as mock_fsstore_add: + mock_fsstore_add.side_effect = store.StoreAddDisabled + req = webob.Request.blank("/images/%s" % image_id) + req.method = 'PUT' + req.headers['Content-Type'] = 'application/octet-stream' + req.body = "chunk00000remainder" + res = req.get_response(self.api) + self.assertEqual(410, res.status_int) + self._verify_image_status(image_id, 'killed') + def _get_image_status(self, image_id): req = webob.Request.blank("/images/%s" % image_id) req.method = 'HEAD' diff --git a/glance/tests/unit/v1/test_upload_utils.py b/glance/tests/unit/v1/test_upload_utils.py index 9b0b0b185..a50fbf88d 100644 --- a/glance/tests/unit/v1/test_upload_utils.py +++ b/glance/tests/unit/v1/test_upload_utils.py @@ -195,6 +195,13 @@ class TestUploadUtils(base.StoreClearingUnitTest): mock_safe_kill.assert_called_with(req, image_meta['id'], 'saving') + def test_upload_data_to_store_raises_store_disabled(self): + """Test StoreDisabled exception is raised while uploading data""" + self._test_upload_data_to_store_exception_with_notify( + glance_store.StoreAddDisabled, + webob.exc.HTTPGone, + image_killed=True) + def test_upload_data_to_store_duplicate(self): """See note in glance.api.v1.upload_utils on why we don't want image to be deleted in this case. diff --git a/glance/tests/unit/v2/test_image_data_resource.py b/glance/tests/unit/v2/test_image_data_resource.py index d88ba17c6..a055ab0f7 100644 --- a/glance/tests/unit/v2/test_image_data_resource.py +++ b/glance/tests/unit/v2/test_image_data_resource.py @@ -276,6 +276,16 @@ class TestImagesController(base.StoreClearingUnitTest): self.controller.upload, request, unit_test_utils.UUID2, 'YY', 2) + def test_upload_storage_store_disabled(self): + """Test that uploading an image file raises StoreDisabled exception""" + request = unit_test_utils.get_fake_request(user=unit_test_utils.USER3) + image = FakeImage() + image.set_data = Raise(glance_store.StoreAddDisabled) + self.image_repo.result = image + self.assertRaises(webob.exc.HTTPGone, + self.controller.upload, + request, unit_test_utils.UUID2, 'YY', 2) + def _test_upload_download_prepare_notification(self): request = unit_test_utils.get_fake_request() self.controller.upload(request, unit_test_utils.UUID2, 'YYYY', 4) |