diff options
author | Jenkins <jenkins@review.openstack.org> | 2012-03-12 17:27:40 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2012-03-12 17:27:40 +0000 |
commit | 9b8275659b5de8c8291d64d48a11edd83a276837 (patch) | |
tree | dd40b777d5d2d1f1c6205c810e569ab125e951f3 /nova | |
parent | e9b3d432d3f85de330a2916c802c831ad8bc85ae (diff) | |
parent | e3f77127fe65872a81280061157512886b84d469 (diff) | |
download | nova-9b8275659b5de8c8291d64d48a11edd83a276837.tar.gz nova-9b8275659b5de8c8291d64d48a11edd83a276837.tar.xz nova-9b8275659b5de8c8291d64d48a11edd83a276837.zip |
Merge "Simply & unify console handling for libvirt drivers"
Diffstat (limited to 'nova')
-rw-r--r-- | nova/tests/fakelibvirt.py | 11 | ||||
-rw-r--r-- | nova/tests/test_libvirt.py | 17 | ||||
-rw-r--r-- | nova/virt/libvirt.xml.template | 23 | ||||
-rw-r--r-- | nova/virt/libvirt/connection.py | 60 |
4 files changed, 60 insertions, 51 deletions
diff --git a/nova/tests/fakelibvirt.py b/nova/tests/fakelibvirt.py index b8f9bb433..24ff5ae55 100644 --- a/nova/tests/fakelibvirt.py +++ b/nova/tests/fakelibvirt.py @@ -357,12 +357,17 @@ class Domain(object): function='0x1'/> </controller> %(nics)s + <serial type='file'> + <source path='dummy.log'/> + <target port='0'/> + </serial> <serial type='pty'> <source pty='/dev/pts/27'/> - <target port='0'/> + <target port='1'/> </serial> - <console type='pty'> - <target type='serial' port='0'/> + <console type='file'> + <source path='dummy.log'/> + <target port='0'/> </console> <input type='tablet' bus='usb'/> <input type='mouse' bus='ps2'/> diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index 672ab221d..8e7b69b84 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -879,6 +879,21 @@ class LibvirtConnTestCase(test.TestCase): check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) + if hypervisor_type in ['qemu', 'kvm']: + check = (lambda t: t.findall('./devices/serial')[0].get( + 'type'), 'file') + check_list.append(check) + check = (lambda t: t.findall('./devices/serial')[1].get( + 'type'), 'pty') + check_list.append(check) + check = (lambda t: t.findall('./devices/serial/source')[0].get( + 'path').split('/')[1], 'console.log') + check_list.append(check) + else: + check = (lambda t: t.find('./devices/console').get( + 'type'), 'pty') + check_list.append(check) + parameter = './devices/interface/filterref/parameter' common_checks = [ (lambda t: t.find('.').tag, 'domain'), @@ -888,8 +903,6 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.findall(parameter)[1].get('name'), 'DHCPSERVER'), (lambda t: _ipv4_like(t.findall(parameter)[1].get('value'), '192.168.*.1'), True), - (lambda t: t.find('./devices/serial/source').get( - 'path').split('/')[1], 'console.log'), (lambda t: t.find('./memory').text, '2097152')] if rescue: common_checks += [ diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index a3c6cc691..b3cc75580 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -162,21 +162,20 @@ #end if #end for - <!-- The order is significant here. File must be defined first --> - <serial type="file"> + +#if $type == 'qemu' or $type == 'kvm' + <!-- The QEMU 'pty' driver throws away any data if no + client app is connected. Thus we can't get away + with a single type=pty console. Instead we have + to configure two separate consoles. --> + <serial type='file'> <source path='${basepath}/console.log'/> - <target port='1'/> </serial> + <serial type='pty'/> +#else + <console type='pty'/> +#end if - <console type='pty' tty='/dev/pts/2'> - <source path='/dev/pts/2'/> - <target port='0'/> - </console> - - <serial type='pty'> - <source path='/dev/pts/2'/> - <target port='0'/> - </serial> #if $getVar('use_usb_tablet', True) and $type != 'lxc' and $type != 'xen' <input type='tablet' bus='usb'/> #end if diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 88922f11b..9d1713106 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -881,20 +881,13 @@ class LibvirtConnection(driver.ComputeDriver): timer = utils.LoopingCall(_wait_for_boot) return timer.start(interval=0.5, now=True) - def _flush_libvirt_console(self, virsh_output): - LOG.info(_('virsh said: %r'), virsh_output) - virsh_output = virsh_output[0].strip() - - if virsh_output.startswith('/dev/'): - LOG.info(_("cool, it's a device")) - out, err = utils.execute('dd', - 'if=%s' % virsh_output, - 'iflag=nonblock', - run_as_root=True, - check_exit_code=False) - return out - else: - return '' + def _flush_libvirt_console(self, pty): + out, err = utils.execute('dd', + 'if=%s' % pty, + 'iflag=nonblock', + run_as_root=True, + check_exit_code=False) + return out def _append_to_file(self, data, fpath): LOG.info(_('data: %(data)r, fpath: %(fpath)r') % locals()) @@ -910,29 +903,28 @@ class LibvirtConnection(driver.ComputeDriver): @exception.wrap_exception() def get_console_output(self, instance): + virt_dom = self._lookup_by_name(instance['name']) + xml = virt_dom.XMLDesc(0) + tree = ElementTree.fromstring(xml) + + # If the guest has a console logging to a file prefer to use that + node = tree.find("./devices/console[@type='file']/source") + if node is not None: + fpath = node.get("path") + return libvirt_utils.load_file(fpath) + + # else if there is a PTY, then try to read latest data from that + node = tree.find("./devices/console[@type='pty']/source") + if node is None: + raise exception.Error(_("Guest does not have a console available")) + + pty = node.get("path") + console_log = os.path.join(FLAGS.instances_path, instance['name'], 'console.log') - libvirt_utils.chown(console_log, os.getuid()) - - if FLAGS.libvirt_type == 'xen': - # Xen is special - virsh_output = utils.execute('virsh', - 'ttyconsole', - instance['name']) - data = self._flush_libvirt_console(virsh_output) - fpath = self._append_to_file(data, console_log) - elif FLAGS.libvirt_type == 'lxc': - # LXC is also special - virsh_output = utils.execute('virsh', - '-c', - 'lxc:///', - 'ttyconsole', - instance['name']) - data = self._flush_libvirt_console(virsh_output) - fpath = self._append_to_file(data, console_log) - else: - fpath = console_log + data = self._flush_libvirt_console(pty) + fpath = self._append_to_file(data, console_log) return libvirt_utils.load_file(fpath) |