Merge lp:~zulcss/nova/2014.1.1 into lp:~ubuntu-server-dev/nova/icehouse

Proposed by Chuck Short
Status: Merged
Merged at revision: 687
Proposed branch: lp:~zulcss/nova/2014.1.1
Merge into: lp:~ubuntu-server-dev/nova/icehouse
Diff against target: 393 lines (+365/-1)
4 files modified
debian/changelog (+49/-0)
debian/nova_sudoers (+1/-1)
debian/patches/fix-lxc-libvirt-starting.patch (+314/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~zulcss/nova/2014.1.1
Reviewer Review Type Date Requested Status
James Page Approve
Review via email: mp+223546@code.launchpad.net

Description of the change

2014.1.1

To post a comment you must log in.
Revision history for this message
James Page (james-page) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2014-05-20 16:19:46 +0000
+++ debian/changelog 2014-06-18 12:31:35 +0000
@@ -1,3 +1,52 @@
1nova (1:2014.1.1-0ubuntu1.3) utopic; urgency=medium
2
3 * Resynchronize with stable/icehouse (867341f) (LP: #1328134)
4 - [867341f] Fix security group race condition while listing and deleting rules
5 - [ffcb176] VMware: ensure rescue instance is deleted when instance is deleted
6 - [fe4fe70] VMware: Log additional details of suds faults
7 - [43f0437] Add info_cache as expected attribute when evacuate instance
8 - [a2da9ce] VMware: uncaught exception during snapshot deletion
9 - [1a45944] Catch InstanceNotFound exception if migration fails
10 - [ee374f1] Do not wait for neutron event if not powering on libvirt domain
11 - [705ad64] Reap child processes gracefully if greenlet thread gets killed
12 - [f769bf8] Fixes arguments parsing when executing command
13 - [bedb66f] Use one query instead of two for quota_usages
14 - [422decd] VMWare - Check for compute node before triggering destroy
15 - [6629116] Use debug level logging in unit tests, but don't save them.
16 - [088b718] support local debug logging
17 - [080f785] Revert "Use debug level logging during unit tests"
18 - [fb03028] VMWare: add power off vm before detach disk during unrescue
19 - [d93427a] Check for None or timestamp in availability zone api sample
20 - [f5c3330f] Pass configured auth strategy to neutronclient
21 - [74d1043] remove unneeded call to network_api on rebuild_instance
22 - [f1fdb3c] Remove unnecessary call to fetch info_cache
23 - [395ec82] Remove metadata's network-api dependence on the database
24 - [a48d268] InvalidCPUInfo exception added to except block
25 - [77392a9] Moved the registration of lifecycle event handler in init_host()
26 - [40ae1ee] Fix display of server group members
27 - [66c7ca1] Change errors_out_migration decorator to work with RPC
28 - [e1e140b] Don't explode if we fail to unplug VIFs after a failed boot
29 - [c816488] Remove unneeded call to fetch network info on shutdown
30 - [7f9f3ef] Don't overwrite instance object with dict in _init_instance()
31 - [2728f1e] Fix bug detach volume fails with "KeyError" in EC2
32 * debian/patches/fix-lxc-libvirt-starting.patch: Fix exception when starting
33 LXC containers. (LP: #1297962)
34
35 -- Chuck Short <zulcss@ubuntu.com> Mon, 09 Jun 2014 12:26:24 -0400
36
37nova (1:2014.1-0ubuntu1.2) trusty-security; urgency=medium
38
39 * SECURITY UPDATE: specify /etc/nova/rootwrap.conf for use with
40 nova-rootwrap
41 - CVE-2013-1068 (LP: #1185019)
42
43 -- Jamie Strandboge <jamie@ubuntu.com> Mon, 09 Jun 2014 09:32:44 -0500
44
45nova (1:2014.1-0ubuntu1.1) trusty; urgency=medium
46
47 * debian/patches/libvirt-Handle-unsupported-host-capabilities.patch: Fix
48 exception when starting instances with libvirt LXC or XEN. (LP: #1297962)
49
1nova (1:2014.1-0ubuntu1) trusty; urgency=medium50nova (1:2014.1-0ubuntu1) trusty; urgency=medium
251
3 [ Chuck Short ]52 [ Chuck Short ]
453
=== modified file 'debian/nova_sudoers'
--- debian/nova_sudoers 2012-06-27 21:00:32 +0000
+++ debian/nova_sudoers 2014-06-18 12:31:35 +0000
@@ -1,3 +1,3 @@
1Defaults:nova !requiretty1Defaults:nova !requiretty
22
3nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap 3nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf *
44
=== added file 'debian/patches/fix-lxc-libvirt-starting.patch'
--- debian/patches/fix-lxc-libvirt-starting.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/fix-lxc-libvirt-starting.patch 2014-06-18 12:31:35 +0000
@@ -0,0 +1,314 @@
1Description: Fix exception when starting LXC containers with libvirt-lxc.
2Author: Chuck Short <zulcss@ubuntu.com>
3Forwarded: Not Needed.
4diff -Naurp nova-2014.1.1.orig/nova/tests/virt/libvirt/fakelibvirt.py nova-2014.1.1/nova/tests/virt/libvirt/fakelibvirt.py
5--- nova-2014.1.1.orig/nova/tests/virt/libvirt/fakelibvirt.py 2014-06-05 17:33:22.000000000 -0400
6+++ nova-2014.1.1/nova/tests/virt/libvirt/fakelibvirt.py 2014-06-09 12:00:11.032072000 -0400
7@@ -172,18 +172,76 @@ def _parse_disk_info(element):
8
9
10 class libvirtError(Exception):
11- def __init__(self, msg,
12- error_code=VIR_ERR_INTERNAL_ERROR,
13- error_domain=VIR_FROM_QEMU):
14- self.error_code = error_code
15- self.error_domain = error_domain
16- Exception(self, msg)
17+ """This class was copied and slightly modified from
18+ `libvirt-python:libvirt-override.py`.
19+
20+ Since a test environment will use the real `libvirt-python` version of
21+ `libvirtError` if it's installed and not this fake, we need to maintain
22+ strict compatability with the original class, including `__init__` args
23+ and instance-attributes.
24+
25+ To create a libvirtError instance you should:
26+
27+ # Create an unsupported error exception
28+ exc = libvirtError('my message')
29+ exc.err = (libvirt.VIR_ERR_NO_SUPPORT,)
30+
31+ self.err is a tuple of form:
32+ (error_code, error_domain, error_message, error_level, str1, str2,
33+ str3, int1, int2)
34+
35+ Alternatively, you can use the `make_libvirtError` convenience function to
36+ allow you to specify these attributes in one shot.
37+ """
38+ def __init__(self, defmsg, conn=None, dom=None, net=None, pool=None,
39+ vol=None):
40+ Exception.__init__(self, defmsg)
41+ self.err = None
42
43 def get_error_code(self):
44- return self.error_code
45+ if self.err is None:
46+ return None
47+ return self.err[0]
48
49 def get_error_domain(self):
50- return self.error_domain
51+ if self.err is None:
52+ return None
53+ return self.err[1]
54+
55+ def get_error_message(self):
56+ if self.err is None:
57+ return None
58+ return self.err[2]
59+
60+ def get_error_level(self):
61+ if self.err is None:
62+ return None
63+ return self.err[3]
64+
65+ def get_str1(self):
66+ if self.err is None:
67+ return None
68+ return self.err[4]
69+
70+ def get_str2(self):
71+ if self.err is None:
72+ return None
73+ return self.err[5]
74+
75+ def get_str3(self):
76+ if self.err is None:
77+ return None
78+ return self.err[6]
79+
80+ def get_int1(self):
81+ if self.err is None:
82+ return None
83+ return self.err[7]
84+
85+ def get_int2(self):
86+ if self.err is None:
87+ return None
88+ return self.err[8]
89
90
91 class NWFilter(object):
92@@ -219,8 +277,10 @@ class Domain(object):
93 try:
94 tree = etree.fromstring(xml)
95 except etree.ParseError:
96- raise libvirtError("Invalid XML.",
97- VIR_ERR_XML_DETAIL, VIR_FROM_DOMAIN)
98+ raise make_libvirtError(
99+ libvirtError, "Invalid XML.",
100+ error_code=VIR_ERR_XML_DETAIL,
101+ error_domain=VIR_FROM_DOMAIN)
102
103 definition = {}
104
105@@ -369,7 +429,11 @@ class Domain(object):
106 123456789L]
107
108 def migrateToURI(self, desturi, flags, dname, bandwidth):
109- raise libvirtError("Migration always fails for fake libvirt!")
110+ raise make_libvirtError(
111+ libvirtError,
112+ "Migration always fails for fake libvirt!",
113+ error_code=VIR_ERR_INTERNAL_ERROR,
114+ error_domain=VIR_FROM_QEMU)
115
116 def attachDevice(self, xml):
117 disk_info = _parse_disk_info(etree.fromstring(xml))
118@@ -380,7 +444,11 @@ class Domain(object):
119 def attachDeviceFlags(self, xml, flags):
120 if (flags & VIR_DOMAIN_AFFECT_LIVE and
121 self._state != VIR_DOMAIN_RUNNING):
122- raise libvirtError("AFFECT_LIVE only allowed for running domains!")
123+ raise make_libvirtError(
124+ libvirtError,
125+ "AFFECT_LIVE only allowed for running domains!",
126+ error_code=VIR_ERR_INTERNAL_ERROR,
127+ error_domain=VIR_FROM_QEMU)
128 self.attachDevice(xml)
129
130 def detachDevice(self, xml):
131@@ -533,9 +601,11 @@ class Connection(object):
132 'test:///default']
133
134 if uri not in uri_whitelist:
135- raise libvirtError("libvirt error: no connection driver "
136- "available for No connection for URI %s" % uri,
137- 5, 0)
138+ raise make_libvirtError(
139+ libvirtError,
140+ "libvirt error: no connection driver "
141+ "available for No connection for URI %s" % uri,
142+ error_code=5, error_domain=0)
143
144 self.readonly = readonly
145 self._uri = uri
146@@ -594,16 +664,20 @@ class Connection(object):
147 def lookupByID(self, id):
148 if id in self._running_vms:
149 return self._running_vms[id]
150- raise libvirtError('Domain not found: no domain with matching '
151- 'id %d' % id,
152- VIR_ERR_NO_DOMAIN, VIR_FROM_QEMU)
153+ raise make_libvirtError(
154+ libvirtError,
155+ 'Domain not found: no domain with matching id %d' % id,
156+ error_code=VIR_ERR_NO_DOMAIN,
157+ error_domain=VIR_FROM_QEMU)
158
159 def lookupByName(self, name):
160 if name in self._vms:
161 return self._vms[name]
162- raise libvirtError('Domain not found: no domain with matching '
163- 'name "%s"' % name,
164- VIR_ERR_NO_DOMAIN, VIR_FROM_QEMU)
165+ raise make_libvirtError(
166+ libvirtError,
167+ 'Domain not found: no domain with matching name "%s"' % name,
168+ error_code=VIR_ERR_NO_DOMAIN,
169+ error_domain=VIR_FROM_QEMU)
170
171 def _emit_lifecycle(self, dom, event, detail):
172 if VIR_DOMAIN_EVENT_ID_LIFECYCLE not in self._event_callbacks:
173@@ -904,14 +978,21 @@ class Connection(object):
174 'user': 26728850000000L,
175 'iowait': 6121490000000L}
176 else:
177- raise libvirtError("invalid argument: Invalid cpu number")
178+ raise make_libvirtError(
179+ libvirtError,
180+ "invalid argument: Invalid cpu number",
181+ error_code=VIR_ERR_INTERNAL_ERROR,
182+ error_domain=VIR_FROM_QEMU)
183
184 def nwfilterLookupByName(self, name):
185 try:
186 return self._nwfilters[name]
187 except KeyError:
188- raise libvirtError("no nwfilter with matching name %s" % name,
189- VIR_ERR_NO_NWFILTER, VIR_FROM_NWFILTER)
190+ raise make_libvirtError(
191+ libvirtError,
192+ "no nwfilter with matching name %s" % name,
193+ error_code=VIR_ERR_NO_NWFILTER,
194+ error_domain=VIR_FROM_NWFILTER)
195
196 def nwfilterDefineXML(self, xml):
197 nwfilter = NWFilter(self, xml)
198@@ -964,6 +1045,24 @@ def registerErrorHandler(handler, ctxt):
199 pass
200
201
202+def make_libvirtError(error_class, msg, error_code=None,
203+ error_domain=None, error_message=None,
204+ error_level=None, str1=None, str2=None, str3=None,
205+ int1=None, int2=None):
206+ """Convenience function for creating `libvirtError` exceptions which
207+ allow you to specify arguments in constructor without having to manipulate
208+ the `err` tuple directly.
209+
210+ We need to pass in `error_class` to this function because it may be
211+ `libvirt.libvirtError` or `fakelibvirt.libvirtError` depending on whether
212+ `libvirt-python` is installed.
213+ """
214+ exc = error_class(msg)
215+ exc.err = (error_code, error_domain, error_message, error_level,
216+ str1, str2, str3, int1, int2)
217+ return exc
218+
219+
220 virDomain = Domain
221
222
223diff -Naurp nova-2014.1.1.orig/nova/tests/virt/libvirt/test_libvirt.py nova-2014.1.1/nova/tests/virt/libvirt/test_libvirt.py
224--- nova-2014.1.1.orig/nova/tests/virt/libvirt/test_libvirt.py 2014-06-05 17:33:22.000000000 -0400
225+++ nova-2014.1.1/nova/tests/virt/libvirt/test_libvirt.py 2014-06-09 12:00:11.040072000 -0400
226@@ -60,6 +60,7 @@ import nova.tests.image.fake
227 from nova.tests import matchers
228 from nova.tests.objects import test_pci_device
229 from nova.tests.virt.libvirt import fake_libvirt_utils
230+from nova.tests.virt.libvirt import fakelibvirt
231 from nova import utils
232 from nova import version
233 from nova.virt import configdrive
234@@ -80,7 +81,7 @@ from nova.virt import netutils
235 try:
236 import libvirt
237 except ImportError:
238- import nova.tests.virt.libvirt.fakelibvirt as libvirt
239+ libvirt = fakelibvirt
240 libvirt_driver.libvirt = libvirt
241
242
243@@ -849,6 +850,42 @@ class LibvirtConnTestCase(test.TestCase)
244 caps = conn.get_host_capabilities()
245 self.assertIn('aes', [x.name for x in caps.host.cpu.features])
246
247+ def test_baseline_cpu_not_supported(self):
248+ conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
249+
250+ # `mock` has trouble stubbing attributes that don't exist yet, so
251+ # fallback to plain-Python attribute setting/deleting
252+ cap_str = 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES'
253+ if not hasattr(libvirt_driver.libvirt, cap_str):
254+ setattr(libvirt_driver.libvirt, cap_str, True)
255+ self.addCleanup(delattr, libvirt_driver.libvirt, cap_str)
256+
257+ # Handle just the NO_SUPPORT error
258+ not_supported_exc = fakelibvirt.make_libvirtError(
259+ libvirt.libvirtError,
260+ 'this function is not supported by the connection driver:'
261+ ' virConnectBaselineCPU',
262+ error_code=libvirt.VIR_ERR_NO_SUPPORT)
263+
264+ with mock.patch.object(conn._conn, 'baselineCPU',
265+ side_effect=not_supported_exc):
266+ caps = conn.get_host_capabilities()
267+ self.assertEqual(vconfig.LibvirtConfigCaps, type(caps))
268+ self.assertNotIn('aes', [x.name for x in caps.host.cpu.features])
269+
270+ # Clear cached result so we can test again...
271+ conn._caps = None
272+
273+ # Other errors should not be caught
274+ other_exc = fakelibvirt.make_libvirtError(
275+ libvirt.libvirtError,
276+ 'other exc',
277+ error_code=libvirt.VIR_ERR_NO_DOMAIN)
278+
279+ with mock.patch.object(conn._conn, 'baselineCPU',
280+ side_effect=other_exc):
281+ self.assertRaises(libvirt.libvirtError, conn.get_host_capabilities)
282+
283 def test_lxc_get_host_capabilities_failed(self):
284 conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
285
286diff -Naurp nova-2014.1.1.orig/nova/virt/libvirt/driver.py nova-2014.1.1/nova/virt/libvirt/driver.py
287--- nova-2014.1.1.orig/nova/virt/libvirt/driver.py 2014-06-05 17:33:22.000000000 -0400
288+++ nova-2014.1.1/nova/virt/libvirt/driver.py 2014-06-09 11:59:55.232072000 -0400
289@@ -76,6 +76,7 @@ from nova.objects import service as serv
290 from nova.openstack.common import excutils
291 from nova.openstack.common import fileutils
292 from nova.openstack.common.gettextutils import _
293+from nova.openstack.common.gettextutils import _LW
294 from nova.openstack.common import importutils
295 from nova.openstack.common import jsonutils
296 from nova.openstack.common import log as logging
297@@ -2859,9 +2860,14 @@ class LibvirtDriver(driver.ComputeDriver
298 # this -1 checking should be removed later.
299 if features and features != -1:
300 self._caps.host.cpu.parse_str(features)
301- except libvirt.VIR_ERR_NO_SUPPORT:
302- # Note(yjiang5): ignore if libvirt has no support
303- pass
304+ except libvirt.libvirtError as ex:
305+ error_code = ex.get_error_code()
306+ if error_code == libvirt.VIR_ERR_NO_SUPPORT:
307+ LOG.warn(_LW("URI %(uri)s does not support full set"
308+ " of host capabilities: " "%(error)s"),
309+ {'uri': self.uri(), 'error': ex})
310+ else:
311+ raise
312 return self._caps
313
314 def get_host_uuid(self):
0315
=== modified file 'debian/patches/series'
--- debian/patches/series 2014-04-01 17:19:14 +0000
+++ debian/patches/series 2014-06-18 12:31:35 +0000
@@ -3,3 +3,4 @@
3skip_ipv6_test.patch3skip_ipv6_test.patch
4arm-console-patch.patch4arm-console-patch.patch
5update-run-tests.patch5update-run-tests.patch
6fix-lxc-libvirt-starting.patch

Subscribers

People subscribed via source and target branches