Merge lp:~billy-olsen/nova/kilo+lp1457517 into lp:~ubuntu-server-dev/nova/kilo

Proposed by Billy Olsen
Status: Merged
Merged at revision: 781
Proposed branch: lp:~billy-olsen/nova/kilo+lp1457517
Merge into: lp:~ubuntu-server-dev/nova/kilo
Diff against target: 524 lines (+500/-0)
3 files modified
debian/changelog (+5/-0)
debian/patches/not-check-disk-size.patch (+494/-0)
debian/patches/series (+1/-0)
To merge this branch: bzr merge lp:~billy-olsen/nova/kilo+lp1457517
Reviewer Review Type Date Requested Status
Ubuntu Server Developers Pending
Review via email: mp+270466@code.launchpad.net

Description of the change

This is a resubmission of Liang's branch for including the upstream patch for not considering a flavor's volume size when booting from volume. His original branch is located at lp:~cbjchen/nova/kilo-sru-lp1457517 but he's currently unavailable.

To post a comment you must log in.

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 2015-08-18 21:07:07 +0000
3+++ debian/changelog 2015-09-08 23:22:49 +0000
4@@ -1,7 +1,12 @@
5 nova (1:2015.1.1-0ubuntu2) UNRELEASED; urgency=medium
6
7+ [ Corey Bryant ]
8 * d/rules: Prevent dh_python2 from guessing dependencies.
9
10+ [ Liang Chen ]
11+ * d/p/not-check-disk-size.patch: Fix booting from volume error
12+ when flavor disk too small (LP: #1457517)
13+
14 -- Corey Bryant <corey.bryant@canonical.com> Thu, 13 Aug 2015 15:13:43 -0400
15
16 nova (1:2015.1.1-0ubuntu1) vivid; urgency=medium
17
18=== added file 'debian/patches/not-check-disk-size.patch'
19--- debian/patches/not-check-disk-size.patch 1970-01-01 00:00:00 +0000
20+++ debian/patches/not-check-disk-size.patch 2015-09-08 23:22:49 +0000
21@@ -0,0 +1,494 @@
22+From 8794b938dcb983b7c918718807c2396cb255b4ce Mon Sep 17 00:00:00 2001
23+From: Matthew Booth <mbooth@redhat.com>
24+Date: Wed, 22 Jul 2015 14:56:52 +0100
25+Subject: [PATCH 1/1] Don't check flavor disk size when booting from volume
26+
27+When creating a volume from an image, cinder copies the image metadata
28+into volume properties. When booting from the volume, we read this
29+metadata from the volume and use it as image metadata once again.
30+
31+While fixing the check against min_ram,
32+change I861a78b5c7efa71e4bf7206d388b8d0d8048c78e introduced a
33+regression which prevents a user from booting a volume which is larger
34+than the flavor's disk. As we are not creating this disk, this check
35+does not make sense. Similarly, it checks the image metadata's
36+min_disk against the flavor disk size, which is not being used.
37+
38+This change leaves the image metadata check unaltered when creating a
39+flavor disk. When booting from a volume, we check min_disk from image
40+metadata against the actual size of the volume. We don't check the
41+volume size at all. The check against min_ram is retained unaltered.
42+
43+Closes-Bug: #1457517
44+Closes-Bug: #1459491
45+Closes-Bug: #1466305
46+Change-Id: I264493172da20b664df571e32876030246c2a87c
47+(cherry picked from commit 642c986f0636d52a9ba279c87e25082b4aa9b3b8)
48+---
49+ nova/compute/api.py | 101 +++++++++++++++-----
50+ nova/tests/unit/compute/test_compute.py | 127 +++++++++++++++++++++++---
51+ nova/tests/unit/compute/test_compute_api.py | 11 ++-
52+ nova/tests/unit/compute/test_compute_cells.py | 8 +-
53+ 4 files changed, 203 insertions(+), 44 deletions(-)
54+
55+diff --git a/nova/compute/api.py b/nova/compute/api.py
56+index 6634918..5937895 100644
57+--- a/nova/compute/api.py
58++++ b/nova/compute/api.py
59+@@ -651,7 +651,8 @@ class API(base.Base):
60+ # reason, we rely on the DB to cast True to a String.
61+ return True if bool_val else ''
62+
63+- def _check_requested_image(self, context, image_id, image, instance_type):
64++ def _check_requested_image(self, context, image_id, image,
65++ instance_type, root_bdm):
66+ if not image:
67+ return
68+
69+@@ -668,15 +669,63 @@ class API(base.Base):
70+ if instance_type['memory_mb'] < int(image.get('min_ram') or 0):
71+ raise exception.FlavorMemoryTooSmall()
72+
73+- # NOTE(johannes): root_gb is allowed to be 0 for legacy reasons
74+- # since libvirt interpreted the value differently than other
75+- # drivers. A value of 0 means don't check size.
76+- root_gb = instance_type['root_gb']
77+- if root_gb:
78+- if int(image.get('size') or 0) > root_gb * (1024 ** 3):
79+- raise exception.FlavorDiskTooSmall()
80++ # Image min_disk is in gb, size is in bytes. For sanity, have them both
81++ # in bytes.
82++ image_min_disk = int(image.get('min_disk') or 0) * units.Gi
83++ image_size = int(image.get('size') or 0)
84++
85++ # Target disk is a volume. Don't check flavor disk size because it
86++ # doesn't make sense, and check min_disk against the volume size.
87++ if (root_bdm is not None and root_bdm.is_volume):
88++ # There are 2 possibilities here: either the target volume already
89++ # exists, or it doesn't, in which case the bdm will contain the
90++ # intended volume size.
91++ #
92++ # Cinder does its own check against min_disk, so if the target
93++ # volume already exists this has already been done and we don't
94++ # need to check it again here. In this case, volume_size may not be
95++ # set on the bdm.
96++ #
97++ # If we're going to create the volume, the bdm will contain
98++ # volume_size. Therefore we should check it if it exists. This will
99++ # still be checked again by cinder when the volume is created, but
100++ # that will not happen until the request reaches a host. By
101++ # checking it here, the user gets an immediate and useful failure
102++ # indication.
103++ #
104++ # The third possibility is that we have failed to consider
105++ # something, and there are actually more than 2 possibilities. In
106++ # this case cinder will still do the check at volume creation time.
107++ # The behaviour will still be correct, but the user will not get an
108++ # immediate failure from the api, and will instead have to
109++ # determine why the instance is in an error state with a task of
110++ # block_device_mapping.
111++ #
112++ # We could reasonably refactor this check into _validate_bdm at
113++ # some future date, as the various size logic is already split out
114++ # in there.
115++ dest_size = root_bdm.volume_size
116++ if dest_size is not None:
117++ dest_size *= units.Gi
118++
119++ if image_min_disk > dest_size:
120++ # TODO(mdbooth) Raise a more descriptive exception here.
121++ # This is the exception which calling code expects, but
122++ # it's potentially misleading to the user.
123++ raise exception.FlavorDiskTooSmall()
124++
125++ # Target disk is a local disk whose size is taken from the flavor
126++ else:
127++ dest_size = instance_type['root_gb'] * units.Gi
128++
129++ # NOTE(johannes): root_gb is allowed to be 0 for legacy reasons
130++ # since libvirt interpreted the value differently than other
131++ # drivers. A value of 0 means don't check size.
132++ if dest_size != 0:
133++ if image_size > dest_size:
134++ raise exception.FlavorDiskTooSmall()
135+
136+- if int(image.get('min_disk') or 0) > root_gb:
137++ if image_min_disk > dest_size:
138+ raise exception.FlavorDiskTooSmall()
139+
140+ def _get_image_defined_bdms(self, base_options, instance_type, image_meta,
141+@@ -767,10 +816,11 @@ class API(base.Base):
142+
143+ def _checks_for_create_and_rebuild(self, context, image_id, image,
144+ instance_type, metadata,
145+- files_to_inject):
146++ files_to_inject, root_bdm):
147+ self._check_metadata_properties_quota(context, metadata)
148+ self._check_injected_file_quota(context, files_to_inject)
149+- self._check_requested_image(context, image_id, image, instance_type)
150++ self._check_requested_image(context, image_id, image,
151++ instance_type, root_bdm)
152+
153+ def _validate_and_build_base_options(self, context, instance_type,
154+ boot_meta, image_href, image_id,
155+@@ -778,7 +828,7 @@ class API(base.Base):
156+ display_description, key_name,
157+ key_data, security_groups,
158+ availability_zone, forced_host,
159+- user_data, metadata, injected_files,
160++ user_data, metadata,
161+ access_ip_v4, access_ip_v6,
162+ requested_networks, config_drive,
163+ auto_disk_config, reservation_id,
164+@@ -810,9 +860,6 @@ class API(base.Base):
165+ except base64.binascii.Error:
166+ raise exception.InstanceUserDataMalformed()
167+
168+- self._checks_for_create_and_rebuild(context, image_id, boot_meta,
169+- instance_type, metadata, injected_files)
170+-
171+ self._check_requested_secgroups(context, security_groups)
172+
173+ # Note: max_count is the number of instances requested by the user,
174+@@ -1095,7 +1142,7 @@ class API(base.Base):
175+ instance_type, boot_meta, image_href, image_id, kernel_id,
176+ ramdisk_id, display_name, display_description,
177+ key_name, key_data, security_groups, availability_zone,
178+- forced_host, user_data, metadata, injected_files, access_ip_v4,
179++ forced_host, user_data, metadata, access_ip_v4,
180+ access_ip_v6, requested_networks, config_drive,
181+ auto_disk_config, reservation_id, max_count)
182+
183+@@ -1115,6 +1162,12 @@ class API(base.Base):
184+ base_options, instance_type, boot_meta, min_count, max_count,
185+ block_device_mapping, legacy_bdm)
186+
187++ # We can't do this check earlier because we need bdms from all sources
188++ # to have been merged in order to get the root bdm.
189++ self._checks_for_create_and_rebuild(context, image_id, boot_meta,
190++ instance_type, metadata, injected_files,
191++ block_device_mapping.root_bdm())
192++
193+ instance_group = self._get_requested_instance_group(context,
194+ scheduler_hints, check_server_group_quota)
195+
196+@@ -2333,8 +2386,9 @@ class API(base.Base):
197+ self._check_auto_disk_config(image=image, **kwargs)
198+
199+ flavor = instance.get_flavor()
200++ root_bdm = self._get_root_bdm(context, instance)
201+ self._checks_for_create_and_rebuild(context, image_id, image,
202+- flavor, metadata, files_to_inject)
203++ flavor, metadata, files_to_inject, root_bdm)
204+
205+ kernel_id, ramdisk_id = self._handle_kernel_and_ramdisk(
206+ context, None, None, image)
207+@@ -3201,15 +3255,18 @@ class API(base.Base):
208+ uuids = [instance.uuid for instance in instances]
209+ return self.db.instance_fault_get_by_instance_uuids(context, uuids)
210+
211+- def is_volume_backed_instance(self, context, instance, bdms=None):
212+- if not instance.image_ref:
213+- return True
214+-
215++ def _get_root_bdm(self, context, instance, bdms=None):
216+ if bdms is None:
217+ bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
218+ context, instance.uuid)
219+
220+- root_bdm = bdms.root_bdm()
221++ return bdms.root_bdm()
222++
223++ def is_volume_backed_instance(self, context, instance, bdms=None):
224++ if not instance.image_ref:
225++ return True
226++
227++ root_bdm = self._get_root_bdm(context, instance, bdms)
228+ if not root_bdm:
229+ return False
230+ return root_bdm.is_volume
231+diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py
232+index bf36960..b18c1e5 100644
233+--- a/nova/tests/unit/compute/test_compute.py
234++++ b/nova/tests/unit/compute/test_compute.py
235+@@ -11356,6 +11356,8 @@ class ComputeInactiveImageTestCase(BaseTestCase):
236+ return {'id': id, 'min_disk': None, 'min_ram': None,
237+ 'name': 'fake_name',
238+ 'status': 'deleted',
239++ 'min_ram': 0,
240++ 'min_disk': 0,
241+ 'properties': {'kernel_id': 'fake_kernel_id',
242+ 'ramdisk_id': 'fake_ramdisk_id',
243+ 'something_else': 'meow'}}
244+@@ -11708,78 +11710,175 @@ class CheckRequestedImageTestCase(test.TestCase):
245+
246+ def test_no_image_specified(self):
247+ self.compute_api._check_requested_image(self.context, None, None,
248+- self.instance_type)
249++ self.instance_type, None)
250+
251+ def test_image_status_must_be_active(self):
252+ image = dict(id='123', status='foo')
253+
254+ self.assertRaises(exception.ImageNotActive,
255+ self.compute_api._check_requested_image, self.context,
256+- image['id'], image, self.instance_type)
257++ image['id'], image, self.instance_type, None)
258+
259+ image['status'] = 'active'
260+ self.compute_api._check_requested_image(self.context, image['id'],
261+- image, self.instance_type)
262++ image, self.instance_type, None)
263+
264+ def test_image_min_ram_check(self):
265+ image = dict(id='123', status='active', min_ram='65')
266+
267+ self.assertRaises(exception.FlavorMemoryTooSmall,
268+ self.compute_api._check_requested_image, self.context,
269+- image['id'], image, self.instance_type)
270++ image['id'], image, self.instance_type, None)
271+
272+ image['min_ram'] = '64'
273+ self.compute_api._check_requested_image(self.context, image['id'],
274+- image, self.instance_type)
275++ image, self.instance_type, None)
276+
277+ def test_image_min_disk_check(self):
278+ image = dict(id='123', status='active', min_disk='2')
279+
280+ self.assertRaises(exception.FlavorDiskTooSmall,
281+ self.compute_api._check_requested_image, self.context,
282+- image['id'], image, self.instance_type)
283++ image['id'], image, self.instance_type, None)
284+
285+ image['min_disk'] = '1'
286+ self.compute_api._check_requested_image(self.context, image['id'],
287+- image, self.instance_type)
288++ image, self.instance_type, None)
289+
290+ def test_image_too_large(self):
291+ image = dict(id='123', status='active', size='1073741825')
292+
293+ self.assertRaises(exception.FlavorDiskTooSmall,
294+ self.compute_api._check_requested_image, self.context,
295+- image['id'], image, self.instance_type)
296++ image['id'], image, self.instance_type, None)
297+
298+ image['size'] = '1073741824'
299+ self.compute_api._check_requested_image(self.context, image['id'],
300+- image, self.instance_type)
301++ image, self.instance_type, None)
302+
303+ def test_root_gb_zero_disables_size_check(self):
304+ self.instance_type['root_gb'] = 0
305+ image = dict(id='123', status='active', size='1073741825')
306+
307+ self.compute_api._check_requested_image(self.context, image['id'],
308+- image, self.instance_type)
309++ image, self.instance_type, None)
310+
311+ def test_root_gb_zero_disables_min_disk(self):
312+ self.instance_type['root_gb'] = 0
313+ image = dict(id='123', status='active', min_disk='2')
314+
315+ self.compute_api._check_requested_image(self.context, image['id'],
316+- image, self.instance_type)
317++ image, self.instance_type, None)
318+
319+ def test_config_drive_option(self):
320+ image = {'id': 1, 'status': 'active'}
321+ image['properties'] = {'img_config_drive': 'optional'}
322+ self.compute_api._check_requested_image(self.context, image['id'],
323+- image, self.instance_type)
324++ image, self.instance_type, None)
325+ image['properties'] = {'img_config_drive': 'mandatory'}
326+ self.compute_api._check_requested_image(self.context, image['id'],
327+- image, self.instance_type)
328++ image, self.instance_type, None)
329+ image['properties'] = {'img_config_drive': 'bar'}
330+ self.assertRaises(exception.InvalidImageConfigDrive,
331+ self.compute_api._check_requested_image,
332+- self.context, image['id'], image, self.instance_type)
333++ self.context, image['id'], image, self.instance_type,
334++ None)
335++
336++ def test_volume_blockdevicemapping(self):
337++ # We should allow a root volume which is larger than the flavor root
338++ # disk.
339++ # We should allow a root volume created from an image whose min_disk is
340++ # larger than the flavor root disk.
341++ image_uuid = str(uuid.uuid4())
342++ image = dict(id=image_uuid, status='active',
343++ size=self.instance_type.root_gb * units.Gi,
344++ min_disk=self.instance_type.root_gb + 1)
345++
346++ volume_uuid = str(uuid.uuid4())
347++ root_bdm = block_device_obj.BlockDeviceMapping(
348++ source_type='volume', destination_type='volume',
349++ volume_id=volume_uuid, volume_size=self.instance_type.root_gb + 1)
350++
351++ self.compute_api._check_requested_image(self.context, image['id'],
352++ image, self.instance_type, root_bdm)
353++
354++ def test_volume_blockdevicemapping_min_disk(self):
355++ # A bdm object volume smaller than the image's min_disk should not be
356++ # allowed
357++ image_uuid = str(uuid.uuid4())
358++ image = dict(id=image_uuid, status='active',
359++ size=self.instance_type.root_gb * units.Gi,
360++ min_disk=self.instance_type.root_gb + 1)
361++
362++ volume_uuid = str(uuid.uuid4())
363++ root_bdm = block_device_obj.BlockDeviceMapping(
364++ source_type='image', destination_type='volume',
365++ image_id=image_uuid, volume_id=volume_uuid,
366++ volume_size=self.instance_type.root_gb)
367++
368++ self.assertRaises(exception.FlavorDiskTooSmall,
369++ self.compute_api._check_requested_image,
370++ self.context, image_uuid, image, self.instance_type,
371++ root_bdm)
372++
373++ def test_volume_blockdevicemapping_min_disk_no_size(self):
374++ # We should allow a root volume whose size is not given
375++ image_uuid = str(uuid.uuid4())
376++ image = dict(id=image_uuid, status='active',
377++ size=self.instance_type.root_gb * units.Gi,
378++ min_disk=self.instance_type.root_gb)
379++
380++ volume_uuid = str(uuid.uuid4())
381++ root_bdm = block_device_obj.BlockDeviceMapping(
382++ source_type='volume', destination_type='volume',
383++ volume_id=volume_uuid, volume_size=None)
384++
385++ self.compute_api._check_requested_image(self.context, image['id'],
386++ image, self.instance_type, root_bdm)
387++
388++ def test_image_blockdevicemapping(self):
389++ # Test that we can succeed when passing bdms, and the root bdm isn't a
390++ # volume
391++ image_uuid = str(uuid.uuid4())
392++ image = dict(id=image_uuid, status='active',
393++ size=self.instance_type.root_gb * units.Gi, min_disk=0)
394++
395++ root_bdm = block_device_obj.BlockDeviceMapping(
396++ source_type='image', destination_type='local', image_id=image_uuid)
397++
398++ self.compute_api._check_requested_image(self.context, image['id'],
399++ image, self.instance_type, root_bdm)
400++
401++ def test_image_blockdevicemapping_too_big(self):
402++ # We should do a size check against flavor if we were passed bdms but
403++ # the root bdm isn't a volume
404++ image_uuid = str(uuid.uuid4())
405++ image = dict(id=image_uuid, status='active',
406++ size=(self.instance_type.root_gb + 1) * units.Gi,
407++ min_disk=0)
408++
409++ root_bdm = block_device_obj.BlockDeviceMapping(
410++ source_type='image', destination_type='local', image_id=image_uuid)
411++
412++ self.assertRaises(exception.FlavorDiskTooSmall,
413++ self.compute_api._check_requested_image,
414++ self.context, image['id'],
415++ image, self.instance_type, root_bdm)
416++
417++ def test_image_blockdevicemapping_min_disk(self):
418++ # We should do a min_disk check against flavor if we were passed bdms
419++ # but the root bdm isn't a volume
420++ image_uuid = str(uuid.uuid4())
421++ image = dict(id=image_uuid, status='active',
422++ size=0, min_disk=self.instance_type.root_gb + 1)
423++
424++ root_bdm = block_device_obj.BlockDeviceMapping(
425++ source_type='image', destination_type='local', image_id=image_uuid)
426++
427++ self.assertRaises(exception.FlavorDiskTooSmall,
428++ self.compute_api._check_requested_image,
429++ self.context, image['id'],
430++ image, self.instance_type, root_bdm)
431+
432+
433+ class ComputeHooksTestCase(test.BaseHookTestCase):
434+diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py
435+index 47848a9..5b4c2b3 100644
436+--- a/nova/tests/unit/compute/test_compute_api.py
437++++ b/nova/tests/unit/compute/test_compute_api.py
438+@@ -2257,15 +2257,16 @@ class _ComputeAPIUnitTestMixIn(object):
439+ vm_state=vm_states.ACTIVE, cell_name='fake-cell',
440+ launched_at=timeutils.utcnow(),
441+ system_metadata=orig_system_metadata,
442++ image_ref='foo',
443+ expected_attrs=['system_metadata'])
444+ get_flavor.return_value = test_flavor.fake_flavor
445+ flavor = instance.get_flavor()
446+- image_href = ''
447++ image_href = 'foo'
448+ image = {"min_ram": 10, "min_disk": 1,
449+ "properties": {'architecture': arch.X86_64}}
450+ admin_pass = ''
451+ files_to_inject = []
452+- bdms = []
453++ bdms = objects.BlockDeviceMappingList()
454+
455+ _get_image.return_value = (None, image)
456+ bdm_get_by_instance_uuid.return_value = bdms
457+@@ -2284,7 +2285,7 @@ class _ComputeAPIUnitTestMixIn(object):
458+
459+ _check_auto_disk_config.assert_called_once_with(image=image)
460+ _checks_for_create_and_rebuild.assert_called_once_with(self.context,
461+- None, image, flavor, {}, [])
462++ None, image, flavor, {}, [], None)
463+ self.assertNotEqual(orig_system_metadata, instance.system_metadata)
464+
465+ @mock.patch.object(objects.Instance, 'save')
466+@@ -2309,7 +2310,7 @@ class _ComputeAPIUnitTestMixIn(object):
467+ 'vm_mode': 'xen'}}
468+ admin_pass = ''
469+ files_to_inject = []
470+- bdms = []
471++ bdms = objects.BlockDeviceMappingList()
472+
473+ instance = fake_instance.fake_instance_obj(self.context,
474+ vm_state=vm_states.ACTIVE, cell_name='fake-cell',
475+@@ -2342,7 +2343,7 @@ class _ComputeAPIUnitTestMixIn(object):
476+
477+ _check_auto_disk_config.assert_called_once_with(image=new_image)
478+ _checks_for_create_and_rebuild.assert_called_once_with(self.context,
479+- None, new_image, flavor, {}, [])
480++ None, new_image, flavor, {}, [], None)
481+ self.assertEqual(vm_mode.XEN, instance.vm_mode)
482+
483+ def _test_check_injected_file_quota_onset_file_limit_exceeded(self,
484+diff --git a/nova/tests/unit/compute/test_compute_cells.py b/nova/tests/unit/compute/test_compute_cells.py
485+index a769e1d..77d3dd7 100644
486+--- a/nova/tests/unit/compute/test_compute_cells.py
487++++ b/nova/tests/unit/compute/test_compute_cells.py
488+@@ -236,11 +236,13 @@ class CellsConductorAPIRPCRedirect(test.NoDBTestCase):
489+ @mock.patch.object(compute_api.API, '_check_and_transform_bdm')
490+ @mock.patch.object(compute_api.API, '_get_image')
491+ @mock.patch.object(compute_api.API, '_validate_and_build_base_options')
492+- def test_build_instances(self, _validate, _get_image, _check_bdm,
493++ @mock.patch.object(compute_api.API, '_checks_for_create_and_rebuild')
494++ def test_build_instances(self, _checks_for_create_and_rebuild,
495++ _validate, _get_image, _check_bdm,
496+ _provision, _record_action_start):
497+ _get_image.return_value = (None, 'fake-image')
498+ _validate.return_value = ({}, 1)
499+- _check_bdm.return_value = 'bdms'
500++ _check_bdm.return_value = objects.BlockDeviceMappingList()
501+ _provision.return_value = 'instances'
502+
503+ self.compute_api.create(self.context, 'fake-flavor', 'fake-image')
504+@@ -309,7 +311,7 @@ class CellsConductorAPIRPCRedirect(test.NoDBTestCase):
505+ "properties": {'architecture': 'x86_64'}}
506+ admin_pass = ''
507+ files_to_inject = []
508+- bdms = []
509++ bdms = objects.BlockDeviceMappingList()
510+
511+ _get_image.return_value = (None, image)
512+ bdm_get_by_instance_uuid.return_value = bdms
513+--
514+2.1.4
515+
516
517=== modified file 'debian/patches/series'
518--- debian/patches/series 2015-08-03 20:04:14 +0000
519+++ debian/patches/series 2015-09-08 23:22:49 +0000
520@@ -7,3 +7,4 @@
521 #rate-limit-power-syncs.patch
522 skip-ubuntu-tests.patch
523 skip-proxy-test.patch
524+not-check-disk-size.patch

Subscribers

People subscribed via source and target branches