Merge lp:~soren/nova/libvirt-is-more-than-kvm-and-qemu into lp:~hudson-openstack/nova/trunk

Proposed by Soren Hansen
Status: Merged
Approved by: Paul Voccio
Approved revision: 815
Merged at revision: 824
Proposed branch: lp:~soren/nova/libvirt-is-more-than-kvm-and-qemu
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 72 lines (+31/-18)
2 files modified
bin/nova-manage (+4/-2)
nova/virt/libvirt_conn.py (+27/-16)
To merge this branch: bzr merge lp:~soren/nova/libvirt-is-more-than-kvm-and-qemu
Reviewer Review Type Date Requested Status
Paul Voccio (community) Approve
Christian Berendt (community) Approve
Rick Harris (community) Approve
Brian Lamar (community) Approve
Review via email: mp+53610@code.launchpad.net

Commit message

Fix a couple of things that assume that libvirt == kvm/qemu.

To post a comment you must log in.
Revision history for this message
Brian Lamar (blamar) wrote :

Looks good. The one comment I have is probably not even your code :)

Line 63: if list(set(tkeys)) != list(set(keys)):

Is the list() call needed? "if set(tkeys) != set(keys):" still works I think, and might be more clear.

review: Approve
Revision history for this message
Rick Harris (rconradharris) wrote :

Nice work.

A couple of tiny nits:

> 30 + if len(arch_nodes):

Usually better to just write:

  if arch_nodes:

> 56 + while topology_node != None:

Comparisons to None should use identity not equivalence:

  while topology_node is not None:

or if its None-ness doesn't matter:

  while topology_node:

> 8 - if FLAGS.connection_type != 'libvirt':
> 9 + if (FLAGS.connection_type != 'libvirt' or
> 10 + (FLAGS.connection_type == 'libvirt' and
> 11 + FLAGS.libvirt_type not in ['kvm', 'qemu'])):
> 12 msg = _('Only KVM is supported for now. Sorry!')
> 13 raise exception.Error(msg)

The logic differs from the logging. Is live-migration supported for both KVM and QEMU now? If so, we should probably update the logging to reflect that: "Only KVM or QEMU is supported.."

review: Needs Fixing
Revision history for this message
Christian Berendt (berendt) wrote :

I fixed the XML paths from //cpu/... to //host/cpu/... with the already merged branch https://code.launchpad.net/~berendt/nova/lp735298. Please fix...

review: Needs Fixing
Revision history for this message
Soren Hansen (soren) wrote :

> A couple of tiny nits:
>
> > 30 + if len(arch_nodes):
>
> Usually better to just write:
>
> if arch_nodes:

The reasoning was that I'm not just referencing it afterwards, I'm specifically indexing into it. To ensure that that is a valid operation, it needs to have a non-zero length, not just be any value that evaluates to True.

> > 56 + while topology_node != None:
> Comparisons to None should use identity not equivalence:

You are quite right. I just didn't go into this to fix existing style issues (I did not write that comparison), but rather just to fix a specific bug.

> while topology_node is not None:
>
> or if its None-ness doesn't matter:
>
> while topology_node:

Right.

I'll fix this as well as the thing Brian points out in a separate patch.

> > 8 - if FLAGS.connection_type != 'libvirt':
> > 9 + if (FLAGS.connection_type != 'libvirt' or
> > 10 + (FLAGS.connection_type == 'libvirt' and
> > 11 + FLAGS.libvirt_type not in ['kvm', 'qemu'])):
> > 12 msg = _('Only KVM is supported for now. Sorry!')
> > 13 raise exception.Error(msg)

> The logic differs from the logging. Is live-migration supported for both KVM
> and QEMU now? If so, we should probably update the logging to reflect that:
> "Only KVM or QEMU is supported.."

Very good point. I do believe QEMu is migratable as well. I'll update the error message.

809. By Soren Hansen

Make error message match the check.

Revision history for this message
Soren Hansen (soren) wrote :

> Looks good. The one comment I have is probably not even your code :)

No, it's not :)

> Line 63: if list(set(tkeys)) != list(set(keys)):
>
> Is the list() call needed? "if set(tkeys) != set(keys):" still works I think,
> and might be more clear.

..and more correct. When list()ifying the set()s, they might end up in different orders and hence fail the comparison. I'll fix this in a different patch.

Revision history for this message
Soren Hansen (soren) wrote :

Filed https://code.launchpad.net/~soren/nova/stuff/+merge/53781 to address the concerns raised here that were unrelated to the problem I was aiming to fix with this patch.

Revision history for this message
Christian Berendt (berendt) wrote :

Do you want to remove the "+<<<<<<< TREE" ... "+>>>>>>> MERGE-SOURCE" stuff? :)

Revision history for this message
Rick Harris (rconradharris) wrote :

> The reasoning was that I'm not just referencing it afterwards, I'm specifically indexing into it.
> To ensure that that is a valid operation, it needs to have a non-zero length, not just be any value
> that evaluates to True.

Sure. Since you're indexing into the object, it's guaranteed to be a sequence. Sequences evaluate to truthy iff it has at least one element, so `if seq:` is just as safe as `if len(seq):`.

The only difference is, the former is Pep-8 and a constant-time operation.

`len(seq)` really only makes sense if you're comparing to a value > 0, or if you're re-using it in a later operation.

That said, it's obviously not a big deal, so, I'll leave to your discretion whether to 'fix'. :)

Revision history for this message
Soren Hansen (soren) wrote :

2011/3/17 Rick Harris <email address hidden>:
>> The reasoning was that I'm not just referencing it afterwards, I'm specifically indexing into it.
>> To ensure that that is a valid operation, it needs to have a non-zero length, not just be any value
>> that evaluates to True.
> Sure. Since you're indexing into the object, it's guaranteed to be a sequence. Sequences evaluate to truthy iff it has at least one element, so `if seq:` is just as safe as `if len(seq):`.

I think you're missing my point. I'm using len() to ensure it's
actually a sequence and not just something else that happens to
evaluate to True. Hmmm.. Come to think of it, I guess I'm screwed
either way. If it's not a sequence, len() will just blow up instead of
the attempt to index into it. /me fixes :)

--
Soren Hansen        | http://linux2go.dk/
Ubuntu Developer    | http://www.ubuntu.com/
OpenStack Developer | http://www.openstack.org/

Revision history for this message
Rick Harris (rconradharris) wrote :

> I think you're missing my point... If it's not a sequence, len() will just blow up instead of
the attempt to index into it

No, that's exactly my point :-) Hence, why I said it was guaranteed to be a sequence. Your code assumed it.

810. By Soren Hansen

Just use 'if foo' instead of 'if len(foo)'. It will fail as spectacularly if its not acting on a sequence anyways.

Revision history for this message
Soren Hansen (soren) wrote :

> Do you want to remove the "+<<<<<<< TREE" ... "+>>>>>>> MERGE-SOURCE" stuff?
> :)

Sorry, merged with trunk now. I didn't notice your branch get merged :)

811. By Soren Hansen

Merge trunk

Revision history for this message
Christian Berendt (berendt) wrote :

You merged line 44 the wrong way...

"+ topology_nodes = xml.xpathEval('//cpu/topology')"

Should be //host/cpu/...

review: Needs Fixing
Revision history for this message
Soren Hansen (soren) wrote :

> You merged line 44 the wrong way...
>
> "+ topology_nodes = xml.xpathEval('//cpu/topology')"
>
> Should be //host/cpu/...

Good catch, thanks. Fixed.

812. By Soren Hansen

I suck at merging.

813. By Soren Hansen

pep8

Revision history for this message
Rick Harris (rconradharris) wrote :

Needs one more round of merge+conflict resolution.

review: Needs Fixing
Revision history for this message
Soren Hansen (soren) wrote :

2011/3/17 Rick Harris <email address hidden>:
> Review: Needs Fixing
> Needs one more round of merge+conflict resolution.

Ok, everybody hold still. It's my turn to get stuff merged. Really :)

--
Soren Hansen        | http://linux2go.dk/
Ubuntu Developer    | http://www.ubuntu.com/
OpenStack Developer | http://www.openstack.org/

Revision history for this message
Soren Hansen (soren) wrote :

> Do you want to remove the "+<<<<<<< TREE" ... "+>>>>>>> MERGE-SOURCE" stuff?
> :)

Just FYI, those were never in bzr, by the way. They just show up here because Launchpad can tell that if you attempted to merge this branch into trunk, these conflicts would be there.

814. By Soren Hansen

Merge with trunk.

Revision history for this message
Rick Harris (rconradharris) wrote :

> 59 - if set(tkeys) != set(keys):
> 65 + if list(set(tkeys)) != list(set(keys)):

Hate to say it, but bad-merge. *Takes cover*

review: Needs Fixing
815. By Soren Hansen

Fix mis-merge

Revision history for this message
Soren Hansen (soren) wrote :

Awesome. Leave it to me to mismerge two branches, both of which I wrote myself.

Revision history for this message
Soren Hansen (soren) wrote :

Anyways, it's fixed now. I'm reasonably sure I didn't break it this time.

Revision history for this message
Rick Harris (rconradharris) wrote :

lgtm

review: Approve
Revision history for this message
Christian Berendt (berendt) wrote :

lgtm

review: Approve
Revision history for this message
Paul Voccio (pvo) wrote :

gogogo

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/nova-manage'
2--- bin/nova-manage 2011-03-16 17:06:30 +0000
3+++ bin/nova-manage 2011-03-17 21:24:52 +0000
4@@ -579,8 +579,10 @@
5 ctxt = context.get_admin_context()
6 instance_id = ec2utils.ec2_id_to_id(ec2_id)
7
8- if FLAGS.connection_type != 'libvirt':
9- msg = _('Only KVM is supported for now. Sorry!')
10+ if (FLAGS.connection_type != 'libvirt' or
11+ (FLAGS.connection_type == 'libvirt' and
12+ FLAGS.libvirt_type not in ['kvm', 'qemu'])):
13+ msg = _('Only KVM and QEmu are supported for now. Sorry!')
14 raise exception.Error(msg)
15
16 if (FLAGS.volume_driver != 'nova.volume.driver.AOEDriver' and \
17
18=== modified file 'nova/virt/libvirt_conn.py'
19--- nova/virt/libvirt_conn.py 2011-03-17 10:44:27 +0000
20+++ nova/virt/libvirt_conn.py 2011-03-17 21:24:52 +0000
21@@ -991,24 +991,35 @@
22 + xml.serialize())
23
24 cpu_info = dict()
25- cpu_info['arch'] = xml.xpathEval('//host/cpu/arch')[0].getContent()
26- cpu_info['model'] = xml.xpathEval('//host/cpu/model')[0].getContent()
27- cpu_info['vendor'] = xml.xpathEval('//host/cpu/vendor')[0].getContent()
28-
29- topology_node = xml.xpathEval('//host/cpu/topology')[0]\
30- .get_properties()
31+
32+ arch_nodes = xml.xpathEval('//host/cpu/arch')
33+ if arch_nodes:
34+ cpu_info['arch'] = arch_nodes[0].getContent()
35+
36+ model_nodes = xml.xpathEval('//host/cpu/model')
37+ if model_nodes:
38+ cpu_info['model'] = model_nodes[0].getContent()
39+
40+ vendor_nodes = xml.xpathEval('//host/cpu/vendor')
41+ if vendor_nodes:
42+ cpu_info['vendor'] = vendor_nodes[0].getContent()
43+
44+ topology_nodes = xml.xpathEval('//host/cpu/topology')
45 topology = dict()
46- while topology_node:
47- name = topology_node.get_name()
48- topology[name] = topology_node.getContent()
49- topology_node = topology_node.get_next()
50+ if topology_nodes:
51+ topology_node = topology_nodes[0].get_properties()
52+ while topology_node:
53+ name = topology_node.get_name()
54+ topology[name] = topology_node.getContent()
55+ topology_node = topology_node.get_next()
56
57- keys = ['cores', 'sockets', 'threads']
58- tkeys = topology.keys()
59- if set(tkeys) != set(keys):
60- ks = ', '.join(keys)
61- raise exception.Invalid(_("Invalid xml: topology(%(topology)s) "
62- "must have %(ks)s") % locals())
63+ keys = ['cores', 'sockets', 'threads']
64+ tkeys = topology.keys()
65+ if set(tkeys) != set(keys):
66+ ks = ', '.join(keys)
67+ raise exception.Invalid(_("Invalid xml: topology"
68+ "(%(topology)s) must have "
69+ "%(ks)s") % locals())
70
71 feature_nodes = xml.xpathEval('//host/cpu/feature')
72 features = list()