Merge lp:~barry/launchpad/435604-mailman into lp:launchpad
- 435604-mailman
- Merge into devel
Proposed by
Barry Warsaw
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Brad Crittenden | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~barry/launchpad/435604-mailman | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
824 lines 17 files modified
lib/canonical/launchpad/mailman/monkeypatches/__init__.py (+35/-80) lib/canonical/launchpad/mailman/monkeypatches/mm_cfg.py.in (+65/-0) lib/lp/services/mailman/doc/basic-integration.txt (+89/-0) lib/lp/services/mailman/doc/bounces.txt (+1/-0) lib/lp/services/mailman/doc/contact-address.txt (+2/-2) lib/lp/services/mailman/doc/create-lists.txt (+2/-2) lib/lp/services/mailman/doc/decorations.txt (+1/-2) lib/lp/services/mailman/doc/logging.txt (+27/-24) lib/lp/services/mailman/doc/messages.txt (+3/-1) lib/lp/services/mailman/doc/modify-lists.txt (+5/-3) lib/lp/services/mailman/doc/postings.txt (+17/-16) lib/lp/services/mailman/doc/reactivate-lists.txt (+4/-2) lib/lp/services/mailman/doc/recovery.txt (+9/-5) lib/lp/services/mailman/doc/staging.txt (+2/-3) lib/lp/services/mailman/doc/subscriptions.txt (+11/-7) lib/lp/services/mailman/testing/helpers.py (+1/-1) lib/lp/services/mailman/testing/logwatcher.py (+2/-2) |
||||
To merge this branch: | bzr merge lp:~barry/launchpad/435604-mailman | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brad Crittenden (community) | release-critical | Approve | |
Paul Hummer (community) | Approve | ||
Review via email: mp+12380@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Barry Warsaw (barry) wrote : | # |
Revision history for this message
Paul Hummer (rockstar) : | # |
review:
Approve
Revision history for this message
Brad Crittenden (bac) wrote : | # |
Hi Barry,
Thanks for the fix. Not to beat a dead horse, but in the future try to keep RC candidate branches as tiny as possible.
Thanks also for hanging around last night as the release happened to ensure everything worked.
review:
Approve
(release-critical)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/canonical/launchpad/mailman/monkeypatches/__init__.py' |
2 | --- lib/canonical/launchpad/mailman/monkeypatches/__init__.py 2009-07-17 00:26:05 +0000 |
3 | +++ lib/canonical/launchpad/mailman/monkeypatches/__init__.py 2009-09-24 20:25:22 +0000 |
4 | @@ -38,7 +38,8 @@ |
5 | # will get appended to Mailman's sys.path. |
6 | import canonical |
7 | from canonical.launchpad.mailman.config import configure_siteowner |
8 | - launchpad_top = os.path.dirname(os.path.dirname(canonical.__file__)) |
9 | + launchpad_top = os.path.dirname( |
10 | + os.path.dirname(os.path.dirname(canonical.__file__))) |
11 | # Read the email footer template for all Launchpad messages. |
12 | from canonical.launchpad.helpers import get_email_template |
13 | footer = get_email_template('mailinglist-footer.txt') |
14 | @@ -46,85 +47,39 @@ |
15 | host, port = as_host_port(config.mailman.smtp) |
16 | owner_address, owner_password = configure_siteowner( |
17 | config.mailman.build_site_list_owner) |
18 | - config_path = os.path.join(mailman_path, 'Mailman', 'mm_cfg.py') |
19 | - config_file = open(config_path, 'w') |
20 | - try: |
21 | - print >> config_file, """\ |
22 | -# Automatically generated by runlaunchpad.py |
23 | - |
24 | -# Set up Mailman's sys.path to pick up the top of Launchpad's tree |
25 | -import sys |
26 | -sys.path.insert(0, '%(launchpad_top)s') |
27 | - |
28 | -# Pick up Launchpad static overrides. This will also pick up the standard |
29 | -# Mailman.Defaults.* variables. |
30 | -from canonical.launchpad.mailman.monkeypatches.defaults import * |
31 | - |
32 | -# Our dynamic overrides of all the static defaults. |
33 | -SMTPHOST = '%(smtp_host)s' |
34 | -SMTPPORT = %(smtp_port)d |
35 | - |
36 | -# Configuration options for the XMLRPCRunner. |
37 | -XMLRPC_URL = '%(xmlrpc_url)s' |
38 | -XMLRPC_SLEEPTIME = %(xmlrpc_sleeptime)s |
39 | -XMLRPC_SUBSCRIPTION_BATCH_SIZE = %(xmlrpc_subscription_batch_size)s |
40 | -LAUNCHPAD_SHARED_SECRET = '%(shared_secret)s' |
41 | - |
42 | -# RFC 2369 header information. |
43 | -LIST_HELP_HEADER = '%(list_help_header)s' |
44 | -LIST_SUBSCRIPTION_HEADERS = '%(list_subscription_headers)s' |
45 | -LIST_ARCHIVE_HEADER_TEMPLATE = '%(archive_url_template)s' |
46 | -LIST_OWNER_HEADER_TEMPLATE = '%(list_owner_header_template)s' |
47 | - |
48 | -# Soft and hard maximum message size limits. Anything below the soft limit is |
49 | -# allowed directly through. Between the soft and hard limits, the message is |
50 | -# held for approval. Above the hard limit, the message is logged and |
51 | -# discarded. Note that the normal Mailman size thresholds are ignored. |
52 | -LAUNCHPAD_SOFT_MAX_SIZE = %(soft_max_size)d |
53 | -LAUNCHPAD_HARD_MAX_SIZE = %(hard_max_size)d |
54 | - |
55 | -SITE_LIST_OWNER = '%(site_list_owner)s' |
56 | - |
57 | -DEFAULT_MSG_FOOTER = '''_______________________________________________ |
58 | -%(footer)s''' |
59 | - |
60 | -# Set up MHonArc archiving. |
61 | -PUBLIC_EXTERNAL_ARCHIVER = '/usr/bin/mhonarc \ |
62 | --add \ |
63 | --dbfile %(var_dir)s/archives/private/%%(listname)s.mbox/mhonarc.db \ |
64 | --outdir %(var_dir)s/mhonarc/%%(listname)s \ |
65 | --definevar ML-NAME=%%(listname)s \ |
66 | --rcfile %(var_dir)s/data/lp-mhonarc-common.mrc \ |
67 | --stderr %(var_dir)s/logs/mhonarc \ |
68 | --stdout %(var_dir)s/logs/mhonarc \ |
69 | --spammode \ |
70 | --umask 022' |
71 | -PRIVATE_EXTERNAL_ARCHIVER = PUBLIC_EXTERNAL_ARCHIVER |
72 | - |
73 | -# How often do we run the bounce processor? For production, the default 15 |
74 | -# minutes is fine, for testing we want to run it more often. |
75 | -REGISTER_BOUNCES_EVERY = %(register_bounces_every)d |
76 | -""" % dict( |
77 | - launchpad_top=launchpad_top, |
78 | - smtp_host=host, |
79 | - smtp_port=port, |
80 | - xmlrpc_url=config.mailman.xmlrpc_url, |
81 | - xmlrpc_sleeptime=config.mailman.xmlrpc_runner_sleep, |
82 | - xmlrpc_subscription_batch_size=config.mailman.subscription_batch_size, |
83 | - site_list_owner=owner_address, |
84 | - list_help_header=config.mailman.list_help_header, |
85 | - list_subscription_headers=config.mailman.list_subscription_headers, |
86 | - archive_url_template=config.mailman.archive_url_template, |
87 | - list_owner_header_template=config.mailman.list_owner_header_template, |
88 | - footer=footer, |
89 | - var_dir=config.mailman.build_var_dir, |
90 | - shared_secret=config.mailman.shared_secret, |
91 | - soft_max_size=config.mailman.soft_max_size, |
92 | - hard_max_size=config.mailman.hard_max_size, |
93 | - register_bounces_every=config.mailman.register_bounces_every, |
94 | - ) |
95 | - finally: |
96 | - config_file.close() |
97 | + config_path_in = os.path.join(os.path.dirname(__file__), 'mm_cfg.py.in') |
98 | + config_file_in = open(config_path_in) |
99 | + try: |
100 | + config_template = config_file_in.read() |
101 | + finally: |
102 | + config_file_in.close() |
103 | + config_path_out = os.path.join(mailman_path, 'Mailman', 'mm_cfg.py') |
104 | + config_file_out = open(config_path_out, 'w') |
105 | + try: |
106 | + print >> config_file_out, config_template % dict( |
107 | + launchpad_top=launchpad_top, |
108 | + smtp_host=host, |
109 | + smtp_port=port, |
110 | + xmlrpc_url=config.mailman.xmlrpc_url, |
111 | + xmlrpc_sleeptime=config.mailman.xmlrpc_runner_sleep, |
112 | + xmlrpc_subscription_batch_size |
113 | + =config.mailman.subscription_batch_size, |
114 | + site_list_owner=owner_address, |
115 | + list_help_header=config.mailman.list_help_header, |
116 | + list_subscription_headers |
117 | + =config.mailman.list_subscription_headers, |
118 | + archive_url_template=config.mailman.archive_url_template, |
119 | + list_owner_header_template |
120 | + =config.mailman.list_owner_header_template, |
121 | + footer=footer, |
122 | + var_dir=config.mailman.build_var_dir, |
123 | + shared_secret=config.mailman.shared_secret, |
124 | + soft_max_size=config.mailman.soft_max_size, |
125 | + hard_max_size=config.mailman.hard_max_size, |
126 | + register_bounces_every=config.mailman.register_bounces_every, |
127 | + ) |
128 | + finally: |
129 | + config_file_out.close() |
130 | # Mailman's qrunner system requires runner modules to live in the |
131 | # Mailman.Queue package. Set things up so that there's a hook module in |
132 | # there for the XMLRPCRunner. |
133 | |
134 | === added file 'lib/canonical/launchpad/mailman/monkeypatches/mm_cfg.py.in' |
135 | --- lib/canonical/launchpad/mailman/monkeypatches/mm_cfg.py.in 1970-01-01 00:00:00 +0000 |
136 | +++ lib/canonical/launchpad/mailman/monkeypatches/mm_cfg.py.in 2009-09-24 20:25:22 +0000 |
137 | @@ -0,0 +1,65 @@ |
138 | +# Automatically generated by runlaunchpad.py |
139 | + |
140 | +# Initialize sys.path so that the Mailman processes, which use the standard |
141 | +# system Python instead of buildout's bin/py, can find all the necessary |
142 | +# packages and modules. Some of these are in sourcecode and some are in |
143 | +# buildout eggs. |
144 | +# |
145 | +# This is a two-step process. First, we hack sys.path in order to find a |
146 | +# directory containing _pythonpath. Then the _pythonpath module does all the |
147 | +# subsequent sys.path hacking necessary. |
148 | + |
149 | +# Set up Mailman's sys.path to pick up the top of Launchpad's tree. This only |
150 | +# gets us a sys.path |
151 | +import sys |
152 | +sys.path.insert(0, '%(launchpad_top)s') |
153 | +import _pythonpath |
154 | + |
155 | +# Pick up Launchpad static overrides. This will also pick up the standard |
156 | +# Mailman.Defaults.* variables. |
157 | +from canonical.launchpad.mailman.monkeypatches.defaults import * |
158 | + |
159 | +# Our dynamic overrides of all the static defaults. |
160 | +SMTPHOST = '%(smtp_host)s' |
161 | +SMTPPORT = %(smtp_port)d |
162 | + |
163 | +# Configuration options for the XMLRPCRunner. |
164 | +XMLRPC_URL = '%(xmlrpc_url)s' |
165 | +XMLRPC_SLEEPTIME = %(xmlrpc_sleeptime)s |
166 | +XMLRPC_SUBSCRIPTION_BATCH_SIZE = %(xmlrpc_subscription_batch_size)s |
167 | +LAUNCHPAD_SHARED_SECRET = '%(shared_secret)s' |
168 | + |
169 | +# RFC 2369 header information. |
170 | +LIST_HELP_HEADER = '%(list_help_header)s' |
171 | +LIST_SUBSCRIPTION_HEADERS = '%(list_subscription_headers)s' |
172 | +LIST_ARCHIVE_HEADER_TEMPLATE = '%(archive_url_template)s' |
173 | +LIST_OWNER_HEADER_TEMPLATE = '%(list_owner_header_template)s' |
174 | + |
175 | +# Soft and hard maximum message size limits. Anything below the soft limit is |
176 | +# allowed directly through. Between the soft and hard limits, the message is |
177 | +# held for approval. Above the hard limit, the message is logged and |
178 | +# discarded. Note that the normal Mailman size thresholds are ignored. |
179 | +LAUNCHPAD_SOFT_MAX_SIZE = %(soft_max_size)d |
180 | +LAUNCHPAD_HARD_MAX_SIZE = %(hard_max_size)d |
181 | + |
182 | +SITE_LIST_OWNER = '%(site_list_owner)s' |
183 | + |
184 | +DEFAULT_MSG_FOOTER = '''_______________________________________________ |
185 | +%(footer)s''' |
186 | + |
187 | +# Set up MHonArc archiving. |
188 | +PUBLIC_EXTERNAL_ARCHIVER = '/usr/bin/mhonarc \ |
189 | +-add \ |
190 | +-dbfile %(var_dir)s/archives/private/%%(listname)s.mbox/mhonarc.db \ |
191 | +-outdir %(var_dir)s/mhonarc/%%(listname)s \ |
192 | +-definevar ML-NAME=%%(listname)s \ |
193 | +-rcfile %(var_dir)s/data/lp-mhonarc-common.mrc \ |
194 | +-stderr %(var_dir)s/logs/mhonarc \ |
195 | +-stdout %(var_dir)s/logs/mhonarc \ |
196 | +-spammode \ |
197 | +-umask 022' |
198 | +PRIVATE_EXTERNAL_ARCHIVER = PUBLIC_EXTERNAL_ARCHIVER |
199 | + |
200 | +# How often do we run the bounce processor? For production, the default 15 |
201 | +# minutes is fine, for testing we want to run it more often. |
202 | +REGISTER_BOUNCES_EVERY = %(register_bounces_every)d |
203 | |
204 | === modified file 'lib/lp/services/mailman/doc/basic-integration.txt' |
205 | --- lib/lp/services/mailman/doc/basic-integration.txt 2009-06-23 17:51:24 +0000 |
206 | +++ lib/lp/services/mailman/doc/basic-integration.txt 2009-09-24 20:25:22 +0000 |
207 | @@ -29,3 +29,92 @@ |
208 | |
209 | >>> withlist('withlist_2.can_import', '-q') |
210 | 99 |
211 | + |
212 | + |
213 | +Binaries |
214 | +======== |
215 | + |
216 | +Mailman contains a number of binary wrappers for integration between the MTA |
217 | +and Mailman. Mailman's 'post' command accepts standard input from the MTA and |
218 | +drops the resulting message in Mailman's incoming queue. |
219 | + |
220 | + # See `subscriptions.txt`_ for more details. |
221 | + >>> from lp.services.mailman.testing import helpers |
222 | + >>> alpha = helpers.create_list('alpha') |
223 | + >>> helpers.subscribe('Anne', 'alpha') |
224 | + |
225 | + # Ignore the list creation notification message. |
226 | + >>> smtpd.reset() |
227 | + |
228 | + >>> sample_message = """\ |
229 | + ... From: anne.person@example.com |
230 | + ... To: alpha@lists.launchpad.dev |
231 | + ... Subject: A test message |
232 | + ... Message-ID: <aardvark> |
233 | + ... |
234 | + ... This is a test message. |
235 | + ... """ |
236 | + |
237 | + # The path to the binary we're testing is relative to the top of the |
238 | + # Launchpad source tree. |
239 | + >>> import canonical |
240 | + >>> launchpad_top = os.path.dirname( |
241 | + ... os.path.dirname(os.path.dirname(canonical.__file__))) |
242 | + >>> binary = os.path.join(launchpad_top, |
243 | + ... 'lib/mailman/mail/mailman') |
244 | + |
245 | + >>> mailman = subprocess.Popen( |
246 | + ... (binary, 'post', 'alpha'), |
247 | + ... stdin=subprocess.PIPE, |
248 | + ... stdout=subprocess.PIPE, |
249 | + ... stderr=subprocess.PIPE) |
250 | + |
251 | + >>> stdout, stderr = mailman.communicate(sample_message) |
252 | + >>> mailman.returncode |
253 | + 0 |
254 | + >>> print stdout |
255 | + <BLANKLINE> |
256 | + >>> print stderr |
257 | + <BLANKLINE> |
258 | + |
259 | +The message was delivered to Anne and the archiver. |
260 | + |
261 | + >>> smtpd_watcher.wait_for_mbox_delivery('aardvark') |
262 | + >>> messages = list(smtpd) |
263 | + >>> len(messages) |
264 | + 2 |
265 | + |
266 | + >>> for message in messages: |
267 | + ... if message['x-rcptto'] == 'anne.person@example.com': |
268 | + ... break |
269 | + |
270 | + >>> print message.as_string() |
271 | + From: anne.person@example.com |
272 | + To: alpha@lists.launchpad.dev |
273 | + Message-ID: <aardvark> |
274 | + Subject: [Alpha] A test message |
275 | + X-BeenThere: alpha@lists.launchpad.dev |
276 | + X-Mailman-Version: ... |
277 | + Precedence: list |
278 | + List-Id: <alpha.lists.launchpad.dev> |
279 | + List-Help: <http://help.launchpad.dev/ListHelp> |
280 | + List-Subscribe: <http://launchpad.dev/~alpha> |
281 | + List-Unsubscribe: <http://launchpad.dev/~alpha> |
282 | + List-Post: <mailto:alpha@lists.launchpad.dev> |
283 | + List-Archive: <http://lists.launchpad.dev/alpha> |
284 | + List-Owner: <http://launchpad.dev/~alpha> |
285 | + MIME-Version: 1.0 |
286 | + Content-Type: text/plain; charset="us-ascii" |
287 | + Content-Transfer-Encoding: 7bit |
288 | + Sender: alpha-bounces+anne.person=example.com@lists.launchpad.dev |
289 | + Errors-To: alpha-bounces+anne.person=example.com@lists.launchpad.dev |
290 | + X-Peer: ... |
291 | + X-MailFrom: alpha-bounces+anne.person=example.com@lists.launchpad.dev |
292 | + X-RcptTo: anne.person@example.com |
293 | + <BLANKLINE> |
294 | + This is a test message. |
295 | + _______________________________________________ |
296 | + Mailing list: http://launchpad.dev/~alpha |
297 | + Post to : alpha@lists.launchpad.dev |
298 | + Unsubscribe : http://launchpad.dev/~alpha |
299 | + More help : http://help.launchpad.dev/ListHelp |
300 | |
301 | === modified file 'lib/lp/services/mailman/doc/bounces.txt' |
302 | --- lib/lp/services/mailman/doc/bounces.txt 2009-06-03 16:03:04 +0000 |
303 | +++ lib/lp/services/mailman/doc/bounces.txt 2009-09-24 20:25:22 +0000 |
304 | @@ -1,3 +1,4 @@ |
305 | +================= |
306 | Bounce processing |
307 | ================= |
308 | |
309 | |
310 | === modified file 'lib/lp/services/mailman/doc/contact-address.txt' |
311 | --- lib/lp/services/mailman/doc/contact-address.txt 2009-06-26 21:58:35 +0000 |
312 | +++ lib/lp/services/mailman/doc/contact-address.txt 2009-09-24 20:25:22 +0000 |
313 | @@ -28,7 +28,7 @@ |
314 | >>> browser.getControl('Change').click() |
315 | |
316 | >>> browser.getLink('Change details').click() |
317 | - >>> browser.getLink('Change contact address').click() |
318 | + >>> browser.getLink('Set contact address').click() |
319 | >>> control = browser.getControl(name='field.contact_method') |
320 | >>> [strip_label(label) for label in control.displayValue] |
321 | ['The Launchpad mailing list for this team...] |
322 | @@ -237,7 +237,7 @@ |
323 | >>> browser.getControl('Change').click() |
324 | |
325 | >>> browser.getLink('Change details').click() |
326 | - >>> browser.getLink('Change contact address').click() |
327 | + >>> browser.getLink('Set contact address').click() |
328 | >>> control = browser.getControl(name='field.contact_method') |
329 | >>> [strip_label(label) for label in control.displayValue] |
330 | ['Each member individually'] |
331 | |
332 | === modified file 'lib/lp/services/mailman/doc/create-lists.txt' |
333 | --- lib/lp/services/mailman/doc/create-lists.txt 2009-06-23 17:51:24 +0000 |
334 | +++ lib/lp/services/mailman/doc/create-lists.txt 2009-09-24 20:25:22 +0000 |
335 | @@ -21,7 +21,7 @@ |
336 | To request a mailing list, No Privileges Person navigates to the 'Configure |
337 | mailing list' page and registers their application for a mailing list. |
338 | |
339 | - >>> browser.getLink('Configure mailing list').click() |
340 | + >>> browser.getLink('Create a mailing list').click() |
341 | >>> browser.getControl('Apply for Mailing List').click() |
342 | |
343 | At this point, Mailman has still not created the mailing list. |
344 | @@ -56,7 +56,7 @@ |
345 | >>> browser.getControl(name='field.subscriptionpolicy').displayValue = [ |
346 | ... 'Open Team'] |
347 | >>> browser.getControl('Create').click() |
348 | - >>> browser.getLink('Configure mailing list').click() |
349 | + >>> browser.getLink('Create a mailing list').click() |
350 | >>> browser.getControl('Apply for Mailing List').click() |
351 | |
352 | This time, however, the mailing list expert declines the application for a new |
353 | |
354 | === modified file 'lib/lp/services/mailman/doc/decorations.txt' |
355 | --- lib/lp/services/mailman/doc/decorations.txt 2009-06-23 19:33:57 +0000 |
356 | +++ lib/lp/services/mailman/doc/decorations.txt 2009-09-24 20:25:22 +0000 |
357 | @@ -117,8 +117,7 @@ |
358 | >>> browser = Browser('no-priv@canonical.com:test') |
359 | >>> browser.open('http://launchpad.dev:8085/~itest-one') |
360 | >>> browser.getLink(id='mailing-list-archive') |
361 | - <Link text='Mailing list archive' |
362 | - url='http://lists.launchpad.dev/itest-one'> |
363 | + <Link text='View archive' url='http://lists.launchpad.dev/itest-one'> |
364 | >>> print message['list-archive'] |
365 | <http://lists.launchpad.dev/itest-one> |
366 | |
367 | |
368 | === modified file 'lib/lp/services/mailman/doc/logging.txt' |
369 | --- lib/lp/services/mailman/doc/logging.txt 2009-04-17 10:32:16 +0000 |
370 | +++ lib/lp/services/mailman/doc/logging.txt 2009-09-24 20:25:22 +0000 |
371 | @@ -1,9 +1,12 @@ |
372 | -= Logging and OOPS reporting = |
373 | +========================== |
374 | +Logging and OOPS reporting |
375 | +========================== |
376 | |
377 | The Mailman XMLRPCRunner logs errors and reports OOPSes. |
378 | |
379 | |
380 | -= MailmanErrorUtility = |
381 | +MailmanErrorUtility |
382 | +=================== |
383 | |
384 | The MailmanErrorUtility is a ErrorReportingUtility that is configured |
385 | in the [mailman] section of config. |
386 | @@ -13,21 +16,22 @@ |
387 | ... MailmanErrorUtility) |
388 | |
389 | >>> error_utility = MailmanErrorUtility() |
390 | - >>> error_utility._default_config_section |
391 | - 'mailman' |
392 | - |
393 | - >>> error_utility.prefix |
394 | - 'TMMX' |
395 | - >>> config.mailman.oops_prefix |
396 | - 'TMMX' |
397 | - |
398 | - >>> error_utility.error_dir |
399 | - '/var/tmp/mailman-xmlrpc.test' |
400 | - >>> config.mailman.error_dir |
401 | - '/var/tmp/mailman-xmlrpc.test' |
402 | - |
403 | - |
404 | -= Error logging = |
405 | + >>> print error_utility._default_config_section |
406 | + mailman |
407 | + |
408 | + >>> print error_utility.prefix |
409 | + TMMX |
410 | + >>> print config.mailman.oops_prefix |
411 | + TMMX |
412 | + |
413 | + >>> print error_utility.error_dir |
414 | + /var/tmp/mailman-xmlrpc.test |
415 | + >>> print config.mailman.error_dir |
416 | + /var/tmp/mailman-xmlrpc.test |
417 | + |
418 | + |
419 | +Error logging |
420 | +============= |
421 | |
422 | The log_exception() function is used by XMLRPCRunner to report known |
423 | exceptions. It reports the OOPS. |
424 | @@ -44,12 +48,12 @@ |
425 | |
426 | >>> test_log_exception() |
427 | >>> oops = error_utility.getLastOopsReport() |
428 | - >>> oops.id |
429 | - 'OOPS-...TMMX...' |
430 | - >>> oops.type |
431 | - 'AssertionError' |
432 | - >>> oops.value |
433 | - 'There is an OOPS in progress.' |
434 | + >>> print oops.id |
435 | + OOPS-...TMMX... |
436 | + >>> print oops.type |
437 | + AssertionError |
438 | + >>> print oops.value |
439 | + There is an OOPS in progress. |
440 | >>> print oops.tb_text |
441 | Traceback (most recent call last): |
442 | ... |
443 | @@ -77,4 +81,3 @@ |
444 | the _create() method. The create-lists-txt test was run to generate a |
445 | "NameError: global name 'defect' is not defined". The error was written |
446 | to the xmlrpc log, and an OOPS was reported. |
447 | - |
448 | |
449 | === modified file 'lib/lp/services/mailman/doc/messages.txt' |
450 | --- lib/lp/services/mailman/doc/messages.txt 2009-04-17 10:32:16 +0000 |
451 | +++ lib/lp/services/mailman/doc/messages.txt 2009-09-24 20:25:22 +0000 |
452 | @@ -1,4 +1,6 @@ |
453 | -= Messages = |
454 | +======== |
455 | +Messages |
456 | +======== |
457 | |
458 | Launchpad uses a custom set of message templates that it installs |
459 | in mailman/templates/site. The installation conforms to the standard |
460 | |
461 | === modified file 'lib/lp/services/mailman/doc/modify-lists.txt' |
462 | --- lib/lp/services/mailman/doc/modify-lists.txt 2009-06-03 16:03:04 +0000 |
463 | +++ lib/lp/services/mailman/doc/modify-lists.txt 2009-09-24 20:25:22 +0000 |
464 | @@ -1,4 +1,6 @@ |
465 | -= Modifying lists = |
466 | +=============== |
467 | +Modifying lists |
468 | +=============== |
469 | |
470 | A team administrator can make changes to the mailing list, although currently |
471 | the only thing they can change is the list's welcome message. |
472 | @@ -13,7 +15,7 @@ |
473 | >>> browser.getControl(name='field.subscriptionpolicy').displayValue = [ |
474 | ... 'Open Team'] |
475 | >>> browser.getControl('Create').click() |
476 | - >>> browser.getLink('Configure mailing list').click() |
477 | + >>> browser.getLink('Create a mailing list').click() |
478 | >>> browser.getControl('Apply for Mailing List').click() |
479 | |
480 | Before approving the creation of the mailing list, let's set the welcome |
481 | @@ -26,7 +28,7 @@ |
482 | >>> from canonical.launchpad.interfaces import ( |
483 | ... ILaunchpadCelebrities, IMailingListSet, MailingListStatus) |
484 | |
485 | - >>> login('foo.bar@canonical.com') |
486 | + >>> login('admin@canonical.com') |
487 | >>> list_set = getUtility(IMailingListSet) |
488 | >>> list_one = list_set.get('itest-one') |
489 | >>> list_one.welcome_message = 'Greetings team members!' |
490 | |
491 | === modified file 'lib/lp/services/mailman/doc/postings.txt' |
492 | --- lib/lp/services/mailman/doc/postings.txt 2009-06-26 21:42:20 +0000 |
493 | +++ lib/lp/services/mailman/doc/postings.txt 2009-09-24 20:25:22 +0000 |
494 | @@ -1,3 +1,4 @@ |
495 | +======= |
496 | Posting |
497 | ======= |
498 | |
499 | @@ -14,7 +15,7 @@ |
500 | |
501 | |
502 | Non-member postings |
503 | -------------------- |
504 | +=================== |
505 | |
506 | Postings from addresses that are not registered and verified with Launchpad |
507 | are summarily discarded. |
508 | @@ -37,7 +38,7 @@ |
509 | |
510 | |
511 | Non-validated member postings |
512 | ------------------------------ |
513 | +============================= |
514 | |
515 | Similarly, an address that has been registered with Launchpad but not verified |
516 | will also be summarily discarded. Anne registers with Launchpad but does not |
517 | @@ -48,7 +49,7 @@ |
518 | >>> from canonical.launchpad.ftests import login, logout |
519 | >>> from canonical.launchpad.interfaces import EmailAddressStatus |
520 | |
521 | - >>> login('foo.bar@canonical.com') |
522 | + >>> login('admin@canonical.com') |
523 | >>> anne = factory.makePersonByName('Anne') |
524 | >>> alternative_email = get_alternative_email(anne) |
525 | |
526 | @@ -75,7 +76,7 @@ |
527 | |
528 | |
529 | Unsubscribed Launchpad members |
530 | ------------------------------- |
531 | +============================== |
532 | |
533 | Anne's preferred email address is still validated, and she posts a message |
534 | from that address. However, because she has not yet joined the team or |
535 | @@ -336,7 +337,7 @@ |
536 | |
537 | |
538 | Unsubscribed team member |
539 | ------------------------- |
540 | +======================== |
541 | |
542 | Once Anne joins the team, she may post to it, though until she subscribes to |
543 | the mailing list, she will not get a copy of the message. |
544 | @@ -356,7 +357,7 @@ |
545 | |
546 | >>> from zope.component import getUtility |
547 | >>> from canonical.launchpad.interfaces import IPersonSet |
548 | - >>> login('foo.bar@canonical.com') |
549 | + >>> login('admin@canonical.com') |
550 | >>> team_one = getUtility(IPersonSet).getByName('itest-one') |
551 | >>> anne.join(team_one) |
552 | >>> transaction.commit() |
553 | @@ -407,7 +408,7 @@ |
554 | |
555 | |
556 | Verified and registered member postings |
557 | ---------------------------------------- |
558 | +======================================= |
559 | |
560 | Anne now subscribes to the team's mailing list. She gets a copy of each |
561 | message posted to the mailing list. |
562 | @@ -503,7 +504,7 @@ |
563 | |
564 | However, once she validates this address, she can post from it. |
565 | |
566 | - >>> login('foo.bar@canonical.com') |
567 | + >>> login('admin@canonical.com') |
568 | >>> alternative_email.status = EmailAddressStatus.VALIDATED |
569 | >>> logout() |
570 | >>> transaction.commit() |
571 | @@ -570,11 +571,11 @@ |
572 | |
573 | |
574 | Leaving and re-joining the team |
575 | -------------------------------- |
576 | +=============================== |
577 | |
578 | Anne now leaves the team, but she does not unsubscribe from the mailing list. |
579 | |
580 | - >>> login('foo.bar@canonical.com') |
581 | + >>> login('admin@canonical.com') |
582 | >>> team_one = getUtility(IPersonSet).getByName('itest-one') |
583 | >>> anne.leave(team_one) |
584 | >>> logout() |
585 | @@ -619,7 +620,7 @@ |
586 | Anne re-joins the team and once again can post to the mailing list. She does |
587 | not need to re-subscribe to the mailing list. |
588 | |
589 | - >>> login('foo.bar@canonical.com') |
590 | + >>> login('admin@canonical.com') |
591 | >>> anne.join(team_one) |
592 | >>> logout() |
593 | >>> transaction.commit() |
594 | @@ -654,12 +655,12 @@ |
595 | |
596 | |
597 | First post moderation |
598 | ---------------------- |
599 | +===================== |
600 | |
601 | Normally, Launchpad members who are not subscribed to the mailing list will |
602 | have their posts held for moderation. |
603 | |
604 | - >>> login('foo.bar@canonical.com') |
605 | + >>> login('admin@canonical.com') |
606 | >>> bart = factory.makePersonByName('Bart') |
607 | >>> transaction.commit() |
608 | >>> bart.personal_standing |
609 | @@ -694,7 +695,7 @@ |
610 | list. |
611 | |
612 | >>> from canonical.launchpad.interfaces import PersonalStanding |
613 | - >>> login('foo.bar@canonical.com') |
614 | + >>> login('admin@canonical.com') |
615 | >>> bart.personal_standing = PersonalStanding.GOOD |
616 | >>> transaction.commit() |
617 | |
618 | @@ -809,7 +810,7 @@ |
619 | |
620 | |
621 | Preventing archiver forgeries |
622 | ------------------------------ |
623 | +============================= |
624 | |
625 | We archive messages by sending them to a special address owned by the Mail |
626 | Archive <http://www.mail-archive.com>. This address becomes a recipient of |
627 | @@ -834,7 +835,7 @@ |
628 | |
629 | |
630 | Large messages |
631 | --------------- |
632 | +============== |
633 | |
634 | Only messages which are less than about 40k in size are allowed straight |
635 | through on the mailing list. A message bigger than that will be held for |
636 | |
637 | === modified file 'lib/lp/services/mailman/doc/reactivate-lists.txt' |
638 | --- lib/lp/services/mailman/doc/reactivate-lists.txt 2009-05-06 15:13:39 +0000 |
639 | +++ lib/lp/services/mailman/doc/reactivate-lists.txt 2009-09-24 20:25:22 +0000 |
640 | @@ -1,4 +1,6 @@ |
641 | -= Re-activating mailing lists = |
642 | +=========================== |
643 | +Re-activating mailing lists |
644 | +=========================== |
645 | |
646 | A team administrator may re-activate a previously deactivated mailing list |
647 | without the need for approval from a Launchpad administrator. When the |
648 | @@ -48,7 +50,7 @@ |
649 | |
650 | Now the team owner reactivates the list. |
651 | |
652 | - >>> browser.getLink('Configure mailing list').click() |
653 | + >>> browser.getLink('Create a mailing list').click() |
654 | >>> browser.getControl('Reactivate this Mailing List').click() |
655 | >>> xmlrpc_watcher.wait_for_reactivation('itest-one') |
656 | |
657 | |
658 | === modified file 'lib/lp/services/mailman/doc/recovery.txt' |
659 | --- lib/lp/services/mailman/doc/recovery.txt 2009-06-03 16:03:04 +0000 |
660 | +++ lib/lp/services/mailman/doc/recovery.txt 2009-09-24 20:25:22 +0000 |
661 | @@ -1,4 +1,6 @@ |
662 | -= Error recovery = |
663 | +============== |
664 | +Error recovery |
665 | +============== |
666 | |
667 | Under various conditions, reporting status from Mailman to Launchpad can |
668 | fail. For example, if during construction, the reportStatus() call has |
669 | @@ -18,14 +20,15 @@ |
670 | >>> browser.getControl(name='field.subscriptionpolicy').displayValue = [ |
671 | ... 'Open Team'] |
672 | >>> browser.getControl('Create').click() |
673 | - >>> browser.getLink('Configure mailing list').click() |
674 | + >>> browser.getLink('Create a mailing list').click() |
675 | >>> browser.getControl('Apply for Mailing List').click() |
676 | |
677 | >>> from lp.services.mailman.testing import helpers |
678 | >>> list_one = helpers.review_list('itest-one') |
679 | |
680 | |
681 | -== Lost construction == |
682 | +Lost construction |
683 | +================= |
684 | |
685 | The mailing list is now active, but let's say that the status reporting |
686 | failed. The mailing list would be in the CONSTRUCTING state. We |
687 | @@ -37,7 +40,7 @@ |
688 | >>> from canonical.launchpad.interfaces import ( |
689 | ... IMailingListSet, MailingListStatus) |
690 | >>> from canonical.launchpad.ftests import login, logout |
691 | - >>> login('foo.bar@canonical.com') |
692 | + >>> login('admin@canonical.com') |
693 | >>> mailing_list_set = getUtility(IMailingListSet) |
694 | >>> itest_one = removeSecurityProxy(mailing_list_set.get('itest-one')) |
695 | >>> itest_one.status = MailingListStatus.CONSTRUCTING |
696 | @@ -84,7 +87,8 @@ |
697 | <DBItem MailingListStatus.ACTIVE, (5) Active> |
698 | |
699 | |
700 | -== Lost updates == |
701 | +Lost updates |
702 | +============ |
703 | |
704 | Another situation can occur if the team owner updates the mailing list, |
705 | say by giving it a welcome message. |
706 | |
707 | === modified file 'lib/lp/services/mailman/doc/staging.txt' |
708 | --- lib/lp/services/mailman/doc/staging.txt 2009-06-30 17:37:35 +0000 |
709 | +++ lib/lp/services/mailman/doc/staging.txt 2009-09-24 20:25:22 +0000 |
710 | @@ -20,8 +20,7 @@ |
711 | |
712 | >>> from canonical.launchpad.ftests import login, logout |
713 | |
714 | - >>> login('foo.bar@canonical.com') |
715 | - >>> from zope.component import getUtility |
716 | + >>> login('admin@canonical.com') |
717 | |
718 | >>> owner = factory.makePerson() |
719 | >>> team_one = factory.makeTeam(owner=owner, name='staging-one') |
720 | @@ -127,7 +126,7 @@ |
721 | >>> from canonical.launchpad.interfaces import ( |
722 | ... EmailAddressStatus, IEmailAddressSet, IPersonSet) |
723 | >>> from zope.component import getUtility |
724 | - >>> login('foo.bar@canonical.com') |
725 | + >>> login('admin@canonical.com') |
726 | >>> team = getUtility(IPersonSet).getByName('staging-two') |
727 | >>> email = getUtility(IEmailAddressSet).new( |
728 | ... 'contact@example.com', team, EmailAddressStatus.VALIDATED) |
729 | |
730 | === modified file 'lib/lp/services/mailman/doc/subscriptions.txt' |
731 | --- lib/lp/services/mailman/doc/subscriptions.txt 2009-06-03 16:03:04 +0000 |
732 | +++ lib/lp/services/mailman/doc/subscriptions.txt 2009-09-24 20:25:22 +0000 |
733 | @@ -1,4 +1,6 @@ |
734 | -= Mailing list subscriptions = |
735 | +========================== |
736 | +Mailing list subscriptions |
737 | +========================== |
738 | |
739 | Both direct and indirect members of a team may subscribe to a team's mailing |
740 | list. First, create the mailing list, which will send a notification messages |
741 | @@ -57,7 +59,7 @@ |
742 | >>> from lp.registry.interfaces.person import IPersonSet |
743 | >>> from zope.component import getUtility |
744 | |
745 | - >>> login('foo.bar@canonical.com') |
746 | + >>> login('admin@canonical.com') |
747 | >>> person_set = getUtility(IPersonSet) |
748 | |
749 | >>> anne = person_set.getByName('anne') |
750 | @@ -88,7 +90,7 @@ |
751 | |
752 | Bart now leaves the team. His subscription is removed. |
753 | |
754 | - >>> login('foo.bar@canonical.com') |
755 | + >>> login('admin@canonical.com') |
756 | >>> bart = person_set.getByName('bart') |
757 | >>> team_one = person_set.getByName('itest-one') |
758 | >>> bart.leave(team_one) |
759 | @@ -97,7 +99,8 @@ |
760 | >>> helpers.ensure_nonmembership('itest-one', bart) |
761 | |
762 | |
763 | -== Alternative addresses == |
764 | +Alternative addresses |
765 | +===================== |
766 | |
767 | Now Anne decides to register another email address with Launchpad, however |
768 | before she can validate this address, subscriptions for the list are |
769 | @@ -105,7 +108,7 @@ |
770 | the membership list, either as an enabled or disabled address. |
771 | |
772 | >>> from canonical.launchpad.interfaces import IEmailAddressSet |
773 | - >>> login('foo.bar@canonical.com') |
774 | + >>> login('admin@canonical.com') |
775 | >>> email_set = getUtility(IEmailAddressSet) |
776 | >>> email = email_set.new( |
777 | ... 'anne.x.person@example.net', anne, account=anne.account) |
778 | @@ -145,7 +148,8 @@ |
779 | No Privileges Person <no-priv@canonical.com> DISABLED |
780 | |
781 | |
782 | -== Case-preservation == |
783 | +Case-preservation |
784 | +================= |
785 | |
786 | Mailing lists preserve the case of the subscribed email address, |
787 | although for subscription purposes, two email addresses that differs |
788 | @@ -154,7 +158,7 @@ |
789 | Emma joins Launchpad as normal, then subscribes a mixed-case alternative |
790 | email address. |
791 | |
792 | - >>> login('foo.bar@canonical.com') |
793 | + >>> login('admin@canonical.com') |
794 | >>> emma = factory.makePersonByName('Emma') |
795 | >>> email = email_set.new( |
796 | ... 'EmmaXPerson@example.org', emma, account=emma.account) |
797 | |
798 | === modified file 'lib/lp/services/mailman/testing/helpers.py' |
799 | --- lib/lp/services/mailman/testing/helpers.py 2009-06-25 04:06:00 +0000 |
800 | +++ lib/lp/services/mailman/testing/helpers.py 2009-09-24 20:25:22 +0000 |
801 | @@ -103,7 +103,7 @@ |
802 | 'Open Team'] |
803 | browser.getControl('Create').click() |
804 | # Create the mailing list. |
805 | - browser.getLink('Configure mailing list').click() |
806 | + browser.getLink('Create a mailing list').click() |
807 | browser.getControl('Apply for Mailing List').click() |
808 | mailing_list = review_list(team_name) |
809 | # pylint: disable-msg=F0401 |
810 | |
811 | === modified file 'lib/lp/services/mailman/testing/logwatcher.py' |
812 | --- lib/lp/services/mailman/testing/logwatcher.py 2009-07-17 00:26:05 +0000 |
813 | +++ lib/lp/services/mailman/testing/logwatcher.py 2009-09-24 20:25:22 +0000 |
814 | @@ -33,8 +33,8 @@ |
815 | |
816 | BREAK_ON_TIMEOUT = bool(os.getenv('BREAK_ON_TIMEOUT')) |
817 | LINES_TO_CAPTURE = 50 |
818 | -LOG_GROWTH_WAIT_INTERVAL = datetime.timedelta(seconds=20) |
819 | -FAILURE_CAPTURE_INTERVAL = datetime.timedelta(seconds=60) |
820 | +LOG_GROWTH_WAIT_INTERVAL = datetime.timedelta(seconds=10) |
821 | +FAILURE_CAPTURE_INTERVAL = datetime.timedelta(seconds=10) |
822 | SECONDS_TO_SNOOZE = 0.1 |
823 | Empty = object() |
824 | NL = '\n' |
reviewer rockstar
= Summary =
Bug 435604 describes a critical problem we discovered while rolling out LP 3.0
on forster, the Mailman (and other) server. The problem is that with the move
to buildout for a lot of our packages, the sys.path that the Mailman binary
uses was not correct. The binary uses the system Python, not bin/py so none
of the buildout eggs were visible to it.
== Proposed fix ==
Extend the path hacking done in Mailman's mm_cfg.py to pick up the necessary
buildout eggs. Do this by importing _pythonpath.
== Pre-implementation notes ==
Discussion during cowboy rollout with gary, spm, and stub.
== Implementation details ==
Along the way, I updated all the MailmanLayer tests. These should all pass
now, with the usual caveat that these tests are flaky. That's why we don't
run them as part of our normal test suite.
== Tests ==
To test the specific critical fix in this branch, run:
% bin/test -vv --layer= MailmanLayer -t basic-integration
To see that all the tests have been updated for LP 3.0, run:
% bin/test -vv --layer= MailmanLayer
You may get spurious failures from the above. Your choices are to run each services/ mailman/ doc separately, or/and do 'make clean && make'
test in lib/lp/
between each run.
== Demo and Q/A ==
No demo or Q/A. Once we cherry pick this onto forster, if the mailing lists
work, we're gold.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: services/ mailman/ doc/logging. txt services/ mailman/ doc/subscriptio ns.txt /launchpad/ mailman/ monkeypatches/ __init_ _.py services/ mailman/ testing/ logwatcher. py services/ mailman/ doc/postings. txt services/ mailman/ doc/bounces. txt services/ mailman/ doc/basic- integration. txt services/ mailman/ doc/decorations .txt services/ mailman/ doc/messages. txt services/ mailman/ doc/recovery. txt services/ mailman/ doc/reactivate- lists.txt services/ mailman/ doc/create- lists.txt /launchpad/ mailman/ monkeypatches/ mm_cfg. py.in services/ mailman/ doc/contact- address. txt services/ mailman/ doc/staging. txt services/ mailman/ testing/ helpers. py services/ mailman/ doc/modify- lists.txt
lib/lp/
lib/lp/
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
== Pyflakes Doctest notices ==
lib/lp/ services/ mailman/ doc/logging. txt
70: undefined name 'error_watcher'
71: undefined name 'error_watcher'
74: undefined name 'error_watcher'
75: undefined name 'error_watcher'
lib/lp/ services/ mailman/ doc/postings. txt
14: undefined name 'smtpd'
35: undefined name 'vette_watcher'
36: undefined name 'smtpd'
73: undefined name 'vette_watcher'
74: undefined name 'smtpd'
88: undefined name 'smtpd'
89: undefined name 'smtpd'
99: undefined name 'vette_watcher'
103: undefined name 'smtpd_watcher'
104: undefined name 'smtpd'
156: undefined name 'Browser'
168: undefined name 'smtpd_watcher'
169: undefined name 'smtpd'
212: undefined name 'vette_watcher'
213: undefined name 'smtpd'
244: undefined name 'smtpd'
259: undefine...