To start off my blog here, I’ve put together a small example of how to use javascript to interact with an unmodified XenServer using the XMLRPC API. Mostly of the work is done by the awesome jquery library and a slightly modified jquery.rpc plugin. To illustrate the basics this demo will simply list the names of the VMs and templates that XenServer knows about – in subsequent posts I’ll put together some more interesting examples. A zip file containing the code can be found here.

The demo consists of an index html page which more-or-less just includes the two jquery files and the demo.js file. The simplest way of trying it out is to is to put the files onto the XenServer to be served by the integrated web server. This is done by creating the webserver root directory ‘/opt/xensource/www’ and copying the files in.  Alternatively, and more usefully, the files can be loaded locally from a file:// URI. However, this is more tricky because there may well be cross-site scripting protection built into the browser – certainly Firefox has this feature and there are commented-out lines in the demo files explaining how to deal with this.

I’ll just describe here the demo.js file. To talk to the XenServer, we must first create the jquery rpc object. In versions of XenServer prior to 5.0 the system.listMethods method was not implemented, so we have to explicitly list the methods that we’ll be using when creating the rpc object.

  rpc = <span class="code-keyword">new</span> $.rpc(
    actual_uri,
    <span class="code-quote">"xml"</span>,
    nextfn,
    <span class="code-keyword">null</span>,
    [<span class="code-quote">"session.login_with_password"</span>,<span class="code-quote">"VM.get_all_records"</span>]
  );

In this case, we’re only going to use two API calls. Of the other parameters, ‘actual_uri’ is the URI of the XenServer to connect to, and could be e.g. “http://<ip>/” if the files are not being hosted by XenServer, or simply “/” if they are. ‘nextfn’ is the function to call on successful creation of the rpc object. Once the object is initialised, we can call API functions:

<span class="code-keyword">var</span> session_result = rpc.session.login_with_password(username,password);

    <span class="code-keyword">if</span>(session_result.Status==<span class="code-quote">"Failure"</span>) {
      raise(<span class="code-quote">"Failed to log in"</span>);
    }
    mysession = session_result.result.Value;

When we first started investigating the javascript route to the API, we found that the parsing of the XMLRPC results was often very slow indeed. We tried a couple of methods for dealing with this – one interesting idea was to use an XSLT transform to turn the xmlrpc response into json, which worked well and significantly speeded up the processing time of calls that produced large results (e.g. VM.get_all_records). However, it was decided as a tradeoff between complexity and effectiveness that inside xapi itself we would put a little converter that translated the XMLRPC ‘result’ field into json, leaving it embedded in a small amount of xmlrpc to avoid adding an entirely new layer of logic into xapi. This had a huge impact on the speed of processing for very little code change. In order to access this semi-json API it’s a simple case of appending ‘/json’ to the URI used for the standard XMLRPC calls. I’ve added a ‘use_json’ field to the demo javascript as an example of how it’s used.

Next time I’ll explain how the event mechanism works, and how it can be used to keep an up-to-date cache of the entire XenServer database.