cinder.image.image_utils module

Helper methods to deal with images.

This is essentially a copy from nova.virt.images.py Some slight modifications, but at some point we should look at maybe pushing this up to Oslo

class TemporaryImages(image_service: GlanceImageService)

Bases: object

Manage temporarily downloaded images to avoid downloading it twice.

In the ‘with TemporaryImages.fetch(image_service, ctx, image_id) as tmp’ clause, ‘tmp’ can be used as the downloaded image path. In addition, image_utils.fetch() will use the pre-fetched image by the TemporaryImages. This is useful to inspect image contents before conversion.

classmethod fetch(image_service: GlanceImageService, context: RequestContext, image_id: str, suffix: str | None = '') Generator[str, None, None]
static for_image_service(image_service: GlanceImageService) TemporaryImages
get(context: RequestContext, image_id: str)
check_available_space(dest: str, image_size: int, image_id: str) None
check_image_conversion_disable(disk_format, volume_format, image_id, upload=False)
check_image_format(source: str, src_format: str | None = None, image_id: str | None = None, data: QemuImgInfo | None = None, run_as_root: bool = True) None

Do some image format checks.

Verifies that the src_format matches what qemu-img thinks the image format is, and does some vmdk subformat checks. See Bug #1996188.

  • Does not check for a qcow2 backing file.

  • Will make a call out to qemu_img if data is None.

Parameters:
  • source – filename of the image to check

  • src_format – source image format recognized by qemu_img, or None

  • image_id – the image ID if this is a Glance image, or None

  • data – a imageutils.QemuImgInfo object from this image, or None

  • run_as_root – when ‘data’ is None, call ‘qemu-img info’ as root

Raises:
  • ImageUnacceptable – when the image fails some format checks

  • ProcessExecutionError – if ‘qemu-img info’ fails

check_qcow2_image(image_id: str, data: QemuImgInfo) None

Check some rules about qcow2 images.

Does not check for a backing_file, because cinder has some legitimate use cases for qcow2 backing files.

Makes sure the image:

  • does not have a data_file

Parameters:
  • image_id – the image id

  • data – an imageutils.QemuImgInfo object

Raises:

ImageUnacceptable – when the image fails the check

check_qemu_img_version(minimum_version: str) None
check_virtual_size(virtual_size: float, volume_size: int, image_id: str) int
check_vmdk_image(image_id: str, data: QemuImgInfo) None

Check some rules about VMDK images.

Make sure the VMDK subformat (the “createType” in vmware docs) is one that we allow as determined by the ‘vmdk_allowed_types’ configuration option. The default set includes only types that do not reference files outside the VMDK file, which can otherwise be used in exploits to expose host information.

Parameters:
  • image_id – the image id

  • data – an imageutils.QemuImgInfo object

Raises:

ImageUnacceptable – when the VMDK createType is not in the allowed list

chown_if_needed(volume_path: str) Generator[None, None, None]
cleanup_temporary_file(backend_name: str) None
coalesce_chain(vhd_chain: list[str]) str
coalesce_vhd(vhd_path: str) None
convert_image(source: str, dest: str, out_format: str, out_subformat: str | None = None, src_format: str | None = None, run_as_root: bool = True, throttle=None, cipher_spec: dict | None = None, passphrase_file: str | None = None, compress: bool = False, src_passphrase_file: str | None = None, image_id: str | None = None, data: QemuImgInfo | None = None, disable_sparse: bool = False) None

Convert image to other format.

NOTE: If the qemu-img convert command fails and this function raises an exception, a non-empty dest file may be left in the filesystem. It is the responsibility of the caller to decide what to do with this file.

Parameters:
  • source – source filename

  • dest – destination filename

  • out_format – output image format of qemu-img

  • out_subformat – output image subformat

  • src_format – source image format (use image_utils.fixup_disk_format() to translate from a Glance format to one recognizable by qemu_img)

  • run_as_root – run qemu-img as root

  • throttle – a cinder.throttling.Throttle object, or None

  • cipher_spec – encryption details

  • passphrase_file – filename containing luks passphrase

  • compress – compress w/ qemu-img when possible (best effort)

  • src_passphrase_file – filename containing source volume’s luks passphrase

  • image_id – the image ID if this is a Glance image, or None

  • data – a imageutils.QemuImgInfo object from this image, or None

Raises:
  • ImageUnacceptable – when the image fails some format checks

  • ProcessExecutionError – when something goes wrong during conversion

create_temporary_file(*args: str, **kwargs: str) str
decode_cipher(cipher_spec: str, key_size: int) dict[str, str]

Decode a dm-crypt style cipher specification string

The assumed format being cipher-chainmode-ivmode, similar to that documented under linux/Documentation/admin-guide/device-mapper/dm-crypt.txt in the kernel source tree. Cinder does not support the [:keycount] or [:ivopts] options.

discover_vhd_chain(directory: str) list[str]
extract_targz(archive_name: str, target: str) None
fetch(context: RequestContext, image_service: GlanceImageService, image_id: str, path: str, _user_id, _project_id) None
fetch_to_raw(context: RequestContext, image_service: GlanceImageService, image_id: str, dest: str, blocksize: int, user_id: str | None = None, project_id: str | None = None, size: int | None = None, run_as_root: bool = True, disable_sparse: bool = False) None
fetch_to_vhd(context: RequestContext, image_service: GlanceImageService, image_id: str, dest: str, blocksize: int, volume_subformat: str | None = None, user_id: str | None = None, project_id: str | None = None, run_as_root: bool = True, disable_sparse: bool = False) None
fetch_to_volume_format(context: RequestContext, image_service: GlanceImageService, image_id: str, dest: str, volume_format: str, blocksize: int, volume_subformat: str | None = None, user_id: str | None = None, project_id: str | None = None, size: int | None = None, run_as_root: bool = True, disable_sparse: bool = False) None
fetch_verify_image(context: RequestContext, image_service: GlanceImageService, image_id: str, dest: str) None
filter_out_reserved_namespaces_metadata(metadata: dict[str, str] | None) dict[str, str]
fix_vhd_chain(vhd_chain: list[str]) None
fixup_disk_format(disk_format: str) str

Return the format to be provided to qemu-img convert.

from_qemu_img_disk_format(disk_format: str) str

Return the conventional format derived from qemu-img format.

get_qemu_data(image_id: str, has_meta: bool, disk_format_raw: bool, dest: str, run_as_root: bool, force_share: bool = False) QemuImgInfo
get_qemu_img_version() list[int] | None

The qemu-img version will be cached until the process is restarted.

get_vhd_size(vhd_path: str) int
is_xenserver_format(image_meta: dict) bool
qemu_img_info(path: str, run_as_root: bool = True, force_share: bool = False, allow_qcow2_backing_file: bool = False) QemuImgInfo

Return an object containing the parsed output from qemu-img info.

replace_xenserver_image_with_coalesced_vhd(image_file: str) None
resize_image(source: str, size: int, run_as_root: bool = False, file_format: str | None = None) None

Changes the virtual size of the image.

resize_vhd(vhd_path: str, size: int, journal: str) None
set_vhd_parent(vhd_path: str, parentpath: str) None
temporary_dir() ContextManager[str]
temporary_file(*args: str, **kwargs) Generator[str, None, None]
upload_volume(context: RequestContext, image_service: GlanceImageService, image_meta: dict, volume_path: str, volume_fd=None, volume_format: str = 'raw', run_as_root: bool = True, compress: bool = True, store_id: str | None = None, base_image_ref: str | None = None) None
validate_stores_id(context: RequestContext, image_service_store_id: str) None
verify_glance_image_signature(context: RequestContext, image_service: GlanceImageService, image_id: str, path: str) bool