mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 19:56:48 +00:00
refactor(computes): the Computes page reads capacity through vrtManager
The capacity read lived in its own module with raw libvirt calls and a thread pool with a deadline, beside helpers that already read the same things. It now uses them: - wvmHostDetails.get_capacity() sums the vCPUs and memory of all and of the running VMs from get_host_instances(), against the host's info. - get_storages_info() also gives each pool's free space. - Compute.capacity joins the two, like cpu_count and ram_size, and is None when the host is down or the read fails. The page reads the hosts one after another, as it already connected to each of them; a host that cannot be reached is given up after the connect timeout. computes/capacity.py and its thread handling are gone. The page looks and sorts as before.
This commit is contained in:
parent
1436ed13af
commit
d9f9ebab58
8 changed files with 114 additions and 185 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import time
|
||||
|
||||
from libvirt import VIR_NODE_CPU_STATS_ALL_CPUS
|
||||
from libvirt import VIR_DOMAIN_SHUTOFF, VIR_NODE_CPU_STATS_ALL_CPUS
|
||||
|
||||
from vrtManager.connection import wvmConnect
|
||||
from vrtManager.util import get_xml_path
|
||||
|
|
@ -83,3 +83,18 @@ class wvmHostDetails(wvmConnect):
|
|||
) # cpu version
|
||||
info.append(self.wvm.getURI()) # uri
|
||||
return info
|
||||
|
||||
def get_capacity(self):
|
||||
"""
|
||||
What the host has given its VMs: vCPUs and memory (bytes) of all VMs
|
||||
and of the running ones, against its CPUs and memory. A shut-off VM
|
||||
takes its share again when it starts.
|
||||
"""
|
||||
vcpus = {"all": 0, "running": 0}
|
||||
assigned = {"all": 0, "running": 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"]
|
||||
return {"cpus": self.host_info[2], "memory": self.host_info[1] * 1048576,
|
||||
"vcpus": vcpus, "assigned": assigned}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class wvmStorages(wvmConnect):
|
|||
stg_status = stg.isActive()
|
||||
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
|
||||
stg_vol = len(stg.listVolumes()) if stg_status else None
|
||||
stg_size = stg.info()[1]
|
||||
_state, stg_size, _allocation, stg_free = stg.info()
|
||||
storages.append(
|
||||
{
|
||||
"name": pool,
|
||||
|
|
@ -22,6 +22,7 @@ class wvmStorages(wvmConnect):
|
|||
"type": stg_type,
|
||||
"volumes": stg_vol,
|
||||
"size": stg_size,
|
||||
"free": stg_free,
|
||||
}
|
||||
)
|
||||
return storages
|
||||
|
|
|
|||
|
|
@ -13,9 +13,19 @@ from django.conf import settings
|
|||
if not settings.configured:
|
||||
settings.configure(MAC_OUI="52:54:10")
|
||||
|
||||
from libvirt import VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET, VIR_ERR_NO_SUPPORT, VIR_ERR_OPERATION_DENIED, VIR_ERR_XML_ERROR, libvirtError
|
||||
from libvirt import (
|
||||
VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET,
|
||||
VIR_DOMAIN_PAUSED,
|
||||
VIR_DOMAIN_RUNNING,
|
||||
VIR_DOMAIN_SHUTOFF,
|
||||
VIR_ERR_NO_SUPPORT,
|
||||
VIR_ERR_OPERATION_DENIED,
|
||||
VIR_ERR_XML_ERROR,
|
||||
libvirtError,
|
||||
)
|
||||
from vrtManager.connection import wvmConnect
|
||||
from vrtManager.hostdetails import wvmHostDetails
|
||||
from vrtManager.storage import wvmStorages
|
||||
|
||||
CAPABILITIES = """<capabilities><host><cpu><arch>x86_64</arch></cpu></host>
|
||||
<guest><os_type>hvm</os_type><arch name='x86_64'><emulator>/usr/bin/qemu-kvm</emulator>
|
||||
|
|
@ -132,3 +142,32 @@ class ChangeInterfacesTestCase(unittest.TestCase):
|
|||
self.assertIs(conn.can_change_interfaces(), changeable)
|
||||
# an invalid definition: nothing can be defined by asking
|
||||
conn.wvm.interfaceDefineXML.assert_called_once_with("<interface/>", 0)
|
||||
|
||||
|
||||
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},
|
||||
})
|
||||
self.assertEqual(conn.get_capacity(), {
|
||||
"cpus": 4, "memory": 2 * gib,
|
||||
"vcpus": {"all": 14, "running": 6},
|
||||
"assigned": {"all": 14 * gib, "running": 6 * gib},
|
||||
})
|
||||
conn.get_host_instances.assert_called_once_with(raw_mem_size=True)
|
||||
|
||||
|
||||
class StoragesInfoTestCase(unittest.TestCase):
|
||||
def test_each_pool_tells_its_free_space(self):
|
||||
conn = connection(wvmStorages)
|
||||
pool = MagicMock(**{"isActive.return_value": 1, "XMLDesc.return_value": "<pool type='dir'/>",
|
||||
"listVolumes.return_value": ["a.qcow2"], "info.return_value": [2, 500, 380, 120]})
|
||||
conn.get_storages = lambda: ["default"]
|
||||
conn.get_storage = lambda name: pool
|
||||
(info,) = conn.get_storages_info()
|
||||
self.assertEqual((info["name"], info["size"], info["free"]), ("default", 500, 120))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue