Archived/XAPI Adding Field
Adding Field to XAPI API
This page describes how to add a field to XenAPI
Bumping the database schema version
Whenever a field is added to or removed from the API, its schema version needs to be increased. XAPI needs this fundamental procedure in order to be able to detect that an automatic database upgrade is necessary, or to find out that the new schema is incompatible with the existing database. If the schema version is not bumped, XAPI will start failing in unpredictable ways. Note that bumping the version is not necessary when adding functions, only when adding fields.
The current version number is kept at the top of the file ocaml/idl/datamodel.ml in the variables schema_major_vsn and schema_minor_version, of which only the latter should be incremented (the major version only exists for historical reasons). When moving to a new XCP release, also update the variable last_release_schema_minor_vsn to the schema version of the last release. To keep track of the schema versions of recent XCP releases, the file contains variables for these, such as miami_release_schema_minor_vsn. After starting a new version of Xapi on an existing server, the database is automatically upgraded if the schema version of the existing database matches the value of last_release_schema_*_vsn in the new Xapi.
As an example, the patch below shows how the schema version was bumped when the new API fields used for [[[ActiveDirectory]]] integration were added:
--- a/ocaml/idl/datamodel.ml Tue Nov 11 16:17:48 2008 +0000 +++ b/ocaml/idl/datamodel.ml Tue Nov 11 15:53:29 2008 +0000 @@ -15,17 +15,20 @@ open Datamodel_types open Datamodel_types (* IMPORTANT: Please bump schema vsn if you change/add/remove a _field_. You do not have to dump vsn if you change/add/remove a message *) let schema_major_vsn = 5 -let schema_minor_vsn = 55 +let schema_minor_vsn = 56 (* Historical schema versions just in case this is useful later *) let rio_schema_major_vsn = 5 let rio_schema_minor_vsn = 19 +let miami_release_schema_major_vsn = 5 +let miami_release_schema_minor_vsn = 35 + (* the schema vsn of the last release: used to determine whether we can upgrade or not.. *) let last_release_schema_major_vsn = 5 -let last_release_schema_minor_vsn = 35 +let last_release_schema_minor_vsn = 55
Adding the new field to some existing class
- add new "field" line the class at idl/datamodel.ml. The new field might require a suitable default value. This default value is used in case the user does not provide a value for the field.
- see datamodel_types.ml for more information on parameters. For instance, for the qualifier parameter, the following values are possible:
| StaticRO (** field is set statically at install-time *) | DynamicRO (** field is computed dynamically from the guest *) | RW (** field is read / write *)
Example of a field in the pool class:
field ~in_oss_since:None ~in_product_since:rel_orlando ~qualifier:DynamicRO ~ty:Bool ~default_value:(Some (VBool false)) "ha_enabled" "true if HA is enabled on the pool, false otherwise";
Adding a field would change the constructors for the class â€“ functions Db.*.create â€“ and therefore, any references to these in the code need to be updated. In the example, the argument ~ha_enabled:false should be added to any call to Db.Pool.create.
The new fields can be tested by copying the newly compiled xapi binary to a test box. After the new xapi service is started, the file /var/log/xensource.log in the test box should contain a few lines reporting the successful upgrade of the metadata schema in the test box:
[...|xapi] Db has schema major_vsn=5, minor_vsn=57 (current is 5 58) (last is 5 57) [...|xapi] Database schema version is that of last release: attempting upgrade [...|sql] attempting to restore database from /var/xapi/state.db [...|sql] finished parsing xml [...|sql] writing db as xml to file '/var/xapi/state.db'. [...|xapi] Database upgrade complete, restarting to use new db
Update the message forwarding code
Don't forget! To be continued...
Making this field accessible as a CLI attribute
[XenAPI] functions to get and set the value of the new field are generated automatically. It requires some extra work, however, to enable such operations in the CLI.
The CLI has commands such as host-param-list and host-param-get. To make a new field accessible by these command, the file client_records/records.ml needs to be edited. For the pool.ha-enabled field, the pool_record function in this file needs contains the following (note the convention to replace underscores by hyphens in the CLI):
let pool_record rpc session_id pool = ... [ ... make_field ~name:"ha-enabled" ~get:(fun () -> string_of_bool (x ()).API.pool_ha_enabled) (); ... ]}
See records.ml for examples of handling field types other than Bool.