1
0
mirror of https://github.com/home-assistant/supervisor.git synced 2026-04-02 08:12:47 +01:00

Wait for startup to complete before running shutdown

If PrepareForShutdown fires while Supervisor is still starting up,
wait for startup to complete before running the graceful shutdown
sequence. This prevents shutting down partially initialized
containers and services.

The _startup_complete event is set automatically in set_state()
whenever state transitions to RUNNING. If SIGTERM arrives during
startup, core.stop() cancels the monitor task via host.unload(),
cleanly interrupting the wait.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Stefan Agner
2026-03-16 15:15:45 +01:00
parent 58bb0c909d
commit def618bccf

View File

@@ -43,6 +43,7 @@ class Core(CoreSysAttributes):
self._state: CoreState = CoreState.INITIALIZE
self.exit_code: int = 0
self._shutdown_event: asyncio.Event = asyncio.Event()
self._startup_complete: asyncio.Event = asyncio.Event()
@property
def state(self) -> CoreState:
@@ -83,6 +84,9 @@ class Core(CoreSysAttributes):
self._state = new_state
await self._write_run_state()
if self._state == CoreState.RUNNING:
self._startup_complete.set()
# Don't attempt to notify anyone on CLOSE as we're about to stop the event loop
if self._state != CoreState.CLOSE:
self.sys_bus.fire_event(BusEvent.SUPERVISOR_STATE_CHANGE, self._state)
@@ -361,6 +365,12 @@ class Core(CoreSysAttributes):
Reentrant: if a shutdown is already in progress, subsequent calls
await completion of the existing shutdown rather than starting a second one.
"""
if self.state in STARTING_STATES:
_LOGGER.debug(
"Shutdown requested while Supervisor is still starting up, waiting for startup to complete"
)
await self._startup_complete.wait()
# Supervisor is already tearing down, no point running shutdown
if self.state in (CoreState.STOPPING, CoreState.CLOSE):
_LOGGER.warning("Ignoring shutdown request, Supervisor is already stopping")