Merge lp:~vishvananda/nova/lp827024 into lp:~hudson-openstack/nova/trunk

Proposed by Vish Ishaya
Status: Merged
Approved by: Rick Harris
Approved revision: 1419
Merged at revision: 1448
Proposed branch: lp:~vishvananda/nova/lp827024
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 72 lines (+14/-12)
1 file modified
nova/image/s3.py (+14/-12)
To merge this branch: bzr merge lp:~vishvananda/nova/lp827024
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Jason Kölker (community) Approve
Devin Carlen (community) Approve
Review via email: mp+71620@code.launchpad.net

Description of the change

Fixes issue with exceptions getting eaten in image/s3.py if there is a failure during register. The variables referenced with locals() were actually out of scope.

To post a comment you must log in.
lp:~vishvananda/nova/lp827024 updated
1419. By Vish Ishaya

log the full exception so we don't lose traceback through eventlet

Revision history for this message
Devin Carlen (devcamcar) wrote :

lgtm

review: Approve
Revision history for this message
Jason Kölker (jason-koelker) wrote :

Is Bueno! The '% locals()' grated on my soul.
s/grated/grates/
;)

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

Vish:

A pattern we use elsewhere is to capture the traceback info before eventlet gets a chance to clear exceptions during its greenthread context switch. We then use a 3-arg raise to re-raise it, something like:

try:
  blah
except Exception as e:
  exc_info = sys.exc_info()
  handler_code() # <- Eventlet will clear exceptions here
  raise exc_info

What I like about that approach is that it continues to 'raise' instead of just logging, keeping the errors a bit more in your face.

Given that we were raising, should we try something like that here?

review: Needs Information
Revision history for this message
Vish Ishaya (vishvananda) wrote :

Rick:

I considered that, although in this case logging.exception logs a traceback in virtually the same way that a straight raise does. I think there is value in your version if there is something that needs to catch the exception, but in this case that method just runs in its own greenthread and nothing is keeping track of it, so I didn't feel like it was necessary to workaround it by reraising. I'm happy to switch it if you have a strong preference, though.

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

Vish: All that sounds reasonable--no strong preference here. I *slightly* prefer re-raising, but logging here seems like a good approach too.

Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/image/s3.py'
2--- nova/image/s3.py 2011-07-28 01:36:55 +0000
3+++ nova/image/s3.py 2011-08-16 00:13:30 +0000
4@@ -193,6 +193,8 @@
5
6 def delayed_create():
7 """This handles the fetching and decrypting of the part files."""
8+ log_vars = {'image_location': image_location,
9+ 'image_path': image_path}
10 metadata['properties']['image_state'] = 'downloading'
11 self.service.update(context, image_id, metadata)
12
13@@ -213,11 +215,11 @@
14 shutil.copyfileobj(part, combined)
15
16 except Exception:
17- LOG.error(_("Failed to download %(image_location)s "
18- "to %(image_path)s"), locals())
19+ LOG.exception(_("Failed to download %(image_location)s "
20+ "to %(image_path)s"), log_vars)
21 metadata['properties']['image_state'] = 'failed_download'
22 self.service.update(context, image_id, metadata)
23- raise
24+ return
25
26 metadata['properties']['image_state'] = 'decrypting'
27 self.service.update(context, image_id, metadata)
28@@ -237,11 +239,11 @@
29 encrypted_iv, cloud_pk,
30 dec_filename)
31 except Exception:
32- LOG.error(_("Failed to decrypt %(image_location)s "
33- "to %(image_path)s"), locals())
34+ LOG.exception(_("Failed to decrypt %(image_location)s "
35+ "to %(image_path)s"), log_vars)
36 metadata['properties']['image_state'] = 'failed_decrypt'
37 self.service.update(context, image_id, metadata)
38- raise
39+ return
40
41 metadata['properties']['image_state'] = 'untarring'
42 self.service.update(context, image_id, metadata)
43@@ -249,11 +251,11 @@
44 try:
45 unz_filename = self._untarzip_image(image_path, dec_filename)
46 except Exception:
47- LOG.error(_("Failed to untar %(image_location)s "
48- "to %(image_path)s"), locals())
49+ LOG.exception(_("Failed to untar %(image_location)s "
50+ "to %(image_path)s"), log_vars)
51 metadata['properties']['image_state'] = 'failed_untar'
52 self.service.update(context, image_id, metadata)
53- raise
54+ return
55
56 metadata['properties']['image_state'] = 'uploading'
57 self.service.update(context, image_id, metadata)
58@@ -262,11 +264,11 @@
59 self.service.update(context, image_id,
60 metadata, image_file)
61 except Exception:
62- LOG.error(_("Failed to upload %(image_location)s "
63- "to %(image_path)s"), locals())
64+ LOG.exception(_("Failed to upload %(image_location)s "
65+ "to %(image_path)s"), log_vars)
66 metadata['properties']['image_state'] = 'failed_upload'
67 self.service.update(context, image_id, metadata)
68- raise
69+ return
70
71 metadata['properties']['image_state'] = 'available'
72 metadata['status'] = 'active'