diff --git a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java index 1fec561dc890..51b13a8c9a61 100644 --- a/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java +++ b/plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/qemu/QemuImg.java @@ -927,7 +927,10 @@ public boolean supportsImageFormat(QemuImg.PhysicalDiskFormat format) { } protected static boolean helpSupportsImageFormat(String text, QemuImg.PhysicalDiskFormat format) { - Pattern pattern = Pattern.compile("Supported\\sformats:[a-zA-Z0-9-_\\s]*?\\b" + format + "\\b", CASE_INSENSITIVE); + // QEMU >= 10.1.0 changed the qemu-img --help header from + // "Supported formats:" to "Supported image formats:", so the word + // "image" must be treated as optional here. + Pattern pattern = Pattern.compile("Supported\\s(image\\s)?formats:[a-zA-Z0-9-_\\s]*?\\b" + format + "\\b", CASE_INSENSITIVE); return pattern.matcher(text).find(); } diff --git a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java index 5a0274257764..15f6785c1fd4 100644 --- a/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java +++ b/plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/qemu/QemuImgTest.java @@ -390,6 +390,21 @@ public void testHelpSupportsImageFormat() throws QemuImgException, LibvirtExcept Assert.assertFalse("should not support http", QemuImg.helpSupportsImageFormat(partialHelp, PhysicalDiskFormat.SHEEPDOG)); } + @Test + public void testHelpSupportsImageFormatQemu101Header() throws QemuImgException, LibvirtException { + // qemu-img 10.1.0 (e.g. RHEL 9.8: qemu-kvm-10.1.0-17.el9_8.3) changed the + // help header from "Supported formats:" to "Supported image formats:" + String help = "Supported image formats:\n" + + " blkdebug blklogwrites blkverify compress copy-before-write copy-on-read\n" + + " file ftp ftps host_cdrom host_device http https io_uring luks nbd null-aio\n" + + " null-co nvme nvme-io_uring preallocate qcow2 quorum raw rbd\n" + + " snapshot-access throttle vdi vhdx virtio-blk-vfio-pci\n" + + " virtio-blk-vhost-user virtio-blk-vhost-vdpa vmdk vpc\n"; + Assert.assertTrue("should support luks", QemuImg.helpSupportsImageFormat(help, PhysicalDiskFormat.LUKS)); + Assert.assertTrue("should support qcow2", QemuImg.helpSupportsImageFormat(help, PhysicalDiskFormat.QCOW2)); + Assert.assertFalse("should not support sheepdog", QemuImg.helpSupportsImageFormat(help, PhysicalDiskFormat.SHEEPDOG)); + } + @Test public void testCheckAndRepair() throws LibvirtException { String filename = "/tmp/" + UUID.randomUUID() + ".qcow2";