mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-18 06:36:30 +00:00
Attempt plugin update before failing job condition (#3796)
This commit is contained in:
parent
5fc9484f73
commit
2cd7f9d1b0
@ -92,7 +92,7 @@ class Job(CoreSysAttributes):
|
|||||||
# Handle condition
|
# Handle condition
|
||||||
if self.conditions:
|
if self.conditions:
|
||||||
try:
|
try:
|
||||||
self._check_conditions()
|
await self._check_conditions()
|
||||||
except JobConditionException as err:
|
except JobConditionException as err:
|
||||||
error_msg = str(err)
|
error_msg = str(err)
|
||||||
if self.on_condition is None:
|
if self.on_condition is None:
|
||||||
@ -150,7 +150,7 @@ class Job(CoreSysAttributes):
|
|||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def _check_conditions(self):
|
async def _check_conditions(self):
|
||||||
"""Check conditions."""
|
"""Check conditions."""
|
||||||
used_conditions = set(self.conditions) - set(self.sys_jobs.ignore_conditions)
|
used_conditions = set(self.conditions) - set(self.sys_jobs.ignore_conditions)
|
||||||
ignored_conditions = set(self.conditions) & set(self.sys_jobs.ignore_conditions)
|
ignored_conditions = set(self.conditions) & set(self.sys_jobs.ignore_conditions)
|
||||||
@ -238,13 +238,22 @@ class Job(CoreSysAttributes):
|
|||||||
f"'{self._method.__qualname__}' blocked from execution, supervisor needs to be updated first"
|
f"'{self._method.__qualname__}' blocked from execution, supervisor needs to be updated first"
|
||||||
)
|
)
|
||||||
|
|
||||||
if JobCondition.PLUGINS_UPDATED in self.conditions and 0 < len(
|
if JobCondition.PLUGINS_UPDATED in self.conditions and (
|
||||||
[plugin for plugin in self.sys_plugins.all_plugins if plugin.need_update]
|
out_of_date := [
|
||||||
|
plugin for plugin in self.sys_plugins.all_plugins if plugin.need_update
|
||||||
|
]
|
||||||
):
|
):
|
||||||
raise JobConditionException(
|
errors = await asyncio.gather(
|
||||||
f"'{self._method.__qualname__}' blocked from execution, plugin(s) {', '.join([plugin.slug for plugin in self.sys_plugins.all_plugins if plugin.need_update])} need to be updated first"
|
*[plugin.update() for plugin in out_of_date], return_exceptions=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if update_failures := [
|
||||||
|
out_of_date[i].slug for i in range(len(errors)) if errors[i] is not None
|
||||||
|
]:
|
||||||
|
raise JobConditionException(
|
||||||
|
f"'{self._method.__qualname__}' blocked from execution, was unable to update plugin(s) {', '.join(update_failures)} and all plugins must be up to date first"
|
||||||
|
)
|
||||||
|
|
||||||
async def _acquire_exection_limit(self) -> None:
|
async def _acquire_exection_limit(self) -> None:
|
||||||
"""Process exection limits."""
|
"""Process exection limits."""
|
||||||
if self.limit not in (
|
if self.limit not in (
|
||||||
|
@ -11,7 +11,7 @@ from supervisor.const import AddonState, BusEvent
|
|||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.docker.const import ContainerState
|
from supervisor.docker.const import ContainerState
|
||||||
from supervisor.docker.monitor import DockerContainerStateEvent
|
from supervisor.docker.monitor import DockerContainerStateEvent
|
||||||
from supervisor.exceptions import AddonsJobError
|
from supervisor.exceptions import AddonsJobError, AudioUpdateError
|
||||||
|
|
||||||
from ..const import TEST_ADDON_SLUG
|
from ..const import TEST_ADDON_SLUG
|
||||||
|
|
||||||
@ -287,6 +287,8 @@ async def test_install_update_fails_if_out_of_date(
|
|||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
||||||
|
), patch.object(
|
||||||
|
type(coresys.plugins.audio), "update", side_effect=AudioUpdateError
|
||||||
):
|
):
|
||||||
with pytest.raises(AddonsJobError):
|
with pytest.raises(AddonsJobError):
|
||||||
await coresys.addons.install(TEST_ADDON_SLUG)
|
await coresys.addons.install(TEST_ADDON_SLUG)
|
||||||
|
@ -4,7 +4,7 @@ from unittest.mock import PropertyMock, patch
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.exceptions import HomeAssistantJobError
|
from supervisor.exceptions import AudioUpdateError, HomeAssistantJobError
|
||||||
|
|
||||||
|
|
||||||
async def test_update_fails_if_out_of_date(coresys: CoreSys):
|
async def test_update_fails_if_out_of_date(coresys: CoreSys):
|
||||||
@ -18,5 +18,9 @@ async def test_update_fails_if_out_of_date(coresys: CoreSys):
|
|||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
||||||
), pytest.raises(HomeAssistantJobError):
|
), patch.object(
|
||||||
|
type(coresys.plugins.audio), "update", side_effect=AudioUpdateError
|
||||||
|
), pytest.raises(
|
||||||
|
HomeAssistantJobError
|
||||||
|
):
|
||||||
await coresys.homeassistant.core.update()
|
await coresys.homeassistant.core.update()
|
||||||
|
@ -9,7 +9,12 @@ import time_machine
|
|||||||
|
|
||||||
from supervisor.const import CoreState
|
from supervisor.const import CoreState
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.exceptions import HassioError, JobException, PluginJobError
|
from supervisor.exceptions import (
|
||||||
|
AudioUpdateError,
|
||||||
|
HassioError,
|
||||||
|
JobException,
|
||||||
|
PluginJobError,
|
||||||
|
)
|
||||||
from supervisor.jobs.const import JobExecutionLimit
|
from supervisor.jobs.const import JobExecutionLimit
|
||||||
from supervisor.jobs.decorator import Job, JobCondition
|
from supervisor.jobs.decorator import Job, JobCondition
|
||||||
from supervisor.resolution.const import UnhealthyReason
|
from supervisor.resolution.const import UnhealthyReason
|
||||||
@ -448,8 +453,11 @@ async def test_plugins_updated(coresys: CoreSys):
|
|||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
type(coresys.plugins.audio), "need_update", new=PropertyMock(return_value=True)
|
||||||
|
), patch.object(
|
||||||
|
type(coresys.plugins.audio), "update", side_effect=[AudioUpdateError, None]
|
||||||
):
|
):
|
||||||
assert not await test.execute()
|
assert not await test.execute()
|
||||||
|
assert await test.execute()
|
||||||
|
|
||||||
|
|
||||||
async def test_auto_update(coresys: CoreSys):
|
async def test_auto_update(coresys: CoreSys):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user