Merge lp:~stephen-xemacs/mailman/sprint-2012-overview into lp:mailman

Proposed by Stephen Turnbull
Status: Merged
Merged at revision: 7122
Proposed branch: lp:~stephen-xemacs/mailman/sprint-2012-overview
Merge into: lp:mailman
Diff against target: 244 lines (+197/-3)
3 files modified
README.rst (+1/-0)
conf.py (+6/-3)
src/mailman/docs/8-miles-high.rst (+190/-0)
To merge this branch: bzr merge lp:~stephen-xemacs/mailman/sprint-2012-overview
Reviewer Review Type Date Requested Status
Mailman Coders Pending
Review via email: mp+97533@code.launchpad.net

Description of the change

Andrea Crotti's work making python setup.py build_sphinx work, plus my "Overview" document.
This branch contains and supersedes lp:~andrea-crotti-o/mailman/conf_py.

To build the docs on my Mac OS X/Macports system I used

$ python2.6 bootstrap.py # get python 2.6 from MacPorts
$ bin/buildout
$ python2.6 setup.py build_sphinx

The output ends up in src/mailman/docs/build/sphinx/html/README.html. No promises for
other platforms. :-p

New files in src/mailman/docs:
  8-miles-high.rst # ReST file containing notes from Mailman sprint at PyCon 2012
  chains.png # used by 8-miles-high:
  pipeline.png # from Barry Warsaw's Mailman presentation
  msg-flow.png # replaced by in-line graphviz code (will be removed)
Other changes to (1) fix build, and (2) integrate 8-miles-high into README.rst.

To post a comment you must log in.
7117. By Stephen Turnbull

Improved layout of graphviz version of chains.

7118. By Stephen Turnbull

source, chains, sink subgraphs form

7119. By Stephen Turnbull

groups help

7120. By Stephen Turnbull

We gots a graphviz! Now WAT?!

7121. By Stephen Turnbull

Remove redundant PNGs.

7122. By Stephen Turnbull

Use minlen to disentagle the POSTING queue.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'README.rst'
--- README.rst 2012-03-13 01:03:35 +0000
+++ README.rst 2012-03-15 22:29:19 +0000
@@ -37,6 +37,7 @@
37 src/mailman/docs/START37 src/mailman/docs/START
38 src/mailman/docs/DATABASE38 src/mailman/docs/DATABASE
39 src/mailman/docs/MTA39 src/mailman/docs/MTA
40 src/mailman/docs/8-miles-high
40 src/mailman/bin/docs/*41 src/mailman/bin/docs/*
41 src/mailman/commands/docs/*42 src/mailman/commands/docs/*
42 src/mailman/database/docs/*43 src/mailman/database/docs/*
4344
=== removed directory '_static'
=== removed directory '_templates'
=== modified file 'conf.py'
--- conf.py 2012-02-12 15:01:07 +0000
+++ conf.py 2012-03-15 22:29:19 +0000
@@ -25,10 +25,12 @@
2525
26# Add any Sphinx extension module names here, as strings. They can be extensions26# Add any Sphinx extension module names here, as strings. They can be extensions
27# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.27# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']28extensions = ['sphinx.ext.autodoc',
29 'sphinx.ext.viewcode',
30 'sphinx.ext.graphviz']
2931
30# Add any paths that contain templates here, relative to this directory.32# Add any paths that contain templates here, relative to this directory.
31templates_path = ['_templates']33# templates_path = ['_templates']
3234
33# The suffix of source filenames.35# The suffix of source filenames.
34source_suffix = '.rst'36source_suffix = '.rst'
@@ -122,7 +124,7 @@
122# Add any paths that contain custom static files (such as style sheets) here,124# Add any paths that contain custom static files (such as style sheets) here,
123# relative to this directory. They are copied after the builtin static files,125# relative to this directory. They are copied after the builtin static files,
124# so a file named "default.css" will overwrite the builtin "default.css".126# so a file named "default.css" will overwrite the builtin "default.css".
125html_static_path = ['_static']127# html_static_path = ['_static']
126128
127# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,129# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
128# using the given strftime format.130# using the given strftime format.
@@ -222,6 +224,7 @@
222 import errno224 import errno
223 cwd = os.getcwd()225 cwd = os.getcwd()
224 try:226 try:
227 os.makedirs('build/sphinx/html')
225 os.chdir('build/sphinx/html')228 os.chdir('build/sphinx/html')
226 os.symlink('README.html', 'index.html')229 os.symlink('README.html', 'index.html')
227 print 'index.html -> README.html'230 print 'index.html -> README.html'
228231
=== added file 'src/mailman/docs/8-miles-high.rst'
--- src/mailman/docs/8-miles-high.rst 1970-01-01 00:00:00 +0000
+++ src/mailman/docs/8-miles-high.rst 2012-03-15 22:29:19 +0000
@@ -0,0 +1,190 @@
1========================================
2Notes from the PyCon 2012 Mailman Sprint
3========================================
4
5.. authorship
6 The notes are based on Barry Warsaw's description of the Mailman 3
7 pipeline at the PyCon 2012 Mailman sprint on March 13, with
8 diagrams from his "Mailman" presentation at PyCon 2012.
9 Transcribed by Stephen Turnbull.
10
11These are notes from the Mailman sprint at PyCon 2012. They are not
12terribly well organized, nor fully fleshed out. Please edit and push
13branches to Launchpad at lp:mailman or post patches to <WHERE?> <URL?>.
14
15The intent of this document is to provide a view of Mailman 3's
16workflow and structures from "eight miles high".
17
18
19Basic Messaging Handling Workflow
20---------------------------------
21
22Mailman accepts a message via the LMTP protocol (RFC 2033). It
23implements a simple LMTP server internally based on the LMTP server
24provided in the Python stdlib. The LMTP server's responsibility is to
25parse the message into a tuple (*mlist*, *msg*, *msg_data*). If the
26parse fails (including messages which Mailman considers to be invalid
27due to lack of Message-Id as strongly recommended by RFC 2822 and RFC
285322), the message will be rejected, otherwise the tuple is pickled,
29and the resulting *message pickle* added to one of the IN, COMMAND, or
30BOUNCE processing queues.
31
32.. graphviz::
33
34 digraph msgflow {
35 rankdir = LR;
36 node [shape=box, color=lightblue, style=filled];
37 msg [shape=ellipse, color=black, fillcolor=white];
38 lmtpd [label="LMTP\nSERVER"];
39 msg -> MTA [label="SMTP"];
40 MTA -> lmtpd [label="LMTP"];
41 lmtpd -> MTA [label="reject"];
42 lmtpd -> IN -> POSTING [label=".pck"];
43 lmtpd -> BOUNCES [label=".pck"];
44 lmtpd -> COMMAND [label=".pck"];
45 }
46
47The IN queue is processed by *filter chains* (explained below) to
48determine whether the post (or administrative request) will be
49processed. If not allowed, the message pickle is discarded, rejected
50(returned to sender), or held (added to the MODERATION queue -- not
51shown). Otherwise the message is added to the POSTING queue.
52
53Each of the COMMAND, BOUNCE, and POSTING queues is processed by a
54*pipeline of handlers* as in Mailman 2's pipeline. (Some functions
55such as spam detection that were handled in the Mailman 2 pipeline are
56now in the filter chains.)
57
58Handlers may copy messages to other queues (*e.g.*, ARCHIVE), and
59eventually posts for distribution end up in the OUT queue for
60injection into the MTA.
61
62The VIRGIN queue is a special queue for messages created by Mailman.
63
64.. graphviz::
65
66 digraph pipeline {
67 node [shape=box, style=rounded, group=0]
68 { "MIME\ndelete" -> "cleanse headers" -> "add headers" -> \
69 "calculate\nrecipients" -> "to digest" -> "to archive" -> \
70 "to outgoing" }
71 node [shape=box, color=lightblue, style=filled, group=1]
72 { rank=same; POSTING -> "MIME\ndelete" }
73 { rank=same; "to digest" -> DIGEST }
74 { rank=same; "to archive" -> ARCHIVE }
75 { rank=same; "to outgoing" -> OUT }
76 }
77
78
79Message Filtering
80-----------------
81
82Once a message has been classified as a post or administrivia, rules
83are applied to determine whether the message should be distributed or
84acted on. Rules include things like "if the message's sender is a
85non-member, hold it for moderation", or "if the message contains an
86Approved field with a valid password, distribute it". A rule may also
87make no decision, in which case the message pickle is passed on to the
88next rule in the filter chain. The default set of rules looks
89something like this:
90
91.. graphviz::
92
93 digraph chain_rules {
94 rankdir=LR /* This gives the right orientation of the columns. */
95 rank=same
96 subgraph in { IN [shape=box, color=lightblue, style=filled] }
97 subgraph rules {
98 rankdir=TB
99 rank=same
100 node [shape=record]
101 approved [group=0, label="<f0> approved | {<f1> | <f2>}"]
102 emergency [group=0, label="<f0> emergency | {<f1> | <f2>}"]
103 loop [group=0, label="<f0> loop | {<f1> | <f2>}"]
104 modmember [group=0, label="<f0> member\nmoderated | {<f1> | <f2>}"]
105 administrivia [group=0, label="<f0> administrivia | <f1>"]
106 maxsize [group=0, label="<f0> max\ size | {<f1> | <f2>}"]
107 any [group=0, label="<f0> any | {<f1> | <f2>}"]
108 truth [label="<f0> truth | <f1>"]
109 approved:f1 -> emergency:f0 [weight=100]
110 emergency:f1 -> loop:f0
111 loop:f1 -> modmember:f0
112 modmember:f1 -> administrivia:f0
113 administrivia:f1 -> maxsize:f0
114 maxsize:f1 -> any:f0
115 any:f1 -> truth:f0
116 }
117 subgraph queues {
118 rankdir=TB
119 rank=same
120 node [shape=box, style=filled];
121 DISCARD [shape=invhouse, color=black, style=solid];
122 MODERATION [color=wheat];
123 HOLD [color=wheat];
124 }
125 { POSTING [shape=box, style=filled, color=cyan]; }
126
127 IN -> approved:f0
128 approved:f2 -> POSTING [minlen=2]
129 loop:f2 -> DISCARD
130 modmember:f2 -> MODERATION
131
132 emergency:f2:e -> HOLD
133 maxsize:f2 -> MODERATION
134 any:f2 -> MODERATION
135 truth:f1 -> POSTING [minlen=2]
136 }
137
138
139Configuration
140-------------
141
142Uses lazr.config.
143
144Each Runner's configuration object knows whether it should be started
145when the Mailman daemon starts, and what queue the Runner manages.
146
147
148Shell Commands
149--------------
150
151bin/mailman: This is an ubercommand, with subcommands for all the
152various things admins might want to do, similar to mailmanctl, but
153with more functionality.
154
155bin/master: The runner manager: starts, watches, stops the runner
156daemons.
157
158bin/runner: Individual runner daemons. Each instance is configured
159with a configure object specified on the command line, and other
160command line options.
161
162
163User Model
164----------
165
166A *user* represents a person. A user has an *id* and a *display
167name*, and a list of addresses.
168
169Each *address* is a separate object, linked to a user with a user id.
170
171A list *member* is a link from a user to a mailing list. Each list
172member has a user id, a mailing list name, an address (which may be
173None, which will be replaced by the user's preferred address, a list
174of preferences, and a *role* such as "owner" or "moderator". Roles
175are used to determine what kinds of mail the user receives via that
176membership. *Owners* will receive mail to *list*-owner, but not posts
177and moderation traffic, for example. A user with multiple roles on a
178single list will therefore have multiple memberships in that list, one
179for each role.
180
181Roles are implemented by "magical, invisible" *rosters*.
182
183
184List Styles
185-----------
186
187Each list *style* is a named object. Its attributes are functions
188used to apply the relevant style settings to the mailing list *at
189creation time*. Since these are functions, they can be composed in
190various ways, to create substyles, *etc*.