summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-03-12 17:27:40 +0000
committerGerrit Code Review <review@openstack.org>2012-03-12 17:27:40 +0000
commit9b8275659b5de8c8291d64d48a11edd83a276837 (patch)
treedd40b777d5d2d1f1c6205c810e569ab125e951f3 /nova
parente9b3d432d3f85de330a2916c802c831ad8bc85ae (diff)
parente3f77127fe65872a81280061157512886b84d469 (diff)
downloadnova-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.py11
-rw-r--r--nova/tests/test_libvirt.py17
-rw-r--r--nova/virt/libvirt.xml.template23
-rw-r--r--nova/virt/libvirt/connection.py60
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)