reguire gnupg1 on f>=31; sense the system to use gpg1 when installed
[nodemanager.git] / doc / NMAPI.xml.in
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3 "@DOCBOOK-43@" [
4 <!ENTITY Methods SYSTEM "Methods.xml">
5 ]>
6
7 <book>
8   <bookinfo>
9     <title>PlanetLab Node Manager API Documentation</title>
10   </bookinfo>
11
12   <chapter id="Introduction">
13     <title>Introduction</title>
14
15     <para>The PlanetLab Node Manager API (NMAPI) is the interface through
16     which the slices access the Node API.</para>
17
18     <section id="Authentication">
19       <title>Authentication</title>
20
21           <para>Authentication for NM operations is based on the identity of the
22           connecting slice.  For slices whose roles are defined as
23           'nm-controller', the target slice must be listed delegated and as
24           controlled by the calling slice.</para>
25
26    </section>
27    <section id="Delegation">
28       <title>Delegation</title>
29           <para> None </para>
30    </section>
31     <section id="Connection">
32       <title>Connection</title>
33
34           <para>The NM XMLRPC server listens locally on every PlanetLab node at http://localhost:812.</para>
35           <para>The NM XMLRPC server can be accessed remotely using an SSH connection through the nm-controller account.  Rather than a standard shell, a special command is run that forwards all standard input to the local XMLRPC server, essentially XML-RPC over ssh.</para>
36    </section>
37     <section id="Example">
38       <title>An Example using the PLC and NM API</title>
39
40           <para>The nm-controller slice is given a stub account such that it can
41           be accessed over ssh.  So rather than logging into NM server listens
42           locally on every PlanetLab node at http://localhost:812.
43           
44           </para>
45       <programlisting>
46 controller_slice_fields = {'name'      : 'princeton_mycontroller',
47                            'instantiation' : 'nm-controller',
48                            'url'           : 'http://www.yourhost.com', 
49                            'description'   : 'a brief description of this slice.', }
50 controller_slice_id = api.AddSlice(plauth, controller_slice_fields)
51       </programlisting>
52
53         <para>After this, the controller owner, should both add users and nodes to
54         this slice.  As well, the controller slice is created using the standard
55         PlanetLab and NM mechanism.  So, wait at least 15 minutes before attempting 
56         to access the controller slice on any node.</para>
57
58         <para> Subsequently, slices that will be delegated to this controller will
59         be registered at PLC.  An example follows.
60         </para>
61
62         <programlisting>
63 delegated_slice_fields = {'name'        : 'anothersite_mydelegated',
64                         'instantiation' : 'delegated',
65                         'url'           : 'http://www.yourhost.com', 
66                         'description'   : 'a brief description of this slice.', }
67 delegated_slice_id = api.AddSlice(plauth, delegated_slice_fields)
68
69 # Get ticket for this slice.
70 ticket = api.GetSliceTicket(plauth, "princetondsl_solteszdelegated")
71         </programlisting>
72
73         <para>After the slice is registered with PLC, and your application has the
74         Ticket, the last step is to redeem the ticket by presenting it to the NM
75         through the nm-controller account.  The following code formats the message
76         correctly.</para>
77
78         <programlisting>
79 # generate an XMLRPC request.
80 print xmlrpclib.dumps((ticket,), 'Ticket')
81         </programlisting>
82
83         <para>Finally, this message must be sent to the NM using the controller
84         account.  It should be possible to create a program that creates the ssh
85         connection or to use a library that does this automatically such as: 
86         <ulink url="http://cheeseshop.python.org/pypi/pyXMLRPCssh/1.0-0">pyXMLRPCssh</ulink>
87         </para>
88
89         <para>
90         Or, you could use something much simpler.  Assuming the output from
91         <literal>dumps()</literal> above, is saved to a file called
92         <literal>ticket.txt</literal>, you could run a command like:
93         </para>
94
95         <programlisting>
96 cat ticket.txt | ssh princeton_mycontroller@mynode.someuniversity.edu
97         </programlisting>
98         <para>
99         Alternately,
100         </para>
101         <programlisting>
102 p = subprocess.Popen(['/usr/bin/ssh', 'princeton_mycontroller@mynode.someuniversity.edu'], 
103                                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
104 print >>p.stdin, xmlrpclib.dumps((ticket,), 'Ticket')
105 p.stdin.close()
106 print xmlrpclib.loads(p.stdout.read())
107 p.wait() 
108         </programlisting>
109         <para>
110         The following is a stub to use as you would use the current
111         xmlrpclib.Server() object, but redirects the connection of SSH.
112         </para>
113         <programlisting>
114 """XML-RPC over SSH.
115
116         To use, create an XmlRpcOverSsh object like so:
117                 >>> api = XmlRpcOverSsh('princeton_deisenst@planetlab-1.cs.princeton.edu')
118         and call methods as with the normal xmlrpclib.ServerProxy interface.
119 """
120
121 from subprocess import PIPE, Popen
122 from xmlrpclib import Fault, dumps, loads
123
124 __all__ = ['XmlRpcOverSsh']
125
126
127 class XmlRpcOverSsh:
128     def __init__(self, userAtHost):
129         self.userAtHost = userAtHost
130
131     def __getattr__(self, method):
132         return _Method(self.userAtHost, method)
133
134
135 class _Method:
136     def __init__(self, userAtHost, method):
137         self.userAtHost = userAtHost
138         self.method = method
139
140     def __call__(self, *args):
141         p = Popen(['ssh', self.userAtHost], stdin=PIPE, stdout=PIPE)
142         stdout, stderr = p.communicate(dumps(args, self.method))
143         if stderr:
144             raise Fault(1, stderr)
145         else:
146             return loads(stdout)
147         </programlisting>
148
149    </section>
150
151   </chapter>
152
153   <chapter id="Methods">
154     <title>PlanetLab API Methods</title>
155     <para></para>
156
157     &Methods;
158   </chapter>
159
160 </book>
161
162 <!-- LocalWords:  PlanetLab API PLCAPI RPC HTTPS listMethods methodSignature
163 -->
164 <!-- LocalWords:  methodHelp multicall AuthMethod GetSession GnuPG Username GPG
165 -->
166 <!-- LocalWords:  AuthString AddPersonKey AddPeer UpdatePeer gpg
167 -->