adding docbook definitions for NodeManager. Currently, 'DocBook.py' is a copy
authorStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 25 Oct 2007 16:39:16 +0000 (16:39 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 25 Oct 2007 16:39:16 +0000 (16:39 +0000)
of the DocBook.py from PLCAPI.  It should be merged at some point in the
future. As well, the Makefile depends on PLCAPI being up to levels in the
directory hierarchy.

doc/DocBook.py [new file with mode: 0755]
doc/DocBookLocal.py [new file with mode: 0644]
doc/Makefile [new file with mode: 0644]
doc/NMAPI.xml [new file with mode: 0644]

diff --git a/doc/DocBook.py b/doc/DocBook.py
new file mode 100755 (executable)
index 0000000..0b279b2
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/python
+#
+# Generates a DocBook section documenting all PLCAPI methods on
+# stdout.
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (C) 2006 The Trustees of Princeton University
+#
+# $Id: DocBook.py,v 1.3 2006/10/25 19:35:36 mlhuang Exp $
+#
+
+import xml.dom.minidom
+from xml.dom.minidom import Element, Text
+import codecs
+
+from PLC.Method import *
+import DocBookLocal
+
+# xml.dom.minidom.Text.writexml adds surrounding whitespace to textual
+# data when pretty-printing. Override this behavior.
+class TrimText(Text):
+    """text"""
+    def __init__(self, text = None):
+        self.data = unicode(text)
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        Text.writexml(self, writer, "", "", "")
+
+class TrimTextElement(Element):
+    """<tagName>text</tagName>"""
+    def __init__(self, tagName, text = None):
+        Element.__init__(self, tagName)
+        if text is not None:
+            self.appendChild(TrimText(text))
+
+    def writexml(self, writer, indent="", addindent="", newl=""):
+        writer.write(indent)
+        Element.writexml(self, writer, "", "", "")
+        writer.write(newl)
+
+class simpleElement(TrimTextElement): pass
+
+class paraElement(simpleElement):
+    """<para>text</para>"""
+    def __init__(self, text = None):
+        simpleElement.__init__(self, 'para', text)
+
+class blockquoteElement(Element):
+    """<blockquote><para>text...</para><para>...text</para></blockquote>"""
+    def __init__(self, text = None):
+        Element.__init__(self, 'blockquote')
+        if text is not None:
+            # Split on blank lines
+            lines = [line.strip() for line in text.strip().split("\n")]
+            lines = "\n".join(lines)
+            paragraphs = lines.split("\n\n")
+
+            for paragraph in paragraphs:
+                self.appendChild(paraElement(paragraph))
+
+def param_type(param):
+    """Return the XML-RPC type of a parameter."""
+    if isinstance(param, Mixed) and len(param):
+        subtypes = [param_type(subparam) for subparam in param]
+        return " or ".join(subtypes)
+    elif isinstance(param, (list, tuple, set)) and len(param):
+        return "array of " + " or ".join([param_type(subparam) for subparam in param])
+    else:
+        return xmlrpc_type(python_type(param))
+
+class paramElement(Element):
+    """An optionally named parameter."""
+    def __init__(self, name, param):
+        # <listitem>
+        Element.__init__(self, 'listitem')
+
+        description = Element('para')
+
+        if name:
+            description.appendChild(simpleElement('parameter', name))
+            description.appendChild(TrimText(": "))
+
+        description.appendChild(TrimText(param_type(param)))
+
+        if isinstance(param, (list, tuple, set)) and len(param) == 1:
+            param = param[0]
+
+        if isinstance(param, Parameter):
+            description.appendChild(TrimText(", " + param.doc))
+            param = param.type
+
+        self.appendChild(description)
+
+        if isinstance(param, dict):
+            itemizedlist = Element('itemizedlist')
+            self.appendChild(itemizedlist)
+            for name, subparam in param.iteritems():
+                itemizedlist.appendChild(paramElement(name, subparam))
+
+        elif isinstance(param, (list, tuple, set)) and len(param):
+            itemizedlist = Element('itemizedlist')
+            self.appendChild(itemizedlist)
+            for subparam in param:
+                itemizedlist.appendChild(paramElement(None, subparam))
+
+api_func_list = DocBookLocal.get_func_list()
+for func in api_func_list:
+    method = func.name
+
+    if func.status == "deprecated":
+        continue
+
+    (min_args, max_args, defaults) = func.args()
+
+    section = Element('section')
+    section.setAttribute('id', func.name)
+    section.appendChild(simpleElement('title', func.name))
+
+    prototype = "%s (%s)" % (method, ", ".join(max_args))
+    para = paraElement('Prototype:')
+    para.appendChild(blockquoteElement(prototype))
+    section.appendChild(para)
+
+    para = paraElement('Description:')
+    para.appendChild(blockquoteElement(func.__doc__))
+    section.appendChild(para)
+
+    para = paraElement('Allowed Roles:')
+    para.appendChild(blockquoteElement(", ".join(func.roles)))
+    section.appendChild(para)
+
+    section.appendChild(paraElement('Parameters:'))
+    params = Element('itemizedlist')
+    if func.accepts:
+        for name, param, default in zip(max_args, func.accepts, defaults):
+            params.appendChild(paramElement(name, param))
+    else:
+        listitem = Element('listitem')
+        listitem.appendChild(paraElement('None'))
+        params.appendChild(listitem)
+    section.appendChild(params)
+
+    section.appendChild(paraElement('Returns:'))
+    returns = Element('itemizedlist')
+    returns.appendChild(paramElement(None, func.returns))
+    section.appendChild(returns)
+
+    print section.toprettyxml(encoding = "UTF-8")
diff --git a/doc/DocBookLocal.py b/doc/DocBookLocal.py
new file mode 100644 (file)
index 0000000..be31df9
--- /dev/null
@@ -0,0 +1,13 @@
+
+import api_calls
+
+def get_func_list():
+       api_function_list = []
+       for func in dir(api_calls):
+               try:
+                       f = api_calls.__getattribute__(func)
+                       if 'group' in f.__dict__.keys():
+                               api_function_list += [api_calls.__getattribute__(func)]
+               except:
+                       pass
+       return api_function_list
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..4308fac
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# (Re)builds API documentation
+#
+# Mark Huang <mlhuang@cs.princeton.edu>
+# Copyright (C) 2006 The Trustees of Princeton University
+#
+# $Id: Makefile,v 1.2 2006/11/03 20:36:05 thierry Exp $
+#
+
+all: NMAPI.html
+
+.NMAPI.xml.valid: Methods.xml
+
+Methods.xml: DocBook.py ../api_calls.py
+       PYTHONPATH=..:../../PLCAPI python $< > $@
+
+#
+# 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
+
+force:
+
+.PHONY: force clean docclean
diff --git a/doc/NMAPI.xml b/doc/NMAPI.xml
new file mode 100644 (file)
index 0000000..7ea30be
--- /dev/null
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+    "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!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="Connection">
+      <title>Connection</title>
+
+         <para>The NM XMLRPC server listens locally on every PlanetLab node at http://localhost:812.</para>
+   </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
+-->