Commit 4352bf6d authored by Iustin Pop's avatar Iustin Pop
Browse files

Convert the RAPI document to restructured text

This patch changes the RAPI document, and the RAPI resources
autogenerated-documentation to restructured text. This meant changing
the autogen tool.

The new fragment can be included via RST directives, and doesn't need
passing through replace-sed-vars. This was also the last sgml document
in doc/, so we remove old makefile rules about it.

Reviewed-by: imsnah
parent 5fcc718f
......@@ -36,7 +36,7 @@
/doc/*.in
/doc/*.pdf
/doc/*.png
/doc/rapi-resources.sgml
/doc/rapi-resources.gen
# doc/examples
/doc/examples/bash_completion
......
......@@ -44,7 +44,7 @@ CLEANFILES = \
doc/*.in \
doc/*.pdf \
$(patsubst %.dot,%.png,$(docdot)) \
doc/rapi-resources.sgml \
doc/rapi-resources.gen \
doc/examples/bash_completion \
doc/examples/ganeti.initd \
doc/examples/ganeti.cron \
......@@ -108,9 +108,6 @@ http_PYTHON = \
lib/http/server.py
docsgml = \
doc/rapi.sgml
docrst = \
doc/admin.rst \
doc/design-2.0.rst \
......@@ -123,9 +120,7 @@ docdot = \
doc/arch-2.0.dot
doc_DATA = \
$(patsubst %.rst,%.html,$(docrst)) \
$(patsubst %.sgml,%.html,$(docsgml)) \
$(patsubst %.sgml,%.pdf,$(docsgml))
$(patsubst %.rst,%.html,$(docrst))
noinst_DATA = $(manhtml)
......@@ -155,7 +150,6 @@ EXTRA_DIST = \
devel/upload.in \
$(docrst) \
$(docdot) \
$(docsgml) \
doc/build-rapi-resources-doc \
doc/examples/bash_completion.in \
doc/examples/ganeti.initd.in \
......@@ -228,6 +222,7 @@ TESTS = $(dist_TESTS) $(nodist_TESTS)
TESTS_ENVIRONMENT = PYTHONPATH=.:$(top_builddir)
RAPI_RESOURCES = $(wildcard lib/rapi/*.py)
all-local: stamp-directories lib/_autoconf.py devel/upload \
doc/examples/bash_completion \
......@@ -250,9 +245,6 @@ man/%.in: man/%.sgml stamp-directories $(REPLACE_VARS_SED)
doc/%.pdf: doc/%.in $(DOCBOOK_WRAPPER)
$(DOCBOOK_WRAPPER) "$(DOCBOOK2PDF)" $< $@
doc/%.html: doc/%.in $(DOCBOOK_WRAPPER)
$(DOCBOOK_WRAPPER) "$(DOCBOOK2HTML) --nochunks" $< $@
doc/%.html: doc/%.rst
$(RST2HTML) $< $@
......@@ -261,10 +253,11 @@ doc/%.png: doc/%.dot
doc/design-2.0.html: doc/design-2.0.rst doc/arch-2.0.png
doc/rapi.pdf doc/rapi.html doc/rapi.in: doc/rapi-resources.sgml
doc/rapi.pdf doc/rapi.html: doc/rapi-resources.gen
doc/rapi-resources.sgml: $(BUILD_RAPI_RESOURCE_DOC) lib/rapi/connector.py
PYTHONPATH=.:$(top_builddir) $(BUILD_RAPI_RESOURCE_DOC) > $@ || rm -f $@
doc/rapi-resources.gen: $(BUILD_RAPI_RESOURCE_DOC) $(RAPI_RESOURCES)
PYTHONPATH=.:$(top_builddir) $(BUILD_RAPI_RESOURCE_DOC) > $@ || \
rm -f $@
man/%.7: man/%.in man/footer.sgml $(DOCBOOK_WRAPPER)
$(DOCBOOK_WRAPPER) "$(DOCBOOK2MAN)" $< $@
......@@ -322,10 +315,6 @@ $(REPLACE_VARS_SED): Makefile stamp-directories
echo 's#@CUSTOM_XEN_KERNEL@#$(XEN_KERNEL)#g'; \
echo 's#@CUSTOM_XEN_INITRD@#$(XEN_INITRD)#g'; \
echo 's#@RPL_FILE_STORAGE_DIR@#$(FILE_STORAGE_DIR)#g'; \
echo '/@INCLUDE_RAPI_RESOURCES@/ {'; \
echo ' r $(abs_top_builddir)/doc/rapi-resources.sgml'; \
echo ' d'; \
echo '}'; \
} > $@
# We need to create symlinks because "make distcheck" will not install Python
......
......@@ -20,6 +20,9 @@
"""Script to generate documentation for remote API resources.
This is hard-coded to the section numbering we have in the master RST
document.
"""
import re
......@@ -33,6 +36,29 @@ from ganeti.rapi import connector
CHECKED_COMMANDS = ["GET", "POST", "PUT", "DELETE"]
def beautify(text):
"""A couple of small enhancements, epydoc-to-rst.
"""
pairs = [
("@return:", "Returns:"),
]
for old, new in pairs:
text = text.replace(old, new)
return text
def indent(text):
"""Returns a text block with all lines indented.
"""
lines = text.splitlines()
lines = [" " + l for l in lines]
return "\n".join(lines)
def main():
# Get list of all resources
all = list(connector.CONNECTOR.itervalues())
......@@ -40,48 +66,35 @@ def main():
# Sort rlib by URI
all.sort(cmp=lambda a, b: cmp(a.DOC_URI, b.DOC_URI))
print "<!-- Automatically generated, do not edit -->"
print ".. Automatically generated, do not edit\n"
for cls in all:
print "<sect2>"
print "<title>%s</title>" % cgi.escape(cls.DOC_URI)
title = cls.DOC_URI
print "%s\n%s\n" % (title, "+" * len(title))
# Class docstring
description = inspect.getdoc(cls)
if description:
print ("<literallayout>%s</literallayout>" %
cgi.escape(description.strip()))
print '<informaltable><tgroup cols="2">'
print '<colspec colwidth="1*">'
print '<colspec colwidth="5*">'
print "<thead>"
print " <row>"
print " <entry>Method</entry>"
print " <entry>Description</entry>"
print " </row>"
print "</thead>"
print '<tbody valign="top">'
print "::\n"
print indent(description.strip())
print
supported = [cmd for cmd in CHECKED_COMMANDS if hasattr(cls, cmd)]
print "It supports the following commands: %s." % (", ".join(supported))
print
for cmd in CHECKED_COMMANDS:
if not hasattr(cls, cmd):
continue
print "%s\n%s\n" % (cmd, "~" * len(cmd))
# Get docstring
text = inspect.getdoc(getattr(cls, cmd))
if not text:
text = ""
print "<row>"
print " <entry>%s</entry>" % cgi.escape(cmd)
print (" <entry><literallayout>%s</literallayout></entry>" %
cgi.escape(text.strip()))
print "</row>"
print "</tbody>"
print "</tgroup></informaltable>"
print "</sect2>"
if text:
text = beautify(text)
print "::\n"
print indent(text)
print
if __name__ == "__main__":
......
Ganeti remote API
=================
Documents Ganeti version 2.0
.. contents::
Introduction
------------
Ganeti supports a remote API for enable external tools to easily
retrieve information about a cluster's state. The remote API daemon,
*ganeti-rapi*, is automatically started on the master node. By default
it runs on TCP port 5080, but this can be changed either in
``.../constants.py`` or via the command line parameter *-p*. SSL mode,
which is used by default, can also be disabled by passing command line
parameters.
Protocol
--------
The protocol used is JSON_ over HTTP designed after the REST_
principle.
.. _JSON: http://www.json.org/
.. _REST: http://en.wikipedia.org/wiki/Representational_State_Transfer
Usage examples
--------------
You can access the API using your favorite programming language as
long as it supports network connections.
Shell
+++++
Using wget::
wget -q -O - https://CLUSTERNAME:5080/2/info
or curl::
curl https://CLUSTERNAME:5080/2/info
Python
++++++
::
import urllib2
f = urllib2.urlopen('https://CLUSTERNAME:5080/info')
print f.read()
JavaScript
++++++++++
.. warning:: While it's possible to use JavaScript, it poses several potential
problems, including browser blocking request due to
non-standard ports or different domain names. Fetching the data
on the webserver is easier.
::
var url = 'https://CLUSTERNAME:5080/info';
var info;
var xmlreq = new XMLHttpRequest();
xmlreq.onreadystatechange = function () {
if (xmlreq.readyState != 4) return;
if (xmlreq.status == 200) {
info = eval("(" + xmlreq.responseText + ")");
alert(info);
} else {
alert('Error fetching cluster info');
}
xmlreq = null;
};
xmlreq.open('GET', url, true);
xmlreq.send(null);
Resources
---------
.. include:: rapi-resources.gen
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2//EN" [
<!ENTITY JsonLink "http://www.json.org/">
<!ENTITY WikipediaRESTLink
"http://en.wikipedia.org/wiki/Representational_State_Transfer">
]>
<article class="specification">
<articleinfo>
<title>Ganeti remote API</title>
</articleinfo>
<para>Documents Ganeti version 2.0</para>
<sect1>
<title>Introduction</title>
<para>Ganeti supports a remote API for enable external tools to
easily retrieve information about a cluster's state. The remote API
daemon, <command>ganeti-rapi</command>, is automatically started on
the master node. By default it runs on TCP port 5080, but this can
be changed either in <filename>&hellip;/constants.py</filename> or
via the command line parameter <option>-p</option>. SSL support can
also be enabled by passing command line parameters.</para>
</sect1>
<sect1>
<title>Protocol</title>
<para>The protocol used is <ulink url="&JsonLink;">JSON</ulink> over HTTP
designed after the <ulink url="&WikipediaRESTLink;">REST</ulink> principle.
</para>
</sect1>
<sect1>
<title>Usage examples</title>
<para>You can access the API using your favorite programming language as long
as it supports network connections.</para>
<sect2>
<title>Shell</title>
<screen>wget -q -O - https://<replaceable>CLUSTERNAME</replaceable>:5080/2/info</screen>
<para>or</para>
<screen>curl https://<replaceable>CLUSTERNAME</replaceable>:5080/2/info</screen>
</sect2>
<sect2>
<title>Python</title>
<screen>import urllib2
f = urllib2.urlopen('https://<replaceable>CLUSTERNAME</replaceable>:5080/info')
print f.read()</screen>
</sect2>
<sect2>
<title>JavaScript</title>
<note>
<para>While it's possible to use JavaScript, it poses several potential
problems, including browser blocking request due to non-standard ports
or different domain names. Fetching the data on the webserver is
easier.</para>
</note>
<screen>var url = 'https://<replaceable>CLUSTERNAME</replaceable>:5080/info';
var info;
var xmlreq = new XMLHttpRequest();
xmlreq.onreadystatechange = function () {
if (xmlreq.readyState != 4) return;
if (xmlreq.status == 200) {
info = eval("(" + xmlreq.responseText + ")");
alert(info);
} else {
alert('Error fetching cluster info');
}
xmlreq = null;
};
xmlreq.open('GET', url, true);
xmlreq.send(null);</screen>
</sect2>
</sect1>
<sect1>
<title>Resources</title>
@INCLUDE_RAPI_RESOURCES@
</sect1>
</article>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment