From 017027bac62eb14824607c1e99f9a2f2582a9258 Mon Sep 17 00:00:00 2001 From: Konstantina Chremmou Date: Fri, 29 Nov 2024 17:11:45 +0000 Subject: [PATCH 1/2] Added manually messages that are not autogenerated. Signed-off-by: Konstantina Chremmou --- ocaml/sdk-gen/csharp/templates/Message2.mustache | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ocaml/sdk-gen/csharp/templates/Message2.mustache b/ocaml/sdk-gen/csharp/templates/Message2.mustache index 3dfe4f4503..b6aa46d5f3 100644 --- a/ocaml/sdk-gen/csharp/templates/Message2.mustache +++ b/ocaml/sdk-gen/csharp/templates/Message2.mustache @@ -43,6 +43,9 @@ namespace XenAPI LEAF_COALESCE_COMPLETED, LEAF_COALESCE_FAILED, POST_ATTACH_SCAN_FAILED, + WLB_HOST_POWER_OFF, + WLB_HOST_POWER_ON, + WLB_SERVER_TIME_DISCREPANCY, WLB_VM_RELOCATION, {{#message_types}} {{{message_type}}}, @@ -74,6 +77,12 @@ namespace XenAPI return MessageType.LEAF_COALESCE_FAILED; case "POST_ATTACH_SCAN_FAILED": return MessageType.POST_ATTACH_SCAN_FAILED; + case "WLB_HOST_POWER_OFF": + return MessageType.WLB_HOST_POWER_OFF; + case "WLB_HOST_POWER_ON": + return MessageType.WLB_HOST_POWER_ON; + case "WLB_SERVER_TIME_DISCREPANCY": + return MessageType.WLB_SERVER_TIME_DISCREPANCY; case "WLB_VM_RELOCATION": return MessageType.WLB_VM_RELOCATION; {{#message_types}} From 039f61fdf3965fa8123328273fd7d9dd40326fc5 Mon Sep 17 00:00:00 2001 From: Konstantina Chremmou Date: Fri, 29 Nov 2024 17:12:07 +0000 Subject: [PATCH 2/2] Docs tidy up: - Moved notes on error structure to the Wire protocol. - Moved duplicate file basics.md and wire-protocol.md from ocaml/doc to doc/content/xen-api. - Moved notes on VM boot parameters to doc/content/xen-api/topics/vm-lifecycle.md and removed ocaml/doc/vm-lifecycle.md. Signed-off-by: Konstantina Chremmou --- doc/content/xen-api/basics.md | 148 ++-- doc/content/xen-api/topics/vm-lifecycle.md | 48 +- doc/content/xen-api/wire-protocol.md | 942 ++++++++++++++++----- ocaml/doc/basics.md | 119 --- ocaml/doc/dune | 10 + ocaml/doc/vm-lifecycle.md | 50 -- ocaml/doc/wire-protocol.md | 664 --------------- ocaml/idl/templates/api_errors.mustache | 132 +-- ocaml/idl/templates/toc.mustache | 2 +- 9 files changed, 856 insertions(+), 1259 deletions(-) delete mode 100644 ocaml/doc/basics.md delete mode 100644 ocaml/doc/vm-lifecycle.md delete mode 100644 ocaml/doc/wire-protocol.md diff --git a/doc/content/xen-api/basics.md b/doc/content/xen-api/basics.md index ce4394c6af..5288090aa3 100644 --- a/doc/content/xen-api/basics.md +++ b/doc/content/xen-api/basics.md @@ -3,14 +3,16 @@ title = "XenAPI Basics" weight = 10 +++ -This document contains a description of the Xen Management API – an interface for +This document contains a description of the Xen Management API - an interface for remotely configuring and controlling virtualised guests running on a Xen-enabled host. -The XenAPI is presented here as a set of Remote Procedure Calls, with a wire -format based upon [XML-RPC](http://xmlrpc.scripting.com). -No specific language bindings are prescribed, -although examples will be given in the python programming language. +The API is presented here as a set of Remote Procedure Calls (RPCs). +There are two supported wire formats, one based upon +[XML-RPC](http://xmlrpc.scripting.com/spec.html) +and one based upon [JSON-RPC](http://www.jsonrpc.org) (v1.0 and v2.0 are both +recognized). No specific language bindings are prescribed, although examples +are given in the Python programming language. Although we adopt some terminology from object-oriented programming, future client language bindings may or may not be object oriented. @@ -21,98 +23,102 @@ specific values. Objects are persistent and exist on the server-side. Clients may obtain opaque references to these server-side objects and then access their fields via get/set RPCs. -For each class we specify a list of fields along with their _types_ and _qualifiers_. A -qualifier is one of: +For each class we specify a list of fields along with their _types_ and +_qualifiers_. A qualifier is one of: -- _RO/runtime_: the field is Read -Only. Furthermore, its value is automatically computed at runtime. -For example: current CPU load and disk IO throughput. -- _RO/constructor_: the field must be manually set -when a new object is created, but is then Read Only for -the duration of the object's life. -For example, the maximum memory addressable by a guest is set -before the guest boots. -- _RW_: the field is Read/Write. For example, the name of a VM. +- _RO/runtime_: the field is Read Only. Furthermore, its value is + automatically computed at runtime. For example, current CPU load and disk IO + throughput. -Types ------ +- _RO/constructor_: the field must be manually set when a new object is + created, but is then Read Only for the duration of the object's life. + For example, the maximum memory addressable by a guest is set + before the guest boots. + +- _RW_: the field is Read/Write. For example, the name of a VM. + +## Types The following types are used to specify methods and fields in the API Reference: -- `string`: Text strings. -- `int`: 64-bit integers. -- `float`: IEEE double-precision floating-point numbers. -- `bool`: Boolean. -- `datetime`: Date and timestamp. -- `c ref`: Reference to an object of class `c`. -- `t set`: Arbitrary-length set of values of type `t`. -- `(k → v) map`: Mapping from values of type `k` to values of type `v`. -- `e enum`: Enumeration type with name `e`. Enums are defined in the API Reference together with classes that use them. - -Note that there are a number of cases where `ref`s are _doubly -linked_ – e.g. a VM has a field called `VIFs` of type -`VIF ref set`; this field lists -the network interfaces attached to a particular VM. Similarly, the VIF -class has a field called `VM` of type `VM ref` which references the VM to which the interface is connected. +- `string`: Text strings. +- `int`: 64-bit integers. +- `float`: IEEE double-precision floating-point numbers. +- `bool`: Boolean. +- `datetime`: Date and timestamp. +- `c ref`: Reference to an object of class `c`. +- `t set`: Arbitrary-length set of values of type `t`. +- `(k -> v) map`: Mapping from values of type `k` to values of type `v`. +- `e enum`: Enumeration type with name `e`. Enums are defined in the API + reference together with classes that use them. + +Note that there are a number of cases where `ref`s are _doubly linked_. +For example, a `VM` has a field called `VIFs` of type `VIF ref set`; +this field lists the network interfaces attached to a particular VM. +Similarly, the `VIF` class has a field called `VM` of type `VM ref` +which references the VM to which the interface is connected. These two fields are _bound together_, in the sense that creating a new VIF causes the `VIFs` field of the corresponding VM object to be updated automatically. -The API reference explicitly lists the fields that are +The API reference lists explicitly the fields that are bound together in this way. It also contains a diagram that shows relationships between classes. In this diagram an edge signifies the -existance of a pair of fields that are bound together, using standard +existence of a pair of fields that are bound together, using standard crows-foot notation to signify the type of relationship (e.g. one-many, many-many). -RPCs associated with fields ---------------------------- +## RPCs associated with fields + +Each field, `f`, has an RPC accessor associated with it that returns `f`'s value: + +- `get_f (r)`: takes a `ref`, `r` that refers to an object and returns the value + of `f`. + +Each field, `f`, with qualifier _RW_ and whose outermost type is `set` has the +following additional RPCs associated with it: -Each field, `f`, has an RPC accessor associated with it -that returns `f`'s value: +- `add_f(r, v)`: adds a new element `v` to the set. + Note that sets cannot contain duplicate values, hence this operation has + no action in the case that `v` is already in the set. -- `get_f (r)`: Takes a `ref`, `r`, that refers to an object and returns the value of `f`. +- `remove_f(r, v)`: removes element `v` from the set. -Each field, `f`, with attribute `RW` and whose outermost type is `set` has the following -additional RPCs associated with it: +Each field, `f`, with qualifier _RW_ and whose outermost type is `map` has the +following additional RPCs associated with it: -- `add_f (r, v)`: Adds a new element `v` to the set. Since sets cannot contain duplicate values this operation has no action in the case -that `v` was already in the set. +- `add_to_f(r, k, v)`: adds new pair `k -> v` to the mapping stored in `f` in + object `r`. Attempting to add a new pair for duplicate key, `k`, fails with a + `MAP_DUPLICATE_KEY` error. -- `remove_f (r, v)`: Removes element `v` from the set. +- `remove_from_f(r, k)`: removes the pair with key `k` + from the mapping stored in `f` in object `r`. -Each field, `f`, with attribute RW and whose outermost type is `map` has the following -additional RPCs associated with it: +Each field whose outermost type is neither `set` nor `map`, but whose +qualifier is _RW_ has an RPC accessor associated with it that sets its value: -- `add_to_f (r, k, v)`: Adds new pair `(k → v)` to the mapping stored in `f` in object `r`. Attempting to add a new pair for duplicate -key, `k`, fails with an `MAP_DUPLICATE_KEY` error. -- `remove_from_f (r, k)`: Removes the pair with key `k` from the mapping stored in `f` in object `r`. +- `set_f(r, v)`: sets the field `f` on object `r` to value `v`. -Each field whose outermost type is neither `set` nor `map`, -but whose attribute is RW has an RPC accessor associated with it -that sets its value: +## RPCs associated with classes -- `set_f (r, v)`: Sets field `f` on object `r` to value `v`. +- Most classes have a _constructor_ RPC named `create` that + takes as parameters all fields marked _RW_ and _RO/constructor_. The result + of this RPC is that a new _persistent_ object is created on the server-side + with the specified field values. -RPCs associated with classes ----------------------------- +- Each class has a `get_by_uuid(uuid)` RPC that returns the object + of that class that has the specified `uuid`. -- Most classes have a _constructor_ RPC named `create` that -takes as parameters all fields marked RW and -RO/constructor. The result of this RPC is that a new _persistent_ object is -created on the server-side with the specified field values. -- Each class has a `get_by_uuid (uuid)` RPC that returns the object -of that class that has the specified UUID. -- Each class that has a `name_label` field has a `get_by_name_label (name_label)` RPC that returns a set of objects of that -class that have the specified `name_label`. -- Most classes have a `destroy (r)` RPC that explicitly deletes the persistent object specified by `r` from the system. This is a -non-cascading delete – if the object being removed is referenced by another -object then the `destroy` call will fail. +- Each class that has a `name_label` field has a + `get_by_name_label(name_label)` RPC that returns a set of objects of that + class that have the specified `name_label`. -Additional RPCs ---------------- +- Most classes have a `destroy(r)` RPC that explicitly deletes + the persistent object specified by `r` from the system. This is a + non-cascading delete - if the object being removed is referenced by another + object then the `destroy` call will fail. -As well as the RPCs enumerated above, most classes have additional RPCs -associated with them. For example, the VM class has RPCs for cloning, +Apart from the RPCs enumerated above, most classes have additional RPCs +associated with them. For example, the `VM` class has RPCs for cloning, suspending, starting etc. Such additional RPCs are described explicitly in the API reference. diff --git a/doc/content/xen-api/topics/vm-lifecycle.md b/doc/content/xen-api/topics/vm-lifecycle.md index 4531acd07f..7390dc61e8 100644 --- a/doc/content/xen-api/topics/vm-lifecycle.md +++ b/doc/content/xen-api/topics/vm-lifecycle.md @@ -2,6 +2,9 @@ title = "VM Lifecycle" +++ +The following figure shows the states that a VM can be in and the +API calls that can be used to move the VM between these states. + ```mermaid graph halted-- start(paused) -->paused @@ -17,7 +20,48 @@ graph halted-- destroy -->destroyed ``` -The figure above shows the states that a VM can be in and the -API calls that can be used to move the VM between these states. +## VM boot parameters + +The `VM` class contains a number of fields that control the way in which the VM +is booted. With reference to the fields defined in the VM class (see later in +this document), this section outlines the boot options available and the +mechanisms provided for controlling them. + +VM booting is controlled by setting one of the two mutually exclusive groups: +"PV" and "HVM". If `HVM.boot_policy` is an empty string, then paravirtual +domain building and booting will be used; otherwise the VM will be loaded as a +HVM domain, and booted using an emulated BIOS. + +When paravirtual booting is in use, the `PV_bootloader` field indicates the +bootloader to use. It may be "pygrub", in which case the platform's default +installation of pygrub will be used, or a full path within the control domain to +some other bootloader. The other fields, `PV_kernel`, `PV_ramdisk`, `PV_args`, +and `PV_bootloader_args` will be passed to the bootloader unmodified, and +interpretation of those fields is then specific to the bootloader itself, +including the possibility that the bootloader will ignore some or all of +those given values. Finally the paths of all bootable disks are added to the +bootloader commandline (a disk is bootable if its VBD has the bootable flag set). +There may be zero, one, or many bootable disks; the bootloader decides which +disk (if any) to boot from. + +If the bootloader is pygrub, then the menu.lst is parsed, if present in the +guest's filesystem, otherwise the specified kernel and ramdisk are used, or an +autodetected kernel is used if nothing is specified and autodetection is +possible. `PV_args` is appended to the kernel command line, no matter which +mechanism is used for finding the kernel. + +If `PV_bootloader` is empty but `PV_kernel` is specified, then the kernel and +ramdisk values will be treated as paths within the control domain. If both +`PV_bootloader` and `PV_kernel` are empty, then the behaviour is as if +`PV_bootloader` were specified as "pygrub". + +When using HVM booting, `HVM_boot_policy` and `HVM_boot_params` specify the boot +handling. Only one policy is currently defined, "BIOS order". In this case, +`HVM_boot_params` should contain one key-value pair "order" = "N" where N is the +string that will be passed to QEMU. +Optionally `HVM_boot_params` can contain another key-value pair "firmware" +with values "bios" or "uefi" (default is "bios" if absent). +By default Secure Boot is not enabled, it can be enabled when "uefi" is enabled +by setting `VM.platform["secureboot"]` to true. {{% children %}} diff --git a/doc/content/xen-api/wire-protocol.md b/doc/content/xen-api/wire-protocol.md index 689819a88a..8a4fe9f501 100644 --- a/doc/content/xen-api/wire-protocol.md +++ b/doc/content/xen-api/wire-protocol.md @@ -3,136 +3,106 @@ title = "Wire Protocol" weight = 20 +++ -API calls are sent over a network to a Xen-enabled host using the -[XML-RPC](http://xmlrpc.scripting.com/spec.html) protocol. On this page, we describe how the higher-level types -used in our API Reference are mapped to primitive XML-RPC types. +API calls are sent over a network to a Xen-enabled host using an RPC protocol. +Here we describe how the higher-level types used in our API Reference are mapped +to primitive RPC types, covering the two supported wire formats +[XML-RPC](http://xmlrpc.scripting.com/spec.html) and [JSON-RPC](http://www.jsonrpc.org). -We specify the signatures of API functions in the following style: - - (VM ref set) VM.get_all () - -This specifies that the function with name `VM.get_all` -takes no parameters and returns a `set` of `VM ref`s. These -types are mapped onto XML-RPC types in a straight-forward manner: - -- `float`s, `bool`s, `datetime`s and `string`s map directly to the XML-RPC - ``, ``, ``, and `` elements. - -- all `ref` types are opaque references, encoded as the - XML-RPC’s `` type. Users of the API should not make - assumptions about the concrete form of these strings and should not - expect them to remain valid after the client’s session with the - server has terminated. - -- fields named `uuid` of type `string` are - mapped to the XML-RPC `` type. The string itself is - the OSF DCE UUID presentation format (as output by - `uuidgen`, etc). - -- `int`s are all assumed to be 64-bit in our API and are encoded as a - string of decimal digits (rather than using XML-RPC’s built-in - 32-bit `` type). - -- values of `enum` types are encoded as strings. For example, a value of - `destroy` of type `enum on_normal_exit`, would be - conveyed as: - - destroy - -- for all our types, `t`, our type `t set` - simply maps to XML-RPC’s `` type, so for example a - value of type `string set` would be transmitted like - this: - - - - - CX8 - PSE36 - FPU - - - +## XML-RPC Protocol -- for types `k` and `v`, our type `(k → v) map` maps onto an XML-RPC ``, with the key as the name of - the struct. Note that the `(k → v) map` type is only valid - when `k` is a `string`, `ref`, or `int`, and in each case the keys of the maps are - stringified as above. For example, the `(string → double) map` containing a the mappings `"Mike" → 2.3` and - `"John" → 1.2` would be represented as: - - - - - Mike - 2.3 - - - John - 1.2 - - - - - -- our `void` type is transmitted as an empty string. - -Note on References vs UUIDs ---------------------------- - -References are opaque types — encoded as XML-RPC strings on the wire — -understood only by the particular server which generated them. Servers -are free to choose any concrete representation they find convenient; -clients should not make any assumptions or attempt to parse the string -contents. References are not guaranteed to be permanent identifiers for -objects; clients should not assume that references generated during one -session are valid for any future session. References do not allow -objects to be compared for equality. Two references to the same object -are not guaranteed to be textually identical. - -UUIDs are intended to be permanent names for objects. They are -guaranteed to be in the OSF DCE UUID presentation format (as output by -`uuidgen`. Clients may store UUIDs on disk and use them to -lookup objects in subsequent sessions with the server. Clients may also -test equality on objects by comparing UUID strings. - -The API provides mechanisms for translating between UUIDs and opaque -references. Each class that contains a UUID field provides: - -- A `get_by_uuid` method that takes a UUID, and - returns an opaque reference to the server-side object that has that - UUID; - -- A `get_uuid` function (a regular “field getter” RPC) - that takes an opaque reference and returns the UUID of the - server-side object that is referenced by it. +We specify the signatures of API functions in the following style: -Return Values/Status Codes --------------------------- +```python +(VM ref set) VM.get_all() +``` + +This specifies that the function with name `VM.get_all` takes +no parameters and returns a `set` of `VM ref`. +These types are mapped onto XML-RPC types in a straight-forward manner: + +- the types `float`, `bool`, `datetime`, and `string` map directly to the XML-RPC + ``, ``, ``, and `` elements. + +- all `ref` types are opaque references, encoded as the + XML-RPC's `` type. Users of the API should not make assumptions + about the concrete form of these strings and should not expect them to + remain valid after the client's session with the server has terminated. + +- fields named `uuid` of type `string` are mapped to + the XML-RPC `` type. The string itself is the OSF + DCE UUID presentation format (as output by `uuidgen`). + +- `int` is assumed to be 64-bit in our API and is encoded as a string + of decimal digits (rather than using XML-RPC's built-in 32-bit `` type). + +- values of `enum` types are encoded as strings. For example, the value + `destroy` of `enum on_normal_exit`, would be conveyed as: + +```xml + destroy +``` + +- for all our types, `t`, our type `t set` simply maps to XML-RPC's `` + type, so, for example, a value of type `string set` would be transmitted like + this: + +```xml + + + CX8 + PSE36 + FPU + + +``` + +- for types `k` and `v`, our type `(k -> v) map` maps onto an + XML-RPC ``, with the key as the name of the struct. Note that the + `(k -> v) map` type is only valid when `k` is a `string`, `ref`, or + `int`, and in each case the keys of the maps are stringified as + above. For example, the `(string -> float) map` containing the mappings + _Mike -> 2.3_ and _John -> 1.2_ would be represented as: + +```xml + + + + Mike + 2.3 + + + John + 1.2 + + + +``` + +- our `void` type is transmitted as an empty string. + +### XML-RPC Return Values and Status Codes The return value of an RPC call is an XML-RPC ``. -- The first element of the struct is named `"Status"`; it - contains a string value indicating whether the result of the call - was a `"Success"` or a `"Failure"`. +- The first element of the struct is named `Status`; it contains a string value + indicating whether the result of the call was a `Success` or a `Failure`. -If `"Status"` was set to `"Success"` then the Struct -contains a second element named `"Value"`: +If the `Status` is `Success` then the struct contains a second element named +`Value`: -- The element of the struct named `"Value"` contains the - function’s return value. +- The element of the struct named `Value` contains the function's return value. -In the case where `"Status"` is set to `"Failure"` -then the struct contains a second element named -`"ErrorDescription"`: +If the `Status` is `Failure` then the struct contains a second element named +`ErrorDescription`: -- The element of the struct named `"ErrorDescription"` - contains an array of string values. The first element of the array - is an error code; the remainder of the array are strings - representing error parameters relating to that code. +- The element of the struct named `ErrorDescription` contains an array of string + values. The first element of the array is an error code; the rest of the + elements are strings representing error parameters relating to that code. -For example, an XML-RPC return value from the -`host.get_resident_VMs` function above may look like this: +For example, an XML-RPC return value from the `host.get_resident_VMs` function +may look like this: +```xml Status @@ -151,149 +121,675 @@ For example, an XML-RPC return value from the +``` + +## JSON-RPC Protocol -Making XML-RPC Calls -==================== +We specify the signatures of API functions in the following style: -Transport Layer ---------------- +```python +(VM ref set) VM.get_all() +``` -The following transport layers are currently supported: +This specifies that the function with name `VM.get_all` takes no parameters and +returns a `set` of `VM ref`. These types are mapped onto JSON-RPC types in the +following manner: -- HTTPS for remote administration +- the types `float` and `bool` map directly to the JSON types `number` and + `boolean`, while `datetime` and `string` are represented as the JSON `string` + type. -- HTTP over Unix domain sockets for local administration +- all `ref` types are opaque references, encoded as the JSON `string` type. + Users of the API should not make assumptions about the concrete form of these + strings and should not expect them to remain valid after the client's session + with the server has terminated. -Session Layer -------------- +- fields named `uuid` of type `string` are mapped to the JSON `string` type. The + string itself is the OSF DCE UUID presentation format (as output by `uuidgen`). -The XML-RPC interface is session-based; before you can make arbitrary -RPC calls you must login and initiate a session. For example: +- `int` is assumed to be 64-bit in our API and is encoded as a JSON `number` + without decimal point or exponent, preserved as a string. - (session ref) session.login_with_password(string uname, string pwd, string version, string originator) +- values of `enum` types are encoded as the JSON `string` type. For example, the + value `destroy` of `enum on_normal_exit`, would be conveyed as: -Where `uname` and `password` refer to your -username and password respectively, as defined by the Xen administrator. -The `session ref` returned by `session.login_with_password` is passed to subequent RPC -calls as an authentication token. +```xml + "destroy" +``` -A session can be terminated with the `session.logout` function: +- for all our types, `t`, our type `t set` simply maps to the JSON `array` + type, so, for example, a value of type `string set` would be transmitted like + this: + +```json + [ "CX8", "PSE36", "FPU" ] +``` - (void) session.logout (session ref) +- for types `k` and `v`, our type `(k -> v) map` maps onto a JSON object which + contains members with name `k` and value `v`. Note that the + `(k -> v) map` type is only valid when `k` is a `string`, `ref`, or + `int`, and in each case the keys of the maps are stringified as + above. For example, the `(string -> float) map` containing the mappings + _Mike -> 2.3_ and _John -> 1.2_ would be represented as: -Synchronous and Asynchronous invocation ---------------------------------------- +```json + { + "Mike": 2.3, + "John": 1.2 + } +``` -Each method call (apart from methods on `session` and `task` objects and -“getters” and “setters” derived from fields) can be made either -synchronously or asynchronously. A synchronous RPC call blocks until the -return value is received; the return value of a synchronous RPC call is -exactly as specified above. +- our `void` type is transmitted as an empty string. -Only synchronous API calls are listed explicitly in this document. All -asynchronous versions are in the special `Async` namespace. -For example, synchronous call `VM.clone (...)` has an asynchronous counterpart, -`Async.VM.clone (...)`, that is non-blocking. +Both versions 1.0 and 2.0 of the JSON-RPC wire format are recognised and, +depending on your client library, you can use either of them. -Instead of returning its result directly, an asynchronous RPC call -returns a task ID (of type `task ref`); this identifier is subsequently used to -track the status of a running asynchronous RPC. Note that an asychronous -call may fail immediately, before a task has even been -created. To represent this eventuality, the returned `task ref` -is wrapped in an XML-RPC struct with a `Status`, -`ErrorDescription` and `Value` fields, exactly as -specified above. +### JSON-RPC v1.0 -The `task ref` is provided in the `Value` field if -`Status` is set to `Success`. +#### JSON-RPC v1.0 Requests -The RPC call +An API call is represented by sending a single JSON object to the server, which +contains the members `method`, `params`, and `id`. - (task ref set) task.get_all (session ref) +- `method`: A JSON `string` containing the name of the function to be invoked. -returns a set of all task IDs known to the system. The status (including -any returned result and error codes) of these tasks can then be queried -by accessing the fields of the Task object in the usual way. Note that, -in order to get a consistent snapshot of a task’s state, it is advisable -to call the `get_record` function. +- `params`: A JSON `array` of values, which represents the parameters of the + function to be invoked. + +- `id`: A JSON `string` or `integer` representing the call id. Note that, + diverging from the JSON-RPC v1.0 specification the API does not accept + _notification_ requests (requests without responses), i.e. the id cannot be + `null`. + +For example, the body of a JSON-RPC v1.0 request to retrieve the resident VMs of +a host may look like this: -Example interactive session -=========================== +```json + { + "method": "host.get_resident_VMs", + "params": [ + "OpaqueRef:74f1a19cd-b660-41e3-a163-10f03e0eae67", + "OpaqueRef:08c34fc9-f418-4f09-8274-b9cb25cd8550" + ], + "id": "xyz" + } +``` -This section describes how an interactive session might look, using the -python XML-RPC client library. +In the above example, the first element of the `params` array is the reference +of the open session to the host, while the second is the host reference. -First, initialise python and import the library `xmlrpc.client`: +#### JSON-RPC v1.0 Return Values - $ python - ... - >>> import xmlrpc.client +The return value of a JSON-RPC v1.0 call is a single JSON object containing +the members `result`, `error`, and `id`. -Create a python object referencing the remote server: +- `result`: If the call is successful, it is a JSON value (`string`, `array` + etc.) representing the return value of the invoked function. If an error has + occurred, it is `null`. - >>> xen = xmlrpc.client.Server("https://localhost:443") +- `error`: If the call is successful, it is `null`. If the call has failed, it + a JSON `array` of `string` values. The first element of the array is an error + code; the remainder of the array are strings representing error parameters + relating to that code. -Acquire a session reference by logging in with a username and password -(error-handling ommitted for brevity; the session reference is returned -under the key `'Value'` in the resulting dictionary) +- `id`: The call id. It is a JSON `string` or `integer` and it is the same id + as the request it is responding to. - >>> session = xen.session.login_with_password("user", "passwd")['Value'] +For example, a JSON-RPC v1.0 return value from the `host.get_resident_VMs` +function may look like this: -When serialised, this call looks like the following: +```json + { + "result": [ + "OpaqueRef:604f51e7-630f-4412-83fa-b11c6cf008ab", + "OpaqueRef:670d08f5-cbeb-4336-8420-ccd56390a65f" + ], + "error": null, + "id": "xyz" + } +``` - - - session.login_with_password - - - user - - - passwd - - - +while the return value of the same call made on a logged out session may look +like this: + +```json + { + "result": null, + "error": [ + "SESSION_INVALID", + "OpaqueRef:93f1a23cd-a640-41e3-b163-10f86e0eae67" + ], + "id": "xyz" + } +``` + +### JSON-RPC v2.0 + +#### JSON-RPC v2.0 Requests + +An API call is represented by sending a single JSON object to the server, which +contains the members `jsonrpc`, `method`, `params`, and `id`. + +- `jsonrpc`: A JSON `string` specifying the version of the JSON-RPC protocol. It + is exactly "2.0". + +- `method`: A JSON `string` containing the name of the function to be invoked. + +- `params`: A JSON `array` of values, which represents the parameters of the + function to be invoked. Although the JSON-RPC v2.0 specification allows this + member to be ommitted, in practice all API calls accept at least one parameter. + +- `id`: A JSON `string` or `integer` representing the call id. Note that, + diverging from the JSON-RPC v2.0 specification it cannot be null. Neither can + it be ommitted because the API does not accept _notification_ requests + (requests without responses). + +For example, the body of a JSON-RPC v2.0 request to retrieve the VMs resident on +a host may may look like this: + +```json + { + "jsonrpc": "2.0", + "method": "host.get_resident_VMs", + "params": [ + "OpaqueRef:c90cd28f-37ec-4dbf-88e6-f697ccb28b39", + "OpaqueRef:08c34fc9-f418-4f09-8274-b9cb25cd8550" + ], + "id": 3 + } +``` + +As before, the first element of the `parameter` array is the reference +of the open session to the host, while the second is the host reference. + +#### JSON-RPC v2.0 Return Values + +The return value of a JSON-RPC v2.0 call is a single JSON object containing the +members `jsonrpc`, either `result` or `error` depending on the outcome of the +call, and `id`. + +- `jsonrpc`: A JSON `string` specifying the version of the JSON-RPC protocol. It + is exactly "2.0". + +- `result`: If the call is successful, it is a JSON value (`string`, `array` etc.) + representing the return value of the invoked function. If an error has + occurred, it does not exist. + +- `error`: If the call is successful, it does not exist. If the call has failed, + it is a single structured JSON object (see below). + +- `id`: The call id. It is a JSON `string` or `integer` and it is the same id + as the request it is responding to. + +The `error` object contains the members `code`, `message`, and `data`. + +- `code`: The API does not make use of this member and only retains it for + compliance with the JSON-RPC v2.0 specification. It is a JSON `integer` + which has a non-zero value. + +- `message`: A JSON `string` representing an API error code. + +- `data`: A JSON array of `string` values representing error parameters + relating to the aforementioned API error code. + +For example, a JSON-RPC v2.0 return value from the `host.get_resident_VMs` +function may look like this: + +```json + { + "jsonrpc": "2.0", + "result": [ + "OpaqueRef:604f51e7-630f-4412-83fa-b11c6cf008ab", + "OpaqueRef:670d08f5-cbeb-4336-8420-ccd56390a65f" + ], + "id": 3 + } +``` + +while the return value of the same call made on a logged out session may look +like this: + +```json + { + "jsonrpc": "2.0", + "error": { + "code": 1, + "message": "SESSION_INVALID", + "data": [ + "OpaqueRef:c90cd28f-37ec-4dbf-88e6-f697ccb28b39" + ] + }, + "id": 3 + } +``` + +## Errors + +When a low-level transport error occurs, or a request is malformed at the HTTP +or RPC level, the server may send an HTTP 500 error response, or the client +may simulate the same. The client must be prepared to handle these errors, +though they may be treated as fatal. + +For example, the following malformed request when using the XML-RPC protocol: + +```sh +$curl -D - -X POST https://server -H 'Content-Type: application/xml' \ + -d ' + + session.logout + ' +``` + +results to the following response: + +```sh +HTTP/1.1 500 Internal Error +content-length: 297 +content-type:text/html +connection:close +cache-control:no-cache, no-store + +

HTTP 500 internal server error

An unexpected error occurred; + please wait a while and try again. If the problem persists, please contact your + support representative.

Additional information

Xmlrpc.Parse_error(&quo +t;close_tag", "open_tag", _) +``` + +When using the JSON-RPC protocol: + +```sh +$curl -D - -X POST https://server/jsonrpc -H 'Content-Type: application/json' \ + -d '{ + "jsonrpc": "2.0", + "method": "session.login_with_password", + "id": 0 + }' +``` + +the response is: + +```sh +HTTP/1.1 500 Internal Error +content-length: 308 +content-type:text/html +connection:close +cache-control:no-cache, no-store + +

HTTP 500 internal server error

An unexpected error occurred; + please wait a while and try again. If the problem persists, please contact your + support representative.

Additional information

Jsonrpc.Malformed_metho +d_request("{jsonrpc=...,method=...,id=...}") +``` + +All other failures are reported with a more structured error response, to +allow better automatic response to failures, proper internationalization of +any error message, and easier debugging. + +On the wire, these are transmitted like this when using the XML-RPC protocol: + +```xml + + + Status + Failure + + + ErrorDescription + + + + MAP_DUPLICATE_KEY + Customer + eSpiel Inc. + eSpiel Incorporated + + + + + +``` + +Note that `ErrorDescription` value is an array of string values. The +first element of the array is an error code; the remainder of the array are +strings representing error parameters relating to that code. In this case, +the client has attempted to add the mapping _Customer -> +eSpiel Incorporated_ to a Map, but it already contains the mapping +_Customer -> eSpiel Inc._, hence the request has failed. + +When using the JSON-RPC protocol v2.0, the above error is transmitted as: + +```json +{ + "jsonrpc": "2.0", + "error": { + "code": 1, + "message": "MAP_DUPLICATE_KEY", + "data": [ + "Customer", + "eSpiel Inc.", + "eSpiel Incorporated" + ] + }, + "id": 3 +} +``` + +Finally, when using the JSON-RPC protocol v1.0: + +```json +{ + "result": null, + "error": [ + "MAP_DUPLICATE_KEY", + "Customer", + "eSpiel Inc.", + "eSpiel Incorporated" + ], + "id": "xyz" +} +``` + +Each possible error code is documented in the last section of the API reference. + +## Note on References vs UUIDs + +References are opaque types - encoded as XML-RPC and JSON-RPC strings on the +wire - understood only by the particular server which generated them. Servers +are free to choose any concrete representation they find convenient; clients +should not make any assumptions or attempt to parse the string contents. +References are not guaranteed to be permanent identifiers for objects; clients +should not assume that references generated during one session are valid for any +future session. References do not allow objects to be compared for equality. Two +references to the same object are not guaranteed to be textually identical. + +UUIDs are intended to be permanent identifiers for objects. They are +guaranteed to be in the OSF DCE UUID presentation format (as output by `uuidgen`). +Clients may store UUIDs on disk and use them to look up objects in subsequent sessions +with the server. Clients may also test equality on objects by comparing UUID strings. + +The API provides mechanisms for translating between UUIDs and opaque references. +Each class that contains a UUID field provides: + +- A `get_by_uuid` method that takes a UUID and returns an opaque reference + to the server-side object that has that UUID; + +- A `get_uuid` function (a regular "field getter" RPC) that takes an opaque reference + and returns the UUID of the server-side object that is referenced by it. + +## Making RPC Calls + +### Transport Layer -Next, the user may acquire a list of all the VMs known to the system: -(Note the call takes the session reference as the only parameter) +The following transport layers are currently supported: - >>> all_vms = xen.VM.get_all(session)['Value'] - >>> all_vms - ['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4'] +- HTTP/HTTPS for remote administration +- HTTP over Unix domain sockets for local administration -The VM references here have the form `OpaqueRef:X`, though -they may not be that simple in the future, and you should treat them as -opaque strings. _Templates_ are VMs with the -`is_a_template` field set to `true`. We can find the subset -of template VMs using a command like the following: +### Session Layer - >>> all_templates = filter(lambda x: xen.VM.get_is_a_template(session, x)['Value'], all_vms) +The RPC interface is session-based; before you can make arbitrary RPC calls +you must login and initiate a session. For example: -Once a reference to a VM has been acquired a lifecycle operation may be -invoked: +```python + (session ref) session.login_with_password(string uname, string pwd, + string version, string originator) +``` - >>> xen.VM.start(session, all_templates[0], False, False) - {'Status': 'Failure', 'ErrorDescription': ['VM_IS_TEMPLATE', 'OpaqueRef:X']} +where `uname` and `password` refer to your username and password, as defined by +the Xen administrator, while `version` and `originator` are optional. The +`session ref` returned by `session.login_with_password` is passed +to subequent RPC calls as an authentication token. Note that a session +reference obtained by a login request to the XML-RPC backend can be used in +subsequent requests to the JSON-RPC backend, and vice-versa. -In this case the `start` message has been rejected, because -the VM is a template, and so an error response has been returned. These -high-level errors are returned as structured data (rather than as -XML-RPC faults), allowing them to be internationalised. +A session can be terminated with the `session.logout` function: -Rather than querying fields individually, whole _records_ -may be returned at once. To retrieve the record of a single object as a -python dictionary: +```python + void session.logout(session ref session_id) +``` + +### Synchronous and Asynchronous Invocation + +Each method call (apart from methods on the `Session` and `Task` objects and +"getters" and "setters" derived from fields) can be made either synchronously or +asynchronously. A synchronous RPC call blocks until the +return value is received; the return value of a synchronous RPC call is +exactly as specified above. + +Only synchronous API calls are listed explicitly in this document. +All their asynchronous counterparts are in the special `Async` namespace. +For example, the synchronous call `VM.clone(...)` has an asynchronous +counterpart, `Async.VM.clone(...)`, that is non-blocking. + +Instead of returning its result directly, an asynchronous RPC call +returns an identifier of type `task ref` which is subsequently used +to track the status of a running asynchronous RPC. + +Note that an asychronous call may fail immediately, before a task has even been +created. When using the XML-RPC wire protocol, this eventuality is represented +by wrapping the returned `task ref` in an XML-RPC struct with a `Status`, +`ErrorDescription`, and `Value` fields, exactly as specified above; the +`task ref` is provided in the `Value` field if `Status` is set to `Success`. +When using the JSON-RPC protocol, the `task ref` is wrapped in a response JSON +object as specified above and it is provided by the value of the `result` member +of a successful call. + +The RPC call + +```python + (task ref set) Task.get_all(session ref session_id) +``` + +returns a set of all task identifiers known to the system. The status (including any +returned result and error codes) of these can then be queried by accessing the +fields of the `Task` object in the usual way. Note that, in order to get a +consistent snapshot of a task's state, it is advisable to call the `get_record` +function. + +## Example interactive session + +This section describes how an interactive session might look, using python +XML-RPC and JSON-RPC client libraries. + +First, initialise python: + +```bash +$ python3 +>>> +``` + +### Using the XML-RPC Protocol + +Import the library `xmlrpc.client` and create a +python object referencing the remote server as shown below: + +```python +>>> import xmlrpc.client +>>> xen = xmlrpc.client.ServerProxy("https://localhost:443") +``` + +Note that you may need to disable SSL certificate validation to establish the +connection, this can be done as follows: + +```python +>>> import ssl +>>> ctx = ssl._create_unverified_context() +>>> xen = xmlrpc.client.ServerProxy("https://localhost:443", context=ctx) +``` + +Acquire a session reference by logging in with a username and password; the +session reference is returned under the key `Value` in the resulting dictionary +(error-handling ommitted for brevity): + +```python +>>> session = xen.session.login_with_password("user", "passwd", +... "version", "originator")['Value'] +``` + +This is what the call looks like when serialized + +```xml + + + session.login_with_password + + user + passwd + version + originator + + +``` + +Next, the user may acquire a list of all the VMs known to the system (note the +call takes the session reference as the only parameter): + +```python +>>> all_vms = xen.VM.get_all(session)['Value'] +>>> all_vms +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] +``` + +The VM references here have the form `OpaqueRef:X` (though they may not be +that simple in reality) and you should treat them as opaque strings. +_Templates_ are VMs with the `is_a_template` field set to `true`. We can +find the subset of template VMs using a command like the following: + +```python +>>> all_templates = filter(lambda x: xen.VM.get_is_a_template(session, x)['Value'], + all_vms) +``` + +Once a reference to a VM has been acquired, a lifecycle operation may be invoked: + +```python +>>> xen.VM.start(session, all_templates[0], False, False) +{'Status': 'Failure', 'ErrorDescription': ['VM_IS_TEMPLATE', 'OpaqueRef:X']} +``` + +In this case the `start` message has been rejected, because the VM is +a template, and so an error response has been returned. These high-level +errors are returned as structured data (rather than as XML-RPC faults), +allowing them to be internationalized. + +Rather than querying fields individually, whole _records_ may be returned at once. +To retrieve the record of a single object as a python dictionary: + +```python +>>> record = xen.VM.get_record(session, all_templates[0])['Value'] +>>> record['power_state'] +'Halted' +>>> record['name_label'] +'Windows 10 (64-bit)' +``` + +To retrieve all the VM records in a single call: - >>> record = xen.VM.get_record(session, all_templates[0])['Value'] - >>> record['power_state'] - 'Halted' - >>> record['name_label'] - 'XenSource P2V Server' +```python +>>> records = xen.VM.get_all_records(session)['Value'] +>>> list(records.keys()) +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] +>>> records['OpaqueRef:1']['name_label'] +'Red Hat Enterprise Linux 7' +``` + +### Using the JSON-RPC Protocol + +For this example we are making use of the package `jsonrpcclient` and the +`requests` library due to their simplicity, although other packages can also be +used. + +First, import the `requests` and `jsonrpcclient` libraries: + +```python +>>> import requests +>>> import jsonrpcclient +``` + +Now we construct a utility method to make using these libraries easier: + +```python +>>> def jsonrpccall(method, params): +... r = requests.post("https://localhost:443/jsonrpc", +... json=jsonrpcclient.request(method, params=params), +... verify=False) +... p = jsonrpcclient.parse(r.json()) +... if isinstance(p, jsonrpcclient.Ok): +... return p.result +... raise Exception(p.message, p.data) +``` + +Acquire a session reference by logging in with a username and password: + +```python +>>> session = jsonrpccall("session.login_with_password", +... ("user", "password", "version", "originator")) +``` + +`jsonrpcclient` uses the JSON-RPC protocol v2.0, so this is what the serialized +request looks like: + +```json + { + "jsonrpc": "2.0", + "method": "session.login_with_password", + "params": ["user", "passwd", "version", "originator"], + "id": 0 + } +``` + +Next, the user may acquire a list of all the VMs known to the system (note the +call takes the session reference as the only parameter): + +```python +>>> all_vms = jsonrpccall("VM.get_all", (session,)) +>>> all_vms +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] +``` + +The VM references here have the form `OpaqueRef:X` (though they may not be +that simple in reality) and you should treat them as opaque strings. +_Templates_ are VMs with the `is_a_template` field set to `true`. We can +find the subset of template VMs using a command like the following: + +```python +>>> all_templates = filter( +... lambda x: jsonrpccall("VM.get_is_a_template", (session, x)), +... all_vms) +``` + +Once a reference to a VM has been acquired, a lifecycle operation may be invoked: + +```python +>>> try: +... jsonrpccall("VM.start", (session, next(all_templates), False, False)) +... except Exception as e: +... e +... +Exception('VM_IS_TEMPLATE', ['OpaqueRef:1', 'start']) +``` + +In this case the `start` message has been rejected because the VM is +a template, hence an error response has been returned. These high-level +errors are returned as structured data, allowing them to be internationalized. + +Rather than querying fields individually, whole _records_ may be returned at once. +To retrieve the record of a single object as a python dictionary: + +```python +>>> record = jsonrpccall("VM.get_record", (session, next(all_templates))) +>>> record['power_state'] +'Halted' +>>> record['name_label'] +'Windows 10 (64-bit)' +``` To retrieve all the VM records in a single call: - >>> records = xen.VM.get_all_records(session)['Value'] - >>> records.keys() - ['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] - >>> records['OpaqueRef:1']['name_label'] - 'RHEL 4.1 Autoinstall Template' +```python +>>> records = jsonrpccall("VM.get_all_records", (session,)) +>>> records.keys() +['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] +>>> records['OpaqueRef:1']['name_label'] +'Red Hat Enterprise Linux 7' +``` diff --git a/ocaml/doc/basics.md b/ocaml/doc/basics.md deleted file mode 100644 index 783797051f..0000000000 --- a/ocaml/doc/basics.md +++ /dev/null @@ -1,119 +0,0 @@ -# API Basics - -This document defines the XenServer Management API - an interface for remotely -configuring and controlling virtualized guests running on a Xen-enabled host. - -The API is presented here as a set of Remote Procedure Calls (RPCs). There are -two supported wire formats, one based upon [XML-RPC](http://xmlrpc.scripting.com/spec.html) -and one based upon [JSON-RPC](http://www.jsonrpc.org) (v1.0 and v2.0 are both -recognized). No specific language bindings are prescribed, although examples -will be given in the python programming language. - -Although we adopt some terminology from object-oriented programming, -future client language bindings may or may not be object oriented. -The API reference uses the terminology _classes_ and _objects_. -For our purposes a _class_ is simply a hierarchical namespace; -an _object_ is an instance of a class with its fields set to -specific values. Objects are persistent and exist on the server-side. -Clients may obtain opaque references to these server-side objects and then -access their fields via get/set RPCs. - -For each class we specify a list of fields along with their _types_ and -_qualifiers_. A qualifier is one of: - -* `RO/runtime`: the field is Read Only. Furthermore, its value is - automatically computed at runtime. For example, current CPU load and disk IO - throughput. - -* `RO/constructor`: the field must be manually set when a new object is - created, but is then Read Only for the duration of the object's life. - For example, the maximum memory addressable by a guest is set - before the guest boots. - -* `RW`: the field is Read/Write. For example, the name of a VM. - -## Types - -The following types are used to specify methods and fields in the API Reference: - -* `string`: Text strings. -* `int`: 64-bit integers. -* `float`: IEEE double-precision floating-point numbers. -* `bool`: Boolean. -* `datetime`: Date and timestamp. -* `c ref`: Reference to an object of class `c`. -* `t set`: Arbitrary-length set of values of type `t`. -* `(k -> v) map`: Mapping from values of type `k` to values of type `v`. -* `e enum`: Enumeration type with name `e`. Enums are defined in the - API reference together with classes that use them. - -Note that there are a number of cases where `ref`s are _doubly linked_. -For example, a `VM` has a field called `VIFs` of type `VIF ref set`; -this field lists the network interfaces attached to a particular VM. -Similarly, the `VIF` class has a field called `VM` of type `VM ref` -which references the VM to which the interface is connected. -These two fields are _bound together_, in the sense that -creating a new VIF causes the `VIFs` field of the corresponding -VM object to be updated automatically. - -The API reference lists explicitly the fields that are -bound together in this way. It also contains a diagram that shows -relationships between classes. In this diagram an edge signifies the -existence of a pair of fields that are bound together, using standard -crows-foot notation to signify the type of relationship (e.g. -one-many, many-many). - -## RPCs associated with fields - -Each field, `f`, has an RPC accessor associated with it that returns `f`'s value: - -* `get_f (r)`: takes a `ref`, `r` that refers to an object and returns the value - of `f`. - -Each field, `f`, with qualifier `RW` and whose outermost type is `set` has the -following additional RPCs associated with it: - -* `add_f(r, v)`: adds a new element `v` to the set. - Note that sets cannot contain duplicate values, hence this operation has - no action in the case that `v` is already in the set. - -* `remove_f(r, v)`: removes element `v` from the set. - -Each field, `f`, with qualifier `RW` and whose outermost type is `map` has the -following additional RPCs associated with it: - -* `add_to_f(r, k, v)`: adds new pair `k -> v` to the mapping stored in `f` in - object`r`. Attempting to add a new pair for duplicate key, `k`, fails with a - `MAP_DUPLICATE_KEY` error. - -* `remove_from_f(r, k)`: removes the pair with key `k` - from the mapping stored in `f` in object `r`. - -Each field whose outermost type is neither `set` nor `map`, but whose -qualifier is `RW` has an RPC accessor associated with it that sets its value: - -* `set_f(r, v)`: sets the field `f` on object `r` to value `v`. - -## RPCs associated with classes - -* Most classes have a _constructor_ RPC named `create` that - takes as parameters all fields marked `RW` and `RO/constructor`. The result - of this RPC is that a new _persistent_ object is created on the server-side - with the specified field values. - -* Each class has a `get_by_uuid(uuid)` RPC that returns the object - of that class that has the specified `uuid`. - -* Each class that has a `name_label` field has a - `get_by_name_label(name_label)` RPC that returns a set of objects of that - class that have the specified `name_label`. - -* Most classes have a `destroy(r)` RPC that explicitly deletes - the persistent object specified by `r` from the system. This is a - non-cascading delete - if the object being removed is referenced by another - object then the `destroy` call will fail. - -Apart from the RPCs enumerated above, some classes have additional RPCs -associated with them. For example, the `VM` class has RPCs for cloning, -suspending, starting etc. Such additional RPCs are described explicitly -in the API reference. diff --git a/ocaml/doc/dune b/ocaml/doc/dune index aa5077ef40..9c4bb6cd47 100644 --- a/ocaml/doc/dune +++ b/ocaml/doc/dune @@ -60,3 +60,13 @@ doc-convert.sh ) ) + +(install + (package xapi) + (section share_root) + (files + (glob_files (../../doc/content/xen-api/basics.md with_prefix markdown)) + (glob_files (../../doc/content/xen-api/wire-protocol.md with_prefix markdown)) + (glob_files (../../doc/content/xen-api/topics/vm-lifecycle.md with_prefix markdown)) + ) +) diff --git a/ocaml/doc/vm-lifecycle.md b/ocaml/doc/vm-lifecycle.md deleted file mode 100644 index 31f31889f3..0000000000 --- a/ocaml/doc/vm-lifecycle.md +++ /dev/null @@ -1,50 +0,0 @@ -# VM Lifecycle - -The following diagram shows the states that a VM can be in -and the API calls that can be used to move the VM between these states. - -![VM lifecycle](vm-lifecycle.png "VM Lifecycle") - -## VM boot parameters - -The `VM` class contains a number of fields that control the way in which the VM -is booted. With reference to the fields defined in the VM class (see later in -this document), this section outlines the boot options available and the -mechanisms provided for controlling them. - -VM booting is controlled by setting one of the two mutually exclusive groups: -"PV" and "HVM". If `HVM.boot_policy` is an empty string, then paravirtual -domain building and booting will be used; otherwise the VM will be loaded as a -HVM domain, and booted using an emulated BIOS. - -When paravirtual booting is in use, the `PV_bootloader` field indicates the -bootloader to use. It may be "pygrub", in which case the platform's default -installation of pygrub will be used, or a full path within the control domain to -some other bootloader. The other fields, `PV_kernel`, `PV_ramdisk`, `PV_args`, -and `PV_bootloader_args` will be passed to the bootloader unmodified, and -interpretation of those fields is then specific to the bootloader itself, -including the possibility that the bootloader will ignore some or all of -those given values. Finally the paths of all bootable disks are added to the -bootloader commandline (a disk is bootable if its VBD has the bootable flag set). -There may be zero, one, or many bootable disks; the bootloader decides which -disk (if any) to boot from. - -If the bootloader is pygrub, then the menu.lst is parsed, if present in the -guest's filesystem, otherwise the specified kernel and ramdisk are used, or an -autodetected kernel is used if nothing is specified and autodetection is -possible. `PV_args` is appended to the kernel command line, no matter which -mechanism is used for finding the kernel. - -If `PV_bootloader` is empty but `PV_kernel` is specified, then the kernel and -ramdisk values will be treated as paths within the control domain. If both -`PV_bootloader` and `PV_kernel` are empty, then the behaviour is as if -`PV_bootloader` were specified as "pygrub". - -When using HVM booting, `HVM_boot_policy` and `HVM_boot_params` specify the boot -handling. Only one policy is currently defined, "BIOS order". In this case, -`HVM_boot_params` should contain one key-value pair "order" = "N" where N is the -string that will be passed to QEMU. -Optionally `HVM_boot_params` can contain another key-value pair "firmware" -with values "bios" or "uefi" (default is "bios" if absent). -By default Secure Boot is not enabled, it can be enabled when "uefi" is enabled by setting -`VM.platform["secureboot"]` to true. diff --git a/ocaml/doc/wire-protocol.md b/ocaml/doc/wire-protocol.md deleted file mode 100644 index 26b911bd2c..0000000000 --- a/ocaml/doc/wire-protocol.md +++ /dev/null @@ -1,664 +0,0 @@ -# Wire Protocol for Remote API Calls - -API calls are sent over a network to a Xen-enabled host using an RPC protocol. -Here we describe how the higher-level types used in our API Reference are mapped -to primitive RPC types, covering the two supported wire formats -[XML-RPC](http://xmlrpc.scripting.com/spec.html) and [JSON-RPC](http://www.jsonrpc.org). - -## XML-RPC Protocol - -We specify the signatures of API functions in the following style: - -```python -(VM ref set) VM.get_all() -``` - -This specifies that the function with name `VM.get_all` takes -no parameters and returns a `set` of `VM ref`. -These types are mapped onto XML-RPC types in a straight-forward manner: - -* the types `float`, `bool`, `datetime`, and `string` map directly to the XML-RPC - ``, ``, ``, and `` elements. - -* all `ref` types are opaque references, encoded as the - XML-RPC's `` type. Users of the API should not make assumptions - about the concrete form of these strings and should not expect them to - remain valid after the client's session with the server has terminated. - -* fields named `uuid` of type `string` are mapped to - the XML-RPC `` type. The string itself is the OSF - DCE UUID presentation format (as output by `uuidgen`). - -* `int` is assumed to be 64-bit in our API and is encoded as a string - of decimal digits (rather than using XML-RPC's built-in 32-bit `` type). - -* values of `enum` types are encoded as strings. For example, the value - `destroy` of `enum on_normal_exit`, would be conveyed as: - -```xml - destroy -``` - -* for all our types, `t`, our type `t set` simply maps to XML-RPC's `` - type, so, for example, a value of type `string set` would be transmitted like - this: - -```xml - - - CX8 - PSE36 - FPU - - -``` - -* for types `k` and `v`, our type `(k -> v) map` maps onto an - XML-RPC ``, with the key as the name of the struct. Note that the - `(k -> v) map` type is only valid when `k` is a `string`, `ref`, or - `int`, and in each case the keys of the maps are stringified as - above. For example, the `(string -> float) map` containing the mappings - _Mike -> 2.3_ and _John -> 1.2_ would be represented as: - -```xml - - - - Mike - 2.3 - - - John - 1.2 - - - -``` - -* our `void` type is transmitted as an empty string. - -### XML-RPC Return Values and Status Codes - -The return value of an RPC call is an XML-RPC ``. - -* The first element of the struct is named `Status`; it contains a string value - indicating whether the result of the call was a `Success` or a `Failure`. - -If the `Status` is `Success` then the struct contains a second element named -`Value`: - -* The element of the struct named `Value` contains the function's return value. - -If the `Status` is `Failure` then the struct contains a second element named -`ErrorDescription`: - -* The element of the struct named `ErrorDescription` contains an array of string - values. The first element of the array is an error code; the rest of the - elements are strings representing error parameters relating to that code. - -For example, an XML-RPC return value from the `host.get_resident_VMs` function -may look like this: - -```xml - - - Status - Success - - - Value - - - - 81547a35-205c-a551-c577-00b982c5fe00 - 61c85a22-05da-b8a2-2e55-06b0847da503 - 1d401ec4-3c17-35a6-fc79-cee6bd9811fe - - - - - -``` - -## JSON-RPC Protocol - -We specify the signatures of API functions in the following style: - -```python -(VM ref set) VM.get_all() -``` - -This specifies that the function with name `VM.get_all` takes no parameters and -returns a `set` of `VM ref`. These types are mapped onto JSON-RPC types in the -following manner: - -* the types `float` and `bool` map directly to the JSON types `number` and - `boolean`, while `datetime` and `string` are represented as the JSON `string` - type. - -* all `ref` types are opaque references, encoded as the JSON `string` type. - Users of the API should not make assumptions about the concrete form of these - strings and should not expect them to remain valid after the client's session - with the server has terminated. - -* fields named `uuid` of type `string` are mapped to the JSON `string` type. The - string itself is the OSF DCE UUID presentation format (as output by `uuidgen`). - -* `int` is assumed to be 64-bit in our API and is encoded as a JSON `number` - without decimal point or exponent, preserved as a string. - -* values of `enum` types are encoded as the JSON `string` type. For example, the - value `destroy` of `enum on_normal_exit`, would be conveyed as: - -```xml - "destroy" -``` - -* for all our types, `t`, our type `t set` simply maps to the JSON `array` - type, so, for example, a value of type `string set` would be transmitted like - this: - -```json - [ "CX8", "PSE36", "FPU" ] -``` - -* for types `k` and `v`, our type `(k -> v) map` maps onto a JSON object which - contains members with name `k` and value `v`. Note that the - `(k -> v) map` type is only valid when `k` is a `string`, `ref`, or - `int`, and in each case the keys of the maps are stringified as - above. For example, the `(string -> float) map` containing the mappings - _Mike -> 2.3_ and _John -> 1.2_ would be represented as: - -```json - { - "Mike": 2.3, - "John": 1.2 - } -``` - -* our `void` type is transmitted as an empty string. - -Both versions 1.0 and 2.0 of the JSON-RPC wire format are recognized and, -depending on your client library, you can use either of them. - -### JSON-RPC v1.0 - -#### JSON-RPC v1.0 Requests - -An API call is represented by sending a single JSON object to the server, which -contains the members `method`, `params`, and `id`. - -* `method`: A JSON `string` containing the name of the function to be invoked. - -* `params`: A JSON `array` of values, which represents the parameters of the - function to be invoked. - -* `id`: A JSON `string` or `integer` representing the call id. Note that, - diverging from the JSON-RPC v1.0 specification the API does not accept - _notification_ requests (requests without responses), i.e. the id cannot be - `null`. - -For example, a JSON-RPC v1.0 request to retrieve the resident VMs of a host may -look like this: - -```json - { - "method": "host.get_resident_VMs", - "params": [ - "OpaqueRef:74f1a19cd-b660-41e3-a163-10f03e0eae67", - "OpaqueRef:08c34fc9-f418-4f09-8274-b9cb25cd8550" - ], - "id": "xyz" - } -``` - -In the above example, the first element of the `params` array is the reference -of the open session to the host, while the second is the host reference. - -#### JSON-RPC v1.0 Return Values - -The return value of a JSON-RPC v1.0 call is a single JSON object containing -the members `result`, `error`, and `id`. - -* `result`: If the call is successful, it is a JSON value (`string`, `array` - etc.) representing the return value of the invoked function. If an error has - occurred, it is `null`. - -* `error`: If the call is successful, it is `null`. If the call has failed, it - a JSON `array` of `string` values. The first element of the array is an error - code; the remainder of the array are strings representing error parameters - relating to that code. - -* `id`: The call id. It is a JSON `string` or `integer` and it is the same id - as the request it is responding to. - -For example, a JSON-RPC v1.0 return value from the `host.get_resident_VMs` -function may look like this: - -```json - { - "result": [ - "OpaqueRef:604f51e7-630f-4412-83fa-b11c6cf008ab", - "OpaqueRef:670d08f5-cbeb-4336-8420-ccd56390a65f" - ], - "error": null, - "id": "xyz" - } -``` - -while the return value of the same call made on a logged out session may look -like this: - -```json - { - "result": null, - "error": [ - "SESSION_INVALID", - "OpaqueRef:93f1a23cd-a640-41e3-b163-10f86e0eae67" - ], - "id": "xyz" - } -``` - -### JSON-RPC v2.0 - -#### JSON-RPC v2.0 Requests - -An API call is represented by sending a single JSON object to the server, which -contains the members `jsonrpc`, `method`, `params`, and `id`. - -* `jsonrpc`: A JSON `string` specifying the version of the JSON-RPC protocol. It - is exactly "2.0". - -* `method`: A JSON `string` containing the name of the function to be invoked. - -* `params`: A JSON `array` of values, which represents the parameters of the - function to be invoked. Although the JSON-RPC v2.0 specification allows this - member to be ommitted, in practice all API calls accept at least one parameter. - -* `id`: A JSON `string` or `integer` representing the call id. Note that, - diverging from the JSON-RPC v2.0 specification it cannot be null. Neither can - it be ommitted because the API does not accept _notification_ requests - (requests without responses). - -For example, a JSON-RPC v2.0 request to retrieve the VMs resident on a host may -may look like this: - -```json - { - "jsonrpc": "2.0", - "method": "host.get_resident_VMs", - "params": [ - "OpaqueRef:c90cd28f-37ec-4dbf-88e6-f697ccb28b39", - "OpaqueRef:08c34fc9-f418-4f09-8274-b9cb25cd8550" - ], - "id": 3 - } -``` - -As before, the first element of the `parameter` array is the reference -of the open session to the host, while the second is the host reference. - -#### JSON-RPC v2.0 Return Values - -The return value of a JSON-RPC v2.0 call is a single JSON object containing the -members `jsonrpc`, either `result` or `error` depending on the outcome of the -call, and `id`. - -* `jsonrpc`: A JSON `string` specifying the version of the JSON-RPC protocol. It - is exactly "2.0". - -* `result`: If the call is successful, it is a JSON value (`string`, `array` etc.) - representing the return value of the invoked function. If an error has - occurred, it does not exist. - -* `error`: If the call is successful, it does not exist. If the call has failed, - it is a single structured JSON object (see below). - -* `id`: The call id. It is a JSON `string` or `integer` and it is the same id - as the request it is responding to. - -The `error` object contains the members `code`, `message`, and `data`. - -* `code`: The API does not make use of this member and only retains it for - compliance with the JSON-RPC v2.0 specification. It is a JSON `integer` - which has a non-zero value. - -* `message`: A JSON `string` representing an API error code. - -* `data`: A JSON array of `string` values representing error parameters - relating to the aforementioned API error code. - -For example, a JSON-RPC v2.0 return value from the `host.get_resident_VMs` -function may look like this: - -```json - { - "jsonrpc": "2.0", - "result": [ - "OpaqueRef:604f51e7-630f-4412-83fa-b11c6cf008ab", - "OpaqueRef:670d08f5-cbeb-4336-8420-ccd56390a65f" - ], - "id": 3 - } -``` - -while the return value of the same call made on a logged out session may look -like this: - -```json - { - "jsonrpc": "2.0", - "error": { - "code": 1, - "message": "SESSION_INVALID", - "data": [ - "OpaqueRef:c90cd28f-37ec-4dbf-88e6-f697ccb28b39" - ] - }, - "id": 3 - } -``` - -## Note on References vs UUIDs - -References are opaque types - encoded as XML-RPC and JSON-RPC strings on the -wire - understood only by the particular server which generated them. Servers -are free to choose any concrete representation they find convenient; clients -should not make any assumptions or attempt to parse the string contents. -References are not guaranteed to be permanent identifiers for objects; clients -should not assume that references generated during one session are valid for any -future session. References do not allow objects to be compared for equality. Two -references to the same object are not guaranteed to be textually identical. - -UUIDs are intended to be permanent identifiers for objects. They are -guaranteed to be in the OSF DCE UUID presentation format (as output by `uuidgen`). -Clients may store UUIDs on disk and use them to look up objects in subsequent sessions -with the server. Clients may also test equality on objects by comparing UUID strings. - -The API provides mechanisms for translating between UUIDs and opaque references. -Each class that contains a UUID field provides: - -* A `get_by_uuid` method that takes a UUID and returns an opaque reference - to the server-side object that has that UUID; - -* A `get_uuid` function (a regular "field getter" RPC) that takes an opaque reference - and returns the UUID of the server-side object that is referenced by it. - -## Making RPC Calls - -### Transport Layer - -The following transport layers are currently supported: - -* HTTP/HTTPS for remote administration -* HTTP over Unix domain sockets for local administration - -### Session Layer - -The RPC interface is session-based; before you can make arbitrary RPC calls -you must login and initiate a session. For example: - -```python - (session ref) session.login_with_password(string uname, string pwd, - string version, string originator) -``` - -where `uname` and `password` refer to your username and password, as defined by -the Xen administrator, while `version` and `originator` are optional. The -`session ref` returned by `session.login_with_password` is passed -to subequent RPC calls as an authentication token. Note that a session -reference obtained by a login request to the XML-RPC backend can be used in -subsequent requests to the JSON-RPC backend, and vice-versa. - -A session can be terminated with the `session.logout` function: - -```python - void session.logout(session ref session_id) -``` - -### Synchronous and Asynchronous Invocation - -Each method call (apart from methods on the `Session` and `Task` objects and -"getters" and "setters" derived from fields) can be made either synchronously or -asynchronously. A synchronous RPC call blocks until the -return value is received; the return value of a synchronous RPC call is -exactly as specified above. - -Only synchronous API calls are listed explicitly in this document. -All their asynchronous counterparts are in the special `Async` namespace. -For example, the synchronous call `VM.clone(...)` has an asynchronous -counterpart, `Async.VM.clone(...)`, that is non-blocking. - -Instead of returning its result directly, an asynchronous RPC call -returns an identifier of type `task ref` which is subsequently used -to track the status of a running asynchronous RPC. - -Note that an asychronous call may fail immediately, before a task has even been -created. When using the XML-RPC wire protocol, this eventuality is represented -by wrapping the returned `task ref` in an XML-RPC struct with a `Status`, -`ErrorDescription`, and `Value` fields, exactly as specified above; the -`task ref` is provided in the `Value` field if `Status` is set to `Success`. -When using the JSON-RPC protocol, the `task ref` is wrapped in a response JSON -object as specified above and it is provided by the value of the `result` member -of a successful call. - -The RPC call - -```python - (task ref set) Task.get_all(session ref session_id) -``` - -returns a set of all task identifiers known to the system. The status (including any -returned result and error codes) of these can then be queried by accessing the -fields of the `Task` object in the usual way. Note that, in order to get a -consistent snapshot of a task's state, it is advisable to call the `get_record` -function. - -## Example interactive session - -This section describes how an interactive session might look, using python -XML-RPC and JSON-RPC client libraries. - -First, initialise python: - -```bash -$ python3 ->>> -``` - -### Using the XML-RPC Protocol - -Import the library `xmlrpc.client` and create a -python object referencing the remote server as shown below: - -```python ->>> import xmlrpc.client ->>> xen = xmlrpc.client.ServerProxy("https://localhost:443") -``` - -Note that you may need to disable SSL certificate validation to establish the -connection, this can be done as follows: - -```python ->>> import ssl ->>> ctx = ssl._create_unverified_context() ->>> xen = xmlrpc.client.ServerProxy("https://localhost:443", context=ctx) -``` - -Acquire a session reference by logging in with a username and password; the -session reference is returned under the key `Value` in the resulting dictionary -(error-handling ommitted for brevity): - -```python ->>> session = xen.session.login_with_password("user", "passwd", -... "version", "originator")['Value'] -``` - -This is what the call looks like when serialized - -```xml - - - session.login_with_password - - user - passwd - version - originator - - -``` - -Next, the user may acquire a list of all the VMs known to the system (note the -call takes the session reference as the only parameter): - -```python ->>> all_vms = xen.VM.get_all(session)['Value'] ->>> all_vms -['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] -``` - -The VM references here have the form `OpaqueRef:X` (though they may not be -that simple in reality) and you should treat them as opaque strings. -_Templates_ are VMs with the `is_a_template` field set to `true`. We can -find the subset of template VMs using a command like the following: - -```python ->>> all_templates = filter(lambda x: xen.VM.get_is_a_template(session, x)['Value'], - all_vms) -``` - -Once a reference to a VM has been acquired, a lifecycle operation may be invoked: - -```python ->>> xen.VM.start(session, all_templates[0], False, False) -{'Status': 'Failure', 'ErrorDescription': ['VM_IS_TEMPLATE', 'OpaqueRef:X']} -``` - -In this case the `start` message has been rejected, because the VM is -a template, and so an error response has been returned. These high-level -errors are returned as structured data (rather than as XML-RPC faults), -allowing them to be internationalized. - -Rather than querying fields individually, whole _records_ may be returned at once. -To retrieve the record of a single object as a python dictionary: - -```python ->>> record = xen.VM.get_record(session, all_templates[0])['Value'] ->>> record['power_state'] -'Halted' ->>> record['name_label'] -'Windows 10 (64-bit)' -``` - -To retrieve all the VM records in a single call: - -```python ->>> records = xen.VM.get_all_records(session)['Value'] ->>> list(records.keys()) -['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] ->>> records['OpaqueRef:1']['name_label'] -'Red Hat Enterprise Linux 7' -``` - -### Using the JSON-RPC Protocol - -For this example we are making use of the package `jsonrpcclient` and the -`requests` library due to their simplicity, although other packages can also be -used. - -First, import the `requests` and `jsonrpcclient` libraries: - -```python ->>> import requests ->>> import jsonrpcclient -``` - -Now we construct a utility method to make using these libraries easier: - -```python ->>> def jsonrpccall(method, params): -... r = requests.post("https://localhost:443/jsonrpc", -... json=jsonrpcclient.request(method, params=params), -... verify=False) -... p = jsonrpcclient.parse(r.json()) -... if isinstance(p, jsonrpcclient.Ok): -... return p.result -... raise Exception(p.message, p.data) -``` - -Acquire a session reference by logging in with a username and password: - -```python ->>> session = jsonrpccall("session.login_with_password", -... ("user", "password", "version", "originator")) -``` - -`jsonrpcclient` uses the JSON-RPC protocol v2.0, so this is what the serialized -request looks like: - -```json - { - "jsonrpc": "2.0", - "method": "session.login_with_password", - "params": ["user", "passwd", "version", "originator"], - "id": 0 - } -``` - -Next, the user may acquire a list of all the VMs known to the system (note the -call takes the session reference as the only parameter): - -```python ->>> all_vms = jsonrpccall("VM.get_all", (session,)) ->>> all_vms -['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] -``` - -The VM references here have the form `OpaqueRef:X` (though they may not be -that simple in reality) and you should treat them as opaque strings. -_Templates_ are VMs with the `is_a_template` field set to `true`. We can -find the subset of template VMs using a command like the following: - -```python ->>> all_templates = filter( -... lambda x: jsonrpccall("VM.get_is_a_template", (session, x)), -... all_vms) -``` - -Once a reference to a VM has been acquired, a lifecycle operation may be invoked: - -```python ->>> try: -... jsonrpccall("VM.start", (session, next(all_templates), False, False)) -... except Exception as e: -... e -... -Exception('VM_IS_TEMPLATE', ['OpaqueRef:1', 'start']) -``` - -In this case the `start` message has been rejected because the VM is -a template, hence an error response has been returned. These high-level -errors are returned as structured data, allowing them to be internationalized. - -Rather than querying fields individually, whole _records_ may be returned at once. -To retrieve the record of a single object as a python dictionary: - -```python ->>> record = jsonrpccall("VM.get_record", (session, next(all_templates))) ->>> record['power_state'] -'Halted' ->>> record['name_label'] -'Windows 10 (64-bit)' -``` - -To retrieve all the VM records in a single call: - -```python ->>> records = jsonrpccall("VM.get_all_records", (session,)) ->>> records.keys() -['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ] ->>> records['OpaqueRef:1']['name_label'] -'Red Hat Enterprise Linux 7' -``` diff --git a/ocaml/idl/templates/api_errors.mustache b/ocaml/idl/templates/api_errors.mustache index 384a737d9a..3bc2cd44a0 100644 --- a/ocaml/idl/templates/api_errors.mustache +++ b/ocaml/idl/templates/api_errors.mustache @@ -1,135 +1,9 @@ -# Error Handling +# Error Codes -When a low-level transport error occurs, or a request is malformed at the HTTP -or RPC level, the server may send an HTTP 500 error response, or the client -may simulate the same. The client must be prepared to handle these errors, -though they may be treated as fatal. - -For example, the following malformed request when using the XML-RPC protocol: - -```sh -$curl -D - -X POST https://server -H 'Content-Type: application/xml' \ -> -d ' -> -> session.logout -> ' -``` - -results to the following response: - -```sh -HTTP/1.1 500 Internal Error -content-length: 297 -content-type:text/html -connection:close -cache-control:no-cache, no-store - -

HTTP 500 internal server error

An unexpected error occurred; - please wait a while and try again. If the problem persists, please contact your - support representative.

Additional information

Xmlrpc.Parse_error(&quo -t;close_tag", "open_tag", _) -``` - -When using the JSON-RPC protocol: - -```sh -$curl -D - -X POST https://server/jsonrpc -H 'Content-Type: application/json' \ -> -d '{ -> "jsonrpc": "2.0", -> "method": "session.login_with_password", -> "id": 0 -> }' -``` - -the response is: - -```sh -HTTP/1.1 500 Internal Error -content-length: 308 -content-type:text/html -connection:close -cache-control:no-cache, no-store - -

HTTP 500 internal server error

An unexpected error occurred; - please wait a while and try again. If the problem persists, please contact your - support representative.

Additional information

Jsonrpc.Malformed_metho -d_request("{jsonrpc=...,method=...,id=...}") -``` - -All other failures are reported with a more structured error response, to -allow better automatic response to failures, proper internationalization of -any error message, and easier debugging. - -On the wire, these are transmitted like this when using the XML-RPC protocol: - -```xml - - - Status - Failure - - - ErrorDescription - - - - MAP_DUPLICATE_KEY - Customer - eSpiel Inc. - eSpiel Incorporated - - - - - -``` - -Note that `ErrorDescription` value is an array of string values. The -first element of the array is an error code; the remainder of the array are -strings representing error parameters relating to that code. In this case, -the client has attempted to add the mapping _Customer -> -eSpiel Incorporated_ to a Map, but it already contains the mapping -_Customer -> eSpiel Inc._, hence the request has failed. - -When using the JSON-RPC protocol v2.0, the above error is transmitted as: - -```json -{ - "jsonrpc": "2.0", - "error": { - "code": 1, - "message": "MAP_DUPLICATE_KEY", - "data": [ - "Customer", - "eSpiel Inc.", - "eSpiel Incorporated" - ] - }, - "id": 3 -} -``` - -Finally, when using the JSON-RPC protocol v1.0: - -```json -{ - "result": null, - "error": [ - "MAP_DUPLICATE_KEY", - "Customer", - "eSpiel Inc.", - "eSpiel Incorporated" - ], - "id": "xyz" -} -``` - -Each possible error code is documented in the following section. - -## Error Codes +The following is a list of all possible errors that can be issued by API calls. {{#errors}} -### {{{error_code}}} +## {{{error_code}}} {{{error_description}}} diff --git a/ocaml/idl/templates/toc.mustache b/ocaml/idl/templates/toc.mustache index 126bf2922e..eca5b54db8 100644 --- a/ocaml/idl/templates/toc.mustache +++ b/ocaml/idl/templates/toc.mustache @@ -11,5 +11,5 @@ - title: "Class: {{{name}}}" url: @root@management-api/class-{{{name_lower}}}.html {{/classes}} - - title: Error Handling + - title: Error Codes url: @root@management-api/api-errors.html