summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-09-26 15:33:52 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-09-26 15:42:52 +0000
commitfe478bd49f031d4f9edaa8def9737af85aef6be6 (patch)
treeb6600cba9e70a5e64ae7850b02a6738bc4045cec /plugins
parentc367fa5e4a5e4712bde9fc319ae6c2f4f2add606 (diff)
downloadnova-fe478bd49f031d4f9edaa8def9737af85aef6be6.tar.gz
nova-fe478bd49f031d4f9edaa8def9737af85aef6be6.tar.xz
nova-fe478bd49f031d4f9edaa8def9737af85aef6be6.zip
xenapi: increase timeout for resetnetwork agent request
Windows can take longer than the default 30 seconds for resetnetwork requests. Double the timeout for the command to 60 seconds, but add a flag so it can be changed without code changes in the future. At the same time, add a flag for all other agent requests too. Change-Id: Iba91c37fd5596ea0dd63c20f74925972df1ca715
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/agent34
1 files changed, 20 insertions, 14 deletions
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
index 1c6bf6610..c83cb1ace 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
@@ -40,7 +40,7 @@ from pluginlib_nova import *
configure_logging("agent")
import xenstore
-AGENT_TIMEOUT = 30
+DEFAULT_TIMEOUT = 30
class TimeoutError(StandardError):
@@ -49,12 +49,13 @@ class TimeoutError(StandardError):
def version(self, arg_dict):
"""Get version of agent."""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
arg_dict["value"] = json.dumps({"name": "version", "value": "agent"})
request_id = arg_dict["id"]
arg_dict["path"] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -66,6 +67,7 @@ def key_init(self, arg_dict):
info to be passed, such as passwords. Returns the shared
secret key value.
"""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
# WARNING: Some older Windows agents will crash if the public key isn't
# a string
pub = arg_dict["pub"]
@@ -74,7 +76,7 @@ def key_init(self, arg_dict):
arg_dict["path"] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -87,13 +89,14 @@ def password(self, arg_dict):
previous call to key_init. The encrypted password value should
be passed as the value for the 'enc_pass' key in arg_dict.
"""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
enc_pass = arg_dict["enc_pass"]
arg_dict["value"] = json.dumps({"name": "password", "value": enc_pass})
request_id = arg_dict["id"]
arg_dict["path"] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -103,12 +106,13 @@ def resetnetwork(self, arg_dict):
"""Writes a resquest to xenstore that tells the agent
to reset networking.
"""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
arg_dict['value'] = json.dumps({'name': 'resetnetwork', 'value': ''})
request_id = arg_dict['id']
arg_dict['path'] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -125,6 +129,7 @@ def inject_file(self, arg_dict):
need to test to determine if the file injection method on the agent has
been disabled, and raise a NotImplemented error if that is the case.
"""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
b64_path = arg_dict["b64_path"]
b64_file = arg_dict["b64_contents"]
request_id = arg_dict["id"]
@@ -151,7 +156,7 @@ def inject_file(self, arg_dict):
arg_dict["path"] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -160,6 +165,7 @@ def inject_file(self, arg_dict):
def agent_update(self, arg_dict):
"""Expects an URL and md5sum of the contents, then directs the agent to
update itself."""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
request_id = arg_dict["id"]
url = arg_dict["url"]
md5sum = arg_dict["md5sum"]
@@ -168,7 +174,7 @@ def agent_update(self, arg_dict):
arg_dict["path"] = "data/host/%s" % request_id
xenstore.write_record(self, arg_dict)
try:
- resp = _wait_for_agent(self, request_id, arg_dict)
+ resp = _wait_for_agent(self, request_id, arg_dict, timeout)
except TimeoutError, e:
raise PluginError(e)
return resp
@@ -176,6 +182,7 @@ def agent_update(self, arg_dict):
def _get_agent_features(self, arg_dict):
"""Return an array of features that an agent supports."""
+ timeout = int(arg_dict.pop('timeout', DEFAULT_TIMEOUT))
tmp_id = commands.getoutput("uuidgen")
dct = {}
dct.update(arg_dict)
@@ -183,7 +190,7 @@ def _get_agent_features(self, arg_dict):
dct["path"] = "data/host/%s" % tmp_id
xenstore.write_record(self, dct)
try:
- resp = _wait_for_agent(self, tmp_id, dct)
+ resp = _wait_for_agent(self, tmp_id, dct, timeout)
except TimeoutError, e:
raise PluginError(e)
response = json.loads(resp)
@@ -193,18 +200,17 @@ def _get_agent_features(self, arg_dict):
return {}
-def _wait_for_agent(self, request_id, arg_dict):
+def _wait_for_agent(self, request_id, arg_dict, timeout):
"""Periodically checks xenstore for a response from the agent.
The request is always written to 'data/host/{id}', and
the agent's response for that request will be in 'data/guest/{id}'.
- If no value appears from the agent within the time specified by
- AGENT_TIMEOUT, the original request is deleted and a TimeoutError
- is returned.
+ If no value appears from the agent within the timeout specified,
+ the original request is deleted and a TimeoutError is raised.
"""
arg_dict["path"] = "data/guest/%s" % request_id
arg_dict["ignore_missing_path"] = True
start = time.time()
- while time.time() - start < AGENT_TIMEOUT:
+ while time.time() - start < timeout:
ret = xenstore.read_record(self, arg_dict)
# Note: the response for None with be a string that includes
# double quotes.
@@ -219,7 +225,7 @@ def _wait_for_agent(self, request_id, arg_dict):
arg_dict["path"] = "data/host/%s" % request_id
xenstore.delete_record(self, arg_dict)
raise TimeoutError(_("TIMEOUT: No response from agent within"
- " %s seconds.") % AGENT_TIMEOUT)
+ " %s seconds.") % timeout)
if __name__ == "__main__":