~cbehrens/nova/lp844160-build-works-with-zones

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/tap.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 
2
  <head>
 
3
<title>Twisted Documentation: Writing a twistd Plugin</title>
 
4
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
 
5
  </head>
 
6
 
 
7
  <body bgcolor="white">
 
8
    <h1 class="title">Writing a twistd Plugin</h1>
 
9
    <div class="toc"><ol><li><a href="#auto0">Goals</a></li><li><a href="#auto1">A note on .tap files</a></li><li><a href="#auto2">Alternatives to twistd plugins</a></li><li><a href="#auto3">Creating the plugin</a></li><li><a href="#auto4">Using cred with your TAP</a></li><li><a href="#auto5">Conclusion</a></li></ol></div>
 
10
    <div class="content">
 
11
<span/>
 
12
 
 
13
<p>This document describes adding subcommands to
 
14
the <code>twistd</code> command, as a way to facilitate the deployment
 
15
of your applications. <em>(This feature was added in Twisted 2.5)</em></p>
 
16
 
 
17
<p>The target audience of this document are those that have developed
 
18
a Twisted application which needs a command line-based deployment
 
19
mechanism.</p>
 
20
 
 
21
<p>There are a few prerequisites to understanding this document:</p>
 
22
<ul>
 
23
  <li>A basic understanding of the Twisted Plugin System (i.e.,
 
24
      the <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.plugin.html" title="twisted.plugin">twisted.plugin</a></code> module) is
 
25
      necessary, however, step-by-step instructions will be
 
26
      given. Reading <a href="plugin.html" shape="rect">The Twisted Plugin
 
27
      System</a> is recommended, in particular the <q>Extending an
 
28
      Existing Program</q> section.</li>
 
29
  <li>The <a href="application.html" shape="rect">Application</a> infrastructure
 
30
    is used in <code>twistd</code> plugins; in particular, you should
 
31
    know how to expose your program's functionality as a Service.</li>
 
32
  <li>In order to parse command line arguments, the <code>twistd</code> plugin
 
33
    mechanism relies
 
34
    on <code>twisted.python.usage</code>, which is documented
 
35
    in <a href="options.html" shape="rect">Using usage.Options</a>.</li>
 
36
</ul>
 
37
 
 
38
<h2>Goals<a name="auto0"/></h2>
 
39
 
 
40
<p>After reading this document, the reader should be able to expose
 
41
their Service-using application as a subcommand
 
42
of <code>twistd</code>, taking into consideration whatever was passed
 
43
on the command line.</p>
 
44
 
 
45
<h2>A note on .tap files<a name="auto1"/></h2>
 
46
 
 
47
<p>Readers may be confused about a historical file type associated
 
48
with Twisted, the <code>.tap</code> file. This was a kind of file that
 
49
was generated by a program named <code>mktap</code> and
 
50
which <code>twistd</code> can read. <code>.tap</code> files are
 
51
deprecated; this document has nothing to do with them, although the
 
52
technology described herein is very closely related to the old
 
53
system. Existing plugins that were written for the mktap system are
 
54
compatible with this <code>twistd</code> plugin system; the following
 
55
commands,
 
56
</p>
 
57
 
 
58
<pre class="shell" xml:space="preserve">
 
59
$ mktap [foo] [options...]
 
60
$ twistd -n -f [foo].tap
 
61
</pre>
 
62
 
 
63
<p>
 
64
are equivalent to the command:</p>
 
65
 
 
66
<pre class="shell" xml:space="preserve">$ twistd -n [foo] [options...]</pre>
 
67
 
 
68
<h2>Alternatives to twistd plugins<a name="auto2"/></h2>
 
69
<p>The major alternative to the twistd plugin mechanism is the <code>.tac</code>
 
70
file, which is a simple script to be used with the
 
71
twistd <code>-y/--python</code> parameter. The twistd plugin mechanism
 
72
exists to offer a more extensible command-line-driven interface to
 
73
your application. For more information on <code>.tac</code> files, see
 
74
the document <a href="application.html" shape="rect">Using the Twisted Application
 
75
Framework</a>.</p>
 
76
 
 
77
 
 
78
<h2>Creating the plugin<a name="auto3"/></h2>
 
79
 
 
80
<p>The following directory structure is assumed of your project:</p>
 
81
 
 
82
<ul>
 
83
  <li><strong>MyProject</strong> - Top level directory
 
84
    <ul>
 
85
      <li><strong>myproject</strong> - Python package
 
86
        <ul><li><strong>__init__.py</strong></li></ul>
 
87
      </li>
 
88
    </ul>
 
89
  </li>
 
90
</ul>
 
91
 
 
92
<p>
 
93
  During development of your project, Twisted plugins can be loaded
 
94
  from a special directory in your project, assuming your top level
 
95
  directory ends up in sys.path. Create a directory
 
96
  named <code>twisted</code> containing a directory
 
97
  named <code>plugins</code>, and add a file
 
98
  named <code>myproject_plugin.py</code> to it. This file will contain your
 
99
  plugin. Note that you should <em>not</em> add any __init__.py files
 
100
  to this directory structure, and the plugin file should <em>not</em>
 
101
  be named <code>myproject.py</code> (because that would conflict with
 
102
  your project's module name).
 
103
</p>
 
104
 
 
105
<p>
 
106
  In this file, define an object which <em>provides</em> the interfaces
 
107
  <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.plugin.IPlugin.html" title="twisted.plugin.IPlugin">twisted.plugin.IPlugin</a></code>
 
108
  and <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.application.service.IServiceMaker.html" title="twisted.application.service.IServiceMaker">twisted.application.service.IServiceMaker</a></code>.
 
109
</p>
 
110
 
 
111
<p>The <code>tapname</code> attribute of your IServiceMaker provider
 
112
will be used as the subcommand name in a command
 
113
like <code class="shell">twistd [subcommand] [args...]</code>, and
 
114
the <code>options</code> attribute (which should be
 
115
a <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.python.usage.Options.html" title="twisted.python.usage.Options">usage.Options</a></code>
 
116
subclass) will be used to parse the given args.</p>
 
117
 
 
118
<pre class="python"><p class="py-linenumber"> 1
 
119
 2
 
120
 3
 
121
 4
 
122
 5
 
123
 6
 
124
 7
 
125
 8
 
126
 9
 
127
10
 
128
11
 
129
12
 
130
13
 
131
14
 
132
15
 
133
16
 
134
17
 
135
18
 
136
19
 
137
20
 
138
21
 
139
22
 
140
23
 
141
24
 
142
25
 
143
26
 
144
27
 
145
28
 
146
29
 
147
30
 
148
31
 
149
32
 
150
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">zope</span>.<span class="py-src-variable">interface</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">implements</span>
 
151
 
 
152
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">usage</span>
 
153
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">plugin</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IPlugin</span>
 
154
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span>.<span class="py-src-variable">service</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IServiceMaker</span>
 
155
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">internet</span>
 
156
 
 
157
<span class="py-src-keyword">from</span> <span class="py-src-variable">myproject</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">MyFactory</span>
 
158
 
 
159
 
 
160
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Options</span>(<span class="py-src-parameter">usage</span>.<span class="py-src-parameter">Options</span>):
 
161
    <span class="py-src-variable">optParameters</span> = [[<span class="py-src-string">&quot;port&quot;</span>, <span class="py-src-string">&quot;p&quot;</span>, <span class="py-src-number">1235</span>, <span class="py-src-string">&quot;The port number to listen on.&quot;</span>]]
 
162
 
 
163
 
 
164
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyServiceMaker</span>(<span class="py-src-parameter">object</span>):
 
165
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IServiceMaker</span>, <span class="py-src-variable">IPlugin</span>)
 
166
    <span class="py-src-variable">tapname</span> = <span class="py-src-string">&quot;myproject&quot;</span>
 
167
    <span class="py-src-variable">description</span> = <span class="py-src-string">&quot;Run this! It'll make your dog happy.&quot;</span>
 
168
    <span class="py-src-variable">options</span> = <span class="py-src-variable">Options</span>
 
169
 
 
170
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">options</span>):
 
171
        <span class="py-src-string">&quot;&quot;&quot;
 
172
        Construct a TCPServer from a factory defined in myproject.
 
173
        &quot;&quot;&quot;</span>
 
174
        <span class="py-src-keyword">return</span> <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-variable">int</span>(<span class="py-src-variable">options</span>[<span class="py-src-string">&quot;port&quot;</span>]), <span class="py-src-variable">MyFactory</span>())
 
175
 
 
176
 
 
177
<span class="py-src-comment"># Now construct an object which *provides* the relevant interfaces</span>
 
178
<span class="py-src-comment"># The name of this variable is irrelevant, as long as there is *some*</span>
 
179
<span class="py-src-comment"># name bound to a provider of IPlugin and IServiceMaker.</span>
 
180
 
 
181
<span class="py-src-variable">serviceMaker</span> = <span class="py-src-variable">MyServiceMaker</span>()
 
182
</pre>
 
183
 
 
184
<p>
 
185
  Now running <code class="shell">twistd --help</code> should
 
186
  print <code>myproject</code> in the list of available subcommands,
 
187
  followed by the description that we specified in the
 
188
  plugin. <code class="shell">twistd -n myproject</code> would,
 
189
  assuming we defined a <code>MyFactory</code> factory
 
190
  inside <code>myproject</code>, start a listening server on port 1235
 
191
  with that factory.
 
192
</p>
 
193
 
 
194
<h2>Using cred with your TAP<a name="auto4"/></h2>
 
195
 
 
196
<p>
 
197
  Twisted ships with a robust authentication framework to use with
 
198
  your application. If your server needs authentication functionality,
 
199
  and you haven't read about <a href="cred.html" shape="rect">twisted.cred</a>
 
200
  yet, read up on it first.
 
201
</p>
 
202
 
 
203
<p>
 
204
  If you are building a twistd plugin and you want to support a wide
 
205
  variety of authentication patterns, Twisted provides an easy-to-use
 
206
  mixin for your Options subclass:
 
207
  <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.cred.strcred.AuthOptionMixin.html" title="twisted.cred.strcred.AuthOptionMixin">strcred.AuthOptionMixin</a></code>.
 
208
  The following code is an example of using this mixin:
 
209
</p>
 
210
 
 
211
<pre class="python"><p class="py-linenumber"> 1
 
212
 2
 
213
 3
 
214
 4
 
215
 5
 
216
 6
 
217
 7
 
218
 8
 
219
 9
 
220
10
 
221
11
 
222
12
 
223
13
 
224
14
 
225
15
 
226
16
 
227
17
 
228
18
 
229
19
 
230
20
 
231
21
 
232
22
 
233
23
 
234
24
 
235
25
 
236
26
 
237
27
 
238
28
 
239
29
 
240
30
 
241
31
 
242
32
 
243
33
 
244
34
 
245
35
 
246
36
 
247
37
 
248
38
 
249
39
 
250
40
 
251
41
 
252
42
 
253
43
 
254
44
 
255
45
 
256
46
 
257
47
 
258
48
 
259
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">cred</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">credentials</span>, <span class="py-src-variable">portal</span>, <span class="py-src-variable">strcred</span>
 
260
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">usage</span>
 
261
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">plugin</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IPlugin</span>
 
262
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">application</span>.<span class="py-src-variable">service</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">IServiceMaker</span>
 
263
<span class="py-src-keyword">from</span> <span class="py-src-variable">myserver</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">myservice</span>
 
264
 
 
265
<span class="py-src-keyword">class</span> <span class="py-src-identifier">ServerOptions</span>(<span class="py-src-parameter">usage</span>.<span class="py-src-parameter">Options</span>, <span class="py-src-parameter">strcred</span>.<span class="py-src-parameter">AuthOptionMixin</span>):
 
266
    <span class="py-src-comment"># This part is optional; it tells AuthOptionMixin what</span>
 
267
    <span class="py-src-comment"># kinds of credential interfaces the user can give us.</span>
 
268
    <span class="py-src-variable">supportedInterfaces</span> = (<span class="py-src-variable">credentials</span>.<span class="py-src-variable">IUsernamePassword</span>,)
 
269
 
 
270
    <span class="py-src-variable">optParameters</span> = [
 
271
        [<span class="py-src-string">&quot;port&quot;</span>, <span class="py-src-string">&quot;p&quot;</span>, <span class="py-src-number">1234</span>, <span class="py-src-string">&quot;Server port number&quot;</span>],
 
272
        [<span class="py-src-string">&quot;host&quot;</span>, <span class="py-src-string">&quot;h&quot;</span>, <span class="py-src-string">&quot;localhost&quot;</span>, <span class="py-src-string">&quot;Server hostname&quot;</span>]]
 
273
 
 
274
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyServerServiceMaker</span>(<span class="py-src-parameter">object</span>):
 
275
    <span class="py-src-variable">implements</span>(<span class="py-src-variable">IServiceMaker</span>, <span class="py-src-variable">IPlugin</span>)
 
276
    <span class="py-src-variable">tapname</span> = <span class="py-src-string">&quot;myserver&quot;</span>
 
277
    <span class="py-src-variable">description</span> = <span class="py-src-string">&quot;This server does nothing productive.&quot;</span>
 
278
    <span class="py-src-variable">options</span> = <span class="py-src-variable">ServerOptions</span>
 
279
 
 
280
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">makeService</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">options</span>):
 
281
        <span class="py-src-string">&quot;&quot;&quot;Construct a service object.&quot;&quot;&quot;</span>
 
282
        <span class="py-src-comment"># The realm is a custom object that your server defines.</span>
 
283
        <span class="py-src-variable">realm</span> = <span class="py-src-variable">myservice</span>.<span class="py-src-variable">MyServerRealm</span>(<span class="py-src-variable">options</span>[<span class="py-src-string">&quot;host&quot;</span>])
 
284
 
 
285
        <span class="py-src-comment"># The portal is something Cred can provide, as long as</span>
 
286
        <span class="py-src-comment"># you have a list of checkers that you'll support. This</span>
 
287
        <span class="py-src-comment"># list is provided my AuthOptionMixin.</span>
 
288
        <span class="py-src-variable">portal</span> = <span class="py-src-variable">portal</span>.<span class="py-src-variable">Portal</span>(<span class="py-src-variable">realm</span>, <span class="py-src-variable">options</span>[<span class="py-src-string">&quot;credCheckers&quot;</span>])
 
289
 
 
290
        <span class="py-src-comment"># OR, if you know you might get multiple interfaces, and</span>
 
291
        <span class="py-src-comment"># only want to give your application one of them, you</span>
 
292
        <span class="py-src-comment"># also have that option with AuthOptionMixin:</span>
 
293
        <span class="py-src-variable">interface</span> = <span class="py-src-variable">credentials</span>.<span class="py-src-variable">IUsernamePassword</span>
 
294
        <span class="py-src-variable">portal</span> = <span class="py-src-variable">portal</span>.<span class="py-src-variable">Portal</span>(<span class="py-src-variable">realm</span>, <span class="py-src-variable">options</span>[<span class="py-src-string">&quot;credInterfaces&quot;</span>][<span class="py-src-variable">interface</span>])
 
295
 
 
296
        <span class="py-src-comment"># The protocol factory is, like the realm, something you implement.</span>
 
297
        <span class="py-src-variable">factory</span> = <span class="py-src-variable">myservice</span>.<span class="py-src-variable">ServerFactory</span>(<span class="py-src-variable">realm</span>, <span class="py-src-variable">portal</span>)
 
298
 
 
299
        <span class="py-src-comment"># Finally, return a service that will listen for connections.</span>
 
300
        <span class="py-src-keyword">return</span> <span class="py-src-variable">internet</span>.<span class="py-src-variable">TCPServer</span>(<span class="py-src-variable">int</span>(<span class="py-src-variable">options</span>[<span class="py-src-string">&quot;port&quot;</span>]), <span class="py-src-variable">factory</span>)
 
301
 
 
302
 
 
303
<span class="py-src-comment"># As in our example above, we have to construct an object that</span>
 
304
<span class="py-src-comment"># provides the IPlugin and IServiceMaker interfaces.</span>
 
305
 
 
306
<span class="py-src-variable">serviceMaker</span> = <span class="py-src-variable">MyServerServiceMaker</span>()
 
307
</pre>
 
308
 
 
309
<p>
 
310
  Now that you have your TAP configured to support any authentication
 
311
  we can throw at it, you're ready to use it. Here is an example of
 
312
  starting your server using the /etc/passwd file for
 
313
  authentication. (Clearly, this won't work on servers with shadow
 
314
  passwords.)
 
315
</p>
 
316
 
 
317
<pre class="shell" xml:space="preserve">
 
318
$ twistd myserver --auth passwd:/etc/passwd
 
319
</pre>
 
320
 
 
321
<p>
 
322
  For a full list of cred plugins supported, see <code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.plugins.html" title="twisted.plugins">twisted.plugins</a></code>, or use the command-line help:
 
323
</p>
 
324
 
 
325
<pre class="shell" xml:space="preserve">
 
326
$ twistd myserver --help-auth
 
327
$ twistd myserver --help-auth-type passwd
 
328
</pre>
 
329
 
 
330
<h2>Conclusion<a name="auto5"/></h2>
 
331
 
 
332
<p>You should now be able to</p>
 
333
<ul>
 
334
  <li>Create a twistd plugin</li>
 
335
  <li>Incorporate authentication into your plugin</li>
 
336
  <li>Use it from your development environment</li>
 
337
  <li>Install it correctly and use it in deployment</li>
 
338
</ul>
 
339
 
 
340
 
 
341
</div>
 
342
 
 
343
    <p><a href="index.html">Index</a></p>
 
344
    <span class="version">Version: 10.0.0</span>
 
345
  </body>
 
346
</html>
 
 
b'\\ No newline at end of file'