使用 python-libvirt 删除包括存储在内的虚拟机

使用 python-libvirt 删除包括存储在内的虚拟机

我正在尝试用 Python 编写脚本libvirt 库,但我目前坚持一件事。

我可以成功创建虚拟机,按照我想要的方式设置它,启动它,访问它,然后关闭它。我什至可以在不再需要它后再次删除它。

但我还没有弄清楚如何摆脱虚拟机的磁盘。

在我的 Bash“原型”中,我可以直接调用virsh undefine <name> --remove-all-storage.但在所有的文档中,我还没有找到在Python中触发这个的方法。

当然我可以这样做,os.system("virsh undefine ...")但那是A)一个可怕的黑客和B)它需要安装virsh。

.undefine()对域的调用会留下虚拟磁盘。我发现了.undefineFlags(),但我发现的标志似乎都不相关(1=删除保存、2=删除快照、4=删除 NVRAM;其中没有一个会删除虚拟磁盘)。

我可以.XMLDesc()调用域并获取完整的 XML、查找定义的磁盘并获取文件路径。如果我的 Python 脚本与虚拟机在同一台机器上运行,我就可以调用os.remove()- 但事实并非如此,它运行在远程机器上。

virsh命令能够通过 libvirt 远程连接删除磁盘,所以我知道它必须以某种方式实现。但即使查看了 virsh--remove-all-storage定义的源代码,我仍然感到困惑。

该应用程序似乎要求virStorageVolWipe安全删除,或virStorageVolDelete仅删除磁盘。这需要我获得一个PythonvirStorageVol对象才能调用它的delete()方法

但是我如何获得这个对象呢?我发现了大量对“存储池”的引用,我可以遍历这些引用来查找路径,或者我什至可以从虚拟机的 XML 中获取存储磁盘的路径;但这并没有给我那个对象,所以我可以调用delete()它。

我是否真的需要循环遍历所有存储池,然后循环遍历所述池中的所有卷,然后以某种方式手动找出每个卷是否连接到我要删除的虚拟机,以便能够完全删除虚拟机当我用完它时?另外,我相信理论上可能有一个不在任何存储池中的卷,所以这也没有帮助......

为什么没有virDomainGetVolumes?我发现virDomainGetBlockInfo但这只是返回路径和类型,而不是对象virStorageVol。我错过了什么吗?

答案1

看来我想得太复杂了。

我可以通过解析返回的 XML 来获取主机到 VM 磁盘的路径.XMLDesc(),然后我可以调用.storageVolLookupByPath()(我显然之前错过了)来获取storageVol要删除的对象:

domain = conn.lookupByName("my-vm-name")
domain_xml = domain.XMLDesc()

for disk_xml_element in ElementTree.fromstring(domain_xml).findall("devices/disk"):
  for src in disk_xml_element.findall("source"):
    disk = virt_conn.storageVolLookupByPath(src.get("file"))
    disk.delete()

相关内容