summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoren Hansen <soren.hansen@rackspace.com>2010-09-20 11:46:18 +0200
committerSoren Hansen <soren.hansen@rackspace.com>2010-09-20 11:46:18 +0200
commita3d003d7ec92f3ae23a667954a790c71efdbfdbe (patch)
treebb5d3f313107a017459b4d4caf4f52527ffa128c
parent75a1815aa2724d64d1f487996265ba9136017029 (diff)
Move the code that extracts the console output into the virt drivers. Move the code that formats it up into the API layer. Add support for Xen console.
-rw-r--r--nova/compute/manager.py18
-rw-r--r--nova/endpoint/cloud.py15
-rw-r--r--nova/virt/fake.py2
-rw-r--r--nova/virt/libvirt_conn.py40
-rw-r--r--nova/virt/xenapi.py3
5 files changed, 56 insertions, 22 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index ae7099812..9f5674be2 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -144,26 +144,10 @@ class ComputeManager(manager.Manager):
@exception.wrap_exception
def get_console_output(self, context, instance_id):
"""Send the console output for an instance."""
- # TODO(vish): Move this into the driver layer
-
logging.debug("instance %s: getting console output", instance_id)
instance_ref = self.db.instance_get(context, instance_id)
- if FLAGS.connection_type == 'libvirt':
- fname = os.path.abspath(os.path.join(FLAGS.instances_path,
- instance_ref['str_id'],
- 'console.log'))
- with open(fname, 'r') as f:
- output = f.read()
- else:
- output = 'FAKE CONSOLE OUTPUT'
-
- # TODO(termie): this stuff belongs in the API layer, no need to
- # munge the data we send to ourselves
- output = {"InstanceId": instance_id,
- "Timestamp": "2",
- "output": base64.b64encode(output)}
- return output
+ return self.driver.get_console_output(instance_ref)
@defer.inlineCallbacks
@exception.wrap_exception
diff --git a/nova/endpoint/cloud.py b/nova/endpoint/cloud.py
index 622b4e2a4..a55c00a0d 100644
--- a/nova/endpoint/cloud.py
+++ b/nova/endpoint/cloud.py
@@ -233,11 +233,16 @@ class CloudController(object):
def get_console_output(self, context, instance_id, **kwargs):
# instance_id is passed in as a list of instances
instance_ref = db.instance_get_by_str(context, instance_id[0])
- return rpc.call('%s.%s' % (FLAGS.compute_topic,
- instance_ref['host']),
- {"method": "get_console_output",
- "args": {"context": None,
- "instance_id": instance_ref['id']}})
+ d = rpc.call('%s.%s' % (FLAGS.compute_topic,
+ instance_ref['host']),
+ { "method" : "get_console_output",
+ "args" : { "context": None,
+ "instance_id": instance_ref['id']}})
+
+ d.addCallback(lambda output: { "InstanceId": instance_id,
+ "Timestamp": "2",
+ "output": base64.b64encode(output)})
+ return d
@rbac.allow('projectmanager', 'sysadmin')
def describe_volumes(self, context, **kwargs):
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 4ae6afcc4..dc6112f20 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -223,6 +223,8 @@ class FakeConnection(object):
"""
return [0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L]
+ def get_console_output(self, instance):
+ return 'FAKE CONSOLE OUTPUT'
class FakeInstance(object):
def __init__(self):
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 09f178c2a..addd9c997 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -248,6 +248,46 @@ class LibvirtConnection(object):
timer.start(interval=0.5, now=True)
yield local_d
+ def _flush_xen_console(self, virsh_output):
+ logging.info('virsh said: %r' % (virsh_output,))
+ virsh_output = virsh_output[0].strip()
+
+ if virsh_output.startswith('/dev/'):
+ logging.info('cool, it\'s a device')
+ d = process.simple_execute("sudo dd if=%s iflag=nonblock" % virsh_output, check_exit_code=False)
+ d.addCallback(lambda r:r[0])
+ return d
+ else:
+ return ''
+
+ def _append_to_file(self, data, fpath):
+ logging.info('data: %r, fpath: %r' % (data, fpath))
+ fp = open(fpath, 'a+')
+ fp.write(data)
+ return fpath
+
+ def _dump_file(self, fpath):
+ fp = open(fpath, 'r+')
+ contents = fp.read()
+ logging.info('Contents: %r' % (contents,))
+ return contents
+
+ @exception.wrap_exception
+ def get_console_output(self, instance):
+ console_log = os.path.join(FLAGS.instances_path, instance['name'], 'console.log')
+ logging.info('console_log: %s' % console_log)
+ logging.info('FLAGS.libvirt_type: %s' % FLAGS.libvirt_type)
+ if FLAGS.libvirt_type == 'xen':
+ # Xen is spethial
+ d = process.simple_execute("virsh ttyconsole %s" % instance['name'])
+ d.addCallback(self._flush_xen_console)
+ d.addCallback(self._append_to_file, console_log)
+ else:
+ d = defer.succeed(console_log)
+ d.addCallback(self._dump_file)
+ return d
+
+
@defer.inlineCallbacks
def _create_image(self, inst, libvirt_xml):
# syntactic nicety
diff --git a/nova/virt/xenapi.py b/nova/virt/xenapi.py
index 1c6de4403..5fdd2b9fc 100644
--- a/nova/virt/xenapi.py
+++ b/nova/virt/xenapi.py
@@ -299,6 +299,9 @@ class XenAPIConnection(object):
'num_cpu': rec['VCPUs_max'],
'cpu_time': 0}
+ def get_console_output(self, instance):
+ return 'FAKE CONSOLE OUTPUT'
+
@utils.deferredToThread
def _lookup(self, i):
return self._lookup_blocking(i)