--- /dev/null
+#
+# (Re)builds API documentation
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (C) 2006 The Trustees of Princeton University
+#
+# $Id: Makefile 5574 2007-10-25 20:33:17Z thierry $
+#
+
+all: Monitor.html
+
+# XML - as opposed to SGML - requires an identifier - see
+# http://www.docbook.org/tdg/en/html/appb.html
+# and, openjade opens http connections when using the official URL
+# as an identifier; this is slow, and sometimes fails and breaks the build
+
+# locating locally installed docbook43 dtd - fedora-specific
+remote-docbook-43 = http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd
+local-docbook-43 = $(wildcard /usr/share/sgml/docbook/xml-dtd-4.3-*/docbookx.dtd)
+docbook-43=$(if $(local-docbook-43),$(local-docbook-43),$(remote-docbook-43))
+
+Monitor.xml: Monitor.xml.in
+ $(if $(local-docbook-43), \
+ echo Using locally installed DTD $(local-docbook-43), \
+ echo WARNING - could not locate local DTD - using remote $(remote-docbook-43))
+ sed -e s:@DOCBOOK-43@:$(docbook-43): $< > $@
+
+.Monitor.xml.valid: Methods.xml
+
+MONITOR_SOURCES = ../web/MonitorWeb/monitorweb/monitor_xmlrpc.py
+
+# path needs to mention PLCAPI/doc (for DocBook) and PLCAPI/ (for PLC.Parameter)
+Methods.xml: DocBookLocal.py $(MONITOR_SOURCES)
+ PYTHONPATH=..:../../PLCAPI:../../PLCAPI/doc ./DocBookLocal.py > $@
+
+#
+# Documentation
+#
+
+# Validate the XML
+.%.xml.valid: %.xml
+ xmllint --valid --output $@ $<
+
+# Remove the temporary output file after compilation
+.SECONDARY: .%.xml.valid
+
+# Compile it into other formats
+FORMATS := dvi html man ps pdf rtf tex texi txt
+
+DOCBOOK2FLAGS := -V biblio-number=1
+
+define docbook2
+%.$(1): %.xml .%.xml.valid
+ docbook2$(1) --nochunks $$(DOCBOOK2FLAGS) $$<
+endef
+
+$(foreach format,$(FORMATS),$(eval $(call docbook2,$(format))))
+
+clean:
+ rm -f $(patsubst %,*.%,$(FORMATS)) .*.xml.valid Methods.xml
+
+.PHONY: clean all
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"@DOCBOOK-43@" [
+<!ENTITY Methods SYSTEM "Methods.xml">
+]>
+
+<book>
+ <bookinfo>
+ <title>PlanetLab Node Manager API Documentation</title>
+ </bookinfo>
+
+ <chapter id="Introduction">
+ <title>Introduction</title>
+
+ <para>The PlanetLab Node Manager API (NMAPI) is the interface through
+ which the slices access the Node API.</para>
+
+ <section id="Authentication">
+ <title>Authentication</title>
+
+ <para>Authentication for NM operations is based on the identity of the
+ connecting slice. For slices whose roles are defined as
+ 'nm-controller', the target slice must be listed delegated and as
+ controlled by the calling slice.</para>
+
+ </section>
+ <section id="Delegation">
+ <title>Delegation</title>
+ <para> None </para>
+ </section>
+ <section id="Connection">
+ <title>Connection</title>
+
+ <para>The NM XMLRPC server listens locally on every PlanetLab node at http://localhost:812.</para>
+ <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>
+ </section>
+ <section id="Example">
+ <title>An Example using the PLC and NM API</title>
+
+ <para>The nm-controller slice is given a stub account such that it can
+ be accessed over ssh. So rather than logging into NM server listens
+ locally on every PlanetLab node at http://localhost:812.
+
+ </para>
+ <programlisting>
+controller_slice_fields = {'name' : 'princeton_mycontroller',
+ 'instantiation' : 'nm-controller',
+ 'url' : 'http://www.yourhost.com',
+ 'description' : 'a brief description of this slice.', }
+controller_slice_id = api.AddSlices(plauth, controller_slice_fields)
+ </programlisting>
+
+ <para>After this, the controller owner, should both add users and nodes to
+ this slice. As well, the controller slice is created using the standard
+ PlanetLab and NM mechanism. So, wait at least 15 minutes before attempting
+ to access the controller slice on any node.</para>
+
+ <para> Subsequently, slices that will be delegated to this controller will
+ be registered at PLC. An example follows.
+ </para>
+
+ <programlisting>
+delegated_slice_fields = {'name' : 'anothersite_mydelegated',
+ 'instantiation' : 'delegated',
+ 'url' : 'http://www.yourhost.com',
+ 'description' : 'a brief description of this slice.', }
+delegated_slice_id = api.AddSlices(plauth, delegated_slice_fields)
+
+# Get ticket for this slice.
+ticket = api.GetSliceTicket(plauth, "princetondsl_solteszdelegated")
+ </programlisting>
+
+ <para>After the slice is registered with PLC, and your application has the
+ Ticket, the last step is to redeem the ticket by presenting it to the NM
+ through the nm-controller account. The following code formats the message
+ correctly.</para>
+
+ <programlisting>
+# generate an XMLRPC request.
+print xmlrpclib.dumps((ticket,), 'Ticket')
+ </programlisting>
+
+ <para>Finally, this message must be sent to the NM using the controller
+ account. It should be possible to create a program that creates the ssh
+ connection or to use a library that does this automatically such as:
+ <ulink url="http://cheeseshop.python.org/pypi/pyXMLRPCssh/1.0-0">pyXMLRPCssh</ulink>
+ </para>
+
+ <para>
+ Or, you could use something much simpler. Assuming the output from
+ <literal>dumps()</literal> above, is saved to a file called
+ <literal>ticket.txt</literal>, you could run a command like:
+ </para>
+
+ <programlisting>
+cat ticket.txt | ssh princeton_mycontroller@mynode.someuniversity.edu
+ </programlisting>
+ <para>
+ Alternately,
+ </para>
+ <programlisting>
+p = subprocess.Popen(['/usr/bin/ssh', 'princeton_mycontroller@mynode.someuniversity.edu'],
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+print >>p.stdin, xmlrpclib.dumps((ticket,), 'Ticket')
+p.stdin.close()
+print xmlrpclib.loads(p.stdout.read())
+p.wait()
+ </programlisting>
+ <para>
+ The following is a stub to use as you would use the current
+ xmlrpclib.Server() object, but redirects the connection of SSH.
+ </para>
+ <programlisting>
+"""XML-RPC over SSH.
+
+ To use, create an XmlRpcOverSsh object like so:
+ >>> api = XmlRpcOverSsh('princeton_deisenst@planetlab-1.cs.princeton.edu')
+ and call methods as with the normal xmlrpclib.ServerProxy interface.
+"""
+
+from subprocess import PIPE, Popen
+from xmlrpclib import Fault, dumps, loads
+
+__all__ = ['XmlRpcOverSsh']
+
+
+class XmlRpcOverSsh:
+ def __init__(self, userAtHost):
+ self.userAtHost = userAtHost
+
+ def __getattr__(self, method):
+ return _Method(self.userAtHost, method)
+
+
+class _Method:
+ def __init__(self, userAtHost, method):
+ self.userAtHost = userAtHost
+ self.method = method
+
+ def __call__(self, *args):
+ p = Popen(['ssh', self.userAtHost], stdin=PIPE, stdout=PIPE)
+ stdout, stderr = p.communicate(dumps(args, self.method))
+ if stderr:
+ raise Fault(1, stderr)
+ else:
+ return loads(stdout)
+ </programlisting>
+
+ </section>
+
+ </chapter>
+
+ <chapter id="Methods">
+ <title>PlanetLab API Methods</title>
+ <para></para>
+
+ &Methods;
+ </chapter>
+
+</book>
+
+<!-- LocalWords: PlanetLab API PLCAPI RPC HTTPS listMethods methodSignature
+-->
+<!-- LocalWords: methodHelp multicall AuthMethod GetSession GnuPG Username GPG
+-->
+<!-- LocalWords: AuthString AddPersonKey AddPeer UpdatePeer gpg
+-->