From 6d81475ca04828b3e849541581ad6008b0dc81c6 Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sat, 9 May 2009 23:18:05 +0200
Subject: [PATCH] Convert from auto-generated RAPI docs to static

This patch removes the autogeneration of the RAPI docs from the code
(based on docstrings) and moves the current autogenerated output to
the rapi.rst file.

The reasons behind this are multiple:
  - the build system becomes a little more simple (this could have been
	achieved also by distributing the built documentation, though)
  - it's hard to actually write documentation in docstrings; you have to
	fit restructured text inside the docstrings, and this results in
	not really nice output
  - even by being close to the code, the documentation manages to get
	out of sync (not paying attention to docstrings)

This will also help with the move to sphinx.

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
---
 Makefile.am                  |  14 +-
 doc/build-rapi-resources-doc | 101 -------
 doc/rapi.rst                 | 531 ++++++++++++++++++++++++++++++++++-
 3 files changed, 532 insertions(+), 114 deletions(-)
 delete mode 100755 doc/build-rapi-resources-doc

diff --git a/Makefile.am b/Makefile.am
index 42b41b447..d441fae76 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -11,7 +11,6 @@ abs_top_srcdir = @abs_top_srcdir@
 
 ACLOCAL_AMFLAGS = -I autotools
 DOCBOOK_WRAPPER = $(top_srcdir)/autotools/docbook-wrapper
-BUILD_RAPI_RESOURCE_DOC = $(top_srcdir)/doc/build-rapi-resources-doc
 REPLACE_VARS_SED = autotools/replace_vars.sed
 
 hypervisordir = $(pkgpythondir)/hypervisor
@@ -45,7 +44,6 @@ MAINTAINERCLEANFILES = \
 CLEANFILES = \
 	autotools/replace_vars.sed \
 	devel/upload \
-	doc/rapi-resources.gen \
 	doc/examples/bash_completion \
 	doc/examples/ganeti.initd \
 	doc/examples/ganeti.cron \
@@ -114,6 +112,7 @@ docrst = \
 	doc/hooks.rst \
 	doc/iallocator.rst \
 	doc/install.rst \
+	doc/rapi.rst \
 	doc/security.rst
 
 dochtml = $(patsubst %.rst,%.html,$(docrst))
@@ -152,7 +151,6 @@ EXTRA_DIST = \
 	devel/upload.in \
 	$(docrst) \
 	$(docdot) \
-	doc/build-rapi-resources-doc \
 	doc/examples/bash_completion.in \
 	doc/examples/ganeti.initd.in \
 	doc/examples/ganeti.cron.in \
@@ -224,8 +222,6 @@ 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 \
 	doc/examples/ganeti.initd doc/examples/ganeti.cron
@@ -248,12 +244,6 @@ doc/%.png: doc/%.dot
 
 doc/design-2.0.html: doc/design-2.0.rst doc/arch-2.0.png
 
-doc/rapi.html: doc/rapi-resources.gen
-
-doc/rapi-resources.gen: $(BUILD_RAPI_RESOURCE_DOC) $(RAPI_RESOURCES)
-	PYTHONPATH=.:$(top_builddir) $(BUILD_RAPI_RESOURCE_DOC) > $@ || \
-	  rm -f $@
-
 man/%.7.in man/%.8.in: man/%.sgml man/footer.sgml $(DOCBOOK_WRAPPER)
 	@test -n "$(DOCBOOK2MAN)" || { echo 'docbook2html' not found during configure; exit 1; }
 	TMPDIR=`mktemp -d` && { \
@@ -281,7 +271,7 @@ man/%.html: man/%.html.in stamp-directories $(REPLACE_VARS_SED)
 
 man/footer.sgml $(TESTS): srclinks
 
-$(TESTS) $(BUILD_RAPI_RESOURCE_DOC): ganeti lib/_autoconf.py
+$(TESTS): ganeti lib/_autoconf.py
 
 lib/_autoconf.py: Makefile stamp-directories
 	set -e; \
diff --git a/doc/build-rapi-resources-doc b/doc/build-rapi-resources-doc
deleted file mode 100755
index 3bc138157..000000000
--- a/doc/build-rapi-resources-doc
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-#
-
-# Copyright (C) 2008 Google Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-"""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
-import cgi
-import inspect
-
-from ganeti.rapi import rlib2
-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())
-
-  # Sort rlib by URI
-  all.sort(cmp=lambda a, b: cmp(a.DOC_URI, b.DOC_URI))
-
-  print ".. Automatically generated, do not edit\n"
-
-  for cls in all:
-    title = cls.DOC_URI
-    print "%s\n%s\n" % (title, "+" * len(title))
-
-    # Class docstring
-    description = inspect.getdoc(cls)
-    if description:
-      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 text:
-        text = beautify(text)
-        print "::\n"
-        print indent(text)
-        print
-
-
-if __name__ == "__main__":
-  main()
diff --git a/doc/rapi.rst b/doc/rapi.rst
index c2ed7c459..91bd1f7d6 100644
--- a/doc/rapi.rst
+++ b/doc/rapi.rst
@@ -82,4 +82,533 @@ JavaScript
 Resources
 ---------
 
-.. include:: rapi-resources.gen
+/
++
+
+::
+
+  / resource.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Show the list of mapped resources.
+
+  Returns: a dictionary with 'name' and 'uri' keys for each of them.
+
+/2
+++
+
+::
+
+  /2 resource, the root of the version 2 API.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Show the list of mapped resources.
+
+  Returns: a dictionary with 'name' and 'uri' keys for each of them.
+
+/2/info
++++++++
+
+::
+
+  Cluster info.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Returns cluster information.
+
+  Example::
+
+  {
+    "config_version": 2000000,
+    "name": "cluster",
+    "software_version": "2.0.0~beta2",
+    "os_api_version": 10,
+    "export_version": 0,
+    "candidate_pool_size": 10,
+    "enabled_hypervisors": [
+      "fake"
+    ],
+    "hvparams": {
+      "fake": {}
+     },
+    "default_hypervisor": "fake",
+    "master": "node1.example.com",
+    "architecture": [
+      "64bit",
+      "x86_64"
+    ],
+    "protocol_version": 20,
+    "beparams": {
+      "default": {
+        "auto_balance": true,
+        "vcpus": 1,
+        "memory": 128
+       }
+      }
+    }
+
+/2/instances
+++++++++++++
+
+::
+
+  /2/instances resource.
+
+It supports the following commands: GET, POST.
+
+GET
+~~~
+
+::
+
+  Returns a list of all available instances.
+
+
+  Example::
+
+    [
+      {
+        "name": "web.example.com",
+        "uri": "\/instances\/web.example.com"
+      },
+      {
+        "name": "mail.example.com",
+        "uri": "\/instances\/mail.example.com"
+      }
+    ]
+
+  If the optional 'bulk' argument is provided and set to 'true'
+  value (i.e '?bulk=1'), the output contains detailed
+  information about instances as a list.
+
+  Example::
+
+    [
+      {
+         "status": "running",
+         "disk_usage": 20480,
+         "nic.bridges": [
+           "xen-br0"
+          ],
+         "name": "web.example.com",
+         "tags": ["tag1", "tag2"],
+         "beparams": {
+           "vcpus": 2,
+           "memory": 512
+         },
+         "disk.sizes": [
+             20480
+         ],
+         "pnode": "node1.example.com",
+         "nic.macs": ["01:23:45:67:89:01"],
+         "snodes": ["node2.example.com"],
+         "disk_template": "drbd",
+         "admin_state": true,
+         "os": "debian-etch",
+         "oper_state": true
+      },
+      ...
+    ]
+
+  Returns: a dictionary with 'name' and 'uri' keys for each of them.
+
+POST
+~~~~
+
+::
+
+  Create an instance.
+
+  Returns: a job id
+
+/2/instances/[instance_name]
+++++++++++++++++++++++++++++
+
+::
+
+  /2/instances/[instance_name] resources.
+
+It supports the following commands: GET, DELETE.
+
+GET
+~~~
+
+::
+
+  Send information about an instance.
+
+
+
+DELETE
+~~~~~~
+
+::
+
+  Delete an instance.
+
+
+
+/2/instances/[instance_name]/reboot
++++++++++++++++++++++++++++++++++++
+
+::
+
+  /2/instances/[instance_name]/reboot resource.
+
+  Implements an instance reboot.
+
+It supports the following commands: POST.
+
+POST
+~~~~
+
+::
+
+  Reboot an instance.
+
+  The URI takes type=[hard|soft|full] and
+  ignore_secondaries=[False|True] parameters.
+
+/2/instances/[instance_name]/shutdown
++++++++++++++++++++++++++++++++++++++
+
+::
+
+  /2/instances/[instance_name]/shutdown resource.
+
+  Implements an instance shutdown.
+
+It supports the following commands: PUT.
+
+PUT
+~~~
+
+::
+
+  Shutdown an instance.
+
+
+
+/2/instances/[instance_name]/startup
+++++++++++++++++++++++++++++++++++++
+
+::
+
+  /2/instances/[instance_name]/startup resource.
+
+  Implements an instance startup.
+
+It supports the following commands: PUT.
+
+PUT
+~~~
+
+::
+
+  Startup an instance.
+
+  The URI takes force=[False|True] parameter to start the instance
+  if even if secondary disks are failing.
+
+/2/instances/[instance_name]/tags
++++++++++++++++++++++++++++++++++
+
+::
+
+  /2/instances/[instance_name]/tags resource.
+
+  Manages per-instance tags.
+
+It supports the following commands: GET, PUT, DELETE.
+
+GET
+~~~
+
+::
+
+  Returns a list of tags.
+
+  Example: ["tag1", "tag2", "tag3"]
+
+PUT
+~~~
+
+::
+
+  Add a set of tags.
+
+  The request as a list of strings should be PUT to this URI. And
+  you'll have back a job id.
+
+DELETE
+~~~~~~
+
+::
+
+  Delete a tag.
+
+  In order to delete a set of tags, the DELETE
+  request should be addressed to URI like:
+  /tags?tag=[tag]&tag=[tag]
+
+/2/jobs
++++++++
+
+::
+
+  /2/jobs resource.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Returns a dictionary of jobs.
+
+  Returns: a dictionary with jobs id and uri.
+
+/2/jobs/[job_id]
+++++++++++++++++
+
+::
+
+  /2/jobs/[job_id] resource.
+
+It supports the following commands: GET, DELETE.
+
+GET
+~~~
+
+::
+
+  Returns a job status.
+
+  Returns: a dictionary with job parameters.
+      The result includes:
+          - id: job ID as a number
+          - status: current job status as a string
+          - ops: involved OpCodes as a list of dictionaries for each
+            opcodes in the job
+          - opstatus: OpCodes status as a list
+          - opresult: OpCodes results as a list of lists
+
+DELETE
+~~~~~~
+
+::
+
+  Cancel not-yet-started job.
+
+
+
+/2/nodes
+++++++++
+
+::
+
+  /2/nodes resource.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Returns a list of all nodes.
+
+  Example::
+
+    [
+      {
+        "id": "node1.example.com",
+        "uri": "\/instances\/node1.example.com"
+      },
+      {
+        "id": "node2.example.com",
+        "uri": "\/instances\/node2.example.com"
+      }
+    ]
+
+  If the optional 'bulk' argument is provided and set to 'true'
+  value (i.e '?bulk=1'), the output contains detailed
+  information about nodes as a list.
+
+  Example::
+
+    [
+      {
+        "pinst_cnt": 1,
+        "mfree": 31280,
+        "mtotal": 32763,
+        "name": "www.example.com",
+        "tags": [],
+        "mnode": 512,
+        "dtotal": 5246208,
+        "sinst_cnt": 2,
+        "dfree": 5171712,
+        "offline": false
+      },
+      ...
+    ]
+
+  Returns: a dictionary with 'name' and 'uri' keys for each of them
+
+/2/nodes/[node_name]/tags
++++++++++++++++++++++++++
+
+::
+
+  /2/nodes/[node_name]/tags resource.
+
+  Manages per-node tags.
+
+It supports the following commands: GET, PUT, DELETE.
+
+GET
+~~~
+
+::
+
+  Returns a list of tags.
+
+  Example: ["tag1", "tag2", "tag3"]
+
+PUT
+~~~
+
+::
+
+  Add a set of tags.
+
+  The request as a list of strings should be PUT to this URI. And
+  you'll have back a job id.
+
+DELETE
+~~~~~~
+
+::
+
+  Delete a tag.
+
+  In order to delete a set of tags, the DELETE
+  request should be addressed to URI like:
+  /tags?tag=[tag]&tag=[tag]
+
+/2/os
++++++
+
+::
+
+  /2/os resource.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Return a list of all OSes.
+
+  Can return error 500 in case of a problem.
+
+  Example: ["debian-etch"]
+
+/2/tags
++++++++
+
+::
+
+  /2/instances/tags resource.
+
+  Manages cluster tags.
+
+It supports the following commands: GET, PUT, DELETE.
+
+GET
+~~~
+
+::
+
+  Returns a list of tags.
+
+  Example: ["tag1", "tag2", "tag3"]
+
+PUT
+~~~
+
+::
+
+  Add a set of tags.
+
+  The request as a list of strings should be PUT to this URI. And
+  you'll have back a job id.
+
+DELETE
+~~~~~~
+
+::
+
+  Delete a tag.
+
+  In order to delete a set of tags, the DELETE
+  request should be addressed to URI like:
+  /tags?tag=[tag]&tag=[tag]
+
+/nodes/[node_name]
+++++++++++++++++++
+
+::
+
+  /2/nodes/[node_name] resources.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Send information about a node.
+
+
+
+/version
+++++++++
+
+::
+
+  /version resource.
+
+  This resource should be used to determine the remote API version and
+  to adapt clients accordingly.
+
+It supports the following commands: GET.
+
+GET
+~~~
+
+::
+
+  Returns the remote API version.
-- 
GitLab