diff options
author | Soren Hansen <soren.hansen@rackspace.com> | 2010-10-13 17:13:35 +0000 |
---|---|---|
committer | Tarmac <> | 2010-10-13 17:13:35 +0000 |
commit | a4aa6725be683e7e1f35df1e54069b755d19551b (patch) | |
tree | 5dada03ad0927ddc10c5dd5bbf78fb05fd006243 | |
parent | d68528b6135b407a7ce0897769d2d6bb92ec6be4 (diff) | |
parent | e2b7c99c6266b24dc8b53c47db3587aebd2381fe (diff) | |
download | nova-a4aa6725be683e7e1f35df1e54069b755d19551b.tar.gz nova-a4aa6725be683e7e1f35df1e54069b755d19551b.tar.xz nova-a4aa6725be683e7e1f35df1e54069b755d19551b.zip |
Xen support.
-rw-r--r-- | nova/api/ec2/cloud.py | 15 | ||||
-rw-r--r-- | nova/compute/manager.py | 18 | ||||
-rw-r--r-- | nova/fakerabbit.py | 1 | ||||
-rw-r--r-- | nova/tests/cloud_unittest.py | 1 | ||||
-rw-r--r-- | nova/virt/fake.py | 2 | ||||
-rw-r--r-- | nova/virt/libvirt.xen.xml.template | 30 | ||||
-rw-r--r-- | nova/virt/libvirt_conn.py | 48 | ||||
-rw-r--r-- | nova/virt/xenapi.py | 3 |
8 files changed, 94 insertions, 24 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 278055be1..a7693cadd 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -452,11 +452,16 @@ class CloudController(object): ec2_id = instance_id[0] internal_id = ec2_id_to_internal_id(ec2_id) instance_ref = db.instance_get_by_internal_id(context, internal_id) - return rpc.call('%s.%s' % (FLAGS.compute_topic, - instance_ref['host']), - {"method": "get_console_output", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + output = rpc.call('%s.%s' % (FLAGS.compute_topic, + instance_ref['host']), + { "method" : "get_console_output", + "args" : { "context": None, + "instance_id": instance_ref['id']}}) + + now = datetime.datetime.utcnow() + return { "InstanceId" : ec2_id, + "Timestamp" : now, + "output" : base64.b64encode(output) } def describe_volumes(self, context, **kwargs): if context.user.is_admin(): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index f36e14aa2..c602d013d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -149,26 +149,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['internal_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/fakerabbit.py b/nova/fakerabbit.py index 835973810..df5e61e6e 100644 --- a/nova/fakerabbit.py +++ b/nova/fakerabbit.py @@ -116,6 +116,7 @@ class Backend(object): message = Message(backend=self, body=message_data, content_type=content_type, content_encoding=content_encoding) + message.result = True logging.debug('Getting from %s: %s', queue, message) return message diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py index a880237f2..ff466135d 100644 --- a/nova/tests/cloud_unittest.py +++ b/nova/tests/cloud_unittest.py @@ -75,7 +75,6 @@ class CloudTestCase(test.TrialTestCase): proxy=self.network) self.network_consumer.attach_to_eventlet() - self.manager = manager.AuthManager() self.user = self.manager.create_user('admin', 'admin', 'admin', True) self.project = self.manager.create_project('proj', 'admin', 'proj') 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.xen.xml.template b/nova/virt/libvirt.xen.xml.template new file mode 100644 index 000000000..9677902c6 --- /dev/null +++ b/nova/virt/libvirt.xen.xml.template @@ -0,0 +1,30 @@ +<domain type='%(type)s'> + <name>%(name)s</name> + <os> + <type>linux</type> + <kernel>%(basepath)s/kernel</kernel> + <initrd>%(basepath)s/ramdisk</initrd> + <root>/dev/xvda1</root> + <cmdline>ro</cmdline> + </os> + <features> + <acpi/> + </features> + <memory>%(memory_kb)s</memory> + <vcpu>%(vcpus)s</vcpu> + <devices> + <disk type='file'> + <source file='%(basepath)s/disk'/> + <target dev='sda' /> + </disk> + <interface type='bridge'> + <source bridge='%(bridge_name)s'/> + <mac address='%(mac_address)s'/> + </interface> + <console type="file"> + <source path='%(basepath)s/console.log'/> + <target port='1'/> + </console> + </devices> +</domain> + diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index 94a36a530..ce97ef1eb 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -50,6 +50,9 @@ FLAGS = flags.FLAGS flags.DEFINE_string('libvirt_xml_template', utils.abspath('virt/libvirt.qemu.xml.template'), 'Libvirt XML Template for QEmu/KVM') +flags.DEFINE_string('libvirt_xen_xml_template', + utils.abspath('virt/libvirt.xen.xml.template'), + 'Libvirt XML Template for Xen') flags.DEFINE_string('libvirt_uml_xml_template', utils.abspath('virt/libvirt.uml.xml.template'), 'Libvirt XML Template for user-mode-linux') @@ -58,7 +61,7 @@ flags.DEFINE_string('injected_network_template', 'Template file for injected network') flags.DEFINE_string('libvirt_type', 'kvm', - 'Libvirt domain type (valid options are: kvm, qemu, uml)') + 'Libvirt domain type (valid options are: kvm, qemu, uml, xen)') flags.DEFINE_string('libvirt_uri', '', 'Override the default libvirt URI (which is dependent' @@ -110,6 +113,9 @@ class LibvirtConnection(object): if FLAGS.libvirt_type == 'uml': uri = FLAGS.libvirt_uri or 'uml:///system' template_file = FLAGS.libvirt_uml_xml_template + elif FLAGS.libvirt_type == 'xen': + uri = FLAGS.libvirt_uri or 'xen:///' + template_file = FLAGS.libvirt_xen_xml_template else: uri = FLAGS.libvirt_uri or 'qemu:///system' template_file = FLAGS.libvirt_xml_template @@ -249,6 +255,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['internal_id'], '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 118e0b687..04e830b64 100644 --- a/nova/virt/xenapi.py +++ b/nova/virt/xenapi.py @@ -294,6 +294,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) |