mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
384 lines
13 KiB
TeX
384 lines
13 KiB
TeX
%
|
|
% Copyright (c) 2006-2007 XenSource, Inc.
|
|
% Copyright (c) 2009 flonatel GmbH & Co. KG
|
|
%
|
|
% Permission is granted to copy, distribute and/or modify this document under
|
|
% the terms of the GNU Free Documentation License, Version 1.2 or any later
|
|
% version published by the Free Software Foundation; with no Invariant
|
|
% Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the
|
|
% license is included in the section entitled
|
|
% "GNU Free Documentation License" or the file fdl.tex.
|
|
%
|
|
% Authors: Ewan Mellor, Richard Sharp, Dave Scott, Jon Harrop.
|
|
% Contributor: Andreas Florath
|
|
%
|
|
|
|
\section{Wire Protocol for Remote API Calls}
|
|
|
|
API calls are sent over a network to a Xen-enabled host using
|
|
the XML-RPC protocol. In this Section we describe how the
|
|
higher-level types used in our API Reference are mapped to
|
|
primitive XML-RPC types.
|
|
|
|
In our API Reference we specify the signatures of API functions in the following
|
|
style:
|
|
\begin{verbatim}
|
|
(ref_vm Set) VM.get_all()
|
|
\end{verbatim}
|
|
This specifies that the function with name {\tt VM.get\_all} takes
|
|
no parameters and returns a Set of {\tt ref\_vm}s.
|
|
These types are mapped onto XML-RPC types in a straight-forward manner:
|
|
\begin{itemize}
|
|
\item Floats, Bools, DateTimes and Strings map directly to the XML-RPC {\tt
|
|
double}, {\tt boolean}, {\tt dateTime.iso8601}, and {\tt string} elements.
|
|
|
|
\item all ``{\tt ref\_}'' types are opaque references, encoded as the
|
|
XML-RPC's {\tt 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.
|
|
|
|
\item fields named ``{\tt uuid}'' of type ``{\tt String}'' are mapped to
|
|
the XML-RPC {\tt String} type. The string itself is the OSF
|
|
DCE UUID presentation format (as output by {\tt uuidgen}, etc).
|
|
|
|
\item ints 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 {\tt
|
|
i4} type).
|
|
|
|
\item values of enum types are encoded as strings. For example, a value of
|
|
{\tt destroy} of type {\tt on\_normal\_exit}, would be conveyed as:
|
|
\begin{verbatim}
|
|
<value><string>destroy</string></value>
|
|
\end{verbatim}
|
|
|
|
\item for all our types, {\tt t}, our type {\tt t Set} simply maps to
|
|
XML-RPC's {\tt Array} type, so for example a value of type {\tt cpu\_feature
|
|
Set} would be transmitted like this:
|
|
|
|
\begin{verbatim}
|
|
<array>
|
|
<data>
|
|
<value><string>CX8</string></value>
|
|
<value><string>PSE36</string></value>
|
|
<value><string>FPU</string></value>
|
|
</data>
|
|
</array>
|
|
\end{verbatim}
|
|
|
|
\item for types {\tt k} and {\tt v}, our type {\tt (k, v) Map} maps onto an
|
|
XML-RPC struct, with the key as the name of the struct. Note that the {\tt
|
|
(k, v) Map} type is only valid when {\tt k} is a {\tt String}, {\tt Ref}, or
|
|
{\tt Int}, and in each case the keys of the maps are stringified as
|
|
above. For example, the {\tt (String, double) Map} containing a the mappings
|
|
Mike $\rightarrow$ 2.3 and John $\rightarrow$ 1.2 would be represented as:
|
|
|
|
\begin{verbatim}
|
|
<value>
|
|
<struct>
|
|
<member>
|
|
<name>Mike</name>
|
|
<value><double>2.3</double></value>
|
|
</member>
|
|
<member>
|
|
<name>John</name>
|
|
<value><double>1.2</double></value>
|
|
</member>
|
|
</struct>
|
|
</value>
|
|
\end{verbatim}
|
|
|
|
\item our {\tt Void} type is transmitted as an empty string.
|
|
|
|
\end{itemize}
|
|
|
|
\subsection{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 {\tt 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:
|
|
\begin{itemize}
|
|
\item A ``{\tt get\_by\_uuid}'' method that takes a UUID, $u$, and returns an opaque reference
|
|
to the server-side object that has UUID=$u$;
|
|
\item A {\tt get\_uuid} function (a regular ``field getter'' RPC) that takes an opaque reference,
|
|
$r$, and returns the UUID of the server-side object that is referenced by $r$.
|
|
\end{itemize}
|
|
|
|
\subsection{Return Values/Status Codes}
|
|
\label{synchronous-result}
|
|
|
|
The return value of an RPC call is an XML-RPC {\tt Struct}.
|
|
|
|
\begin{itemize}
|
|
\item The first element of the struct is named {\tt Status}; it
|
|
contains a string value indicating whether the result of the call was
|
|
a ``{\tt Success}'' or a ``{\tt Failure}''.
|
|
\end{itemize}
|
|
|
|
If {\tt Status} was set to {\tt Success} then the Struct contains a second
|
|
element named {\tt Value}:
|
|
\begin{itemize}
|
|
\item The element of the struct named {\tt Value} contains the function's return value.
|
|
\end{itemize}
|
|
|
|
In the case where {\tt Status} is set to {\tt Failure} then
|
|
the struct contains a second element named {\tt ErrorDescription}:
|
|
\begin{itemize}
|
|
\item The element of the struct named {\tt 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.
|
|
\end{itemize}
|
|
|
|
For example, an XML-RPC return value from the {\tt host.get\_resident\_VMs}
|
|
function above
|
|
may look like this:
|
|
\begin{verbatim}
|
|
<struct>
|
|
<member>
|
|
<name>Status</name>
|
|
<value>Success</value>
|
|
</member>
|
|
<member>
|
|
<name>Value</name>
|
|
<value>
|
|
<array>
|
|
<data>
|
|
<value>81547a35-205c-a551-c577-00b982c5fe00</value>
|
|
<value>61c85a22-05da-b8a2-2e55-06b0847da503</value>
|
|
<value>1d401ec4-3c17-35a6-fc79-cee6bd9811fe</value>
|
|
</data>
|
|
</array>
|
|
</value>
|
|
</member>
|
|
</struct>
|
|
\end{verbatim}
|
|
|
|
\section{Making XML-RPC Calls}
|
|
|
|
\subsection{Transport Layer}
|
|
|
|
The following transport layers are currently supported:
|
|
\begin{itemize}
|
|
\item HTTP/S for remote administration
|
|
\item HTTP over Unix domain sockets for local administration
|
|
\end{itemize}
|
|
|
|
\subsection{Session Layer}
|
|
|
|
The XML-RPC interface is session-based; before you can make arbitrary RPC calls
|
|
you must login and initiate a session. For example:
|
|
\begin{verbatim}
|
|
session_id session.login_with_password(string uname, string pwd)
|
|
\end{verbatim}
|
|
Where {\tt uname} and {\tt password} refer to your username and password
|
|
respectively, as defined by the Xen administrator.
|
|
The {\tt session\_id} returned by {\tt session.login\_with\_password} is passed
|
|
to subsequent RPC calls as an authentication token.
|
|
|
|
A session can be terminated with the {\tt session.logout} function:
|
|
\begin{verbatim}
|
|
void session.logout(session_id session)
|
|
\end{verbatim}
|
|
|
|
\subsection{Synchronous and Asynchronous invocation}
|
|
|
|
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 in Section~\ref{synchronous-result}.
|
|
|
|
Only synchronous API calls are listed explicitly in this document.
|
|
All asynchronous versions are in the special {\tt Async} namespace.
|
|
For example, synchronous call {\tt VM.clone(...)}
|
|
(described in Chapter~\ref{api-reference})
|
|
has an asynchronous counterpart, {\tt
|
|
Async.VM.clone(...)}, that is non-blocking.
|
|
|
|
Instead of returning its result directly, an asynchronous RPC call
|
|
returns a {\tt task-id}; this identifier is subsequently used
|
|
to track the status of a running asynchronous RPC. Note that an asynchronous
|
|
call may fail immediately, before a {\tt task-id} has even been created---to
|
|
represent this eventuality, the returned {\tt task-id}
|
|
is wrapped in an XML-RPC struct with a {\tt Status}, {\tt ErrorDescription} and
|
|
{\tt Value} fields, exactly as specified in Section~\ref{synchronous-result}.
|
|
|
|
The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set to
|
|
{\tt Success}.
|
|
|
|
The RPC call
|
|
\begin{verbatim}
|
|
(ref_task Set) Task.get_all(session_id s)
|
|
\end{verbatim}
|
|
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.
|
|
|
|
\section{Example interactive session}
|
|
This section describes how an interactive session might look, using
|
|
the python API. All python versions starting from 2.4 should work.
|
|
|
|
The examples in this section use a remote Xen host with the ip address
|
|
of \texttt{192.168.7.20} and the xmlrpc port \texttt{9363}. No
|
|
authentication is used.
|
|
|
|
Note that the remote server must be configured in the way, that it
|
|
accepts remote connections. Some lines must be added to the
|
|
xend-config.sxp configuration file:
|
|
\begin{verbatim}
|
|
(xen-api-server ((9363 none)
|
|
(unix none)))
|
|
(xend-tcp-xmlrpc-server yes)
|
|
\end{verbatim}
|
|
The xend must be restarted after changing the configuration.
|
|
|
|
Before starting python, the \texttt{PYTHONPATH} must be set that the
|
|
\texttt{XenAPI.py} can be found. Typically the \texttt{XenAPI.py} is
|
|
installed with one of the Xen helper packages which the last part of
|
|
the path is \texttt{xen/xm/XenAPI.py}.
|
|
|
|
Example: Under Debian 5.0 the package which contains the
|
|
\texttt{XenAPI.py} is \texttt{xen-utils-3.2-1}. \texttt{XenAPI.py} is
|
|
located in \texttt{/usr/lib/xen-3.2-1/lib/python/xen/xm}. The
|
|
following command will set the \texttt{PYTHONPATH} environment
|
|
variable in a bash:
|
|
|
|
\begin{verbatim}
|
|
$ export PYTHONPATH=/usr/lib/xen-3.2-1/lib/python
|
|
\end{verbatim}
|
|
|
|
Then python can be started and the XenAPI must be imported:
|
|
|
|
\begin{verbatim}
|
|
$ python
|
|
...
|
|
>>> import xen.xm.XenAPI
|
|
\end{verbatim}
|
|
|
|
To create a session to the remote server, the
|
|
\texttt{xen.xm.XenAPI.Session} constructor is used:
|
|
\begin{verbatim}
|
|
>>> session = xen.xm.XenAPI.Session("http://192.168.7.20:9363")
|
|
\end{verbatim}
|
|
|
|
For authentication with a username and password the
|
|
\texttt{login\_with\_password} is used:
|
|
\begin{verbatim}
|
|
>>> session.login_with_password("", "")
|
|
\end{verbatim}
|
|
|
|
When serialised, this call looks like:
|
|
\begin{verbatim}
|
|
POST /RPC2 HTTP/1.0
|
|
Host: 192.168.7.20:9363
|
|
User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
|
|
Content-Type: text/xml
|
|
Content-Length: 221
|
|
|
|
<?xml version='1.0'?>
|
|
<methodCall>
|
|
<methodName>session.login_with_password</methodName>
|
|
<params>
|
|
<param>
|
|
<value><string></string></value>
|
|
</param>
|
|
<param>
|
|
<value><string></string></value>
|
|
</param>
|
|
</params>
|
|
</methodCall>
|
|
\end{verbatim}
|
|
|
|
And the response:
|
|
\begin{verbatim}
|
|
HTTP/1.1 200 OK
|
|
Server: BaseHTTP/0.3 Python/2.5.2
|
|
Date: Fri, 10 Jul 2009 09:01:27 GMT
|
|
Content-Type: text/xml
|
|
Content-Length: 313
|
|
|
|
<?xml version='1.0'?>
|
|
<methodResponse>
|
|
<params>
|
|
<param>
|
|
<value><struct>
|
|
<member>
|
|
<name>Status</name>
|
|
<value><string>Success</string></value>
|
|
</member>
|
|
<member>
|
|
<name>Value</name>
|
|
<value><string>68e3a009-0249-725b-246b-7fc43cf4f154</string></value>
|
|
</member>
|
|
</struct></value>
|
|
</param>
|
|
</params>
|
|
</methodResponse>
|
|
\end{verbatim}
|
|
|
|
Next, the user may acquire a list of all the VMs known to the host:
|
|
|
|
\begin{verbatim}
|
|
>>> vms = session.xenapi.VM.get_all()
|
|
>>> vms
|
|
['00000000-0000-0000-0000-000000000000', 'b28e4ee3-216f-fa85-9cae-615e954dbbe7']
|
|
\end{verbatim}
|
|
|
|
The VM references here have the form of an uuid, though they may
|
|
change in the future, and they should be treated as opaque strings.
|
|
|
|
Some examples of using accessors for object fields:
|
|
\begin{verbatim}
|
|
>>> session.xenapi.VM.get_name_label(vms[1])
|
|
'guest002'
|
|
>>> session.xenapi.VM.get_actions_after_reboot(vms[1])
|
|
'restart'
|
|
\end{verbatim}
|
|
|
|
Grab the actual memory and cpu utilisation of one vm:
|
|
\begin{verbatim}
|
|
>>> m = session.xenapi.VM.get_metrics(vms[1])
|
|
>>> session.xenapi.VM_metrics.get_memory_actual(m)
|
|
'268435456'
|
|
>>> session.xenapi.VM_metrics.get_VCPUs_utilisation(m)
|
|
{'0': 0.00041759955632935362}
|
|
\end{verbatim}
|
|
(The virtual machine has about 256 MByte RAM and is idle.)
|
|
|
|
Pausing and unpausing a vm:
|
|
\begin{verbatim}
|
|
>>> session.xenapi.VM.pause(vms[1])
|
|
''
|
|
>>> session.xenapi.VM.unpause(vms[1])
|
|
''
|
|
\end{verbatim}
|
|
|
|
Trying to start an vm:
|
|
\begin{verbatim}
|
|
>>> session.xenapi.VM.start(vms[1], False)
|
|
...
|
|
: Xen-API failure: ['VM_BAD_POWER_STATE', \
|
|
'b28e4ee3-216f-fa85-9cae-615e954dbbe7', 'Halted', 'Running']
|
|
\end{verbatim}
|
|
|
|
In this case the {\tt start} message has been rejected, because the VM is
|
|
already running, 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.
|