Merge lp:~jaypipes/glance/bug759018 into lp:~glance-coresec/glance/cactus-trunk

Proposed by Jay Pipes
Status: Merged
Approved by: Jay Pipes
Approved revision: 114
Merged at revision: 113
Proposed branch: lp:~jaypipes/glance/bug759018
Merge into: lp:~glance-coresec/glance/cactus-trunk
Diff against target: 100 lines (+24/-22)
2 files modified
glance/server.py (+20/-22)
tests/functional/test_curl_api.py (+4/-0)
To merge this branch: bzr merge lp:~jaypipes/glance/bug759018
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Review via email: mp+57546@code.launchpad.net

Description of the change

Removes capture of exception from eventlet in _upload_and_activate(), which catches the exceptions that come from the _safe_kill() method properly.

Also fixes an incorrect call to _safe_kill() with mapping instead of image ID in the block of code that kills an image if a bad checksum is given.

Fixes bug #759018.

To post a comment you must log in.
Revision history for this message
Rick Harris (rconradharris) wrote :

> 47 + raise HTTPConflict(msg, request=req)
> 52 + raise HTTPBadRequest(msg, request=req)

Looks like `msg` needs interpolation. Perhaps:

    msg = ("Attempt to upload duplicate image: %s" % str(e))

> 15 + logger.debug(msg)
> 33 + logger.debug(msg)

Might be better to log this at the error level so it's more in our face.

Otherwise, looks good and tests pass.

review: Needs Fixing
Revision history for this message
Rick Harris (rconradharris) wrote :

Looks good, thanks for the fixups!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'glance/server.py'
2--- glance/server.py 2011-04-11 18:57:52 +0000
3+++ glance/server.py 2011-04-13 21:02:10 +0000
4@@ -227,17 +227,20 @@
5 :raises HTTPConflict if image already exists
6 :retval The location where the image was stored
7 """
8+ image_id = image_meta['id']
9 content_type = req.headers.get('content-type', 'notset')
10 if content_type != 'application/octet-stream':
11- raise HTTPBadRequest(
12- "Content-Type must be application/octet-stream")
13+ self._safe_kill(req, image_id)
14+ msg = ("Content-Type must be application/octet-stream")
15+ logger.error(msg)
16+ raise HTTPBadRequest(msg, content_type="text/plain",
17+ request=req)
18
19 store_name = req.headers.get(
20 'x-image-meta-store', self.options['default_store'])
21
22 store = self.get_store_or_400(req, store_name)
23
24- image_id = image_meta['id']
25 logger.debug("Setting image %s to status 'saving'"
26 % image_id)
27 registry.update_image_metadata(self.options, image_id,
28@@ -257,7 +260,8 @@
29 "checksum generated from uploaded image "
30 "(%(checksum)s) did not match. Setting image "
31 "status to 'killed'.") % locals()
32- self._safe_kill(req, image_meta)
33+ logger.error(msg)
34+ self._safe_kill(req, image_id)
35 raise HTTPBadRequest(msg, content_type="text/plain",
36 request=req)
37
38@@ -272,8 +276,15 @@
39
40 return location
41 except exception.Duplicate, e:
42- logger.error("Error adding image to store: %s", str(e))
43- raise HTTPConflict(str(e), request=req)
44+ msg = ("Attempt to upload duplicate image: %s") % str(e)
45+ logger.error(msg)
46+ self._safe_kill(req, image_id)
47+ raise HTTPConflict(msg, request=req)
48+ except Exception, e:
49+ msg = ("Error uploading image: %s") % str(e)
50+ logger.error(msg)
51+ self._safe_kill(req, image_id)
52+ raise HTTPBadRequest(msg, request=req)
53
54 def _activate(self, req, image_id, location):
55 """
56@@ -329,22 +340,9 @@
57
58 :retval Mapping of updated image data
59 """
60- try:
61- image_id = image_meta['id']
62- location = self._upload(req, image_meta)
63- return self._activate(req, image_id, location)
64- except: # unqualified b/c we're re-raising it
65- exc_type, exc_value, exc_traceback = sys.exc_info()
66- self._safe_kill(req, image_id)
67- # NOTE(sirp): _safe_kill uses httplib which, in turn, uses
68- # Eventlet's GreenSocket. Eventlet subsequently clears exceptions
69- # by calling `sys.exc_clear()`.
70- #
71- # This is why we can't use a raise with no arguments here: our
72- # exception context was destroyed by Eventlet. To work around
73- # this, we need to 'memorize' the exception context, and then
74- # re-raise here.
75- raise exc_type(exc_value)
76+ image_id = image_meta['id']
77+ location = self._upload(req, image_meta)
78+ return self._activate(req, image_id, location)
79
80 def create(self, req):
81 """
82
83=== modified file 'tests/functional/test_curl_api.py'
84--- tests/functional/test_curl_api.py 2011-04-11 18:57:52 +0000
85+++ tests/functional/test_curl_api.py 2011-04-13 21:02:10 +0000
86@@ -415,6 +415,8 @@
87 "Size was supposed to be %d. Got:\n%s."
88 % (FIVE_GB, out))
89
90+ self.stop_servers()
91+
92 def test_traceback_not_consumed(self):
93 """
94 A test that errors coming from the POST API do not
95@@ -447,3 +449,5 @@
96 expected = "Content-Type must be application/octet-stream"
97 self.assertTrue(expected in out,
98 "Could not find '%s' in '%s'" % (expected, out))
99+
100+ self.stop_servers()

Subscribers

People subscribed via source and target branches