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:
Pascal Vizeli 2020-09-07 14:25:38 +02:00 committed by GitHub
parent 6fbec53f8a
commit 3a35561d1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import logging
import sys
from supervisor import bootstrap
from supervisor.const import CoreState
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -47,14 +48,15 @@ if __name__ == "__main__":
loop.run_until_complete(coresys.core.setup())
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:
_LOGGER.info("Run Supervisor")
loop.run_forever()
finally:
_LOGGER.info("Stopping Supervisor")
loop.run_until_complete(coresys.core.stop())
if coresys.core.state != CoreState.CLOSE:
_LOGGER.info("Stopping Supervisor")
loop.run_until_complete(coresys.core.stop())
executor.shutdown(wait=False)
loop.close()

View File

@ -240,20 +240,26 @@ def check_environment() -> None:
_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."""
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):
_LOGGER.warning("Could not bind to SIGTERM")
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):
_LOGGER.warning("Could not bind to SIGHUP")
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):
_LOGGER.warning("Could not bind to SIGINT")

View File

@ -395,7 +395,9 @@ class CoreState(str, Enum):
STARTUP = "startup"
RUNNING = "running"
FREEZE = "freeze"
SHUTDOWN = "shutdown"
STOPPING = "stopping"
CLOSE = "close"
class LogLevel(str, Enum):

View File

@ -241,8 +241,10 @@ class Core(CoreSysAttributes):
async def stop(self):
"""Stop a running orchestration."""
# store new last boot / prevent time adjustments
if self.state == CoreState.RUNNING:
if self.state in (CoreState.RUNNING, CoreState.SHUTDOWN):
self._update_last_boot()
if self.state in (CoreState.STOPPING, CoreState.CLOSE):
return
# don't process scheduler anymore
self.state = CoreState.STOPPING
@ -269,12 +271,14 @@ class Core(CoreSysAttributes):
_LOGGER.warning("Stage 2: Force Shutdown!")
_LOGGER.info("Supervisor is down")
self.state = CoreState.CLOSE
self.sys_loop.stop()
async def shutdown(self):
"""Shutdown all running containers in correct order."""
# don't process scheduler anymore
if self.state == CoreState.RUNNING:
self.state = CoreState.STOPPING
self.state = CoreState.SHUTDOWN
# Shutdown Application Add-ons, using Home Assistant API
await self.sys_addons.shutdown(AddonStartup.APPLICATION)
@ -289,7 +293,7 @@ class Core(CoreSysAttributes):
await self.sys_addons.shutdown(AddonStartup.INITIALIZE)
# Shutdown all Plugins
if self.state == CoreState.STOPPING:
if self.state in (CoreState.STOPPING, CoreState.SHUTDOWN):
await self.sys_plugins.shutdown()
def _update_last_boot(self):

View File

@ -61,7 +61,10 @@ class Scheduler(CoreSysAttributes):
if self.sys_core.state == CoreState.RUNNING:
await task.coro_callback()
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)
else:
self._tasks.remove(task)

View File

@ -124,7 +124,7 @@ class Supervisor(CoreSysAttributes):
with suppress(SupervisorError):
await self.update_apparmor()
self.sys_loop.call_later(5, self.sys_loop.stop)
self.sys_create_task(self.sys_core.stop())
@property
def in_progress(self) -> bool: