Skip to content

Commit 2321661

Browse files
fix(drivers): prefer the logical network name when reporting a port's source
A type='network' interface backed by a libvirt network with <forward mode='bridge'/> (e.g. a boot network riding the same bridge as the main network) gets rewritten by libvirt to type='bridge' in the live domain XML, but its <source> element keeps both the original 'network' attribute and the underlying 'bridge' one. Reading by iface type alone picked up the bridge name, permanently diverging from the target state's logical network name and leaving update_on_dp() stuck logging "Unknown update action" every iteration since no tracked field actually looked different to it.
1 parent c1ab9fc commit 2321661

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

exordos_core/compute/pool/drivers/libvirt.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@
4141
CONSOLE_LOG_DIR = "/var/log/libvirt/qemu"
4242

4343

44+
def _interface_source(
45+
iface: ET.Element, source_el: tp.Optional[ET.Element]
46+
) -> tp.Optional[str]:
47+
"""Return the logical network/bridge name this interface connects to.
48+
49+
A domain interface created as type='network' backed by a libvirt
50+
network with <forward mode='bridge'/> gets rewritten by libvirt in
51+
the live/persistent XML to type='bridge', but its <source> element
52+
keeps both the original 'network' attribute (the logical name the
53+
orchestrator/target state actually tracks) and the 'bridge' one
54+
(the real underlying device). Prefer 'network' when present so a
55+
boot port riding such a network still reports its logical name
56+
instead of the bridge it happens to be implemented with.
57+
"""
58+
if source_el is None:
59+
return None
60+
return source_el.get("network") or source_el.get(iface.get("type"))
61+
62+
4463
class StoragePoolType(enum.Enum):
4564
DIR = "dir"
4665
ZFS = "zfs"
@@ -621,11 +640,7 @@ def _domain2machine(
621640
mac_el = iface.find("mac")
622641
source_el = iface.find("source")
623642
mac = mac_el.get("address")
624-
# The boot-network port is always type='network' regardless of
625-
# the hypervisor's own network_type (see create_machine) - read
626-
# the source attribute this specific interface actually has
627-
# ('network' or 'bridge'), not the hypervisor's configured type.
628-
source = source_el.get(iface.get("type"))
643+
source = _interface_source(iface, source_el)
629644

630645
if not mac or not source:
631646
raise ValueError(f"Interface {iface} has no mac or source")
@@ -704,9 +719,7 @@ def _list_interfaces(self, machine: models.Machine) -> tp.List[models.Port]:
704719
mac_el = iface.find("mac")
705720
source_el = iface.find("source")
706721
mac = mac_el.get("address")
707-
# See _domain2machine: read the source attribute this specific
708-
# interface actually has, not the hypervisor's network_type.
709-
source = source_el.get(iface.get("type"))
722+
source = _interface_source(iface, source_el)
710723

711724
if not mac or not source:
712725
raise ValueError(f"Interface {iface} has no mac or source")

0 commit comments

Comments
 (0)