Skip to content

Commit e177c71

Browse files
authored
Merge pull request #37 from stackhpc/upstream/2023.1-2024-07-15
Synchronise 2023.1 with upstream
2 parents a33d6aa + edd75b7 commit e177c71

File tree

9 files changed

+516
-31
lines changed

9 files changed

+516
-31
lines changed

.zuul.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
description: |
206206
The regular tempest-integrated-storage job but with glance metadata injection
207207
post-run: playbooks/post-check-metadata-injection.yaml
208+
timeout: 10800
208209
vars:
209210
configure_swap_size: 8192
210211
tempest_concurrency: 3
@@ -235,6 +236,7 @@
235236
"$TEMPEST_CONFIG":
236237
image:
237238
image_caching_enabled: True
239+
disk_formats: qcow2,ari,aki,vhd,vmdk,raw,ami,vdi,iso,vhdx
238240

239241
- job:
240242
name: glance-multistore-cinder-import
@@ -299,6 +301,7 @@
299301
description: |
300302
This job runs the Tempest tests with scope and new defaults enabled
301303
Glance services.
304+
timeout: 10800
302305
vars:
303306
devstack_localrc:
304307
NOVA_ENFORCE_SCOPE: true

glance/async_/flows/base_import.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ def execute(self, image_id):
181181
'bfile': backing_file}
182182
raise RuntimeError(msg)
183183

184+
try:
185+
data_file = metadata['format-specific']['data']['data-file']
186+
except KeyError:
187+
data_file = None
188+
if data_file is not None:
189+
msg = _("File %(path)s has invalid data-file "
190+
"%(dfile)s, aborting.") % {"path": path,
191+
"dfile": data_file}
192+
raise RuntimeError(msg)
193+
184194
return path
185195

186196
def revert(self, image_id, result, **kwargs):

glance/async_/flows/plugins/image_conversion.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from taskflow import task
2626

2727
from glance.async_ import utils
28+
from glance.common import format_inspector
2829
from glance.i18n import _, _LI
2930

3031
LOG = logging.getLogger(__name__)
@@ -87,8 +88,40 @@ def _execute(self, action, file_path, **kwargs):
8788
'target': target_format}
8889
self.dest_path = dest_path
8990

91+
source_format = action.image_disk_format
92+
inspector_cls = format_inspector.get_inspector(source_format)
93+
if not inspector_cls:
94+
# We cannot convert from disk_format types that qemu-img doesn't
95+
# support (like iso, ploop, etc). The ones it supports overlaps
96+
# with the ones we have inspectors for, so reject conversion for
97+
# any format we don't have an inspector for.
98+
raise RuntimeError(
99+
'Unable to convert from format %s' % source_format)
100+
101+
# Use our own cautious inspector module (if we have one for this
102+
# format) to make sure a file is the format the submitter claimed
103+
# it is and that it passes some basic safety checks _before_ we run
104+
# qemu-img on it.
105+
# See https://bugs.launchpad.net/nova/+bug/2059809 for details.
106+
try:
107+
inspector = inspector_cls.from_file(src_path)
108+
if not inspector.safety_check():
109+
LOG.error('Image failed %s safety check; aborting conversion',
110+
source_format)
111+
raise RuntimeError('Image has disallowed configuration')
112+
except RuntimeError:
113+
raise
114+
except format_inspector.ImageFormatError as e:
115+
LOG.error('Image claimed to be %s format failed format '
116+
'inspection: %s', source_format, e)
117+
raise RuntimeError('Image format detection failed')
118+
except Exception as e:
119+
LOG.exception('Unknown error inspecting image format: %s', e)
120+
raise RuntimeError('Unable to inspect image')
121+
90122
try:
91123
stdout, stderr = putils.trycmd("qemu-img", "info",
124+
"-f", source_format,
92125
"--output=json",
93126
src_path,
94127
prlimit=utils.QEMU_IMG_PROC_LIMITS,
@@ -105,13 +138,10 @@ def _execute(self, action, file_path, **kwargs):
105138
raise RuntimeError(stderr)
106139

107140
metadata = json.loads(stdout)
108-
try:
109-
source_format = metadata['format']
110-
except KeyError:
111-
msg = ("Failed to do introspection as part of image "
112-
"conversion for %(iid)s: Source format not reported")
113-
LOG.error(msg, {'iid': self.image_id})
114-
raise RuntimeError(msg)
141+
if metadata.get('format') != source_format:
142+
LOG.error('Image claiming to be %s reported as %s by qemu-img',
143+
source_format, metadata.get('format', 'unknown'))
144+
raise RuntimeError('Image metadata disagrees about format')
115145

116146
virtual_size = metadata.get('virtual-size', 0)
117147
action.set_image_attribute(virtual_size=virtual_size)
@@ -121,6 +151,14 @@ def _execute(self, action, file_path, **kwargs):
121151
raise RuntimeError(
122152
'QCOW images with backing files are not allowed')
123153

154+
try:
155+
data_file = metadata['format-specific']['data']['data-file']
156+
except KeyError:
157+
data_file = None
158+
if data_file is not None:
159+
raise RuntimeError(
160+
'QCOW images with data-file set are not allowed')
161+
124162
if metadata.get('format') == 'vmdk':
125163
create_type = metadata.get(
126164
'format-specific', {}).get(

0 commit comments

Comments
 (0)