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