mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-04-02 00:07:16 +01:00
Respect auto-update setting for plug-in auto-updates (#6606)
* Respect auto-update setting for plug-in auto-updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Also skip auto-updating plug-ins in decorator * Raise if auto-update flag is not set and plug-in is not up to date --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -457,6 +457,11 @@ class Job(CoreSysAttributes):
|
||||
if plugin.need_update
|
||||
]
|
||||
):
|
||||
if not coresys.sys_updater.auto_update:
|
||||
raise JobConditionException(
|
||||
f"'{method_name}' blocked from execution, plugin(s) {', '.join(plugin.slug for plugin in out_of_date)} are not up to date and auto-update is disabled"
|
||||
)
|
||||
|
||||
errors = await asyncio.gather(
|
||||
*[plugin.update() for plugin in out_of_date], return_exceptions=True
|
||||
)
|
||||
|
||||
@@ -53,7 +53,10 @@ RUN_WATCHDOG_OBSERVER_APPLICATION = 180
|
||||
|
||||
RUN_CORE_BACKUP_CLEANUP = 86200
|
||||
|
||||
PLUGIN_AUTO_UPDATE_CONDITIONS = PLUGIN_UPDATE_CONDITIONS + [JobCondition.RUNNING]
|
||||
PLUGIN_AUTO_UPDATE_CONDITIONS = PLUGIN_UPDATE_CONDITIONS + [
|
||||
JobCondition.AUTO_UPDATE,
|
||||
JobCondition.RUNNING,
|
||||
]
|
||||
|
||||
OLD_BACKUP_THRESHOLD = timedelta(days=2)
|
||||
|
||||
|
||||
@@ -86,6 +86,13 @@ class PluginManager(CoreSysAttributes):
|
||||
if self.sys_supervisor.need_update:
|
||||
return
|
||||
|
||||
# Skip plugin auto-updates if auto updates are disabled
|
||||
if not self.sys_updater.auto_update:
|
||||
_LOGGER.debug(
|
||||
"Skipping plugin auto-updates because Supervisor auto-update is disabled"
|
||||
)
|
||||
return
|
||||
|
||||
# Check requirements
|
||||
for plugin in self.all_plugins:
|
||||
# Check if need an update
|
||||
|
||||
@@ -528,6 +528,35 @@ async def test_plugins_updated(coresys: CoreSys):
|
||||
assert await test.execute()
|
||||
|
||||
|
||||
async def test_plugins_updated_skips_update_when_auto_update_disabled(coresys: CoreSys):
|
||||
"""Test plugins updated condition blocks when auto update is disabled."""
|
||||
|
||||
class TestClass:
|
||||
"""Test class."""
|
||||
|
||||
def __init__(self, coresys: CoreSys):
|
||||
"""Initialize the test class."""
|
||||
self.coresys = coresys
|
||||
|
||||
@Job(
|
||||
name="test_plugins_updated_auto_update_disabled_execute",
|
||||
conditions=[JobCondition.PLUGINS_UPDATED],
|
||||
)
|
||||
async def execute(self) -> bool:
|
||||
"""Execute the class method."""
|
||||
return True
|
||||
|
||||
test = TestClass(coresys)
|
||||
coresys.updater.auto_update = False
|
||||
|
||||
with (
|
||||
patch.object(PluginAudio, "need_update", new=PropertyMock(return_value=True)),
|
||||
patch.object(PluginAudio, "update") as update,
|
||||
):
|
||||
assert not await test.execute()
|
||||
update.assert_not_called()
|
||||
|
||||
|
||||
async def test_auto_update(coresys: CoreSys):
|
||||
"""Test the auto update decorator."""
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ from supervisor.homeassistant.api import HomeAssistantAPI
|
||||
from supervisor.homeassistant.const import LANDINGPAGE
|
||||
from supervisor.homeassistant.core import HomeAssistantCore
|
||||
from supervisor.misc.tasks import Tasks
|
||||
from supervisor.plugins.dns import PluginDns
|
||||
from supervisor.supervisor import Supervisor
|
||||
|
||||
from tests.common import MockResponse, get_fixture_path
|
||||
@@ -229,6 +230,20 @@ async def test_core_backup_cleanup(tasks: Tasks, coresys: CoreSys):
|
||||
assert not old_tar.exists()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("no_job_throttle")
|
||||
async def test_update_dns_skipped_when_auto_update_disabled(
|
||||
tasks: Tasks, coresys: CoreSys
|
||||
):
|
||||
"""Test plugin auto-update task is skipped when auto update is disabled."""
|
||||
await coresys.core.set_state(CoreState.RUNNING)
|
||||
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
|
||||
coresys.updater.auto_update = False
|
||||
|
||||
with patch.object(PluginDns, "update") as update:
|
||||
await tasks._update_dns()
|
||||
update.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("tmp_supervisor_data")
|
||||
async def test_update_addons_auto_update_success(
|
||||
tasks: Tasks,
|
||||
|
||||
@@ -69,3 +69,31 @@ async def test_load(
|
||||
|
||||
assert attach.call_count == 10
|
||||
assert update.call_count == 5
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("no_job_throttle")
|
||||
async def test_load_skip_update_auto_update_disabled(
|
||||
coresys: CoreSys, mock_update_data: MockResponse, supervisor_internet: AsyncMock
|
||||
):
|
||||
"""Test plugin manager load skips updates when auto update is disabled."""
|
||||
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
|
||||
await coresys.updater.load()
|
||||
await coresys.updater.reload()
|
||||
|
||||
coresys.updater.auto_update = False
|
||||
|
||||
with (
|
||||
patch.object(DockerInterface, "attach") as attach,
|
||||
patch.object(DockerInterface, "update") as update,
|
||||
patch.object(Supervisor, "need_update", new=PropertyMock(return_value=False)),
|
||||
patch.object(PluginBase, "need_update", new=PropertyMock(return_value=True)),
|
||||
patch.object(
|
||||
PluginBase,
|
||||
"version",
|
||||
new=PropertyMock(return_value=AwesomeVersion("1970-01-01")),
|
||||
),
|
||||
):
|
||||
await coresys.plugins.load()
|
||||
|
||||
assert attach.call_count == 5
|
||||
update.assert_not_called()
|
||||
|
||||
Reference in New Issue
Block a user