Difference between revisions of "GuestAgentXenStoreCommunication"
Line 60: | Line 60: | ||
<pre><nowiki> | <pre><nowiki> | ||
− | + | def __init__(self, dom_id): | |
self.dom_id = dom_id | self.dom_id = dom_id | ||
uuid = pick_unique_id | uuid = pick_unique_id | ||
Line 66: | Line 66: | ||
self.response_path = "/local/domain/%d/data/guest/%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) | # Convert data for stuffing into XenStore (this currently should convert a dict to JSON) | ||
encoded_data = self.encode_data(command_dict) | encoded_data = self.encode_data(command_dict) | ||
`xenstore-write self.request_path % (self.dom_id, self.uuid) encoded_data` | `xenstore-write self.request_path % (self.dom_id, self.uuid) encoded_data` | ||
− | + | def recv_response(self) | |
do_while_some_timer(): | do_while_some_timer(): | ||
if data = `xenstore-read self.response_path` succeeds: | if data = `xenstore-read self.response_path` succeeds: |
Revision as of 20:42, 27 December 2010
- Launchpad Entry:
- Created: ChrisBehrens
- Contributors:
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.
User stories
Assumptions
An agent is installed into the guest to communicate. See <a href="/GuestAgent">the GuestAgent wiki entry</a> to find more information about the agent and currently supported commands.
Design
On dom0, requests are pushed into a path named /local/domain/<dom-id>/data/host/<UUID>.
<
>
When a response is returned, /local/domain/<dom-id>/data/guest/<UUID> will exist and contain the response.
(Note that the guest side sees these paths as /data/host/<UUID> and /data/guest/<UUID>.)
The <domid> can be obtained by running:
xe vm-list Find the UUID of the guest in question and run: xe vm-param-get uuid=<uuid> param-name=dom-id
<UUID> 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": "<command_name>", "value": "<command_arguments>"}"
Responses have the format of:
"{ "returncode": "<value>", "message": "<value>" }"
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
For now, it will be easiest to exec the xen utilties named 'xenstore-write', 'xenstore-read', and 'xenstore-rm'. 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 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) `xenstore-write self.request_path % (self.dom_id, self.uuid) encoded_data` def recv_response(self) do_while_some_timer(): if data = `xenstore-read self.response_path` succeeds: `xenstore-rm 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:
xenstore-write /local/domain/<dom_id>/host/TEST_REQUEST1 "{ 'name': 'version', 'value:' 'agent' }" repeat until response is found: xenstore-read /local/domain/<dom_id>/guest/TEST_REQUEST1 xenstore-rm /local/domain/<dom_id>/guest/TEST_REQUEST1