diff --git a/hassio/addons/__init__.py b/hassio/addons/__init__.py index 6b21290ce..58c728af1 100644 --- a/hassio/addons/__init__.py +++ b/hassio/addons/__init__.py @@ -5,7 +5,7 @@ import logging from .addon import Addon from .repository import Repository from .data import AddonsData -from ..const import REPOSITORY_CORE, REPOSITORY_LOCAL, BOOT_AUTO +from ..const import REPOSITORY_CORE, REPOSITORY_LOCAL, BOOT_AUTO, STATE_STARTED from ..coresys import CoreSysAttributes _LOGGER = logging.getLogger(__name__) @@ -131,7 +131,7 @@ class AddonManager(CoreSysAttributes): for addon_slug in del_addons: self.addons_obj.pop(addon_slug) - async def auto_boot(self, stage): + async def boot(self, stage): """Boot addons with mode auto.""" tasks = [] for addon in self.addons_obj.values(): @@ -143,3 +143,16 @@ class AddonManager(CoreSysAttributes): if tasks: await asyncio.wait(tasks) await asyncio.sleep(self.sys_config.wait_boot) + + async def shutdown(self, stage): + """Shutdown addons.""" + tasks = [] + for addon in self.addons_obj.values(): + if addon.is_installed and \ + await addon.state() == STATE_STARTED and \ + addon.startup == stage: + tasks.append(addon.stop()) + + _LOGGER.info("Shutdown %s stop %d addons", stage, len(tasks)) + if tasks: + await asyncio.wait(tasks) diff --git a/hassio/core.py b/hassio/core.py index b537ca95e..d32431ae9 100644 --- a/hassio/core.py +++ b/hassio/core.py @@ -1,10 +1,12 @@ """Main file for HassIO.""" +from contextlib import suppress import asyncio import logging from .coresys import CoreSysAttributes from .const import ( STARTUP_SYSTEM, STARTUP_SERVICES, STARTUP_APPLICATION, STARTUP_INITIALIZE) +from .exceptions import HassioError from .utils.dt import fetch_timezone _LOGGER = logging.getLogger(__name__) @@ -68,7 +70,7 @@ class HassIO(CoreSysAttributes): _LOGGER.info("Start API on %s", self.sys_docker.network.supervisor) # start addon mark as initialize - await self.sys_addons.auto_boot(STARTUP_INITIALIZE) + await self.sys_addons.boot(STARTUP_INITIALIZE) try: # HomeAssistant is already running / supervisor have only reboot @@ -80,17 +82,17 @@ class HassIO(CoreSysAttributes): self.sys_services.reset() # start addon mark as system - await self.sys_addons.auto_boot(STARTUP_SYSTEM) + await self.sys_addons.boot(STARTUP_SYSTEM) # start addon mark as services - await self.sys_addons.auto_boot(STARTUP_SERVICES) + await self.sys_addons.boot(STARTUP_SERVICES) # run HomeAssistant if self.sys_homeassistant.boot: await self.sys_homeassistant.start() # start addon mark as application - await self.sys_addons.auto_boot(STARTUP_APPLICATION) + await self.sys_addons.boot(STARTUP_APPLICATION) # store new last boot self.sys_config.last_boot = self.sys_hardware.last_boot @@ -118,3 +120,15 @@ class HassIO(CoreSysAttributes): self.sys_websession.close(), self.sys_websession_ssl.close() ]) + + async def shutdown(self): + """Shutdown all running containers in correct order.""" + await self.sys_addons.shutdown(STARTUP_APPLICATION) + + # Close Home Assistant + with suppress(HassioError): + await self.sys_homeassistant.stop() + + await self.sys_addons.shutdown(STARTUP_SERVICES) + await self.sys_addons.shutdown(STARTUP_SYSTEM) + await self.sys_addons.shutdown(STARTUP_INITIALIZE) diff --git a/hassio/snapshots/__init__.py b/hassio/snapshots/__init__.py index bb346167f..9b5370df7 100644 --- a/hassio/snapshots/__init__.py +++ b/hassio/snapshots/__init__.py @@ -222,14 +222,7 @@ class SnapshotManager(CoreSysAttributes): tasks = [] # Stop Home-Assistant / Add-ons - tasks.append(self.sys_homeassistant.stop()) - for addon in self.sys_addons.list_addons: - if addon.is_installed: - tasks.append(addon.stop()) - - if tasks: - _LOGGER.info("Restore %s stop tasks", snapshot.slug) - await asyncio.wait(tasks) + await self.sys_core.shutdown() # Restore folders _LOGGER.info("Restore %s run folders", snapshot.slug)