From cba6466361ec9ef910880faffd309a44475734f4 Mon Sep 17 00:00:00 2001 From: Fiona Ebner Date: Fri, 6 Dec 2024 17:25:30 +0100 Subject: [PATCH] drive: add helpers for additional checks for storage layer info about volume First step towards using the storage layer format instead of the extension based format from qemu_img_format() as a source of truth everywhere. Currently, some callers use qemu_img_format() and some use parse_volname(). For import, special handling is needed, because the format can be a combined ova+$extracted_format. There is a fallback for 'raw' format when no format is returned by the storage layer for backwards compatibility, e.g. ISOs. Formats that are not part of the $QEMU_FORMAT_RE are not allowed. Signed-off-by: Fiona Ebner --- PVE/QemuServer/Drive.pm | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/PVE/QemuServer/Drive.pm b/PVE/QemuServer/Drive.pm index 6e98c095..7b298454 100644 --- a/PVE/QemuServer/Drive.pm +++ b/PVE/QemuServer/Drive.pm @@ -14,6 +14,8 @@ use base qw(Exporter); our @EXPORT_OK = qw( is_valid_drivename +checked_parse_volname +checked_volume_format drive_is_cloudinit drive_is_cdrom drive_is_read_only @@ -31,6 +33,43 @@ PVE::JSONSchema::register_standard_option('pve-qm-image-format', { optional => 1, }); +# Check that a volume can be used for image-related operations with QEMU, in +# particular, attached as VM image or ISO, used for qemu-img, or (live-)imported. +# NOTE Currently, this helper cannot be used for backups. +# TODO allow configuring certain restrictions via $opts argument, e.g. expected vtype? +sub checked_parse_volname { + my ($storecfg, $volid) = @_; + + my ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format) = + PVE::Storage::parse_volname($storecfg, $volid); + + if ($vtype eq 'import') { + die "unable to parse format for import volume '$volid'\n" if !$format; + if ($format =~ m/^ova\+(.*)$/) { + my $extracted_format = $1; + die "volume '$volid' - unknown import format '$format'\n" + if $extracted_format !~ m/^($QEMU_FORMAT_RE)$/; + return ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format); + } + } + + # TODO PVE 9 - consider switching to die for an undefined format + $format = 'raw' if !defined($format); + + die "volume '$volid' - not a QEMU image format '$format'\n" + if $format !~ m/^($QEMU_FORMAT_RE)$/; + + # For iso content type, no format is returned yet. + + return ($vtype, $name, $vmid, $basename, $basevmid, $isBase, $format); +} + +sub checked_volume_format { + my ($storecfg, $volid) = @_; + + return (checked_parse_volname($storecfg, $volid))[6]; +} + my $MAX_IDE_DISKS = 4; my $MAX_SCSI_DISKS = 31; my $MAX_VIRTIO_DISKS = 16;