Merge lp:~newell-jensen/maas/fix-1690781 into lp:~maas-committers/maas/trunk

Proposed by Newell Jensen
Status: Merged
Approved by: Newell Jensen
Approved revision: no longer in the source branch.
Merged at revision: 6056
Proposed branch: lp:~newell-jensen/maas/fix-1690781
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 35 lines (+14/-0)
2 files modified
src/provisioningserver/drivers/pod/tests/test_virsh.py (+4/-0)
src/provisioningserver/drivers/pod/virsh.py (+10/-0)
To merge this branch: bzr merge lp:~newell-jensen/maas/fix-1690781
Reviewer Review Type Date Requested Status
Данило Шеган (community) Approve
MAAS Maintainers Pending
Review via email: mp+324220@code.launchpad.net

Commit message

Raises VirshError if the `virsh domcapabilities --virttype kvm|qemu` command returns empty XML with a suggestion on how to potentially fix the situation.

To post a comment you must log in.
Revision history for this message
Newell Jensen (newell-jensen) wrote :

I was unable to reproduce this bug following the steps outlined in the bug report. Regardless of this fact, it is a good idea to test to see whether or not the XML is empty from running `virsh domcapabilities --virttype kvm|qemu` as a precaution since the bug reporters has run into this.

Revision history for this message
Данило Шеган (danilo) wrote :

It's really weird that you couldn't reproduce this.

If qemu-system-x86 package is not installed, there should be no /usr/bin/qemu-system-x86_64 emulator binary, and that's what domcapabilities uses to check for domain capabilities (or whatever architecture you've got if it's not x86_64).

I'll confirm this fixes it, though I fully suspect it does.

I'd also prefer a fix were self.run() raises an exception when the return code is not 0, but that would probably be a much bigger change that's not suitable for upcoming 2.2.

(I've added another review slot for myself since Andres mentioned that he wants others to confirm our reviews too)

Revision history for this message
Данило Шеган (danilo) wrote :

Unfortunately, this doesn't fix the problem: some parts of my analysis were incorrect.

Virsh driver is actually running virsh and then running individual commands in there, so the output is always the full error output and not just a newline (iow, it does "virsh qemu:..." and then runs individual commands like "domcapabilities" there). So it still fails with the same error.

This means that we can't rely on virsh exit code either, so it seems the best way forward is to catch the XML parsing exception, and then fail with the error you added.

As for reproducing it, note that the error I get is:

  error: failed to get emulator capabilities
  error: invalid argument: unable to find any emulator to serve 'x86_64' architecture

Thus, when an emulator binary is missing (eg. qemu-system-x86 package not installed which provides /usr/bin/qemu-system-x86_64), I don't see how you could not get this error message. Make sure to restart libvirt-bin service after you remove the package, though, because libvirtd seems to cache the result.

Perhaps we can match on "error:" lines to find the error output.

  ubuntu@skrinja:~$ LC_ALL=en_US.UTF-8 virsh
  Welcome to virsh, the virtualization interactive terminal.

  Type: 'help' for help with commands
         'quit' to quit

  virsh # domcapabilities
  error: failed to get emulator capabilities
  error: invalid argument: unable to find any emulator to serve 'x86_64' architecture

  virsh # not-a-command
  error: unknown command: 'not-a-command'
  virsh #

(note how all the errors are preceded with "error" in an en_US.UTF-8 locale, so maybe it's best to make run() raise a VirshError exception if it sees lines starting with "error:" in the output)

review: Needs Fixing
Revision history for this message
Newell Jensen (newell-jensen) wrote :

I was able to reproduce the bug this time and have updated the branch to test that the output starts with 'error'.

Revision history for this message
Данило Шеган (danilo) wrote :

I would still prefer if we catch the etree.XMLSyntaxError in etree.XML(xml) call, and if we include the full virsh call output in the error (for easier debugging), but this is definitely good enough.

Thanks for bearing with me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/drivers/pod/tests/test_virsh.py'
2--- src/provisioningserver/drivers/pod/tests/test_virsh.py 2017-05-17 12:08:54 +0000
3+++ src/provisioningserver/drivers/pod/tests/test_virsh.py 2017-05-19 03:57:28 +0000
4@@ -890,6 +890,10 @@
5 'emulator': '/usr/bin/qemu-system-x86_64',
6 }, conn.get_domain_capabilities())
7
8+ def test_get_domain_capabilities_raises_error(self):
9+ conn = self.configure_virshssh('error: some error')
10+ self.assertRaises(virsh.VirshError, conn.get_domain_capabilities)
11+
12 def test_cleanup_disks_deletes_all(self):
13 conn = self.configure_virshssh('')
14 volumes = [
15
16=== modified file 'src/provisioningserver/drivers/pod/virsh.py'
17--- src/provisioningserver/drivers/pod/virsh.py 2017-05-17 12:08:54 +0000
18+++ src/provisioningserver/drivers/pod/virsh.py 2017-05-19 03:57:28 +0000
19@@ -645,6 +645,16 @@
20 # Fallback to qemu support. Fail if qemu not supported.
21 xml = self.run(['domcapabilities', '--virttype', 'qemu'])
22 emulator_type = 'qemu'
23+
24+ # XXX newell 2017-05-18 bug=1690781
25+ # Check to see if the XML output was an error.
26+ # See bug for details about why and how this can occur.
27+ if xml.startswith('error'):
28+ raise VirshError(
29+ "`virsh domcapabilities --virttype %s` errored. Please "
30+ "verify that package qemu-kvm is installed and restart "
31+ "libvirt-bin service." % emulator_type)
32+
33 doc = etree.XML(xml)
34 evaluator = etree.XPathEvaluator(doc)
35 emulator = evaluator('/domainCapabilities/path')[0].text