1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 03:36:48 +00:00

perf(vrtManager): the Computes page reads each host's VMs once

A host's capacity (Computes page, new VM dialog) came from
get_host_instances, which listed the VMs by ID and by name and then
looked each up, read its XML and its info: four calls a VM, for every
host on the page. It now uses the VM lists' get_domain_rows: the states
in one call and each VM's XML once. get_host_instances had no other
caller and is gone.

Checked on QEMU against the per-VM info of every domain (running, paused,
shut off): the same vCPUs and memory. A VM gone while the host is read
is left out instead of making the host's capacity unreadable.
This commit is contained in:
catborise 2026-11-04 21:20:44 +03:00
parent 2d0f41ee57
commit 40087143a1
3 changed files with 13 additions and 44 deletions

View file

@ -1225,39 +1225,6 @@ class wvmConnect(object):
for dev in self.wvm.listAllDevices(libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET)
]
def get_host_instances(self, raw_mem_size=False):
vname = {}
def get_info(doc):
mem = util.get_xpath(doc, "/domain/currentMemory")
mem = int(mem) // 1024
if raw_mem_size:
mem = int(mem) * (1024 * 1024)
cur_vcpu = util.get_xpath(doc, "/domain/vcpu/@current")
if cur_vcpu:
vcpu = cur_vcpu
else:
vcpu = util.get_xpath(doc, "/domain/vcpu")
title = util.get_xpath(doc, "/domain/title")
title = title if title else ""
description = util.get_xpath(doc, "/domain/description")
description = description if description else ""
return mem, vcpu, title, description
for name in self.get_instances():
dom = self.get_instance(name)
xml = dom.XMLDesc(0)
(mem, vcpu, title, description) = util.get_xml_path(xml, func=get_info)
vname[dom.name()] = {
"status": dom.info()[0],
"uuid": dom.UUIDString(),
"vcpu": vcpu,
"memory": mem,
"title": title,
"description": description,
}
return vname
def get_user_instances(self, name):
dom = self.get_instance(name)
xml = dom.XMLDesc(0)

View file

@ -111,11 +111,12 @@ class wvmHostDetails(wvmConnect):
vcpus = {"all": 0, "running": 0}
assigned = {"all": 0, "running": 0}
vms = {"running": 0, "paused": 0, "shutoff": 0, "other": 0}
for vm in self.get_host_instances(raw_mem_size=True).values():
for share in ("all",) if vm["status"] == VIR_DOMAIN_SHUTOFF else ("all", "running"):
vcpus[share] += int(vm["vcpu"])
assigned[share] += vm["memory"]
vms[VM_STATES.get(vm["status"], "other")] += 1
# the VM lists' read: the states in one call, each VM's XML once
for (state, _max_memory, memory, vcpu), _title in self.get_domain_rows().values():
for share in ("all",) if state == VIR_DOMAIN_SHUTOFF else ("all", "running"):
vcpus[share] += vcpu
assigned[share] += memory * 1024
vms[VM_STATES.get(state, "other")] += 1
return {"cpus": self.host_info[2], "memory": self.host_info[1] * 1048576,
"vcpus": vcpus, "assigned": assigned, "vms": vms}

View file

@ -153,11 +153,12 @@ class CapacityTestCase(unittest.TestCase):
def test_a_host_gives_its_vms_cpus_and_memory(self):
conn = connection(wvmHostDetails)
gib = 1024 ** 3
# get_host_instances gives the vCPUs as text, the memory in bytes
conn.get_host_instances = MagicMock(return_value={
"web": {"status": VIR_DOMAIN_RUNNING, "vcpu": "4", "memory": 4 * gib},
"db": {"status": VIR_DOMAIN_PAUSED, "vcpu": "2", "memory": 2 * gib},
"old": {"status": VIR_DOMAIN_SHUTOFF, "vcpu": "8", "memory": 8 * gib},
kib = gib // 1024
# get_domain_rows: info (state, max memory KiB, memory KiB, vCPUs) and title
conn.get_domain_rows = MagicMock(return_value={
"u-web": ([VIR_DOMAIN_RUNNING, 8 * kib, 4 * kib, 4], ""),
"u-db": ([VIR_DOMAIN_PAUSED, 2 * kib, 2 * kib, 2], ""),
"u-old": ([VIR_DOMAIN_SHUTOFF, 8 * kib, 8 * kib, 8], ""),
})
self.assertEqual(conn.get_capacity(), {
"cpus": 4, "memory": 2 * gib,
@ -165,7 +166,7 @@ class CapacityTestCase(unittest.TestCase):
"assigned": {"all": 14 * gib, "running": 6 * gib},
"vms": {"running": 1, "paused": 1, "shutoff": 1, "other": 0},
})
conn.get_host_instances.assert_called_once_with(raw_mem_size=True)
conn.get_domain_rows.assert_called_once_with()
class CpuTopologyTestCase(unittest.TestCase):