mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-19 15:16:33 +00:00
Change shutdown/close handling to prevent abort (#2022)
* Change shutdown/close handling to prevent abort * add coresys * Ignore shutdown * add comment back * migrate supervisor update
This commit is contained in:
parent
6fbec53f8a
commit
3a35561d1d
@ -5,6 +5,7 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from supervisor import bootstrap
|
from supervisor import bootstrap
|
||||||
|
from supervisor.const import CoreState
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -47,12 +48,13 @@ if __name__ == "__main__":
|
|||||||
loop.run_until_complete(coresys.core.setup())
|
loop.run_until_complete(coresys.core.setup())
|
||||||
|
|
||||||
loop.call_soon_threadsafe(loop.create_task, coresys.core.start())
|
loop.call_soon_threadsafe(loop.create_task, coresys.core.start())
|
||||||
loop.call_soon_threadsafe(bootstrap.reg_signal, loop)
|
loop.call_soon_threadsafe(bootstrap.reg_signal, loop, coresys)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_LOGGER.info("Run Supervisor")
|
_LOGGER.info("Run Supervisor")
|
||||||
loop.run_forever()
|
loop.run_forever()
|
||||||
finally:
|
finally:
|
||||||
|
if coresys.core.state != CoreState.CLOSE:
|
||||||
_LOGGER.info("Stopping Supervisor")
|
_LOGGER.info("Stopping Supervisor")
|
||||||
loop.run_until_complete(coresys.core.stop())
|
loop.run_until_complete(coresys.core.stop())
|
||||||
executor.shutdown(wait=False)
|
executor.shutdown(wait=False)
|
||||||
|
@ -240,20 +240,26 @@ def check_environment() -> None:
|
|||||||
_LOGGER.critical("Can't find gdbus!")
|
_LOGGER.critical("Can't find gdbus!")
|
||||||
|
|
||||||
|
|
||||||
def reg_signal(loop) -> None:
|
def reg_signal(loop, coresys: CoreSys) -> None:
|
||||||
"""Register SIGTERM and SIGKILL to stop system."""
|
"""Register SIGTERM and SIGKILL to stop system."""
|
||||||
try:
|
try:
|
||||||
loop.add_signal_handler(signal.SIGTERM, lambda: loop.call_soon(loop.stop))
|
loop.add_signal_handler(
|
||||||
|
signal.SIGTERM, lambda: loop.create_task(coresys.core.stop())
|
||||||
|
)
|
||||||
except (ValueError, RuntimeError):
|
except (ValueError, RuntimeError):
|
||||||
_LOGGER.warning("Could not bind to SIGTERM")
|
_LOGGER.warning("Could not bind to SIGTERM")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loop.add_signal_handler(signal.SIGHUP, lambda: loop.call_soon(loop.stop))
|
loop.add_signal_handler(
|
||||||
|
signal.SIGHUP, lambda: loop.create_task(coresys.core.stop())
|
||||||
|
)
|
||||||
except (ValueError, RuntimeError):
|
except (ValueError, RuntimeError):
|
||||||
_LOGGER.warning("Could not bind to SIGHUP")
|
_LOGGER.warning("Could not bind to SIGHUP")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loop.add_signal_handler(signal.SIGINT, lambda: loop.call_soon(loop.stop))
|
loop.add_signal_handler(
|
||||||
|
signal.SIGINT, lambda: loop.create_task(coresys.core.stop())
|
||||||
|
)
|
||||||
except (ValueError, RuntimeError):
|
except (ValueError, RuntimeError):
|
||||||
_LOGGER.warning("Could not bind to SIGINT")
|
_LOGGER.warning("Could not bind to SIGINT")
|
||||||
|
|
||||||
|
@ -395,7 +395,9 @@ class CoreState(str, Enum):
|
|||||||
STARTUP = "startup"
|
STARTUP = "startup"
|
||||||
RUNNING = "running"
|
RUNNING = "running"
|
||||||
FREEZE = "freeze"
|
FREEZE = "freeze"
|
||||||
|
SHUTDOWN = "shutdown"
|
||||||
STOPPING = "stopping"
|
STOPPING = "stopping"
|
||||||
|
CLOSE = "close"
|
||||||
|
|
||||||
|
|
||||||
class LogLevel(str, Enum):
|
class LogLevel(str, Enum):
|
||||||
|
@ -241,8 +241,10 @@ class Core(CoreSysAttributes):
|
|||||||
async def stop(self):
|
async def stop(self):
|
||||||
"""Stop a running orchestration."""
|
"""Stop a running orchestration."""
|
||||||
# store new last boot / prevent time adjustments
|
# store new last boot / prevent time adjustments
|
||||||
if self.state == CoreState.RUNNING:
|
if self.state in (CoreState.RUNNING, CoreState.SHUTDOWN):
|
||||||
self._update_last_boot()
|
self._update_last_boot()
|
||||||
|
if self.state in (CoreState.STOPPING, CoreState.CLOSE):
|
||||||
|
return
|
||||||
|
|
||||||
# don't process scheduler anymore
|
# don't process scheduler anymore
|
||||||
self.state = CoreState.STOPPING
|
self.state = CoreState.STOPPING
|
||||||
@ -269,12 +271,14 @@ class Core(CoreSysAttributes):
|
|||||||
_LOGGER.warning("Stage 2: Force Shutdown!")
|
_LOGGER.warning("Stage 2: Force Shutdown!")
|
||||||
|
|
||||||
_LOGGER.info("Supervisor is down")
|
_LOGGER.info("Supervisor is down")
|
||||||
|
self.state = CoreState.CLOSE
|
||||||
|
self.sys_loop.stop()
|
||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
"""Shutdown all running containers in correct order."""
|
"""Shutdown all running containers in correct order."""
|
||||||
# don't process scheduler anymore
|
# don't process scheduler anymore
|
||||||
if self.state == CoreState.RUNNING:
|
if self.state == CoreState.RUNNING:
|
||||||
self.state = CoreState.STOPPING
|
self.state = CoreState.SHUTDOWN
|
||||||
|
|
||||||
# Shutdown Application Add-ons, using Home Assistant API
|
# Shutdown Application Add-ons, using Home Assistant API
|
||||||
await self.sys_addons.shutdown(AddonStartup.APPLICATION)
|
await self.sys_addons.shutdown(AddonStartup.APPLICATION)
|
||||||
@ -289,7 +293,7 @@ class Core(CoreSysAttributes):
|
|||||||
await self.sys_addons.shutdown(AddonStartup.INITIALIZE)
|
await self.sys_addons.shutdown(AddonStartup.INITIALIZE)
|
||||||
|
|
||||||
# Shutdown all Plugins
|
# Shutdown all Plugins
|
||||||
if self.state == CoreState.STOPPING:
|
if self.state in (CoreState.STOPPING, CoreState.SHUTDOWN):
|
||||||
await self.sys_plugins.shutdown()
|
await self.sys_plugins.shutdown()
|
||||||
|
|
||||||
def _update_last_boot(self):
|
def _update_last_boot(self):
|
||||||
|
@ -61,7 +61,10 @@ class Scheduler(CoreSysAttributes):
|
|||||||
if self.sys_core.state == CoreState.RUNNING:
|
if self.sys_core.state == CoreState.RUNNING:
|
||||||
await task.coro_callback()
|
await task.coro_callback()
|
||||||
finally:
|
finally:
|
||||||
if task.repeat and self.sys_core.state != CoreState.STOPPING:
|
if task.repeat and self.sys_core.state not in (
|
||||||
|
CoreState.STOPPING,
|
||||||
|
CoreState.CLOSE,
|
||||||
|
):
|
||||||
self._schedule_task(task)
|
self._schedule_task(task)
|
||||||
else:
|
else:
|
||||||
self._tasks.remove(task)
|
self._tasks.remove(task)
|
||||||
|
@ -124,7 +124,7 @@ class Supervisor(CoreSysAttributes):
|
|||||||
|
|
||||||
with suppress(SupervisorError):
|
with suppress(SupervisorError):
|
||||||
await self.update_apparmor()
|
await self.update_apparmor()
|
||||||
self.sys_loop.call_later(5, self.sys_loop.stop)
|
self.sys_create_task(self.sys_core.stop())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def in_progress(self) -> bool:
|
def in_progress(self) -> bool:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user