aboutsummaryrefslogtreecommitdiffstats
path: root/docs/xen-api/wire-protocol.tex
blob: dcb1a1c69dc6af8eb48d14de50e2cdd998bb5e48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
%
% 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.