Skip to content

Commit 9055e1b

Browse files
authored
Merge pull request #75 from stackhpc/upstream/zed-2024-12-09
Synchronise zed with upstream
2 parents d02493c + e7a0346 commit 9055e1b

File tree

4 files changed

+59
-34
lines changed

4 files changed

+59
-34
lines changed

.zuul.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
"$TEMPEST_CONFIG":
236236
image:
237237
image_caching_enabled: True
238+
disk_formats: qcow2,ari,aki,vhd,vmdk,raw,ami,vdi,iso,vhdx
238239

239240
- job:
240241
name: glance-multistore-cinder-import

glance/common/format_inspector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ def __str__(self):
655655
#
656656
# https://www.vmware.com/app/vmdk/?src=vmdk
657657
class VMDKInspector(FileInspector):
658-
"""vmware VMDK format (monolithicSparse variant only)
658+
"""vmware VMDK format (monolithicSparse and streamOptimized variants only)
659659
660660
This needs to store the 512 byte header and the descriptor region
661661
which should be just after that. The descriptor region is some
@@ -732,7 +732,7 @@ def virtual_size(self):
732732
vmdktype = descriptor[type_idx:type_end]
733733
else:
734734
vmdktype = b'formatnotfound'
735-
if vmdktype != b'monolithicSparse':
735+
if vmdktype not in (b'monolithicSparse', b'streamOptimized'):
736736
LOG.warning('Unsupported VMDK format %s', vmdktype)
737737
return 0
738738

glance/tests/unit/common/test_format_inspector.py

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,31 @@ def _create_img(self, fmt, size, subformat=None, options=None,
8181
shell=True)
8282
return fn
8383

84-
def _create_allocated_vmdk(self, size_mb):
84+
def _create_allocated_vmdk(self, size_mb, subformat=None):
8585
# We need a "big" VMDK file to exercise some parts of the code of the
8686
# format_inspector. A way to create one is to first create an empty
8787
# file, and then to convert it with the -S 0 option.
88-
fn = tempfile.mktemp(prefix='glance-unittest-formatinspector-',
89-
suffix='.vmdk')
88+
89+
if subformat is None:
90+
# Matches qemu-img default, see `qemu-img convert -O vmdk -o help`
91+
subformat = 'monolithicSparse'
92+
93+
prefix = 'glance-unittest-formatinspector-%s-' % subformat
94+
fn = tempfile.mktemp(prefix=prefix, suffix='.vmdk')
9095
self._created_files.append(fn)
91-
zeroes = tempfile.mktemp(prefix='glance-unittest-formatinspector-',
92-
suffix='.zero')
93-
self._created_files.append(zeroes)
96+
raw = tempfile.mktemp(prefix=prefix, suffix='.raw')
97+
self._created_files.append(raw)
9498

95-
# Create an empty file
99+
# Create a file with pseudo-random data, otherwise it will get
100+
# compressed in the streamOptimized format
96101
subprocess.check_output(
97-
'dd if=/dev/zero of=%s bs=1M count=%i' % (zeroes, size_mb),
102+
'dd if=/dev/urandom of=%s bs=1M count=%i' % (raw, size_mb),
98103
shell=True)
99104

100105
# Convert it to VMDK
101106
subprocess.check_output(
102-
'qemu-img convert -f raw -O vmdk -S 0 %s %s' % (zeroes, fn),
107+
'qemu-img convert -f raw -O vmdk -o subformat=%s -S 0 %s %s' % (
108+
subformat, raw, fn),
103109
shell=True)
104110
return fn
105111

@@ -118,8 +124,9 @@ def _test_format_at_block_size(self, format_name, img, block_size):
118124
wrapper.close()
119125
return fmt
120126

121-
def _test_format_at_image_size(self, format_name, image_size):
122-
img = self._create_img(format_name, image_size)
127+
def _test_format_at_image_size(self, format_name, image_size,
128+
subformat=None):
129+
img = self._create_img(format_name, image_size, subformat=subformat)
123130

124131
# Some formats have internal alignment restrictions making this not
125132
# always exactly like image_size, so get the real value for comparison
@@ -141,11 +148,12 @@ def _test_format_at_image_size(self, format_name, image_size):
141148
'Format used more than 512KiB of memory: %s' % (
142149
fmt.context_info))
143150

144-
def _test_format(self, format_name):
151+
def _test_format(self, format_name, subformat=None):
145152
# Try a few different image sizes, including some odd and very small
146153
# sizes
147154
for image_size in (512, 513, 2057, 7):
148-
self._test_format_at_image_size(format_name, image_size * units.Mi)
155+
self._test_format_at_image_size(format_name, image_size * units.Mi,
156+
subformat=subformat)
149157

150158
def test_qcow2(self):
151159
self._test_format('qcow2')
@@ -159,12 +167,30 @@ def test_vhdx(self):
159167
def test_vmdk(self):
160168
self._test_format('vmdk')
161169

162-
def test_vmdk_bad_descriptor_offset(self):
170+
def test_vmdk_stream_optimized(self):
171+
self._test_format('vmdk', 'streamOptimized')
172+
173+
def test_from_file_reads_minimum(self):
174+
img = self._create_img('qcow2', 10 * units.Mi)
175+
file_size = os.stat(img).st_size
176+
fmt = format_inspector.QcowInspector.from_file(img)
177+
# We know everything we need from the first 512 bytes of a QCOW image,
178+
# so make sure that we did not read the whole thing when we inspect
179+
# a local file.
180+
self.assertLess(fmt.actual_size, file_size)
181+
182+
def test_qed_always_unsafe(self):
183+
img = self._create_img('qed', 10 * units.Mi)
184+
fmt = format_inspector.get_inspector('qed').from_file(img)
185+
self.assertTrue(fmt.format_match)
186+
self.assertFalse(fmt.safety_check())
187+
188+
def _test_vmdk_bad_descriptor_offset(self, subformat=None):
163189
format_name = 'vmdk'
164190
image_size = 10 * units.Mi
165191
descriptorOffsetAddr = 0x1c
166192
BAD_ADDRESS = 0x400
167-
img = self._create_img(format_name, image_size)
193+
img = self._create_img(format_name, image_size, subformat=subformat)
168194

169195
# Corrupt the header
170196
fd = open(img, 'r+b')
@@ -184,7 +210,13 @@ def test_vmdk_bad_descriptor_offset(self):
184210
'size %i block %i') % (format_name, image_size,
185211
block_size))
186212

187-
def test_vmdk_bad_descriptor_mem_limit(self):
213+
def test_vmdk_bad_descriptor_offset(self):
214+
self._test_vmdk_bad_descriptor_offset()
215+
216+
def test_vmdk_bad_descriptor_offset_stream_optimized(self):
217+
self._test_vmdk_bad_descriptor_offset(subformat='streamOptimized')
218+
219+
def _test_vmdk_bad_descriptor_mem_limit(self, subformat=None):
188220
format_name = 'vmdk'
189221
image_size = 5 * units.Mi
190222
virtual_size = 5 * units.Mi
@@ -193,7 +225,8 @@ def test_vmdk_bad_descriptor_mem_limit(self):
193225
twoMBInSectors = (2 << 20) // 512
194226
# We need a big VMDK because otherwise we will not have enough data to
195227
# fill-up the CaptureRegion.
196-
img = self._create_allocated_vmdk(image_size // units.Mi)
228+
img = self._create_allocated_vmdk(image_size // units.Mi,
229+
subformat=subformat)
197230

198231
# Corrupt the end of descriptor address so it "ends" at 2MB
199232
fd = open(img, 'r+b')
@@ -217,20 +250,11 @@ def test_vmdk_bad_descriptor_mem_limit(self):
217250
'Format used more than 1.5MiB of memory: %s' % (
218251
fmt.context_info))
219252

220-
def test_qed_always_unsafe(self):
221-
img = self._create_img('qed', 10 * units.Mi)
222-
fmt = format_inspector.get_inspector('qed').from_file(img)
223-
self.assertTrue(fmt.format_match)
224-
self.assertFalse(fmt.safety_check())
253+
def test_vmdk_bad_descriptor_mem_limit(self):
254+
self._test_vmdk_bad_descriptor_mem_limit()
225255

226-
def test_from_file_reads_minimum(self):
227-
img = self._create_img('qcow2', 10 * units.Mi)
228-
file_size = os.stat(img).st_size
229-
fmt = format_inspector.QcowInspector.from_file(img)
230-
# We know everything we need from the first 512 bytes of a QCOW image,
231-
# so make sure that we did not read the whole thing when we inspect
232-
# a local file.
233-
self.assertLess(fmt.actual_size, file_size)
256+
def test_vmdk_bad_descriptor_mem_limit_stream_optimized(self):
257+
self._test_vmdk_bad_descriptor_mem_limit(subformat='streamOptimized')
234258

235259
def test_qcow2_safety_checks(self):
236260
# Create backing and data-file names (and initialize the backing file)

glance/tests/unit/v2/test_tasks_resource.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ def test_create_with_wrong_import_form(self):
415415
"non-local source of image data.")
416416
else:
417417
supported = ['http', ]
418-
msg = ("The given URI is not valid. Please specify a "
419-
"valid URI from the following list of supported URI "
418+
msg = ("The given uri is not valid. Please specify a "
419+
"valid uri from the following list of supported uri "
420420
"%(supported)s") % {'supported': supported}
421421
self.assertEqual(msg, final_task.message)
422422

0 commit comments

Comments
 (0)