Merge lp:~rvb/maas/add-power-params-doc into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 2289
Proposed branch: lp:~rvb/maas/add-power-params-doc
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 183 lines (+86/-1)
4 files modified
src/maasserver/api.py (+9/-0)
src/maasserver/apidoc.py (+46/-0)
src/maasserver/tests/test_apidoc.py (+30/-0)
src/provisioningserver/power_schema.py (+1/-1)
To merge this branch: bzr merge lp:~rvb/maas/add-power-params-doc
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+216894@code.launchpad.net

Commit message

Add documentation about the power types and the related power parameters.

Description of the change

Here is how it looks like: http://people.canonical.com/~rvb/power_types_doc.png

The tests are minimal but testing the exact formatting would be a bit pointless I think. A test that the whole API doc can be translated from rST into HTML already exists.

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

I don't think we should be documenting this like this, other than some
examples perhaps.

This is because clusters can and will have varying power types available
- it's not a heterogeneous environment, especially during staged cluster
upgrades.

What I think we should do is implement an API function that returns
available power types and each one's parameters based on the cluster and
encourage API users to derive from that when editing/adding nodes.

Revision history for this message
Raphaël Badin (rvb) wrote :

> I don't think we should be documenting this like this, other than some
> examples perhaps.
>
> This is because clusters can and will have varying power types available
> - it's not a heterogeneous environment, especially during staged cluster
> upgrades.
>
> What I think we should do is implement an API function that returns
> available power types and each one's parameters based on the cluster and
> encourage API users to derive from that when editing/adding nodes.

An API call is probably needed indeed since some of the power types are registered dynamically.

But I still think it's worth documentation all the built-in power types. I'll change the introduction sentence to make it clear that those are the *built-in* power types and that others can be dynamically registered using clusters.

What do you say?

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On 24/04/14 16:53, Raphaël Badin wrote:
>> I don't think we should be documenting this like this, other than some
>> examples perhaps.
>>
>> This is because clusters can and will have varying power types available
>> - it's not a heterogeneous environment, especially during staged cluster
>> upgrades.
>>
>> What I think we should do is implement an API function that returns
>> available power types and each one's parameters based on the cluster and
>> encourage API users to derive from that when editing/adding nodes.
>
> An API call is probably needed indeed since some of the power types are registered dynamically.
>
> But I still think it's worth documentation all the built-in power types. I'll change the introduction sentence to make it clear that those are the *built-in* power types and that others can be dynamically registered using clusters.
>
> What do you say?
>

Well all power types are built in, that's how MAAS rolls. I still
prefer a simple example of the more common types and an example of how
to use this new API call in conjunction with adding a node.

But this is just my opinion, see what others say too.

Revision history for this message
Raphaël Badin (rvb) wrote :

> Well all power types are built in, that's how MAAS rolls.

Not really, if you're using a custom-made cluster controller that registers an extra power type, that power type will be available in MAAS and it's not "built-in".

> I still
> prefer a simple example of the more common types and an example of how
> to use this new API call in conjunction with adding a node.

I really think documenting all the power types and power parameters we know about is better.

Revision history for this message
Raphaël Badin (rvb) wrote :

> But I still think it's worth documentation all the built-in power types. I'll
> change the introduction sentence to make it clear that those are the *built-
> in* power types and that others can be dynamically registered using clusters.

Done:

78 + line(
79 + "This is the list of the built-in power types and their "
80 + "associated power parameters. Note that other power types "
81 + "can be registered, at runtime, by cluster controllers with "
82 + "extra capabilities.")

Revision history for this message
Gavin Panella (allenap) wrote :

I think having some static docs on maas.ubuntu.com has some value.

However, I also think we ought to make all the docs available via the MAAS UI too, including dynamically (re)generating the code-derived docs. This would complement the API call that Julian suggests.

Once we have the docs-in-UI, the docs on maas.ubuntu.com should then have a section explaining to use the docs on your local MAAS installation for the most accurate information.

Right now these docs appear to be LISP by the count of braces.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api.py'
2--- src/maasserver/api.py 2014-04-22 09:08:02 +0000
3+++ src/maasserver/api.py 2014-04-24 08:03:14 +0000
4@@ -149,6 +149,7 @@
5 describe_resource,
6 find_api_resources,
7 generate_api_docs,
8+ generate_power_types_doc,
9 )
10 from maasserver.clusterrpc.power_parameters import (
11 get_all_power_types_from_clusters,
12@@ -334,6 +335,8 @@
13 :param power_type: The new power type for this node. If you use the
14 default value, power_parameters will be set to the empty string.
15 Available to admin users.
16+ See the `Power types`_ section for a list of the available power
17+ types.
18 :type power_type: unicode
19 :param power_parameters_{param1}: The new value for the 'param1'
20 power parameter. Note that this is dynamic as the available
21@@ -342,6 +345,8 @@
22 parameter is 'power_address' so one would want to pass 'myaddress'
23 as the value of the 'power_parameters_power_address' parameter.
24 Available to admin users.
25+ See the `Power types`_ section for a list of the available power
26+ parameters for each power type.
27 :type power_parameters_{param1}: unicode
28 :param power_parameters_skip_check: Whether or not the new power
29 parameters for this node should be checked against the expected
30@@ -2293,6 +2298,10 @@
31 line(" ", docline, sep="")
32 line()
33
34+ line()
35+ line()
36+ line(generate_power_types_doc())
37+
38 return output.getvalue()
39
40
41
42=== modified file 'src/maasserver/apidoc.py'
43--- src/maasserver/apidoc.py 2014-03-27 15:12:48 +0000
44+++ src/maasserver/apidoc.py 2014-04-24 08:03:14 +0000
45@@ -19,6 +19,8 @@
46 "generate_api_docs",
47 ]
48
49+from cStringIO import StringIO
50+from functools import partial
51 from inspect import getdoc
52 from itertools import izip_longest
53
54@@ -32,6 +34,7 @@
55 from piston.doc import generate_doc
56 from piston.handler import BaseHandler
57 from piston.resource import Resource
58+from provisioningserver.power_schema import JSON_POWER_TYPE_PARAMETERS
59
60
61 def accumulate_api_resources(resolver, accumulator):
62@@ -67,6 +70,49 @@
63 return accumulator
64
65
66+def generate_power_types_doc():
67+ """Generate ReST documentation for the supported power types.
68+
69+ The documentation is derived from the `JSON_POWER_TYPE_PARAMETERS`
70+ object.
71+ """
72+ output = StringIO()
73+ line = partial(print, file=output)
74+
75+ line('Power types')
76+ line('-----------')
77+ line()
78+ line("This is the list of the supported power types and their "
79+ "associated power parameters. Note that the list of usable "
80+ "power types for a particular cluster might be a subset of this "
81+ "list if the cluster in question is from an older version of "
82+ "MAAS.")
83+ line()
84+ for item in JSON_POWER_TYPE_PARAMETERS:
85+ title = "%s (%s)" % (item['name'], item['description'])
86+ line(title)
87+ line('=' * len(title))
88+ line('')
89+ line("Power parameters:")
90+ line('')
91+ for field in item['fields']:
92+ field_description = []
93+ field_description.append(
94+ "* %s (%s)." % (field['name'], field['label']))
95+ choices = field.get('choices', [])
96+ if len(choices) > 0:
97+ field_description.append(
98+ " Choices: %s" % ', '.join(
99+ "'%s' (%s)" % (choice[0], choice[1])
100+ for choice in choices))
101+ default = field.get('default', '')
102+ if default is not '':
103+ field_description.append(" Default: '%s'." % default)
104+ line(''.join(field_description))
105+ line('')
106+ return output.getvalue()
107+
108+
109 def generate_api_docs(resources):
110 """Generate ReST documentation objects for the ReST API.
111
112
113=== modified file 'src/maasserver/tests/test_apidoc.py'
114--- src/maasserver/tests/test_apidoc.py 2014-03-27 15:16:18 +0000
115+++ src/maasserver/tests/test_apidoc.py 2014-04-24 08:03:14 +0000
116@@ -25,6 +25,7 @@
117 )
118 from django.core.exceptions import ImproperlyConfigured
119 from django.core.urlresolvers import reverse
120+from maasserver import apidoc
121 from maasserver.api_support import (
122 operation,
123 OperationsHandler,
124@@ -35,6 +36,7 @@
125 describe_resource,
126 find_api_resources,
127 generate_api_docs,
128+ generate_power_types_doc,
129 )
130 from maasserver.testing.factory import factory
131 from maasserver.testing.testcase import MAASServerTestCase
132@@ -42,6 +44,8 @@
133 from piston.doc import HandlerDocumentation
134 from piston.handler import BaseHandler
135 from piston.resource import Resource
136+from provisioningserver.power_schema import make_json_field
137+from testtools.matchers import ContainsAll
138
139
140 class TestFindingResources(MAASServerTestCase):
141@@ -306,3 +310,29 @@
142 "name": "ExampleHandler",
143 }
144 self.assertEqual(expected, describe_resource(resource))
145+
146+
147+class TestGeneratePowerTypesDoc(MAASServerTestCase):
148+ """Tests for `generate_power_types_doc`."""
149+
150+ def test__generate_power_types_doc_generates_doc(self):
151+ doc = generate_power_types_doc()
152+ self.assertThat(doc, ContainsAll(["Power types", "IPMI"]))
153+
154+ def test__generate_power_types_doc_generates_describes_power_type(self):
155+ name = factory.make_name('name')
156+ description = factory.make_name('description')
157+ param_name = factory.make_name('param_name')
158+ param_description = factory.make_name('param_description')
159+ json_fields = [{
160+ 'name': name,
161+ 'description': description,
162+ 'fields': [
163+ make_json_field(param_name, param_description),
164+ ],
165+ }]
166+ self.patch(apidoc, "JSON_POWER_TYPE_PARAMETERS", json_fields)
167+ doc = generate_power_types_doc()
168+ self.assertThat(
169+ doc,
170+ ContainsAll([name, description, param_name, param_description]))
171
172=== modified file 'src/provisioningserver/power_schema.py'
173--- src/provisioningserver/power_schema.py 2014-04-22 08:27:47 +0000
174+++ src/provisioningserver/power_schema.py 2014-04-24 08:03:14 +0000
175@@ -164,7 +164,7 @@
176 },
177 {
178 'name': 'virsh',
179- 'description': 'virsh (virtual systems)',
180+ 'description': 'Virsh (virtual systems)',
181 'fields': [
182 make_json_field('power_address', "Power address"),
183 make_json_field('power_id', "Power ID"),