diff --git a/supervisor/api/host.py b/supervisor/api/host.py index 92dce42d8..ad77e2f26 100644 --- a/supervisor/api/host.py +++ b/supervisor/api/host.py @@ -43,7 +43,7 @@ class APIHost(CoreSysAttributes): ATTR_DISK_FREE: self.sys_host.info.free_space, ATTR_DISK_TOTAL: self.sys_host.info.total_space, ATTR_DISK_USED: self.sys_host.info.used_space, - ATTR_FEATURES: self.sys_host.supported_features, + ATTR_FEATURES: self.sys_host.features, ATTR_HOSTNAME: self.sys_host.info.hostname, ATTR_KERNEL: self.sys_host.info.kernel, ATTR_OPERATING_SYSTEM: self.sys_host.info.operating_system, diff --git a/supervisor/api/info.py b/supervisor/api/info.py index 6fc098ca0..6827b486a 100644 --- a/supervisor/api/info.py +++ b/supervisor/api/info.py @@ -39,7 +39,7 @@ class APIInfo(CoreSysAttributes): ATTR_DOCKER: self.sys_docker.info.version, ATTR_HOSTNAME: self.sys_host.info.hostname, ATTR_OPERATING_SYSTEM: self.sys_host.info.operating_system, - ATTR_FEATURES: self.sys_host.supported_features, + ATTR_FEATURES: self.sys_host.features, ATTR_MACHINE: self.sys_machine, ATTR_ARCH: self.sys_arch.default, ATTR_SUPPORTED_ARCH: self.sys_arch.supported, diff --git a/supervisor/dbus/__init__.py b/supervisor/dbus/__init__.py index 8571cd85f..da89bffc8 100644 --- a/supervisor/dbus/__init__.py +++ b/supervisor/dbus/__init__.py @@ -55,3 +55,5 @@ class DBusManager(CoreSysAttributes): _LOGGER.error( "No D-Bus support on Host. Disabled any kind of host control!" ) + + self.sys_host.supported_features.cache_clear() diff --git a/supervisor/hassos.py b/supervisor/hassos.py index 8cafeafe3..2780616a7 100644 --- a/supervisor/hassos.py +++ b/supervisor/hassos.py @@ -107,6 +107,7 @@ class HassOS(CoreSysAttributes): return else: self._available = True + self.sys_host.supported_features.cache_clear() # Store meta data self._version = cpe.get_version()[0] diff --git a/supervisor/host/__init__.py b/supervisor/host/__init__.py index 36e239e92..a08edc9e0 100644 --- a/supervisor/host/__init__.py +++ b/supervisor/host/__init__.py @@ -1,6 +1,8 @@ """Host function like audio, D-Bus or systemd.""" from contextlib import suppress +from functools import lru_cache import logging +from typing import List from ..const import HostFeature from ..coresys import CoreSys, CoreSysAttributes @@ -60,7 +62,12 @@ class HostManager(CoreSysAttributes): return self._sound @property - def supported_features(self): + def features(self) -> List[HostFeature]: + """Return a list of host features.""" + return self.supported_features() + + @lru_cache + def supported_features(self) -> List[HostFeature]: """Return a list of supported host features.""" features = [] @@ -95,6 +102,7 @@ class HostManager(CoreSysAttributes): await self.sound.update() _LOGGER.info("Host information reload completed") + self.supported_features.cache_clear() # pylint: disable=no-member async def load(self): """Load host information.""" diff --git a/supervisor/misc/tasks.py b/supervisor/misc/tasks.py index 040476a32..17979e52c 100644 --- a/supervisor/misc/tasks.py +++ b/supervisor/misc/tasks.py @@ -1,7 +1,7 @@ """A collection of tasks.""" import logging -from ..const import AddonState +from ..const import AddonState, HostFeature from ..coresys import CoreSysAttributes from ..exceptions import ( AddonsError, @@ -457,7 +457,7 @@ class Tasks(CoreSysAttributes): # Check connectivity try: await self.sys_supervisor.check_connectivity() - if self.sys_dbus.network.is_connected: + if HostFeature.NETWORK in self.sys_host.features: await self.sys_host.network.check_connectivity() finally: self._cache["connectivity"] = 0 diff --git a/supervisor/resolution/evaluations/network_manager.py b/supervisor/resolution/evaluations/network_manager.py index 2e6c26161..1d32a5db7 100644 --- a/supervisor/resolution/evaluations/network_manager.py +++ b/supervisor/resolution/evaluations/network_manager.py @@ -26,4 +26,4 @@ class EvaluateNetworkManager(EvaluateBase): async def evaluate(self): """Run evaluation.""" - return HostFeature.NETWORK not in self.sys_host.supported_features + return HostFeature.NETWORK not in self.sys_host.features diff --git a/supervisor/resolution/evaluations/systemd.py b/supervisor/resolution/evaluations/systemd.py index 227348f09..2644a1a90 100644 --- a/supervisor/resolution/evaluations/systemd.py +++ b/supervisor/resolution/evaluations/systemd.py @@ -27,7 +27,7 @@ class EvaluateSystemd(EvaluateBase): async def evaluate(self): """Run evaluation.""" return any( - feature not in self.sys_host.supported_features + feature not in self.sys_host.features for feature in ( HostFeature.HOSTNAME, HostFeature.SERVICES, diff --git a/tests/host/test_supported_features.py b/tests/host/test_supported_features.py index 048586ed4..97a47bcfd 100644 --- a/tests/host/test_supported_features.py +++ b/tests/host/test_supported_features.py @@ -4,8 +4,11 @@ def test_supported_features(coresys): """Test host features.""" - assert "network" in coresys.host.supported_features + assert "network" in coresys.host.features coresys._dbus.network.is_connected = False - assert "network" not in coresys.host.supported_features + assert "network" in coresys.host.features + + coresys.host.supported_features.cache_clear() + assert "network" not in coresys.host.features diff --git a/tests/resolution/evaluation/test_evaluate_network_manager.py b/tests/resolution/evaluation/test_evaluate_network_manager.py index 4ce35dc8e..ba267b9c1 100644 --- a/tests/resolution/evaluation/test_evaluate_network_manager.py +++ b/tests/resolution/evaluation/test_evaluate_network_manager.py @@ -19,6 +19,8 @@ async def test_evaluation(coresys: CoreSys): assert network_manager.reason in coresys.resolution.unsupported coresys.dbus.network.is_connected = True + coresys.host.supported_features.cache_clear() + await network_manager() assert network_manager.reason not in coresys.resolution.unsupported diff --git a/tests/resolution/evaluation/test_evaluate_systemd.py b/tests/resolution/evaluation/test_evaluate_systemd.py index 714ba6edb..654b42245 100644 --- a/tests/resolution/evaluation/test_evaluate_systemd.py +++ b/tests/resolution/evaluation/test_evaluate_systemd.py @@ -16,11 +16,11 @@ async def test_evaluation(coresys: CoreSys): coresys._host = MagicMock() - coresys.host.supported_features = [HostFeature.HOSTNAME] + coresys.host.features = [HostFeature.HOSTNAME] await systemd() assert systemd.reason in coresys.resolution.unsupported - coresys.host.supported_features = [ + coresys.host.features = [ HostFeature.SERVICES, HostFeature.SHUTDOWN, HostFeature.REBOOT,