Watchdog shouldn't rebuild addons (#3766)

* Watchdog shouldn't rebuild addons

* pylint fix
This commit is contained in:
Mike Degatano 2022-08-03 06:06:59 -04:00 committed by GitHub
parent 5d6e2eeaac
commit 2b4f46f6b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 54 deletions

View File

@ -914,23 +914,17 @@ class Addon(AddonModel):
await asyncio.sleep(WATCHDOG_RETRY_SECONDS)
elif event.state == ContainerState.FAILED:
rebuild = False
# Ensure failed container is removed before attempting reanimation
with suppress(DockerError):
await self.instance.stop(remove_container=True)
while await self.instance.current_state() == event.state:
if not self.in_progress:
_LOGGER.warning(
"Watchdog found addon %s failed, restarting...", self.name
)
if not rebuild:
try:
await self.start()
except AddonsError as err:
self.sys_capture_exception(err)
rebuild = True
else:
break
try:
await self.rebuild()
await self.start()
except AddonsError as err:
_LOGGER.error(
"Watchdog reanimation of addon %s failed!", self.name

View File

@ -10,7 +10,6 @@ from supervisor.const import AddonState, BusEvent
from supervisor.coresys import CoreSys
from supervisor.docker.const import ContainerState
from supervisor.docker.monitor import DockerContainerStateEvent
from supervisor.exceptions import AddonsError
from ..const import TEST_ADDON_SLUG
@ -131,6 +130,10 @@ async def mock_current_state(state: ContainerState) -> ContainerState:
return state
async def mock_stop() -> None:
"""Mock for stop method."""
async def test_addon_watchdog(coresys: CoreSys, install_addon_ssh: Addon) -> None:
"""Test addon watchdog works correctly."""
with patch.object(type(install_addon_ssh.instance), "attach"):
@ -159,18 +162,23 @@ async def test_addon_watchdog(coresys: CoreSys, install_addon_ssh: Addon) -> Non
restart.reset_mock()
current_state.return_value = mock_current_state(ContainerState.FAILED)
coresys.bus.fire_event(
BusEvent.DOCKER_CONTAINER_STATE_CHANGE,
DockerContainerStateEvent(
name=f"addon_{TEST_ADDON_SLUG}",
state=ContainerState.FAILED,
id="abc123",
time=1,
),
)
await asyncio.sleep(0)
restart.assert_not_called()
start.assert_called_once()
with patch.object(
type(install_addon_ssh.instance), "stop", return_value=mock_stop()
) as stop:
coresys.bus.fire_event(
BusEvent.DOCKER_CONTAINER_STATE_CHANGE,
DockerContainerStateEvent(
name=f"addon_{TEST_ADDON_SLUG}",
state=ContainerState.FAILED,
id="abc123",
time=1,
),
)
await asyncio.sleep(0)
stop.assert_called_once_with(remove_container=True)
restart.assert_not_called()
start.assert_called_once()
start.reset_mock()
# Do not process event if container state has changed since fired
@ -217,36 +225,6 @@ async def test_addon_watchdog(coresys: CoreSys, install_addon_ssh: Addon) -> Non
start.assert_not_called()
async def test_addon_watchdog_rebuild_on_failure(
coresys: CoreSys, install_addon_ssh: Addon
) -> None:
"""Test addon watchdog rebuilds if start fails."""
with patch.object(type(install_addon_ssh.instance), "attach"):
await install_addon_ssh.load()
install_addon_ssh.watchdog = True
with patch.object(Addon, "start", side_effect=AddonsError()) as start, patch.object(
Addon, "rebuild"
) as rebuild, patch.object(
type(install_addon_ssh.instance),
"current_state",
return_value=mock_current_state(ContainerState.FAILED),
):
coresys.bus.fire_event(
BusEvent.DOCKER_CONTAINER_STATE_CHANGE,
DockerContainerStateEvent(
name=f"addon_{TEST_ADDON_SLUG}",
state=ContainerState.FAILED,
id="abc123",
time=1,
),
)
await asyncio.sleep(0)
start.assert_called_once()
rebuild.assert_called_once()
async def test_listener_attached_on_install(coresys: CoreSys, repository):
"""Test events listener attached on addon install."""
container_collection = MagicMock()