From dc26a1d2520383f49996a93eb591e1013b3179b8 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Mon, 4 Sep 2023 17:50:31 +0200 Subject: [PATCH 1/2] network: fix crash upon accessing Help after creating a bond When accessing the Help menu, Subiquity looks up the IP addresses currently configured - so it knows whether to show the "Help on SSH access" option. Unfortunately, it also looks for IP addresses on devices that were "configured" through the network screen but that still do not exist in the system. When such a device exist (e.g., a bond), the Subiquity client crashes with the following exception: Traceback (most recent call last): File "subiquity/common/api/server.py", line 164, in handler result = await implementation(**args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "subiquity/server/server.py", line 117, in ssh_info_GET ips.extend(map(str, dev.actual_global_ip_addresses)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "subiquitycore/models/network.py", line 394, in actual_global_ip_addresses for _, addr in sorted(self.info.addresses.items()) ^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'addresses' A similar crash is observed when calling /network/global_addresses after creating the bond. Fixed by only checking the IP addresses of devices that have a probert.network.Link instance (i.e., they exist in the system). Signed-off-by: Olivier Gayot --- subiquity/server/controllers/network.py | 2 ++ subiquity/server/server.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/subiquity/server/controllers/network.py b/subiquity/server/controllers/network.py index 463c8131..d1414958 100644 --- a/subiquity/server/controllers/network.py +++ b/subiquity/server/controllers/network.py @@ -255,6 +255,8 @@ class NetworkController(BaseNetworkController, SubiquityController): async def global_addresses_GET(self) -> List[str]: ips: List[str] = [] for dev in self.model.get_all_netdevs(): + if dev.info is None: + continue ips.extend(map(str, dev.actual_global_ip_addresses)) return ips diff --git a/subiquity/server/server.py b/subiquity/server/server.py index 5550b8e5..175aa597 100644 --- a/subiquity/server/server.py +++ b/subiquity/server/server.py @@ -114,6 +114,8 @@ class MetaController: ips: List[str] = [] if self.app.base_model.network: for dev in self.app.base_model.network.get_all_netdevs(): + if dev.info is None: + continue ips.extend(map(str, dev.actual_global_ip_addresses)) if not ips: return None From 221466aa7008ba2456d5d79c28f471c874ad6836 Mon Sep 17 00:00:00 2001 From: Olivier Gayot Date: Wed, 6 Sep 2023 14:42:53 +0200 Subject: [PATCH 2/2] network: document and add type hint for NetworkDev.info Signed-off-by: Olivier Gayot --- subiquitycore/models/network.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/subiquitycore/models/network.py b/subiquitycore/models/network.py index 587ba056..e8158980 100644 --- a/subiquitycore/models/network.py +++ b/subiquitycore/models/network.py @@ -21,6 +21,7 @@ from socket import AF_INET, AF_INET6 from typing import Dict, List, Optional import attr +import probert.network import yaml from subiquitycore import netplan @@ -189,13 +190,16 @@ class BondParameters: ] -class NetworkDev(object): +class NetworkDev: def __init__(self, model, name, typ): self._model = model self._name = name self.type = typ self.config = {} - self.info = None + # Devices that have been configured in Subiquity but do not (yet) exist + # on the system have their "info" field set to None. Once they exist, + # probert should pass on the information through a call to new_link(). + self.info: Optional[probert.network.Link] = None self.disabled_reason = None self.dhcp_events = {} self._dhcp_state = {