GuestAgentXenStoreCommunication


 * Launchpad Entry:
 * Created: 12/27/2010
 * Contributors: ChrisBehrens

Summary
Rackspace uses XenStore to communicate with guest agents today. This spec describes that 'protocol'.

Release Note
No end-user impact should be noticed, other than the guest images should have a guest agent installed and this will be noticed in the process list. Under Linux, this agent is currently named 'agent-smith'.

Rationale
Initial guest communication for XenServer guests will be via XenStore in order to satisfy Rackspace requirements that the current Rackspace guest agents will function without changes.

Assumptions
An agent is installed into the guest to communicate. See the GuestAgent wiki entry to find more information about the agent and currently supported commands.

Design
The XenAPI needs to be extended to support generic xenstore read, write, and rm calls. The compute node will make XenAPI calls to talk to the live xenstore. <> As far as the details on the communication:

On dom0, requests are pushed into a path named /local/domain//data/host/. <> When a response is returned, /local/domain//data/guest/ will exist and contain the response.

(Note that the guest side sees these paths as /data/host/ and /data/guest/.)

The  is the xen domain number, and will need to be obtained in some way. The "xe way" is listed below under tests.  is some unique identifer. The agent currently doesn't check the format of this UUID.

The requests and responses are both encoded in JSON. The requests have the format of:

"{ "name": "", "value": ""}"

Responses have the format of:

"{ "returncode": " ", "message": " " }"

Most 'returncode's return a successful response as "0" except for the "keyinit" command which returns "D0" as success. Other values for 'returncode' are considered errors.

Implementation
As mentioned above, XenAPI needs to be extended. This could be done in the current nova plugin. For now, it will be easiest to exec the xen utilties named 'xenstore-write', 'xenstore-read', and 'xenstore-rm' from this plugin. Ultimately, there should be a Python binding for which you can make direct calls into libxenstore.so, but that can be done later.

One could stub out a quick python class for XenStore communication to the guests from the compute node which contain something like:

def __init__(self, dom_id): self.dom_id = dom_id uuid = pick_unique_id self.request_path = "/local/domain/%d/data/host/%s" % (dom_id, uuid) self.response_path = "/local/domain/%d/data/guest/%s" % (dom_id, uuid)

def send_request(self, command_dict): # Convert data for stuffing into XenStore (this currently should convert a dict to JSON) encoded_data = self.encode_data(command_dict) XenAPI.write_to_xenstore(self.request_path, encoded_data)

def recv_response(self) do_while_some_timer: if (data = XenAPI.read_from_xenstore(self.response_path)) succeeds: XenAPI.rm_from_xenstore(self.response_path) return self.decode_data(data) return {}

In a thread, one could then call send_request/recv_request... possibly the calls could be combined into one.

Test/Demo Plan
One can test via command line with a guest agent today by doing:

xe vm-list xe vm-param-get uuid= param-name=dom-id
 * 1) Find a 
 * 1) Find the UUID of the guest in question and run:

xenstore-write /local/domain//host/TEST_REQUEST1 "{ 'name': 'version', 'value:' 'agent' }" repeat until response is found: xenstore-read /local/domain//guest/TEST_REQUEST1 xenstore-rm /local/domain/<dom_id>/guest/TEST_REQUEST1