Skip to content

Commit 79e6840

Browse files
kk7dspriteau
authored andcommitted
Reject qcow files with data-file attributes
Change-Id: Ic3fa16f55acc38cf6c1a4ac1dce4487225e66d04 Closes-Bug: #2059809 (cherry picked from commit ec9c55c) (cherry picked from commit 58d933e) (cherry picked from commit 736328f) (cherry picked from commit af4d819) (cherry picked from commit d69d441) (cherry picked from commit f844c8f)
1 parent 4b85693 commit 79e6840

File tree

1 file changed

+4
-114
lines changed

1 file changed

+4
-114
lines changed

nova/tests/unit/virt/test_images.py

Lines changed: 4 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
from nova.compute import utils as compute_utils
2323
from nova import exception
24-
from nova.image import format_inspector
2524
from nova import test
2625
from nova.virt import images
2726

@@ -100,17 +99,11 @@ def test_qemu_img_info_with_disk_not_found(self, exists, mocked_execute):
10099
exists.assert_called_once_with(path)
101100
mocked_execute.assert_called_once()
102101

103-
@mock.patch.object(images, 'IMAGE_API')
104-
@mock.patch('nova.image.format_inspector.get_inspector')
105102
@mock.patch.object(images, 'convert_image',
106103
side_effect=exception.ImageUnacceptable)
107104
@mock.patch.object(images, 'qemu_img_info')
108105
@mock.patch.object(images, 'fetch')
109-
def test_fetch_to_raw_errors(self, convert_image, qemu_img_info, fetch,
110-
get_inspector, glance):
111-
inspector = get_inspector.return_value.from_file.return_value
112-
inspector.safety_check.return_value = True
113-
glance.get.return_value = {'disk_format': 'qcow2'}
106+
def test_fetch_to_raw_errors(self, convert_image, qemu_img_info, fetch):
114107
qemu_img_info.backing_file = None
115108
qemu_img_info.file_format = 'qcow2'
116109
qemu_img_info.virtual_size = 20
@@ -119,17 +112,12 @@ def test_fetch_to_raw_errors(self, convert_image, qemu_img_info, fetch,
119112
images.fetch_to_raw,
120113
None, 'href123', '/no/path')
121114

122-
@mock.patch.object(images, 'IMAGE_API')
123-
@mock.patch('nova.image.format_inspector.get_inspector')
124115
@mock.patch.object(images, 'convert_image',
125116
side_effect=exception.ImageUnacceptable)
126117
@mock.patch.object(images, 'qemu_img_info')
127118
@mock.patch.object(images, 'fetch')
128119
def test_fetch_to_raw_data_file(self, convert_image, qemu_img_info_fn,
129-
fetch, mock_gi, mock_glance):
130-
mock_glance.get.return_value = {'disk_format': 'qcow2'}
131-
inspector = mock_gi.return_value.from_file.return_value
132-
inspector.safety_check.return_value = True
120+
fetch):
133121
# NOTE(danms): the above test needs the following line as well, as it
134122
# is broken without it.
135123
qemu_img_info = qemu_img_info_fn.return_value
@@ -142,16 +130,12 @@ def test_fetch_to_raw_data_file(self, convert_image, qemu_img_info_fn,
142130
images.fetch_to_raw,
143131
None, 'href123', '/no/path')
144132

145-
@mock.patch('nova.image.format_inspector.get_inspector')
146-
@mock.patch.object(images, 'IMAGE_API')
147133
@mock.patch('os.rename')
148134
@mock.patch.object(images, 'qemu_img_info')
149135
@mock.patch.object(images, 'fetch')
150-
def test_fetch_to_raw_from_raw(self, fetch, qemu_img_info_fn, mock_rename,
151-
mock_glance, mock_gi):
136+
def test_fetch_to_raw_from_raw(self, fetch, qemu_img_info_fn, mock_rename):
152137
# Make sure we support a case where we fetch an already-raw image and
153138
# qemu-img returns None for "format_specific".
154-
mock_glance.get.return_value = {'disk_format': 'raw'}
155139
qemu_img_info = qemu_img_info_fn.return_value
156140
qemu_img_info.file_format = 'raw'
157141
qemu_img_info.backing_file = None
@@ -214,15 +198,9 @@ def test_convert_image_vmdk_allowed_list_checking(self):
214198
imageutils.QemuImgInfo(jsonutils.dumps(info),
215199
format='json'))
216200

217-
@mock.patch.object(images, 'IMAGE_API')
218-
@mock.patch('nova.image.format_inspector.get_inspector')
219201
@mock.patch.object(images, 'fetch')
220202
@mock.patch('nova.privsep.qemu.unprivileged_qemu_img_info')
221-
def test_fetch_checks_vmdk_rules(self, mock_info, mock_fetch, mock_gi,
222-
mock_glance):
223-
mock_glance.get.return_value = {'disk_format': 'vmdk'}
224-
inspector = mock_gi.return_value.from_file.return_value
225-
inspector.safety_check.return_value = True
203+
def test_fetch_checks_vmdk_rules(self, mock_info, mock_fetch):
226204
info = {'format': 'vmdk',
227205
'format-specific': {
228206
'type': 'vmdk',
@@ -234,91 +212,3 @@ def test_fetch_checks_vmdk_rules(self, mock_info, mock_fetch, mock_gi,
234212
e = self.assertRaises(exception.ImageUnacceptable,
235213
images.fetch_to_raw, None, 'foo', 'anypath')
236214
self.assertIn('Invalid VMDK create-type specified', str(e))
237-
238-
@mock.patch.object(images, 'IMAGE_API')
239-
@mock.patch('nova.image.format_inspector.get_inspector')
240-
@mock.patch.object(images, 'qemu_img_info')
241-
@mock.patch.object(images, 'fetch')
242-
def test_fetch_to_raw_inspector(self, fetch, qemu_img_info, mock_gi,
243-
mock_glance):
244-
# Image claims to be qcow2, is qcow2, but fails safety check, so we
245-
# abort before qemu-img-info
246-
mock_glance.get.return_value = {'disk_format': 'qcow2'}
247-
inspector = mock_gi.return_value.from_file.return_value
248-
inspector.safety_check.return_value = False
249-
self.assertRaises(exception.ImageUnacceptable,
250-
images.fetch_to_raw, None, 'href123', '/no.path')
251-
qemu_img_info.assert_not_called()
252-
mock_gi.assert_called_once_with('qcow2')
253-
mock_gi.return_value.from_file.assert_called_once_with('/no.path.part')
254-
inspector.safety_check.assert_called_once_with()
255-
mock_glance.get.assert_called_once_with(None, 'href123')
256-
257-
# Image claims to be qcow2, is qcow2, passes safety check, so we make
258-
# it all the way to qemu-img-info
259-
inspector.safety_check.return_value = True
260-
qemu_img_info.side_effect = test.TestingException
261-
self.assertRaises(test.TestingException,
262-
images.fetch_to_raw, None, 'href123', '/no.path')
263-
264-
# Image claims to be qcow2 in glance, but the image is something else,
265-
# so we abort before qemu-img-info
266-
qemu_img_info.reset_mock()
267-
mock_gi.reset_mock()
268-
inspector.safety_check.reset_mock()
269-
mock_gi.return_value.from_file.side_effect = (
270-
format_inspector.ImageFormatError)
271-
self.assertRaises(exception.ImageUnacceptable,
272-
images.fetch_to_raw, None, 'href123', '/no.path')
273-
mock_gi.assert_called_once_with('qcow2')
274-
inspector.safety_check.assert_not_called()
275-
qemu_img_info.assert_not_called()
276-
277-
@mock.patch.object(images, 'IMAGE_API')
278-
@mock.patch('nova.image.format_inspector.get_inspector')
279-
@mock.patch.object(images, 'qemu_img_info')
280-
@mock.patch.object(images, 'fetch')
281-
def test_fetch_to_raw_inspector_disabled(self, fetch, qemu_img_info,
282-
mock_gi, mock_glance):
283-
self.flags(disable_deep_image_inspection=True,
284-
group='workarounds')
285-
qemu_img_info.side_effect = test.TestingException
286-
self.assertRaises(test.TestingException,
287-
images.fetch_to_raw, None, 'href123', '/no.path')
288-
# If deep inspection is disabled, we should never call the inspector
289-
mock_gi.assert_not_called()
290-
# ... and we let qemu-img detect the format itself.
291-
qemu_img_info.assert_called_once_with('/no.path.part',
292-
format=None)
293-
mock_glance.get.assert_not_called()
294-
295-
@mock.patch.object(images, 'IMAGE_API')
296-
@mock.patch.object(images, 'qemu_img_info')
297-
def test_fetch_inspect_ami(self, imginfo, glance):
298-
glance.get.return_value = {'disk_format': 'ami'}
299-
self.assertRaises(exception.ImageUnacceptable,
300-
images.fetch_to_raw, None, 'href123', '/no.path')
301-
# Make sure 'ami was translated into 'raw' before we call qemu-img
302-
imginfo.assert_called_once_with('/no.path.part', format='raw')
303-
304-
@mock.patch.object(images, 'IMAGE_API')
305-
@mock.patch.object(images, 'qemu_img_info')
306-
def test_fetch_inspect_unknown_format(self, imginfo, glance):
307-
glance.get.return_value = {'disk_format': 'commodore-64-disk'}
308-
self.assertRaises(exception.ImageUnacceptable,
309-
images.fetch_to_raw, None, 'href123', '/no.path')
310-
# Unsupported formats do not make it past deep inspection
311-
imginfo.assert_not_called()
312-
313-
@mock.patch.object(images, 'IMAGE_API')
314-
@mock.patch.object(images, 'qemu_img_info')
315-
@mock.patch('nova.image.format_inspector.get_inspector')
316-
def test_fetch_inspect_disagrees_qemu(self, mock_gi, imginfo, glance):
317-
glance.get.return_value = {'disk_format': 'qcow2'}
318-
# Glance and inspector think it is a qcow2 file, but qemu-img does not
319-
# agree. It was forced to interpret as a qcow2, but returned no
320-
# format information as a result.
321-
imginfo.return_value.data_file = None
322-
self.assertRaises(exception.ImageUnacceptable,
323-
images.fetch_to_raw, None, 'href123', '/no.path')
324-
imginfo.assert_called_once_with('/no.path.part', format='qcow2')

0 commit comments

Comments
 (0)