Merge lp:~cjwatson/launchpad/gpg-timeline into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18573
Proposed branch: lp:~cjwatson/launchpad/gpg-timeline
Merge into: lp:launchpad
Diff against target: 158 lines (+41/-15)
1 file modified
lib/lp/services/gpg/handler.py (+41/-15)
To merge this branch: bzr merge lp:~cjwatson/launchpad/gpg-timeline
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+340554@code.launchpad.net

Commit message

Add timeline information to all GPGME calls.

Description of the change

It can otherwise be rather hard to work out where time is being spent.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/services/gpg/handler.py'
2--- lib/lp/services/gpg/handler.py 2018-01-26 22:18:38 +0000
3+++ lib/lp/services/gpg/handler.py 2018-03-02 23:28:29 +0000
4@@ -11,6 +11,7 @@
5 ]
6
7 import atexit
8+from contextlib import contextmanager
9 import httplib
10 import os
11 import shutil
12@@ -66,6 +67,17 @@
13 """
14
15
16+@contextmanager
17+def gpgme_timeline(name, detail):
18+ request = get_current_browser_request()
19+ timeline = get_request_timeline(request)
20+ action = timeline.start("gpgme-%s" % name, detail, allow_nested=True)
21+ try:
22+ yield
23+ finally:
24+ action.finish()
25+
26+
27 @implementer(IGPGHandler)
28 class GPGHandler:
29 """See IGPGHandler."""
30@@ -178,16 +190,19 @@
31 # store the content
32 plain = StringIO(content)
33 args = (sig, plain, None)
34+ timeline_detail = "detached signature"
35 else:
36 # store clearsigned signature
37 sig = StringIO(content)
38 # writeable content
39 plain = StringIO()
40 args = (sig, None, plain)
41+ timeline_detail = "clear signature"
42
43 # process it
44 try:
45- signatures = ctx.verify(*args)
46+ with gpgme_timeline("verify", timeline_detail):
47+ signatures = ctx.verify(*args)
48 except gpgme.GpgmeError as e:
49 error = GPGVerificationError(e.strerror)
50 for attr in ("args", "code", "signatures", "source"):
51@@ -238,7 +253,8 @@
52 context = self._getContext()
53
54 newkey = StringIO(content)
55- result = context.import_(newkey)
56+ with gpgme_timeline("import", "new public key"):
57+ result = context.import_(newkey)
58
59 if len(result.imports) == 0:
60 raise GPGKeyNotFoundError(content)
61@@ -271,7 +287,8 @@
62
63 context = self._getContext()
64 newkey = StringIO(content)
65- import_result = context.import_(newkey)
66+ with gpgme_timeline("import", "new secret key"):
67+ import_result = context.import_(newkey)
68
69 secret_imports = [
70 fingerprint
71@@ -303,8 +320,9 @@
72 # Only 'utf-8' encoding is supported by gpgme.
73 # See more information at:
74 # http://pyme.sourceforge.net/doc/gpgme/Generating-Keys.html
75- result = context.genkey(
76- signing_only_param % {'name': name.encode('utf-8')})
77+ with gpgme_timeline("genkey", name):
78+ result = context.genkey(
79+ signing_only_param % {'name': name.encode('utf-8')})
80
81 # Right, it might seem paranoid to have this many assertions,
82 # but we have to take key generation very seriously.
83@@ -346,9 +364,10 @@
84 % key.fingerprint)
85
86 # encrypt content
87- ctx.encrypt(
88- [removeSecurityProxy(key.key)], gpgme.ENCRYPT_ALWAYS_TRUST,
89- plain, cipher)
90+ with gpgme_timeline("encrypt", key.fingerprint):
91+ ctx.encrypt(
92+ [removeSecurityProxy(key.key)], gpgme.ENCRYPT_ALWAYS_TRUST,
93+ plain, cipher)
94
95 return cipher.getvalue()
96
97@@ -379,7 +398,8 @@
98
99 # Sign the text.
100 try:
101- context.sign(plaintext, signature, mode)
102+ with gpgme_timeline("sign", key.fingerprint):
103+ context.sign(plaintext, signature, mode)
104 except gpgme.GpgmeError:
105 return None
106
107@@ -397,8 +417,10 @@
108 if type(filter) == unicode:
109 filter = filter.encode('utf-8')
110
111- for key in ctx.keylist(filter, secret):
112- yield PymeKey.newFromGpgmeKey(key)
113+ with gpgme_timeline(
114+ "keylist", "filter: %r, secret: %r" % (filter, secret)):
115+ for key in ctx.keylist(filter, secret):
116+ yield PymeKey.newFromGpgmeKey(key)
117
118 def retrieveKey(self, fingerprint):
119 """See IGPGHandler."""
120@@ -414,7 +436,8 @@
121 key = self.importPublicKey(pubkey)
122 if fingerprint != key.fingerprint:
123 ctx = self._getContext()
124- ctx.delete(key.key)
125+ with gpgme_timeline("delete", key.fingerprint):
126+ ctx.delete(key.key)
127 raise GPGKeyMismatchOnServer(fingerprint, key.fingerprint)
128 return key
129
130@@ -490,7 +513,8 @@
131 request = get_current_browser_request()
132 timeline = get_request_timeline(request)
133 action = timeline.start(
134- 'retrieving GPG key', 'Fingerprint: %s' % fingerprint)
135+ 'retrieving GPG key', 'Fingerprint: %s' % fingerprint,
136+ allow_nested=True)
137 try:
138 return self._grabPage('get', fingerprint)
139 # We record an OOPS for most errors: If the keyserver does not
140@@ -568,7 +592,8 @@
141 context = self._getContext()
142 # retrive additional key information
143 try:
144- key = context.get_key(fingerprint, False)
145+ with gpgme_timeline("get-key", fingerprint):
146+ key = context.get_key(fingerprint, False)
147 except gpgme.GpgmeError:
148 key = None
149
150@@ -616,7 +641,8 @@
151
152 context = self._getContext()
153 keydata = StringIO()
154- context.export(self.fingerprint.encode('ascii'), keydata)
155+ with gpgme_timeline("export", self.fingerprint):
156+ context.export(self.fingerprint.encode('ascii'), keydata)
157
158 return keydata.getvalue()
159