mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
305 lines
11 KiB
TeX
305 lines
11 KiB
TeX
%
|
|
% Copyright (c) 2006-2007 XenSource, Inc.
|
|
%
|
|
% 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.
|
|
%
|
|
|
|
\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 subequent 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 asychronous
|
|
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
|
|
XML-RPC client library.
|
|
|
|
First, initialise python and import the library {\tt xmlrpclib}:
|
|
|
|
\begin{verbatim}
|
|
\$ python2.4
|
|
...
|
|
>>> import xmlrpclib
|
|
\end{verbatim}
|
|
|
|
Create a python object referencing the remote server:
|
|
|
|
\begin{verbatim}
|
|
>>> xen = xmlrpclib.Server("http://test:4464")
|
|
\end{verbatim}
|
|
|
|
Acquire a session token by logging in with a username and password
|
|
(error-handling ommitted for brevity; the session token is pointed to by the
|
|
key {\tt 'Value'} in the returned dictionary)
|
|
|
|
\begin{verbatim}
|
|
>>> session = session.login_with_password("user", "passwd")['Value']
|
|
\end{verbatim}
|
|
|
|
When serialised, this call looks like the following:
|
|
|
|
\begin{verbatim}
|
|
<?xml version='1.0'?>
|
|
<methodCall>
|
|
<methodName>session.login_with_password</methodName>
|
|
<params>
|
|
<param>
|
|
<value><string>user</string></value>
|
|
</param>
|
|
<param>
|
|
<value><string>passwd</string></value>
|
|
</param>
|
|
</params>
|
|
</methodCall>
|
|
\end{verbatim}
|
|
|
|
Next, the user may acquire a list of all the VMs known to the host: (Note the
|
|
call takes the session token as the only parameter)
|
|
|
|
\begin{verbatim}
|
|
>>> all_vms = host.get_resident_VMs(session)['Value']
|
|
>>> all_vms
|
|
['OpaqueRef:1', 'OpaqueRef:2', 'OpaqueRef:3', 'OpaqueRef:4' ]
|
|
\end{verbatim}
|
|
|
|
The VM references here have the form {\tt OpaqueRef:X}, though they may not be
|
|
that simple in the future, and you should treat them as opaque strings.
|
|
Once a reference to a VM has been acquired a lifecycle operation may be invoked:
|
|
|
|
\begin{verbatim}
|
|
>>> xen.VM.start(session, all_vms[3], False)
|
|
{'Status': 'Failure', 'ErrorDescription': ['VM_BAD_POWER_STATE', '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. Finally, here are some examples of
|
|
using accessors for object fields:
|
|
|
|
\begin{verbatim}
|
|
>>> xen.VM.get_name_label(session, all_vms[3])['Value']
|
|
'SMP'
|
|
>>> xen.VM.get_name_description(session, all_vms[3])['Value']
|
|
'Debian for Xen'
|
|
\end{verbatim}
|