From 40087143a194e60916d6b04ebb372ba011f6a187 Mon Sep 17 00:00:00 2001 From: catborise Date: Wed, 4 Nov 2026 21:20:44 +0300 Subject: [PATCH] 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. --- vrtManager/connection.py | 33 ----------------------------- vrtManager/hostdetails.py | 11 +++++----- vrtManager/tests/test_host_reads.py | 13 ++++++------ 3 files changed, 13 insertions(+), 44 deletions(-) diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 746cb56e..5498f588 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -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) diff --git a/vrtManager/hostdetails.py b/vrtManager/hostdetails.py index 08f30c65..1ff700ea 100644 --- a/vrtManager/hostdetails.py +++ b/vrtManager/hostdetails.py @@ -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} diff --git a/vrtManager/tests/test_host_reads.py b/vrtManager/tests/test_host_reads.py index edb32ebe..33965376 100644 --- a/vrtManager/tests/test_host_reads.py +++ b/vrtManager/tests/test_host_reads.py @@ -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):