如何使用 API 将 qcow2 镜像上传到 libvirt 存储并保持压缩?

How do I upload qcow2 images to libvirt storage using the API and keep compression?

提问人:dcode 提问时间:6/3/2023 最后编辑:dcode 更新时间:6/3/2023 访问量:118

问:

使用 libvirt-python 模块,我尝试使用 XML 创建卷,使用输出中提供的信息。然后我使用流上传。这可行,磁盘可以正常工作,但 libvirt 分配的物理大小等于虚拟大小。qemu-img info

import libvirt 
import pathlib

conn = libvirt.open("qemu:///system")
template_pool = conn.storagePoolLookupByName("default")
image_filename = "fedora-cloud-base-38-x86_64.qcow2"
spool_file = pathlib.Path("Fedora-Cloud-Base-38-1.6.x86_64.qcow2")

# Size from output of `qemu-img info --output=json Fedora-Cloud-Base-38-1.6.x86_64.qcow2`
image_size = 497291264
image_vsize = 5368709120
stgvol_xml = f"""
<volume>
  <name>{image_filename}</name>
  <allocation>{ image_size }</allocation>
  <capacity unit="bytes">{image_vsize}</capacity>
</volume>"""

stgvol = template_pool.createXML(stgvol_xml, 0)

def stream_handler(stream, data, file_):
    return file_.read(data)

stream = conn.newStream(0)
stgvol.upload(stream, 0, 0)
with spool_file.open(mode="rb") as f:
    stream.sendAll(stream_handler, f)
    stream.finish()

在我的测试中,我使用的是下载站点上的 Fedora Cloud Base 38 qcow2 镜像。全新下载后,SHA256 哈希将进行验证,分配的大小为 475MB,与输出一致qemu-img info

> ls -lsh Fedora-Cloud-Base-38-1.6.x86_64.qcow2
475M -rw-r--r-- 1 dcode primarygroup 475M Jun  3 10:05 Fedora-Cloud-Base-38-1.6.x86_64.qcow2

> sha256sum Fedora-Cloud-Base-38-1.6.x86_64.qcow2
d334670401ff3d5b4129fcc662cf64f5a6e568228af59076cc449a4945318482  Fedora-Cloud-Base-38-1.6.x86_64.qcow2

> qemu-img info Fedora-Cloud-Base-38-1.6.x86_64.qcow2 
image: Fedora-Cloud-Base-38-1.6.x86_64.qcow2
file format: qcow2
virtual size: 5 GiB (5368709120 bytes)
disk size: 474 MiB
cluster_size: 65536
Format specific information:
    compat: 0.10
    compression type: zlib
    refcount bits: 16

但是,在数据存储中,文件将作为稀疏图像扩展为完整的“虚拟大小”。当然,这会更改哈希值,但图像信息保持不变。

# ls -lsh Fedora-Cloud-Base-38-1.6.x86_64.qcow2 
475M -rw-------. 1 root root 5.0G Jun  3 15:10 Fedora-Cloud-Base-38-1.6.x86_64.qcow2

# sha256sum Fedora-Cloud-Base-38-1.6.x86_64.qcow2
2327ccac1781e9ff561737eb986f9863ff65827fe53efd565e6c2b801273625f  Fedora-Cloud-Base-38-1.6.x86_64.qcow2

# qemu-img info Fedora-Cloud-Base-38-1.6.x86_64.qcow2 
image: Fedora-Cloud-Base-38-1.6.x86_64.qcow2
file format: qcow2
virtual size: 5 GiB (5368709120 bytes)
disk size: 474 MiB
cluster_size: 65536
Format specific information:
    compat: 0.10
    compression type: zlib
    refcount bits: 16

作为解决方法,我使用该选项在生成的磁盘上运行,该选项确实将大小减小到接近原始大小的某个位置,但我无法使用匹配的哈希值重现原始文件。无论如何,这不是一个很好的解决方案,因为我使用的代码可能没有对 libvirt 数据存储的本地访问权限。virt-sparsify--compress

我还尝试使用 libvirt-python 中的 sparsestream.py 示例进行处理,但我不太清楚发生了什么,这似乎不是一个稀疏问题,而是压缩问题。

python qemu libvirt sparse-file

评论

0赞 Nick ODell 6/3/2023
您可以添加运行此代码所需的导入吗?
1赞 dcode 6/3/2023
做。只要原始文件 (spool_file) 位于当前工作目录中,并且您有权连接到 URI,它就应该可以工作。qemu:///system

答: 暂无答案