mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
fix(instances): a paused VM's guest agent counts as not read
A paused guest cannot answer its agent, so the address search and the VM report asked it nothing, but counted the VM neither as without an agent nor as not read: the coverage line read as if every address had been seen. It now counts among the agents not read, and the line names the paused case.
This commit is contained in:
parent
ecb850739f
commit
a6218df6b2
4 changed files with 18 additions and 8 deletions
|
|
@ -152,14 +152,14 @@ def _read_host(target, network, everything, mac):
|
|||
"""The cheap first phase on one compute: leases and ARP of each running
|
||||
VM in scope (with everything, the shut-off ones are listed too). Returns
|
||||
the VMs' records, the observations, the (domain, vm, MACs) whose agent is
|
||||
to be asked, the number of running VMs read and of those without a
|
||||
connected agent; None when the compute cannot be reached (connecting may
|
||||
to be asked, the number of running VMs read, of those without a
|
||||
connected agent, and of paused ones whose agent cannot answer; None when the compute cannot be reached (connecting may
|
||||
take the connect timeout, so this too runs on the compute's thread). A
|
||||
VM that stops or leaves meanwhile is skipped. With a mac, only the VMs
|
||||
with a NIC of that MAC, and only that NIC's addresses."""
|
||||
if target.compute.status is not True:
|
||||
return None
|
||||
records, found, agents, checked, no_agent = [], [], [], 0, 0
|
||||
records, found, agents, checked, no_agent, paused = [], [], [], 0, 0, 0
|
||||
listing = 0 if everything else VIR_CONNECT_LIST_DOMAINS_ACTIVE
|
||||
for dom in target.compute.connection.listAllDomains(listing):
|
||||
try:
|
||||
|
|
@ -187,9 +187,11 @@ def _read_host(target, network, everything, mac):
|
|||
found += _matching(dom, vm, source, macs, network) or []
|
||||
if not agent_connected(xml):
|
||||
no_agent += 1
|
||||
elif state == VIR_DOMAIN_RUNNING: # a paused guest cannot answer
|
||||
elif state == VIR_DOMAIN_RUNNING:
|
||||
agents.append((dom, vm, macs))
|
||||
return records, found, agents, checked, no_agent
|
||||
else:
|
||||
paused += 1
|
||||
return records, found, agents, checked, no_agent, paused
|
||||
def _rows(observations):
|
||||
"""One row per VM, MAC and address with its sources; sorted by address.
|
||||
A VM is its compute and UUID: one UUID may be defined on two hosts."""
|
||||
|
|
@ -236,11 +238,12 @@ def _survey(targets, network, deadline, everything, with_os=False, mac=None):
|
|||
if read_host is None:
|
||||
hosts_down.append(hosts[done].name)
|
||||
continue
|
||||
host_records, found, agents, host_checked, host_no_agent = read_host
|
||||
host_records, found, agents, host_checked, host_no_agent, host_paused = read_host
|
||||
records += host_records
|
||||
observations += found
|
||||
checked += host_checked
|
||||
no_agent += host_no_agent
|
||||
unread += host_paused # a paused guest cannot answer its agent
|
||||
# the OS on its own thread: a hung OS read keeps the addresses read
|
||||
for dom, vm, macs in agents:
|
||||
agent_reads.append(pool.submit(_counted, _matching, dom, vm,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
data-unregistered="{% trans "(not registered in the panel)" %}" data-conflict="{% trans "possible conflict" %}"
|
||||
data-checked="{% trans "Running VMs checked: %(n)s." %}"
|
||||
data-no-agent="{% trans "%(n)s had no connected guest agent; a static address on them cannot be seen." %}"
|
||||
data-unread="{% trans "Guest agents not read (no answer in time, or an error): %(n)s." %}"
|
||||
data-unread="{% trans "Guest agents not read (a paused VM, no answer in time, or an error): %(n)s." %}"
|
||||
data-hosts-down="{% trans "Not reached: %(hosts)s." %}"
|
||||
data-hosts-unfinished="{% trans "Not finished in time: %(hosts)s." %}"
|
||||
data-read-at="{% trans "Read at %(time)s." %}"
|
||||
|
|
|
|||
|
|
@ -171,6 +171,13 @@ class FindTests(unittest.TestCase):
|
|||
result = self.find(addresses.Target(c, None))
|
||||
self.assertEqual((result["checked"], result["no_agent"]), (2, 1))
|
||||
|
||||
def test_a_paused_vm_with_an_agent_is_an_agent_not_read(self):
|
||||
# a paused guest cannot answer its agent: not "checked and empty"
|
||||
paused = FakeDomain({ARP: {"e": iface(MAC1, (0, "192.0.2.10", 24))}}, state=3)
|
||||
result = self.find(addresses.Target(compute("c1", paused), None))
|
||||
self.assertEqual((result["checked"], result["no_agent"], result["unread"]), (1, 0, 1))
|
||||
self.assertEqual([m["sources"] for m in result["matches"]], [["ARP"]])
|
||||
|
||||
def test_a_hung_agent_does_not_hold_the_answer(self):
|
||||
hung = threading.Event()
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ def vm_report(request):
|
|||
f"VMs listed: {len(rows)}",
|
||||
f"Running VMs read: {result['checked']}",
|
||||
f"Without a connected guest agent (a static address on them cannot be seen): {result['no_agent']}",
|
||||
f"Guest agents not read (no answer in time, or an error): {result['unread']}"]
|
||||
f"Guest agents not read (a paused VM, no answer in time, or an error): {result['unread']}"]
|
||||
if result["hosts_down"]:
|
||||
notes.append("Hosts not reached: " + ", ".join(result["hosts_down"]))
|
||||
if result["hosts_unfinished"]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue