summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/virt/xenapi/vmops.py14
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/agent95
2 files changed, 12 insertions, 97 deletions
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 206970c35..c10943aa1 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -220,6 +220,9 @@ class VMOps(object):
dh = SimpleDH()
args = {'id': transaction_id, 'pub': str(dh.get_public())}
resp = self._make_agent_call('key_init', instance, '', args)
+ if resp is None:
+ # No response from the agent
+ return
resp_dict = json.loads(resp)
# Successful return code from key_init is 'D0'
if resp_dict['returncode'] != 'D0':
@@ -232,6 +235,9 @@ class VMOps(object):
# Send the encrypted password
args['enc_pass'] = enc_pass
resp = self._make_agent_call('password', instance, '', args)
+ if resp is None:
+ # No response from the agent
+ return
resp_dict = json.loads(resp)
# Successful return code from password is '0'
if resp_dict['returncode'] != '0':
@@ -384,12 +390,16 @@ class VMOps(object):
task = self._session.async_call_plugin(plugin, method, args)
ret = self._session.wait_for_task(instance_id, task)
except self.XenAPI.Failure, e:
+ ret = None
err_trace = e.details[-1]
err_msg = err_trace.splitlines()[-1]
+ strargs = str(args)
if 'TIMEOUT:' in err_msg:
- raise exception.TimeoutException(err_msg)
+ LOG.error(_('TIMEOUT: The call to %(method)s timed out. '
+ 'VM id=%(instance_id)s; args=%(strargs)s') % locals())
else:
- raise RuntimeError("%s" % e.details[-1])
+ LOG.error(_('The call to %(method)s returned an error: %(e)s. '
+ 'VM id=%(instance_id)s; args=%(strargs)s') % locals())
return ret
def add_to_xenstore(self, vm, path, key, value):
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
index 82dd5466e..12c3a19c8 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/agent
@@ -51,101 +51,6 @@ class TimeoutError(StandardError):
pass
-class SimpleDH(object):
- """This class wraps all the functionality needed to implement
- basic Diffie-Hellman-Merkle key exchange in Python. It features
- intelligent defaults for the prime and base numbers needed for the
- calculation, while allowing you to supply your own. It requires that
- the openssl binary be installed on the system on which this is run,
- as it uses that to handle the encryption and decryption. If openssl
- is not available, a RuntimeError will be raised.
-
- Please note that nova already uses the M2Crypto library for most
- cryptographic functions, and that it includes a Diffie-Hellman
- implementation. However, that is a much more complex implementation,
- and is not compatible with the DH algorithm that the agent uses. Hence
- the need for this 'simple' version.
- """
- def __init__(self, prime=None, base=None, secret=None):
- """You can specify the values for prime and base if you wish;
- otherwise, reasonable default values will be used.
- """
- if prime is None:
- self._prime = 162259276829213363391578010288127
- else:
- self._prime = prime
- if base is None:
- self._base = 5
- else:
- self._base = base
- if secret is None:
- self._secret = random.randint(5000, 15000)
- else:
- self._secret = secret
- self._shared = self._public = None
-
- def get_public(self):
- """Return the public key"""
- self._public = (self._base ** self._secret) % self._prime
- return self._public
-
- def compute_shared(self, other):
- """Given the other end's public key, compute the
- shared secret.
- """
- self._shared = (other ** self._secret) % self._prime
- return self._shared
-
- def _run_ssl(self, text, which):
- """The encryption/decryption methods require running the openssl
- installed on the system. This method abstracts out the common
- code required.
- """
- base_cmd = ("cat %(tmpfile)s | openssl enc -aes-128-cbc "
- "-a -pass pass:%(shared)s -nosalt %(dec_flag)s")
- if which.lower()[0] == "d":
- dec_flag = " -d"
- else:
- dec_flag = ""
- # Note: instead of using 'cat' and a tempfile, it is also
- # possible to just 'echo' the value. However, we can not assume
- # that the value is 'safe'; i.e., it may contain semi-colons,
- # octothorpes, or other characters that would not be allowed
- # in an 'echo' construct.
- fd, tmpfile = tempfile.mkstemp()
- os.close(fd)
- file(tmpfile, "w").write(text)
- shared = self._shared
- cmd = base_cmd % locals()
- try:
- return _run_command(cmd)
- except PluginError, e:
- raise RuntimeError("OpenSSL error: %s" % e)
-
- def encrypt(self, text):
- """Uses the shared key to encrypt the given text."""
- return self._run_ssl(text, "enc")
-
- def decrypt(self, text):
- """Uses the shared key to decrypt the given text."""
- return self._run_ssl(text, "dec")
-
-
-def _run_command(cmd):
- """Abstracts out the basics of issuing system commands. If the command
- returns anything in stderr, a PluginError is raised with that information.
- Otherwise, the output from stdout is returned.
- """
- pipe = subprocess.PIPE
- proc = subprocess.Popen([cmd], shell=True, stdin=pipe, stdout=pipe,
- stderr=pipe, close_fds=True)
- proc.wait()
- err = proc.stderr.read()
- if err:
- raise PluginError(err)
- return proc.stdout.read()
-
-
@jsonify
def key_init(self, arg_dict):
"""Handles the Diffie-Hellman key exchange with the agent to