From af0651946010e6bcc966005aa9fc2a1f38d3748a Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Mon, 30 Jul 2012 13:03:39 +0100 Subject: Avoid error during snapshot of ISO booted instance Fixes bug #1023492 If you boot an instance from an image with disk_format=iso and then attempt to snapshot (i.e. nova image-create) you currently get a traceback because we do: qemu-img convert -f qcow2 -O iso -s $snap $disk $out and 'iso' is not a format that qemu-img knows anything about. When booting the image, we use qemu-img to detect that the file is a raw image so we avoid having to special case disk_format=iso there. However, there's no way of avoiding the special casing when extracting a snapshot. Note 1 - it's not very clever to take a snapshot of a read-only disk downloaded from glance and upload it back to glance again. Adding such smarts would be a nice enhancement. Note 2 - only the destination format is important here because we can only be extracting from a qcow2 image since snapshots only work where use_cow_images=True. See also #1030844. Change-Id: I21ff6db8ebb59a83d27f224283fb76f582c38a0e --- nova/tests/test_libvirt.py | 15 ++++++++++++--- nova/virt/libvirt/utils.py | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index bb885e8c1..4e6e1ec48 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -3303,15 +3303,24 @@ disk size: 4.4M''', '')) self.mox.ReplayAll() libvirt_utils.chown('/some/path', 'soren') - def test_extract_snapshot(self): + def _do_test_extract_snapshot(self, dest_format='raw', out_format='raw'): self.mox.StubOutWithMock(utils, 'execute') - utils.execute('qemu-img', 'convert', '-f', 'qcow2', '-O', 'raw', + utils.execute('qemu-img', 'convert', '-f', 'qcow2', '-O', out_format, '-s', 'snap1', '/path/to/disk/image', '/extracted/snap') # Start test self.mox.ReplayAll() libvirt_utils.extract_snapshot('/path/to/disk/image', 'qcow2', - 'snap1', '/extracted/snap', 'raw') + 'snap1', '/extracted/snap', dest_format) + + def test_extract_snapshot_raw(self): + self._do_test_extract_snapshot() + + def test_extract_snapshot_iso(self): + self._do_test_extract_snapshot(dest_format='iso') + + def test_extract_snapshot_qcow2(self): + self._do_test_extract_snapshot(dest_format='qcow2', out_format='qcow2') def test_load_file(self): dst_fd, dst_path = tempfile.mkstemp() diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py index b71aec5dc..55bca7996 100644 --- a/nova/virt/libvirt/utils.py +++ b/nova/virt/libvirt/utils.py @@ -322,6 +322,9 @@ def extract_snapshot(disk_path, source_fmt, snapshot_name, out_path, dest_fmt): :param snapshot_name: Name of snapshot in disk image :param out_path: Desired path of extracted snapshot """ + # NOTE(markmc): ISO is just raw to qemu-img + if dest_fmt == 'iso': + dest_fmt = 'raw' qemu_img_cmd = ('qemu-img', 'convert', '-f', -- cgit