1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00

fix(instances): a VM without a guest agent shows its ARP address

The ARP lookup passed 3 as the address source; libvirt's
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP is 2 and libvirt refused 3 as an
unknown source. The error was suppressed, so a VM without a guest agent
never showed an address.
This commit is contained in:
catborise 2026-10-09 08:11:48 +03:00
parent f094982737
commit 95b4418c96
3 changed files with 57 additions and 2 deletions

View file

@ -534,6 +534,7 @@ A rollback leaves the clone on a detached HEAD at the restored commit; the updat
- A VM that vanishes from its compute keeps its owners for `INSTANCE_OWNERSHIP_RETENTION_DAYS` (30) in case the same UUID comes back; superusers list and remove these records on the "Removed VMs" admin page.
- The log rotates (10 MB × 5) in `data/webvirtcloud.log`.
- A disk can be grown while its VM runs or is paused, not only when it is shut off.
- A running VM without a guest agent shows the IPv4 address the host learned by ARP (the lookup always failed before).
- After a live migration the VM's NVRAM file is deleted on the source, when it is in libvirt's `/var/lib/libvirt/qemu/nvram` and the destination does not share that directory (a VM created there later with the same name would start with those UEFI variables).
- gstfsd finds the guest's operating system the way libguestfs inspects it, so a root on LVM works, and it always answers (an error when it finds no or several operating systems). Update `/usr/local/bin/gstfsd` on every compute (see [Adding a Compute Node](#adding-a-compute-node), step 3).
- Docker no longer publishes port 6080; the console goes through nginx on the panel's port (`WS_PUBLIC_PORT`, default 80).

View file

@ -14,6 +14,7 @@ try:
VIR_DOMAIN_AFFECT_CONFIG,
VIR_DOMAIN_AFFECT_LIVE,
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT,
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP,
VIR_DOMAIN_RUNNING,
VIR_DOMAIN_XML_SECURE,
VIR_DOMAIN_XML_INACTIVE,
@ -671,8 +672,7 @@ class wvmInstance(wvmConnect):
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
)
arp_flag = 3 # libvirt."VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP"
self._ip_cache["arp"] = self._get_interface_addresses(arp_flag)
self._ip_cache["arp"] = self._get_interface_addresses(VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP)
def get_net_devices(self, config=False):
def networks(ctx):

View file

@ -0,0 +1,54 @@
"""A running VM's addresses come from the guest agent when it answers and
from the host's ARP table, so a VM without an agent shows its IPv4 address."""
import unittest
from unittest.mock import MagicMock, patch
from django.conf import settings
if not settings.configured:
settings.configure(MAC_OUI="52:54:10")
from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT, VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP
from vrtManager.instance import wvmInstance
MAC = "52:54:00:00:00:01"
ARP = {"vnet0": {"hwaddr": MAC, "addrs": [{"type": 0, "addr": "192.0.2.10", "prefix": 0}]}}
AGENT = {"eth0": {"hwaddr": MAC, "addrs": [{"type": 0, "addr": "192.0.2.20", "prefix": 24}]}}
def vm(agent):
inst = wvmInstance.__new__(wvmInstance)
inst._ip_cache = None
inst.instance = MagicMock()
inst.instance.interfaceAddresses.side_effect = lambda source: {
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT: AGENT,
VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP: ARP,
}[source]
patch.object(inst, "get_status", return_value=1).start()
patch.object(inst, "is_agent_ready", return_value=agent).start()
return inst
class InterfaceAddressesTestCase(unittest.TestCase):
def tearDown(self):
patch.stopall()
def test_a_vm_without_an_agent_shows_its_arp_address(self):
inst = vm(agent=False)
self.assertEqual(inst.get_interface_addresses(MAC), (["192.0.2.10"], []))
self.assertEqual(
[c.args for c in inst.instance.interfaceAddresses.call_args_list], [(VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP,)]
)
def test_the_agents_address_comes_first(self):
inst = vm(agent=True)
self.assertEqual(inst.get_interface_addresses(MAC), (["192.0.2.20"], []))
self.assertEqual(
[c.args for c in inst.instance.interfaceAddresses.call_args_list],
[(VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT,), (VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_ARP,)],
)
if __name__ == "__main__":
unittest.main()