Handle volumes on stopped pools in virt.vm_info

For VMs having at least a disk on a stopped volume, we don't want the
user to get an exception when running virt.vm_info. Instead just provide
less information.
This commit is contained in:
Cédric Bosdonnat 2021-05-05 09:07:43 +02:00 committed by Megan Wilhite
parent a8d72d06ce
commit e3c52e5fba
3 changed files with 50 additions and 33 deletions

1
changelog/60132.fixed Normal file
View file

@ -0,0 +1 @@
Gracefuly handle errors in virt.vm_info

View file

@ -516,41 +516,50 @@ def _get_disks(conn, dom):
def _get_disk_volume_data(pool_name, volume_name):
qemu_target = "{}/{}".format(pool_name, volume_name)
pool = conn.storagePoolLookupByName(pool_name)
vol = pool.storageVolLookupByName(volume_name)
vol_info = vol.info()
extra_properties = {
"virtual size": vol_info[1],
"disk size": vol_info[2],
}
backing_files = [
{
"file": node.find("source").get("file"),
"file format": node.find("format").get("type"),
extra_properties = {}
try:
vol = pool.storageVolLookupByName(volume_name)
vol_info = vol.info()
extra_properties = {
"virtual size": vol_info[1],
"disk size": vol_info[2],
}
for node in elem.findall(".//backingStore[source]")
]
if backing_files:
# We had the backing files in a flat list, nest them again.
extra_properties["backing file"] = backing_files[0]
parent = extra_properties["backing file"]
for sub_backing_file in backing_files[1:]:
parent["backing file"] = sub_backing_file
parent = sub_backing_file
backing_files = [
{
"file": node.find("source").get("file"),
"file format": node.find("format").get("type"),
}
for node in elem.findall(".//backingStore[source]")
]
else:
# In some cases the backing chain is not displayed by the domain definition
# Try to see if we have some of it in the volume definition.
vol_desc = ElementTree.fromstring(vol.XMLDesc())
backing_path = vol_desc.find("./backingStore/path")
backing_format = vol_desc.find("./backingStore/format")
if backing_path is not None:
extra_properties["backing file"] = {"file": backing_path.text}
if backing_format is not None:
extra_properties["backing file"][
"file format"
] = backing_format.get("type")
if backing_files:
# We had the backing files in a flat list, nest them again.
extra_properties["backing file"] = backing_files[0]
parent = extra_properties["backing file"]
for sub_backing_file in backing_files[1:]:
parent["backing file"] = sub_backing_file
parent = sub_backing_file
else:
# In some cases the backing chain is not displayed by the domain definition
# Try to see if we have some of it in the volume definition.
vol_desc = ElementTree.fromstring(vol.XMLDesc())
backing_path = vol_desc.find("./backingStore/path")
backing_format = vol_desc.find("./backingStore/format")
if backing_path is not None:
extra_properties["backing file"] = {
"file": backing_path.text
}
if backing_format is not None:
extra_properties["backing file"][
"file format"
] = backing_format.get("type")
except libvirt.libvirtError:
# The volume won't be found if the pool is not started, just output less infos
log.info(
"Couldn't extract all volume informations: pool is likely not running or refreshed"
)
return (qemu_target, extra_properties)
if disk_type == "file":

View file

@ -192,6 +192,11 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
<disk type='volume' device='disk'>
<driver name='qemu' type='qcow2' cache='none' io='native'/>
<source pool='stopped' volume='vm05_data'/>
<target dev='vdd' bus='virtio'/>
</disk>
<disk type='network' device='cdrom'>
<driver name='qemu' type='raw' cache='none' io='native'/>
<source protocol='http' name='/pub/iso/myimage.iso' query='foo=bar&amp;baz=flurb' index='1'>
@ -205,11 +210,12 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
</devices>
</domain>
"""
domain_mock = make_mock_vm(vm_def)
make_mock_vm(vm_def)
pool_mock = make_mock_storage_pool(
"default", "dir", ["srv01_system", "srv01_data", "vm05_system"]
)
make_mock_storage_pool("stopped", "dir", [])
# Append backing store to srv01_data volume XML description
srv1data_mock = pool_mock.storageVolLookupByName("srv01_data")
@ -256,6 +262,7 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
},
},
},
"vdd": {"type": "disk", "file": "stopped/vm05_data", "file format": "qcow2"},
"hda": {
"type": "cdrom",
"file format": "raw",