Skip to content

Commit 3b77f00

Browse files
committed
Merge pull request #87 from ravippandey/CP-10898
CP-10898: Adding developer guide section
2 parents e977fb1 + fbaf828 commit 3b77f00

File tree

3 files changed

+453
-0
lines changed

3 files changed

+453
-0
lines changed

_data/navbar.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,7 @@
5555
- title: Design Docs
5656
docs:
5757
- design-docs/index.md
58+
- title: Developer Guide
59+
docs:
60+
- devguide/howtos/add-field.md
61+
- devguide/howtos/add-function.md

devguide/howtos/add-field.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
title: Adding a field to the API
3+
layout: default
4+
---
5+
This page describes how to add a field to XenAPI.
6+
7+
Bumping the database schema version
8+
-----------------------------------
9+
Whenever a field is added to or removed from the API, its schema version needs
10+
to be increased. XAPI needs this fundamental procedure in order to be able to
11+
detect that an automatic database upgrade is necessary, or to find out that the
12+
new schema is incompatible with the existing database. If the schema version is
13+
not bumped, XAPI will start failing in unpredictable ways. Note that bumping
14+
the version is not necessary when adding functions, only when adding fields.
15+
16+
The current version number is kept at the top of the file
17+
`ocaml/idl/datamodel.ml` in the variables `schema_major_vsn` and
18+
`schema_minor_vsn`, of which only the latter should be incremented (the major
19+
version only exists for historical reasons). When moving to a new XenServer
20+
release, also update the variable `last_release_schema_minor_vsn` to the schema
21+
version of the last release. To keep track of the schema versions of recent
22+
XenServer releases, the file contains variables for these, such as
23+
`miami_release_schema_minor_vsn`. After starting a new version of Xapi on an
24+
existing server, the database is automatically upgraded if the schema version
25+
of the existing database matches the value of `last_release_schema_*_vsn` in the
26+
new Xapi.
27+
28+
As an example, the patch below shows how the schema version was bumped when the
29+
new API fields used for ActiveDirectory integration were added:
30+
31+
--- a/ocaml/idl/datamodel.ml Tue Nov 11 16:17:48 2008 +0000
32+
+++ b/ocaml/idl/datamodel.ml Tue Nov 11 15:53:29 2008 +0000
33+
@@ -15,17 +15,20 @@ open Datamodel_types
34+
open Datamodel_types
35+
36+
(* IMPORTANT: Please bump schema vsn if you change/add/remove a _field_.
37+
You do not have to dump vsn if you change/add/remove a message *)
38+
39+
let schema_major_vsn = 5
40+
-let schema_minor_vsn = 55
41+
+let schema_minor_vsn = 56
42+
43+
(* Historical schema versions just in case this is useful later *)
44+
let rio_schema_major_vsn = 5
45+
let rio_schema_minor_vsn = 19
46+
47+
+let miami_release_schema_major_vsn = 5
48+
+let miami_release_schema_minor_vsn = 35
49+
+
50+
(* the schema vsn of the last release: used to determine whether we can
51+
upgrade or not.. *)
52+
let last_release_schema_major_vsn = 5
53+
-let last_release_schema_minor_vsn = 35
54+
+let last_release_schema_minor_vsn = 55
55+
56+
Adding the new field to some existing class
57+
-------------------------------------------
58+
## ocaml/idl/datamodel.ml
59+
Add new "field" line the class in idl/datamodel.ml. The new field might require
60+
a suitable default value. This default value is used in case the user does not
61+
provide a value for the field.
62+
63+
A field has a number of parameters:
64+
65+
- The lifecycle parameter, which shows how the field has evolved over time.
66+
- The qualifier parameter, which controls access to the field. The following
67+
values are possible:
68+
69+
| Values | Meaning |
70+
| --------- | --------------------------------------------- |
71+
| StaticRO | Field is set statically at install-time. |
72+
| DynamicRO | Field is computed dynamically from the guest. |
73+
| RW | Field is read/write. |
74+
75+
- The ty parameter for the type of the field.
76+
- The default_value parameter.
77+
- The name of the field.
78+
- A documentation string.
79+
80+
Example of a field in the pool class:
81+
82+
field ~lifecycle:[Published, rel_orlando, "Controls whether HA is enabled"]
83+
~qualifier:DynamicRO ~ty:Bool
84+
~default_value:(Some (VBool false)) "ha_enabled" "true if HA is enabled on the pool, false otherwise";
85+
86+
See datamodel_types.ml for information about other parameters.
87+
88+
Adding a field would change the constructors for the class – functions
89+
Db.*.create – and therefore, any references to these in the code need to be
90+
updated. In the example, the argument ~ha_enabled:false should be added to any
91+
call to Db.Pool.create.
92+
93+
## ocaml/client_records/records.ml
94+
If you want this field to show up in the CLI (which you probably do), you will
95+
also need to modify the Records module, in the file
96+
`ocaml/client_records/records.ml`. Find the record function for the class which
97+
you have modified, add a new entry to the fields list using make_field, which
98+
has the type:
99+
100+
Type: ?add_to_set:(string -> unit) ->
101+
?remove_from_set:(string -> unit) ->
102+
?add_to_map:(string -> string -> unit) ->
103+
?remove_from_map:(string -> unit) ->
104+
?set_in_map:(string -> string -> unit) ->
105+
?set:(string -> unit) ->
106+
?get_set:(unit -> string list) ->
107+
?get_map:(unit -> (string * string) list) ->
108+
?expensive:bool ->
109+
?hidden:bool ->
110+
?deprecated:bool ->
111+
?case_insensitive:bool ->
112+
name:string ->
113+
get:(unit -> string) ->
114+
unit -> field
115+
116+
The only required parameters are name and get (and unit, of course ).
117+
If your field is a map or set, then you will need to pass in get_{map,set}, and
118+
optionally set_{map,set}, if it is a RW field. The hidden parameter is useful
119+
if you don't want this field to show up in a *_params_list call. As an example,
120+
here is a field that we've just added to the SM class:
121+
122+
make_field ~name:"versioned-capabilities"
123+
~get:(fun () -> Record_util.s2sm_to_string "; " (x ()).API.sM_versioned_capabilities)
124+
~get_map:(fun () -> (x ()).API.sM_versioned_capabilities)
125+
~hidden:true ();
126+
127+
Testing
128+
-------
129+
The new fields can be tested by copying the newly compiled xapi binary to a
130+
test box. After the new xapi service is started, the file
131+
*/var/log/xensource.log* in the test box should contain a few lines reporting the
132+
successful upgrade of the metadata schema in the test box:
133+
134+
[...|xapi] Db has schema major_vsn=5, minor_vsn=57 (current is 5 58) (last is 5 57)
135+
[...|xapi] Database schema version is that of last release: attempting upgrade
136+
[...|sql] attempting to restore database from /var/xapi/state.db
137+
[...|sql] finished parsing xml
138+
[...|sql] writing db as xml to file '/var/xapi/state.db'.
139+
[...|xapi] Database upgrade complete, restarting to use new db
140+
141+
Making this field accessible as a CLI attribute
142+
-----------------------------------------------
143+
XenAPI functions to get and set the value of the new field are generated
144+
automatically. It requires some extra work, however, to enable such operations
145+
in the CLI.
146+
147+
The CLI has commands such as host-param-list and host-param-get. To make a new
148+
field accessible by these command, the file client_records/records.ml needs to
149+
be edited. For the pool.ha-enabled field, the pool_record function in this file
150+
contains the following (note the convention to replace underscores by hyphens
151+
in the CLI):
152+
153+
let pool_record rpc session_id pool =
154+
...
155+
[
156+
...
157+
make_field ~name:"ha-enabled" ~get:(fun () -> string_of_bool (x ()).API.pool_ha_enabled) ();
158+
...
159+
]}
160+
161+
See records.ml for examples of handling field types other than Bool.

0 commit comments

Comments
 (0)