From 681a1ecff56bb505225e82c0966cd048108cb244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Sun, 7 Mar 2021 11:47:46 +0100 Subject: [PATCH] Set connectivity state on network tasks (#2686) * Set connectivity state on network tasks * target connectivity error --- supervisor/exceptions.py | 4 ++++ supervisor/hassos.py | 1 + supervisor/host/network.py | 15 +++++++++++++-- supervisor/resolution/checks/addon_pwned.py | 5 ++++- supervisor/supervisor.py | 17 ++++++++++++++--- supervisor/updater.py | 1 + supervisor/utils/pwned.py | 4 ++-- 7 files changed, 39 insertions(+), 8 deletions(-) diff --git a/supervisor/exceptions.py b/supervisor/exceptions.py index 9365c58b5..590c7684d 100644 --- a/supervisor/exceptions.py +++ b/supervisor/exceptions.py @@ -303,6 +303,10 @@ class PwnedError(HassioError): """Errors while checking pwned passwords.""" +class PwnedConnectivityError(PwnedError): + """Connectivity errors while checking pwned passwords.""" + + # docker/api diff --git a/supervisor/hassos.py b/supervisor/hassos.py index 7c0616e4b..69ef1e933 100644 --- a/supervisor/hassos.py +++ b/supervisor/hassos.py @@ -89,6 +89,7 @@ class HassOS(CoreSysAttributes): return raucb except (aiohttp.ClientError, asyncio.TimeoutError) as err: + self.sys_supervisor.connectivity = False _LOGGER.warning("Can't fetch versions from %s: %s", url, err) except OSError as err: diff --git a/supervisor/host/network.py b/supervisor/host/network.py index e55607384..6c6706f25 100644 --- a/supervisor/host/network.py +++ b/supervisor/host/network.py @@ -8,6 +8,7 @@ from typing import List, Optional, Union import attr +from ..const import ATTR_HOST_INTERNET from ..coresys import CoreSys, CoreSysAttributes from ..dbus.const import ( DBUS_NAME_NM_CONNECTION_ACTIVE_CHANGED, @@ -46,6 +47,16 @@ class NetworkManager(CoreSysAttributes): """Return true current connectivity state.""" return self._connectivity + @connectivity.setter + def connectivity(self, state: bool) -> None: + """Set host connectivity state.""" + if self._connectivity == state: + return + self._connectivity = state + self.sys_homeassistant.websocket.supervisor_update_event( + "network", {ATTR_HOST_INTERNET: state} + ) + @property def interfaces(self) -> List[Interface]: """Return a dictionary of active interfaces.""" @@ -79,10 +90,10 @@ class NetworkManager(CoreSysAttributes): # Check connectivity try: state = await self.sys_dbus.network.check_connectivity() - self._connectivity = state[0] == 4 + self.connectivity = state[0] == 4 except DBusError as err: _LOGGER.warning("Can't update connectivity information: %s", err) - self._connectivity = False + self.connectivity = False def get(self, inet_name: str) -> Interface: """Return interface from interface name.""" diff --git a/supervisor/resolution/checks/addon_pwned.py b/supervisor/resolution/checks/addon_pwned.py index 1fcc67d23..c87f93f6f 100644 --- a/supervisor/resolution/checks/addon_pwned.py +++ b/supervisor/resolution/checks/addon_pwned.py @@ -4,7 +4,7 @@ from datetime import timedelta from typing import List, Optional from ...const import AddonState, CoreState -from ...exceptions import PwnedError +from ...exceptions import PwnedConnectivityError, PwnedError from ...jobs.const import JobCondition, JobExecutionLimit from ...jobs.decorator import Job from ...utils.pwned import check_pwned_password @@ -34,6 +34,9 @@ class CheckAddonPwned(CheckBase): try: if not await check_pwned_password(self.sys_websession, secret): continue + except PwnedConnectivityError: + self.sys_supervisor.connectivity = False + continue except PwnedError: continue diff --git a/supervisor/supervisor.py b/supervisor/supervisor.py index 32d55f52c..e94a2d20b 100644 --- a/supervisor/supervisor.py +++ b/supervisor/supervisor.py @@ -13,7 +13,7 @@ from awesomeversion import AwesomeVersion, AwesomeVersionException from supervisor.jobs.decorator import Job, JobCondition -from .const import SUPERVISOR_VERSION, URL_HASSIO_APPARMOR +from .const import ATTR_SUPERVISOR_INTERNET, SUPERVISOR_VERSION, URL_HASSIO_APPARMOR from .coresys import CoreSys, CoreSysAttributes from .docker.stats import DockerStats from .docker.supervisor import DockerSupervisor @@ -53,6 +53,16 @@ class Supervisor(CoreSysAttributes): """Return true if we are connected to the internet.""" return self._connectivity + @connectivity.setter + def connectivity(self, state: bool) -> None: + """Set supervisor connectivity state.""" + if self._connectivity == state: + return + self._connectivity = state + self.sys_homeassistant.websocket.supervisor_update_event( + "network", {ATTR_SUPERVISOR_INTERNET: state} + ) + @property def ip_address(self) -> IPv4Address: """Return IP of Supervisor instance.""" @@ -98,6 +108,7 @@ class Supervisor(CoreSysAttributes): data = await request.text() except (aiohttp.ClientError, asyncio.TimeoutError) as err: + self.sys_supervisor.connectivity = False _LOGGER.warning("Can't fetch AppArmor profile: %s", err) raise SupervisorError() from err @@ -198,6 +209,6 @@ class Supervisor(CoreSysAttributes): "https://version.home-assistant.io/online.txt", timeout=timeout ) except (ClientError, asyncio.TimeoutError): - self._connectivity = False + self.connectivity = False else: - self._connectivity = True + self.connectivity = True diff --git a/supervisor/updater.py b/supervisor/updater.py index a89f18071..e10e45325 100644 --- a/supervisor/updater.py +++ b/supervisor/updater.py @@ -186,6 +186,7 @@ class Updater(FileConfiguration, CoreSysAttributes): data = await request.json(content_type=None) except (aiohttp.ClientError, asyncio.TimeoutError) as err: + self.sys_supervisor.connectivity = False _LOGGER.warning("Can't fetch versions from %s: %s", url, err) raise UpdaterError() from err diff --git a/supervisor/utils/pwned.py b/supervisor/utils/pwned.py index 271f16c6f..29c00e0b8 100644 --- a/supervisor/utils/pwned.py +++ b/supervisor/utils/pwned.py @@ -5,7 +5,7 @@ import logging import aiohttp -from ..exceptions import PwnedError +from ..exceptions import PwnedConnectivityError, PwnedError _LOGGER: logging.Logger = logging.getLogger(__name__) _API_CALL = "https://api.pwnedpasswords.com/range/{hash}" @@ -30,6 +30,6 @@ async def check_pwned_password(websession: aiohttp.ClientSession, sha1_pw: str) except (aiohttp.ClientError, asyncio.TimeoutError) as err: _LOGGER.warning("Can't fetch hibp data: %s", err) - raise PwnedError() from err + raise PwnedConnectivityError() from err return False