diff --git a/supervisor/dbus/network/interface.py b/supervisor/dbus/network/interface.py index bce44f2d4..eb8de4407 100644 --- a/supervisor/dbus/network/interface.py +++ b/supervisor/dbus/network/interface.py @@ -31,6 +31,7 @@ class NetworkInterface(DBusInterfaceProxy): bus_name: str = DBUS_NAME_NM properties_interface: str = DBUS_IFACE_DEVICE + sync_properties: bool = False def __init__(self, nm_dbus: DBus, object_path: str) -> None: """Initialize NetworkConnection object.""" @@ -100,7 +101,11 @@ class NetworkInterface(DBusInterfaceProxy): async def connect(self, bus: MessageBus) -> None: """Connect to D-Bus.""" - return await super().connect(bus) + await super().connect(bus) + + self.sync_properties = self.managed + if self.sync_properties and self.is_connected: + self.dbus.sync_property_changes(self.properties_interface, self.update) @dbus_connected async def update(self, changed: dict[str, Any] | None = None) -> None: diff --git a/tests/dbus/network/test_interface.py b/tests/dbus/network/test_interface.py index a4d8f1737..18c96a8df 100644 --- a/tests/dbus/network/test_interface.py +++ b/tests/dbus/network/test_interface.py @@ -6,6 +6,7 @@ import pytest from supervisor.dbus.const import DeviceType, InterfaceMethod from supervisor.dbus.network import NetworkManager +from supervisor.dbus.network.interface import NetworkInterface from tests.common import fire_property_change_signal from tests.const import TEST_INTERFACE, TEST_INTERFACE_WLAN @@ -15,6 +16,7 @@ from tests.const import TEST_INTERFACE, TEST_INTERFACE_WLAN async def test_network_interface_ethernet(network_manager: NetworkManager): """Test network interface.""" interface = network_manager.interfaces[TEST_INTERFACE] + assert interface.sync_properties is True assert interface.name == TEST_INTERFACE assert interface.type == DeviceType.ETHERNET assert interface.connection.state == 2 @@ -55,6 +57,7 @@ async def test_network_interface_ethernet(network_manager: NetworkManager): async def test_network_interface_wlan(network_manager: NetworkManager): """Test network interface.""" interface = network_manager.interfaces[TEST_INTERFACE_WLAN] + assert interface.sync_properties is True assert interface.name == TEST_INTERFACE_WLAN assert interface.type == DeviceType.WIRELESS @@ -83,3 +86,19 @@ async def test_old_wireless_disconnect(network_manager: NetworkManager): assert interface.wireless is None assert wireless.is_connected is False + + +async def test_unmanaged_interface(network_manager: NetworkManager): + """Test unmanaged interfaces don't sync properties.""" + interface = NetworkInterface( + network_manager.dbus, "/org/freedesktop/NetworkManager/Devices/35" + ) + await interface.connect(network_manager.dbus.bus) + + assert interface.managed is False + assert interface.connection is None + assert interface.driver == "veth" + assert interface.sync_properties is False + + with pytest.raises(AssertionError): + fire_property_change_signal(interface, {"Driver": "test"}) diff --git a/tests/fixtures/org_freedesktop_NetworkManager_Device_35.json b/tests/fixtures/org_freedesktop_NetworkManager_Device_35.json new file mode 100644 index 000000000..ac9af67ca --- /dev/null +++ b/tests/fixtures/org_freedesktop_NetworkManager_Device_35.json @@ -0,0 +1,34 @@ +{ + "Udi": "/sys/devices/virtual/net/veth87bd238'", + "Path": "", + "Interface": "veth87bd238", + "IpInterface": "veth87bd238", + "Driver": "veth", + "DriverVersion": "1.0", + "FirmwareVersion": "", + "Capabilities": 7, + "Ip4Address": 0, + "State": 10, + "StateReason": [10, 0], + "ActiveConnection": "/", + "Ip4Config": "/", + "Dhcp4Config": "/", + "Ip6Config": "/", + "Dhcp6Config": "/", + "Managed": false, + "Autoconnect": true, + "FirmwareMissing": false, + "NmPluginMissing": false, + "DeviceType": 20, + "AvailableConnections": [], + "PhysicalPortId": "", + "Mtu": 1500, + "Metered": 0, + "LldpNeighbors": [], + "Real": true, + "Ip4Connectivity": 0, + "Ip6Connectivity": 0, + "InterfaceFlags": 65539, + "HwAddress": "9A:4B:E3:9A:F8:D3", + "Ports": [] +}