summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Kearney <josh.kearney@rackspace.com>2010-12-21 14:13:18 -0600
committerJosh Kearney <josh.kearney@rackspace.com>2010-12-21 14:13:18 -0600
commitb3fce81e384aec46c0963db1f144cc58d02340a4 (patch)
treef5b5cb1ac00c28f2f637c858b1f1e7b72359b541
parentd2eb04cea6b7f0a669758fc1fba32e77a008a7eb (diff)
downloadnova-b3fce81e384aec46c0963db1f144cc58d02340a4.tar.gz
nova-b3fce81e384aec46c0963db1f144cc58d02340a4.tar.xz
nova-b3fce81e384aec46c0963db1f144cc58d02340a4.zip
Log all XenAPI actions
-rw-r--r--nova/db/api.py5
-rw-r--r--nova/db/sqlalchemy/api.py12
-rw-r--r--nova/db/sqlalchemy/models.py1
-rw-r--r--nova/virt/xenapi/vmops.py16
-rw-r--r--nova/virt/xenapi_conn.py33
5 files changed, 48 insertions, 19 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index 8f9dc2443..4e15596d9 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -334,6 +334,11 @@ def instance_add_security_group(context, instance_id, security_group_id):
security_group_id)
+def instance_action_create(context, values):
+ """Create an instance action from the values dictionary."""
+ return IMPL.instance_action_create(context, values)
+
+
###################
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index 935063609..63b367d2e 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -749,6 +749,18 @@ def instance_add_security_group(context, instance_id, security_group_id):
instance_ref.save(session=session)
+@require_context
+def instance_action_create(context, values):
+ """Create an instance action and the action results"""
+ action_ref = models.InstanceActions()
+ action_ref.update(values)
+
+ session = get_session()
+ with session.begin():
+ action_ref.save(session=session)
+ return action_ref
+
+
###################
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 96d981571..eac6a304e 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -248,7 +248,6 @@ class InstanceActions(BASE, NovaBase):
instance_id = Column(Integer, ForeignKey('instances.id'))
action = Column(String(255))
- result = Column(Boolean)
error = Column(Text)
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index bedf131df..5b9495b67 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -87,7 +87,7 @@ class VMOps(object):
if vm is None:
raise Exception('instance not present %s' % instance_name)
task = self._session.call_xenapi('Async.VM.clean_reboot', vm)
- self._session.wait_for_task(task)
+ self._session.wait_for_task(instance.id, task)
def destroy(self, instance):
"""Destroy VM instance"""
@@ -101,7 +101,7 @@ class VMOps(object):
try:
task = self._session.call_xenapi('Async.VM.hard_shutdown',
vm)
- self._session.wait_for_task(task)
+ self._session.wait_for_task(instance.id, task)
except XenAPI.Failure, exc:
logging.warn(exc)
# Disk clean-up
@@ -109,19 +109,19 @@ class VMOps(object):
for vdi in vdis:
try:
task = self._session.call_xenapi('Async.VDI.destroy', vdi)
- self._session.wait_for_task(task)
+ self._session.wait_for_task(instance.id, task)
except XenAPI.Failure, exc:
logging.warn(exc)
try:
task = self._session.call_xenapi('Async.VM.destroy', vm)
- self._session.wait_for_task(task)
+ self._session.wait_for_task(instance.id, task)
except XenAPI.Failure, exc:
logging.warn(exc)
- def _wait_with_callback(self, task, callback):
+ def _wait_with_callback(self, instance_id, task, callback):
ret = None
try:
- ret = self._session.wait_for_task(task)
+ ret = self._session.wait_for_task(instance_id, task)
except XenAPI.Failure, exc:
logging.warn(exc)
callback(ret)
@@ -133,7 +133,7 @@ class VMOps(object):
if vm is None:
raise Exception('instance not present %s' % instance_name)
task = self._session.call_xenapi('Async.VM.pause', vm)
- self._wait_with_callback(task, callback)
+ self._wait_with_callback(instance.id, task, callback)
def unpause(self, instance, callback):
"""Unpause VM instance"""
@@ -142,7 +142,7 @@ class VMOps(object):
if vm is None:
raise Exception('instance not present %s' % instance_name)
task = self._session.call_xenapi('Async.VM.unpause', vm)
- self._wait_with_callback(task, callback)
+ self._wait_with_callback(instance.id, task, callback)
def get_info(self, instance_id):
"""Return data about VM instance"""
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 3a9084d89..33a55d7b2 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -54,6 +54,8 @@ import xmlrpclib
from eventlet import event
from eventlet import tpool
+from nova import context
+from nova import db
from nova import utils
from nova import flags
from nova.virt.xenapi.vmops import VMOps
@@ -183,35 +185,46 @@ class XenAPISession(object):
self._session.xenapi.Async.host.call_plugin,
self.get_xenapi_host(), plugin, fn, args)
- def wait_for_task(self, task):
+ def wait_for_task(self, instance_id, task):
"""Return a Deferred that will give the result of the given task.
The task is polled until it completes."""
done = event.Event()
- loop = utils.LoopingCall(self._poll_task, task, done)
+ loop = utils.LoopingCall(self._poll_task, instance_id, task, done)
loop.start(FLAGS.xenapi_task_poll_interval, now=True)
rv = done.wait()
loop.stop()
return rv
- def _poll_task(self, task, done):
+ def _poll_task(self, instance_id, task, done):
"""Poll the given XenAPI task, and fire the given Deferred if we
get a result."""
try:
- #logging.debug('Polling task %s...', task)
+ name = self._session.xenapi.task.get_name_label(task)
status = self._session.xenapi.task.get_status(task)
- if status == 'pending':
+ action = dict(
+ instance_id=int(instance_id),
+ action=name,
+ error=None)
+ if status == "pending":
return
- elif status == 'success':
+ elif status == "success":
result = self._session.xenapi.task.get_result(task)
- logging.info('Task %s status: success. %s', task, result)
+ logging.info("Task [%s] %s status: success %s" % (
+ name,
+ task,
+ result))
done.send(_parse_xmlrpc_value(result))
else:
error_info = self._session.xenapi.task.get_error_info(task)
- logging.warn('Task %s status: %s. %s', task, status,
- error_info)
+ action["error"] = str(error_info)
+ logging.warn("Task [%s] %s status: %s %s" % (
+ name,
+ task,
+ status,
+ error_info))
done.send_exception(XenAPI.Failure(error_info))
- #logging.debug('Polling task %s done.', task)
+ db.instance_action_create(context.get_admin_context(), action)
except XenAPI.Failure, exc:
logging.warn(exc)
done.send_exception(*sys.exc_info())