From 8251b6c61c060a3c8b7a5ca6cbe06d0a89cadc59 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 21 May 2025 13:50:46 +0200 Subject: [PATCH] Process NetworkManager PrimaryConnection changes (#5903) Process NetworkManager interface updates in case PrimaryConnection changes. This makes sure that the /network/interface/default/info endpoint can be used to get the IP address of the primary interface. --- supervisor/dbus/network/__init__.py | 12 ++++++++---- tests/dbus/network/test_network_manager.py | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/supervisor/dbus/network/__init__.py b/supervisor/dbus/network/__init__.py index ac2ff0f8c..b42999a5e 100644 --- a/supervisor/dbus/network/__init__.py +++ b/supervisor/dbus/network/__init__.py @@ -185,10 +185,14 @@ class NetworkManager(DBusInterfaceProxy): if not changed and self.dns.is_connected: await self.dns.update() - if changed and ( - DBUS_ATTR_DEVICES not in changed - or {intr.object_path for intr in self.interfaces if intr.managed}.issubset( - set(changed[DBUS_ATTR_DEVICES]) + if ( + changed + and DBUS_ATTR_PRIMARY_CONNECTION not in changed + and ( + DBUS_ATTR_DEVICES not in changed + or { + intr.object_path for intr in self.interfaces if intr.managed + }.issubset(set(changed[DBUS_ATTR_DEVICES])) ) ): # If none of our managed devices were removed then most likely this is just veths changing. diff --git a/tests/dbus/network/test_network_manager.py b/tests/dbus/network/test_network_manager.py index 4a0da3262..894c64ced 100644 --- a/tests/dbus/network/test_network_manager.py +++ b/tests/dbus/network/test_network_manager.py @@ -249,3 +249,25 @@ async def test_network_manager_stopped( capture_exception.assert_called_once() assert isinstance(capture_exception.call_args.args[0], DBusServiceUnkownError) assert "NetworkManager not responding" in caplog.text + + +async def test_primary_connection_update( + network_manager_service: NetworkManagerService, + network_manager: NetworkManager, +): + """Test handling of primary connection change.""" + interface = next( + ( + intr + for intr in network_manager.interfaces + if intr.object_path == "/org/freedesktop/NetworkManager/Devices/1" + ), + None, + ) + await network_manager.update({"PrimaryConnection": "/"}) + assert interface.primary is False + + await network_manager.update( + {"PrimaryConnection": "/org/freedesktop/NetworkManager/ActiveConnection/1"} + ) + assert interface.primary is True