Improve supported / healthy handling and more checks (#1905)

Co-authored-by: Joakim Sørensen <joasoe@gmail.com>
This commit is contained in:
Pascal Vizeli 2020-08-13 16:49:34 +02:00 committed by GitHub
parent 00969a67ac
commit 8d7b15cbeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 27 deletions

View File

@ -39,7 +39,7 @@ class APIHost(CoreSysAttributes):
return { return {
ATTR_CHASSIS: self.sys_host.info.chassis, ATTR_CHASSIS: self.sys_host.info.chassis,
ATTR_CPE: self.sys_host.info.cpe, ATTR_CPE: self.sys_host.info.cpe,
ATTR_FEATURES: self.sys_host.supperted_features, ATTR_FEATURES: self.sys_host.supported_features,
ATTR_HOSTNAME: self.sys_host.info.hostname, ATTR_HOSTNAME: self.sys_host.info.hostname,
ATTR_OPERATING_SYSTEM: self.sys_host.info.operating_system, ATTR_OPERATING_SYSTEM: self.sys_host.info.operating_system,
ATTR_DEPLOYMENT: self.sys_host.info.deployment, ATTR_DEPLOYMENT: self.sys_host.info.deployment,

View File

@ -39,7 +39,7 @@ class APIInfo(CoreSysAttributes):
ATTR_MACHINE: self.sys_machine, ATTR_MACHINE: self.sys_machine,
ATTR_ARCH: self.sys_arch.default, ATTR_ARCH: self.sys_arch.default,
ATTR_SUPPORTED_ARCH: self.sys_arch.supported, ATTR_SUPPORTED_ARCH: self.sys_arch.supported,
ATTR_SUPPORTED: self.sys_supported, ATTR_SUPPORTED: self.sys_core.supported,
ATTR_CHANNEL: self.sys_updater.channel, ATTR_CHANNEL: self.sys_updater.channel,
ATTR_LOGGING: self.sys_config.logging, ATTR_LOGGING: self.sys_config.logging,
ATTR_TIMEZONE: self.sys_timezone, ATTR_TIMEZONE: self.sys_timezone,

View File

@ -100,7 +100,7 @@ class APISupervisor(CoreSysAttributes):
ATTR_VERSION_LATEST: self.sys_updater.version_supervisor, ATTR_VERSION_LATEST: self.sys_updater.version_supervisor,
ATTR_CHANNEL: self.sys_updater.channel, ATTR_CHANNEL: self.sys_updater.channel,
ATTR_ARCH: self.sys_supervisor.arch, ATTR_ARCH: self.sys_supervisor.arch,
ATTR_SUPPORTED: self.sys_supported, ATTR_SUPPORTED: self.sys_core.supported,
ATTR_HEALTHY: self.sys_core.healthy, ATTR_HEALTHY: self.sys_core.healthy,
ATTR_IP_ADDRESS: str(self.sys_supervisor.ip_address), ATTR_IP_ADDRESS: str(self.sys_supervisor.ip_address),
ATTR_WAIT_BOOT: self.sys_config.wait_boot, ATTR_WAIT_BOOT: self.sys_config.wait_boot,

View File

@ -329,6 +329,8 @@ ROLE_ALL = [ROLE_DEFAULT, ROLE_HOMEASSISTANT, ROLE_BACKUP, ROLE_MANAGER, ROLE_AD
CHAN_ID = "chan_id" CHAN_ID = "chan_id"
CHAN_TYPE = "chan_type" CHAN_TYPE = "chan_type"
SUPERVISED_SUPPORTED_OS = ["Debian GNU/Linux 10 (buster)"]
class AddonStartup(str, Enum): class AddonStartup(str, Enum):
"""Startup types of Add-on.""" """Startup types of Add-on."""

View File

@ -5,7 +5,7 @@ import logging
import async_timeout import async_timeout
from .const import SOCKET_DBUS, AddonStartup, CoreStates from .const import SOCKET_DBUS, SUPERVISED_SUPPORTED_OS, AddonStartup, CoreStates
from .coresys import CoreSys, CoreSysAttributes from .coresys import CoreSys, CoreSysAttributes
from .exceptions import HassioError, HomeAssistantError, SupervisorUpdateError from .exceptions import HassioError, HomeAssistantError, SupervisorUpdateError
@ -19,12 +19,8 @@ class Core(CoreSysAttributes):
"""Initialize Supervisor object.""" """Initialize Supervisor object."""
self.coresys: CoreSys = coresys self.coresys: CoreSys = coresys
self.state: CoreStates = CoreStates.INITIALIZE self.state: CoreStates = CoreStates.INITIALIZE
self._healthy: bool = True self.healthy: bool = True
self.supported: bool = True
@property
def healthy(self) -> bool:
"""Return True if system is healthy."""
return self._healthy and self.sys_supported
async def connect(self): async def connect(self):
"""Connect Supervisor container.""" """Connect Supervisor container."""
@ -32,23 +28,25 @@ class Core(CoreSysAttributes):
# If host docker is supported? # If host docker is supported?
if not self.sys_docker.info.supported_version: if not self.sys_docker.info.supported_version:
self.coresys.supported = False self.supported = False
self.healthy = False
_LOGGER.error( _LOGGER.error(
"Docker version %s is not supported by Supervisor!", "Docker version %s is not supported by Supervisor!",
self.sys_docker.info.version, self.sys_docker.info.version,
) )
elif self.sys_docker.info.inside_lxc: elif self.sys_docker.info.inside_lxc:
self.coresys.supported = False self.supported = False
self.healthy = False
_LOGGER.error( _LOGGER.error(
"Detected Docker running inside LXC. Running Home Assistant with the Supervisor on LXC is not supported!" "Detected Docker running inside LXC. Running Home Assistant with the Supervisor on LXC is not supported!"
) )
if self.sys_docker.info.check_requirements(): if self.sys_docker.info.check_requirements():
self.coresys.supported = False self.supported = False
# Dbus available # Dbus available
if not SOCKET_DBUS.exists(): if not SOCKET_DBUS.exists():
self.coresys.supported = False self.supported = False
_LOGGER.error( _LOGGER.error(
"DBus is required for Home Assistant. This system is not supported!" "DBus is required for Home Assistant. This system is not supported!"
) )
@ -60,13 +58,13 @@ class Core(CoreSysAttributes):
self.sys_config.version == "dev" self.sys_config.version == "dev"
or self.sys_supervisor.instance.version == "dev" or self.sys_supervisor.instance.version == "dev"
): ):
self.coresys.supported = False self.supported = False
_LOGGER.warning( _LOGGER.warning(
"Found a development supervisor outside dev channel (%s)", "Found a development supervisor outside dev channel (%s)",
self.sys_updater.channel, self.sys_updater.channel,
) )
elif self.sys_config.version != self.sys_supervisor.version: elif self.sys_config.version != self.sys_supervisor.version:
self._healthy = False self.healthy = False
_LOGGER.error( _LOGGER.error(
"Update %s of Supervisor %s fails!", "Update %s of Supervisor %s fails!",
self.sys_config.version, self.sys_config.version,
@ -122,13 +120,37 @@ class Core(CoreSysAttributes):
# Load secrets # Load secrets
await self.sys_secrets.load() await self.sys_secrets.load()
# Check supported OS
if not self.sys_hassos.available:
if self.sys_host.info.operating_system not in SUPERVISED_SUPPORTED_OS:
self.supported = False
_LOGGER.error(
"Using '%s' as the OS is not supported",
self.sys_host.info.operating_system,
)
else:
# Check rauc connectivity on our OS
if not self.sys_dbus.rauc.is_connected:
self.healthy = False
# Check all DBUS connectivity
if not self.sys_dbus.hostname.is_connected:
self.supported = False
_LOGGER.error("Hostname DBUS is not connected")
if not self.sys_dbus.nmi_dns.is_connected:
self.supported = False
_LOGGER.error("NetworkManager DNS DBUS is not connected")
if not self.sys_dbus.systemd.is_connected:
self.supported = False
_LOGGER.error("Systemd DBUS is not connected")
async def start(self): async def start(self):
"""Start Supervisor orchestration.""" """Start Supervisor orchestration."""
self.state = CoreStates.STARTUP self.state = CoreStates.STARTUP
await self.sys_api.start() await self.sys_api.start()
# Check if system is healthy # Check if system is healthy
if not self.sys_supported: if not self.supported:
_LOGGER.critical("System running in a unsupported environment!") _LOGGER.critical("System running in a unsupported environment!")
elif not self.healthy: elif not self.healthy:
_LOGGER.critical( _LOGGER.critical(

View File

@ -48,9 +48,6 @@ class CoreSys:
self._machine_id: Optional[str] = None self._machine_id: Optional[str] = None
self._machine: Optional[str] = None self._machine: Optional[str] = None
# Static attributes
self.supported: bool = True
# External objects # External objects
self._loop: asyncio.BaseEventLoop = asyncio.get_running_loop() self._loop: asyncio.BaseEventLoop = asyncio.get_running_loop()
self._websession: aiohttp.ClientSession = aiohttp.ClientSession() self._websession: aiohttp.ClientSession = aiohttp.ClientSession()
@ -462,11 +459,6 @@ class CoreSysAttributes:
"""Return True if we run dev mode.""" """Return True if we run dev mode."""
return self.coresys.dev return self.coresys.dev
@property
def sys_supported(self) -> bool:
"""Return True if the system is supported."""
return self.coresys.supported
@property @property
def sys_timezone(self) -> str: def sys_timezone(self) -> str:
"""Return timezone.""" """Return timezone."""

View File

@ -66,7 +66,7 @@ class HostManager(CoreSysAttributes):
return self._sound return self._sound
@property @property
def supperted_features(self): def supported_features(self):
"""Return a list of supported host features.""" """Return a list of supported host features."""
features = [] features = []

View File

@ -28,7 +28,7 @@ class HwMonitor(CoreSysAttributes):
self.monitor = pyudev.Monitor.from_netlink(self.context) self.monitor = pyudev.Monitor.from_netlink(self.context)
self.observer = pyudev.MonitorObserver(self.monitor, self._udev_events) self.observer = pyudev.MonitorObserver(self.monitor, self._udev_events)
except OSError: except OSError:
self.coresys.supported = False self.sys_core.healthy = False
_LOGGER.critical("Not privileged to run udev monitor!") _LOGGER.critical("Not privileged to run udev monitor!")
else: else:
self.observer.start() self.observer.start()