Delete from store after registry delete.

Because we rely on the registry to determine authorization in the glance
v1 api, we must attempt a registry delete before deleting an image from
the image store.

This patch includes the test for the bug, which was posted separately
on the bug.

Fixes bug 1065187.

Change-Id: I1a06b7c7421524066c684539e2f3516c4ed2c475
This commit is contained in:
Mark Washenberger 2012-11-07 09:59:56 -05:00 committed by Russell Bryant
parent 6b2300fb0c
commit 6ab0992e54
4 changed files with 39 additions and 6 deletions

View File

@ -827,22 +827,28 @@ class Controller(controller.BaseController):
raise HTTPForbidden(explanation=msg, request=req,
content_type="text/plain")
status = 'deleted'
if image['location'] and CONF.delayed_delete:
status = 'pending_delete'
else:
status = 'deleted'
try:
# Delete the image from the registry first, since we rely on it
# for authorization checks.
# See https://bugs.launchpad.net/glance/+bug/1065187
registry.update_image_metadata(req.context, id, {'status': status})
registry.delete_image_metadata(req.context, id)
# The image's location field may be None in the case
# of a saving or queued image, therefore don't ask a backend
# to delete the image if the backend doesn't yet store it.
# See https://bugs.launchpad.net/glance/+bug/747799
if image['location']:
if CONF.delayed_delete:
status = 'pending_delete'
schedule_delayed_delete_from_backend(image['location'], id)
else:
safe_delete_from_backend(image['location'],
req.context, id)
registry.update_image_metadata(req.context, id, {'status': status})
registry.delete_image_metadata(req.context, id)
except exception.NotFound, e:
msg = ("Failed to find image to delete: %(e)s" % locals())
for line in msg.split('\n'):

View File

@ -60,7 +60,13 @@ class FakeRegistryConnection(object):
def getresponse(self):
mapper = routes.Mapper()
api = context.UnauthenticatedContextMiddleware(rserver.API(mapper))
server = rserver.API(mapper)
# NOTE(markwash): we need to pass through context auth information if
# we have it.
if 'X-Auth-Token' in self.req.headers:
api = utils.FakeAuthMiddleware(server)
else:
api = context.UnauthenticatedContextMiddleware(server)
webob_res = self.req.get_response(api)
return utils.FakeHTTPResponse(status=webob_res.status_int,

View File

@ -3015,6 +3015,26 @@ class TestGlanceAPI(base.IsolatedUnitTest):
res = req.get_response(self.api)
self.assertEquals(res.status_int, webob.exc.HTTPNotFound.code)
def test_delete_not_allowed(self):
# Verify we can get the image data
req = webob.Request.blank("/images/%s" % UUID2)
req.method = 'GET'
req.headers['X-Auth-Token'] = 'user:tenant:'
res = req.get_response(self.api)
self.assertEqual(res.status_int, 200)
self.assertEqual(len(res.body), 19)
# Verify we cannot delete the image
req.method = 'DELETE'
res = req.get_response(self.api)
self.assertEqual(res.status_int, 403)
# Verify the image data is still there
req.method = 'GET'
res = req.get_response(self.api)
self.assertEqual(res.status_int, 200)
self.assertEqual(len(res.body), 19)
def test_delete_queued_image(self):
"""Delete an image in a queued state

View File

@ -372,6 +372,7 @@ class FakeAuthMiddleware(wsgi.Middleware):
'tenant': tenant,
'roles': roles,
'is_admin': self.is_admin,
'auth_tok': auth_tok,
}
req.context = context.RequestContext(**kwargs)