Jump to: navigation, search

Difference between revisions of "GuestAgentXenStoreCommunication"

m (Text replace - "__NOTOC__" to "")
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
__NOTOC__
+
 
 
* '''Launchpad Entry''':
 
* '''Launchpad Entry''':
* '''Created''': [[ChrisBehrens]]
+
* '''Created''': 12/27/2010
* '''Contributors''':  
+
* '''Contributors''': [[ChrisBehrens]]
  
 
== Summary ==
 
== Summary ==
Line 20: Line 20:
 
== Assumptions ==
 
== 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.
+
An agent is installed into the guest to communicate.  See the [[GuestAgent]] wiki entry</a> to find more information about the agent and currently supported commands.
  
 
== Design ==
 
== 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.
 +
<<BR>>
 +
As far as the details on the communication:
  
 
On dom0, requests are pushed into a path named /local/domain/<dom-id>/data/host/<UUID>.
 
On dom0, requests are pushed into a path named /local/domain/<dom-id>/data/host/<UUID>.
Line 28: Line 32:
 
When a response is returned, /local/domain/<dom-id>/data/guest/<UUID> will exist and contain the response.
 
When a response is returned, /local/domain/<dom-id>/data/guest/<UUID> will exist and contain the response.
  
The <domid> can be obtained by running:
+
(Note that the guest side sees these paths as /data/host/<UUID> and /data/guest/<UUID>.)
 
 
xe vm-list
 
Find the UUID of the guest in question and run:
 
xe vm-param-get uuid=<uuid> param-name=dom-id
 
  
 +
The <dom-id> is the xen domain number, and will need to be obtained in some way.  The "xe way" is listed below under tests.
 
<UUID> is some unique identifer.  The agent currently doesn't check the format of this UUID.
 
<UUID> is some unique identifer.  The agent currently doesn't check the format of this UUID.
  
Line 52: Line 53:
 
== Implementation ==
 
== 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.
+
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 which contain something like:
+
One could stub out a quick python class for [[XenStore]] communication to the guests from the compute node which contain something like:
  
  
 
<pre><nowiki>
 
<pre><nowiki>
sub __init__(self, dom_id):
+
def __init__(self, dom_id):
 
   self.dom_id = dom_id
 
   self.dom_id = dom_id
 
   uuid = pick_unique_id
 
   uuid = pick_unique_id
Line 64: Line 65:
 
   self.response_path = "/local/domain/%d/data/guest/%s" % (dom_id, uuid)
 
   self.response_path = "/local/domain/%d/data/guest/%s" % (dom_id, uuid)
  
sub send_request(self, command_dict):
+
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`
+
   XenAPI.write_to_xenstore(self.request_path, encoded_data)
  
sub recv_response(self)
+
def recv_response(self)
 
   do_while_some_timer():
 
   do_while_some_timer():
     if data = `xenstore-read self.response_path` succeeds:
+
     if (data = XenAPI.read_from_xenstore(self.response_path)) succeeds:
       `xenstore-rm self.response_path`
+
       XenAPI.rm_from_xenstore(self.response_path)
 
       return self.decode_data(data)
 
       return self.decode_data(data)
 
   return {}
 
   return {}
Line 86: Line 87:
  
 
<pre><nowiki>
 
<pre><nowiki>
 +
# Find a <dom_id>
 +
xe vm-list
 +
# Find the UUID of the guest in question and run:
 +
xe vm-param-get uuid=<uuid> param-name=dom-id
 +
 
xenstore-write /local/domain/<dom_id>/host/TEST_REQUEST1 "{ 'name': 'version', 'value:' 'agent' }"
 
xenstore-write /local/domain/<dom_id>/host/TEST_REQUEST1 "{ 'name': 'version', 'value:' 'agent' }"
 
repeat until response is found:
 
repeat until response is found:
xenstore-read /local/domain/<dom_id>/guest/TEST_REQUEST1
+
  xenstore-read /local/domain/<dom_id>/guest/TEST_REQUEST1
 
xenstore-rm /local/domain/<dom_id>/guest/TEST_REQUEST1
 
xenstore-rm /local/domain/<dom_id>/guest/TEST_REQUEST1
 
</nowiki></pre>
 
</nowiki></pre>

Latest revision as of 23:29, 17 February 2013

  • 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.

User stories

Assumptions

An agent is installed into the guest to communicate. See the GuestAgent wiki entry</a> 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/<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 <dom-id> is the xen domain number, and will need to be obtained in some way. The "xe way" is listed below under tests. <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

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:


# Find a <dom_id>
xe vm-list
# Find the UUID of the guest in question and run:
xe vm-param-get uuid=<uuid> param-name=dom-id

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


Unresolved issues

BoF agenda and discussion