summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorabhishekkekane <abhishek.kekane@nttdata.com>2014-09-24 04:36:13 -0700
committerNikhil Komawar <nikhilskomawar@gmail.com>2014-10-09 09:46:44 -0400
commitace6197bbaaba7d53c05ff6eb2c39a642cfc463d (patch)
tree0f3dff2e46b3939d333d6e38eea9796fae54f521
parent9eff67b8fff812acdbf787f2dc119761f3cf3153 (diff)
downloadglance-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.py9
-rw-r--r--glance/api/v2/image_data.py8
-rw-r--r--glance/tests/unit/v1/test_api.py39
-rw-r--r--glance/tests/unit/v1/test_upload_utils.py7
-rw-r--r--glance/tests/unit/v2/test_image_data_resource.py10
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)