diff --git a/supervisor/addons/addon.py b/supervisor/addons/addon.py index 0373083e1..fae0bc346 100644 --- a/supervisor/addons/addon.py +++ b/supervisor/addons/addon.py @@ -551,6 +551,7 @@ class Addon(AddonModel): try: await self.instance.run() except DockerAPIError as err: + self.state = AddonState.ERROR raise AddonsError() from err else: self.state = AddonState.STARTED @@ -560,6 +561,7 @@ class Addon(AddonModel): try: return await self.instance.stop() except DockerAPIError as err: + self.state = AddonState.ERROR raise AddonsError() from err else: self.state = AddonState.STOPPED diff --git a/supervisor/addons/model.py b/supervisor/addons/model.py index f4fc8060b..48e97bbde 100644 --- a/supervisor/addons/model.py +++ b/supervisor/addons/model.py @@ -66,7 +66,7 @@ from ..const import ( SECURITY_DEFAULT, SECURITY_DISABLE, SECURITY_PROFILE, - AddonStages, + AddonStage, AddonStartup, ) from ..coresys import CoreSys, CoreSysAttributes @@ -207,7 +207,7 @@ class AddonModel(CoreSysAttributes, ABC): return self.data[ATTR_ADVANCED] @property - def stage(self) -> AddonStages: + def stage(self) -> AddonStage: """Return stage mode of add-on.""" return self.data[ATTR_STAGE] diff --git a/supervisor/addons/validate.py b/supervisor/addons/validate.py index 9142826b4..b07bbfaa3 100644 --- a/supervisor/addons/validate.py +++ b/supervisor/addons/validate.py @@ -87,7 +87,7 @@ from ..const import ( PRIVILEGED_ALL, ROLE_ALL, ROLE_DEFAULT, - AddonStages, + AddonStage, AddonStartup, AddonState, ) @@ -196,7 +196,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema( vol.Required(ATTR_BOOT): vol.In([BOOT_AUTO, BOOT_MANUAL]), vol.Optional(ATTR_INIT, default=True): vol.Boolean(), vol.Optional(ATTR_ADVANCED, default=False): vol.Boolean(), - vol.Optional(ATTR_STAGE, default=AddonStages.STABLE): vol.Coerce(AddonStages), + vol.Optional(ATTR_STAGE, default=AddonStage.STABLE): vol.Coerce(AddonStage), vol.Optional(ATTR_PORTS): docker_ports, vol.Optional(ATTR_PORTS_DESCRIPTION): docker_ports_description, vol.Optional(ATTR_WATCHDOG): vol.Match( diff --git a/supervisor/api/supervisor.py b/supervisor/api/supervisor.py index 503405751..d6e826283 100644 --- a/supervisor/api/supervisor.py +++ b/supervisor/api/supervisor.py @@ -41,7 +41,7 @@ from ..const import ( CONTENT_TYPE_BINARY, SUPERVISOR_VERSION, LogLevel, - UpdateChannels, + UpdateChannel, ) from ..coresys import CoreSysAttributes from ..exceptions import APIError @@ -54,7 +54,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__) # pylint: disable=no-value-for-parameter SCHEMA_OPTIONS = vol.Schema( { - vol.Optional(ATTR_CHANNEL): vol.Coerce(UpdateChannels), + vol.Optional(ATTR_CHANNEL): vol.Coerce(UpdateChannel), vol.Optional(ATTR_ADDONS_REPOSITORIES): repositories, vol.Optional(ATTR_TIMEZONE): validate_timezone, vol.Optional(ATTR_WAIT_BOOT): wait_boot, diff --git a/supervisor/bootstrap.py b/supervisor/bootstrap.py index 5d03c41be..24e110ee6 100644 --- a/supervisor/bootstrap.py +++ b/supervisor/bootstrap.py @@ -24,7 +24,7 @@ from .const import ( SOCKET_DOCKER, SUPERVISOR_VERSION, LogLevel, - UpdateChannels, + UpdateChannel, ) from .core import Core from .coresys import CoreSys @@ -170,7 +170,7 @@ def initialize_system_data(coresys: CoreSys) -> None: # Check if ENV is in development mode if bool(os.environ.get(ENV_SUPERVISOR_DEV, 0)): _LOGGER.warning("SUPERVISOR_DEV is set") - coresys.updater.channel = UpdateChannels.DEV + coresys.updater.channel = UpdateChannel.DEV coresys.config.logging = LogLevel.DEBUG coresys.config.debug = True diff --git a/supervisor/const.py b/supervisor/const.py index 916cb3950..dc04227fd 100644 --- a/supervisor/const.py +++ b/supervisor/const.py @@ -359,7 +359,7 @@ class AddonStartup(str, Enum): ONCE = "once" -class AddonStages(str, Enum): +class AddonStage(str, Enum): """Stage types of add-on.""" STABLE = "stable" @@ -373,9 +373,10 @@ class AddonState(str, Enum): STARTED = "started" STOPPED = "stopped" UNKNOWN = "unknown" + ERROR = "error" -class UpdateChannels(str, Enum): +class UpdateChannel(str, Enum): """Core supported update channels.""" STABLE = "stable" @@ -383,7 +384,7 @@ class UpdateChannels(str, Enum): DEV = "dev" -class CoreStates(str, Enum): +class CoreState(str, Enum): """Represent current loading state.""" INITIALIZE = "initialize" diff --git a/supervisor/core.py b/supervisor/core.py index e2ce98af5..5e458acd1 100644 --- a/supervisor/core.py +++ b/supervisor/core.py @@ -5,7 +5,7 @@ import logging import async_timeout -from .const import SOCKET_DBUS, SUPERVISED_SUPPORTED_OS, AddonStartup, CoreStates +from .const import SOCKET_DBUS, SUPERVISED_SUPPORTED_OS, AddonStartup, CoreState from .coresys import CoreSys, CoreSysAttributes from .exceptions import ( DockerAPIError, @@ -23,7 +23,7 @@ class Core(CoreSysAttributes): def __init__(self, coresys: CoreSys): """Initialize Supervisor object.""" self.coresys: CoreSys = coresys - self.state: CoreStates = CoreStates.INITIALIZE + self.state: CoreState = CoreState.INITIALIZE self.healthy: bool = True self.supported: bool = True @@ -78,7 +78,7 @@ class Core(CoreSysAttributes): async def setup(self): """Start setting up supervisor orchestration.""" - self.state = CoreStates.SETUP + self.state = CoreState.SETUP # Load DBus await self.sys_dbus.load() @@ -152,7 +152,7 @@ class Core(CoreSysAttributes): async def start(self): """Start Supervisor orchestration.""" - self.state = CoreStates.STARTUP + self.state = CoreState.STARTUP await self.sys_api.start() # Check if system is healthy @@ -232,16 +232,16 @@ class Core(CoreSysAttributes): self.sys_create_task(self.sys_updater.reload()) _LOGGER.info("Supervisor is up and running") - self.state = CoreStates.RUNNING + self.state = CoreState.RUNNING async def stop(self): """Stop a running orchestration.""" # store new last boot / prevent time adjustments - if self.state == CoreStates.RUNNING: + if self.state == CoreState.RUNNING: self._update_last_boot() # don't process scheduler anymore - self.state = CoreStates.STOPPING + self.state = CoreState.STOPPING # Stage 1 try: @@ -269,8 +269,8 @@ class Core(CoreSysAttributes): async def shutdown(self): """Shutdown all running containers in correct order.""" # don't process scheduler anymore - if self.state == CoreStates.RUNNING: - self.state = CoreStates.STOPPING + if self.state == CoreState.RUNNING: + self.state = CoreState.STOPPING # Shutdown Application Add-ons, using Home Assistant API await self.sys_addons.shutdown(AddonStartup.APPLICATION) @@ -285,7 +285,7 @@ class Core(CoreSysAttributes): await self.sys_addons.shutdown(AddonStartup.INITIALIZE) # Shutdown all Plugins - if self.state == CoreStates.STOPPING: + if self.state == CoreState.STOPPING: await self.sys_plugins.shutdown() def _update_last_boot(self): diff --git a/supervisor/coresys.py b/supervisor/coresys.py index 55e36b187..e98d308ef 100644 --- a/supervisor/coresys.py +++ b/supervisor/coresys.py @@ -8,7 +8,7 @@ import aiohttp import sentry_sdk from .config import CoreConfig -from .const import UpdateChannels +from .const import UpdateChannel from .docker import DockerAPI from .misc.hardware import Hardware @@ -86,7 +86,7 @@ class CoreSys: """Return True if we run dev mode.""" if self._updater is None: return False - return self._updater.channel == UpdateChannels.DEV + return self._updater.channel == UpdateChannel.DEV @property def loop(self) -> asyncio.BaseEventLoop: diff --git a/supervisor/misc/filter.py b/supervisor/misc/filter.py index e04cc7c4e..bafac4b7f 100644 --- a/supervisor/misc/filter.py +++ b/supervisor/misc/filter.py @@ -4,7 +4,7 @@ import re from aiohttp import hdrs -from ..const import ENV_SUPERVISOR_DEV, HEADER_TOKEN_OLD, CoreStates +from ..const import ENV_SUPERVISOR_DEV, HEADER_TOKEN_OLD, CoreState from ..coresys import CoreSys from ..exceptions import AddonConfigurationError @@ -35,7 +35,7 @@ def filter_data(coresys: CoreSys, event: dict, hint: dict) -> dict: return None # Not full startup - missing information - if coresys.core.state in (CoreStates.INITIALIZE, CoreStates.SETUP): + if coresys.core.state in (CoreState.INITIALIZE, CoreState.SETUP): return event # List installed addons diff --git a/supervisor/misc/scheduler.py b/supervisor/misc/scheduler.py index 30c48d0ca..03b1ea9e0 100644 --- a/supervisor/misc/scheduler.py +++ b/supervisor/misc/scheduler.py @@ -8,7 +8,7 @@ from uuid import UUID, uuid4 import async_timeout import attr -from ..const import CoreStates +from ..const import CoreState from ..coresys import CoreSys, CoreSysAttributes _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -58,10 +58,10 @@ class Scheduler(CoreSysAttributes): async def _wrap_task(): """Run schedule task and reschedule.""" try: - if self.sys_core.state == CoreStates.RUNNING: + if self.sys_core.state == CoreState.RUNNING: await task.coro_callback() finally: - if task.repeat and self.sys_core.state != CoreStates.STOPPING: + if task.repeat and self.sys_core.state != CoreState.STOPPING: self._schedule_task(task) else: self._tasks.remove(task) diff --git a/supervisor/snapshots/__init__.py b/supervisor/snapshots/__init__.py index 942e2e9b9..a45e63aa2 100644 --- a/supervisor/snapshots/__init__.py +++ b/supervisor/snapshots/__init__.py @@ -3,7 +3,7 @@ import asyncio import logging from pathlib import Path -from ..const import FOLDER_HOMEASSISTANT, SNAPSHOT_FULL, SNAPSHOT_PARTIAL, CoreStates +from ..const import FOLDER_HOMEASSISTANT, SNAPSHOT_FULL, SNAPSHOT_PARTIAL, CoreState from ..coresys import CoreSysAttributes from ..exceptions import AddonsError from ..utils.dt import utcnow @@ -126,7 +126,7 @@ class SnapshotManager(CoreSysAttributes): snapshot = self._create_snapshot(name, SNAPSHOT_FULL, password) _LOGGER.info("Full-Snapshot %s start", snapshot.slug) try: - self.sys_core.state = CoreStates.FREEZE + self.sys_core.state = CoreState.FREEZE await self.lock.acquire() async with snapshot: @@ -148,7 +148,7 @@ class SnapshotManager(CoreSysAttributes): return snapshot finally: - self.sys_core.state = CoreStates.RUNNING + self.sys_core.state = CoreState.RUNNING self.lock.release() async def do_snapshot_partial( @@ -165,7 +165,7 @@ class SnapshotManager(CoreSysAttributes): _LOGGER.info("Partial-Snapshot %s start", snapshot.slug) try: - self.sys_core.state = CoreStates.FREEZE + self.sys_core.state = CoreState.FREEZE await self.lock.acquire() async with snapshot: @@ -197,7 +197,7 @@ class SnapshotManager(CoreSysAttributes): return snapshot finally: - self.sys_core.state = CoreStates.RUNNING + self.sys_core.state = CoreState.RUNNING self.lock.release() async def do_restore_full(self, snapshot, password=None): @@ -216,7 +216,7 @@ class SnapshotManager(CoreSysAttributes): _LOGGER.info("Full-Restore %s start", snapshot.slug) try: - self.sys_core.state = CoreStates.FREEZE + self.sys_core.state = CoreState.FREEZE await self.lock.acquire() async with snapshot: @@ -269,7 +269,7 @@ class SnapshotManager(CoreSysAttributes): return True finally: - self.sys_core.state = CoreStates.RUNNING + self.sys_core.state = CoreState.RUNNING self.lock.release() async def do_restore_partial( @@ -289,7 +289,7 @@ class SnapshotManager(CoreSysAttributes): _LOGGER.info("Partial-Restore %s start", snapshot.slug) try: - self.sys_core.state = CoreStates.FREEZE + self.sys_core.state = CoreState.FREEZE await self.lock.acquire() async with snapshot: @@ -343,5 +343,5 @@ class SnapshotManager(CoreSysAttributes): return True finally: - self.sys_core.state = CoreStates.RUNNING + self.sys_core.state = CoreState.RUNNING self.lock.release() diff --git a/supervisor/updater.py b/supervisor/updater.py index 10fe6e6c7..ac3aded26 100644 --- a/supervisor/updater.py +++ b/supervisor/updater.py @@ -20,7 +20,7 @@ from .const import ( ATTR_SUPERVISOR, FILE_HASSIO_UPDATER, URL_HASSIO_VERSION, - UpdateChannels, + UpdateChannel, ) from .coresys import CoreSysAttributes from .exceptions import HassioUpdaterError @@ -133,12 +133,12 @@ class Updater(JsonConfig, CoreSysAttributes): ) @property - def channel(self) -> UpdateChannels: + def channel(self) -> UpdateChannel: """Return upstream channel of Supervisor instance.""" return self._data[ATTR_CHANNEL] @channel.setter - def channel(self, value: UpdateChannels): + def channel(self, value: UpdateChannel): """Set upstream mode.""" self._data[ATTR_CHANNEL] = value diff --git a/supervisor/validate.py b/supervisor/validate.py index cf6b6fc37..76ba41645 100644 --- a/supervisor/validate.py +++ b/supervisor/validate.py @@ -39,7 +39,7 @@ from .const import ( ATTR_WATCHDOG, SUPERVISOR_VERSION, LogLevel, - UpdateChannels, + UpdateChannel, ) from .utils.validate import validate_timezone @@ -128,8 +128,8 @@ SCHEMA_HASS_CONFIG = vol.Schema( SCHEMA_UPDATER_CONFIG = vol.Schema( { - vol.Optional(ATTR_CHANNEL, default=UpdateChannels.STABLE): vol.Coerce( - UpdateChannels + vol.Optional(ATTR_CHANNEL, default=UpdateChannel.STABLE): vol.Coerce( + UpdateChannel ), vol.Optional(ATTR_HOMEASSISTANT): vol.All(version_tag, str), vol.Optional(ATTR_SUPERVISOR): vol.All(version_tag, str), diff --git a/tests/misc/test_filter_data.py b/tests/misc/test_filter_data.py index cb38cc459..aceab23f0 100644 --- a/tests/misc/test_filter_data.py +++ b/tests/misc/test_filter_data.py @@ -1,7 +1,7 @@ """Test sentry data filter.""" from unittest.mock import patch -from supervisor.const import SUPERVISOR_VERSION, CoreStates +from supervisor.const import SUPERVISOR_VERSION, CoreState from supervisor.exceptions import AddonConfigurationError from supervisor.misc.filter import filter_data @@ -41,10 +41,10 @@ def test_not_started(coresys): coresys.config.diagnostics = True coresys.core.supported = True - coresys.core.state = CoreStates.INITIALIZE + coresys.core.state = CoreState.INITIALIZE assert filter_data(coresys, SAMPLE_EVENT, {}) == SAMPLE_EVENT - coresys.core.state = CoreStates.SETUP + coresys.core.state = CoreState.SETUP assert filter_data(coresys, SAMPLE_EVENT, {}) == SAMPLE_EVENT @@ -53,7 +53,7 @@ def test_defaults(coresys): coresys.config.diagnostics = True coresys.supported = True - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING with patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0 ** 3))): filtered = filter_data(coresys, SAMPLE_EVENT, {}) @@ -81,7 +81,7 @@ def test_sanitize(coresys): coresys.config.diagnostics = True coresys.supported = True - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING with patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0 ** 3))): filtered = filter_data(coresys, event, {}) diff --git a/tests/misc/test_scheduler.py b/tests/misc/test_scheduler.py index a7d4af2da..216b1ac64 100644 --- a/tests/misc/test_scheduler.py +++ b/tests/misc/test_scheduler.py @@ -1,12 +1,12 @@ """Test Supervisor scheduler backend.""" import asyncio -from supervisor.const import CoreStates +from supervisor.const import CoreState async def test_simple_task(coresys): """Schedule a simple task.""" - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING trigger = [] async def test_task(): @@ -21,7 +21,7 @@ async def test_simple_task(coresys): async def test_simple_task_repeat(coresys): """Schedule a simple task and repeat.""" - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING trigger = [] async def test_task(): @@ -36,7 +36,7 @@ async def test_simple_task_repeat(coresys): async def test_simple_task_shutdown(coresys): """Schedule a simple task with shudown.""" - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING trigger = [] async def test_task(): @@ -57,7 +57,7 @@ async def test_simple_task_shutdown(coresys): async def test_simple_task_repeat_block(coresys): """Schedule a simple task with repeat and block.""" - coresys.core.state = CoreStates.RUNNING + coresys.core.state = CoreState.RUNNING trigger = [] async def test_task():