Auto updates to new version delay for 24 hours (#4838)

This commit is contained in:
Mike Degatano 2024-01-30 08:58:28 -05:00 committed by GitHub
parent 88d718271d
commit 140b769a42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 50 additions and 0 deletions

View File

@ -3,6 +3,7 @@ import asyncio
from collections.abc import Awaitable
from contextlib import suppress
from copy import deepcopy
from datetime import datetime
import errno
from ipaddress import IPv4Address
import logging
@ -47,6 +48,7 @@ from ..const import (
ATTR_USER,
ATTR_UUID,
ATTR_VERSION,
ATTR_VERSION_TIMESTAMP,
ATTR_WATCHDOG,
DNS_SUFFIX,
AddonBoot,
@ -344,6 +346,11 @@ class Addon(AddonModel):
"""Return version of add-on."""
return self.data_store[ATTR_VERSION]
@property
def latest_version_timestamp(self) -> datetime:
"""Return when latest version was first seen."""
return datetime.fromtimestamp(self.data_store[ATTR_VERSION_TIMESTAMP])
@property
def protected(self) -> bool:
"""Return if add-on is in protected mode."""

View File

@ -3,6 +3,7 @@ from abc import ABC, abstractmethod
from collections import defaultdict
from collections.abc import Callable
from contextlib import suppress
from datetime import datetime
import logging
from pathlib import Path
from typing import Any
@ -71,6 +72,7 @@ from ..const import (
ATTR_URL,
ATTR_USB,
ATTR_VERSION,
ATTR_VERSION_TIMESTAMP,
ATTR_VIDEO,
ATTR_WATCHDOG,
ATTR_WEBUI,
@ -222,6 +224,11 @@ class AddonModel(JobGroup, ABC):
"""Return latest version of add-on."""
return self.data[ATTR_VERSION]
@property
def latest_version_timestamp(self) -> datetime:
"""Return when latest version was first seen."""
return datetime.fromtimestamp(self.data[ATTR_VERSION_TIMESTAMP])
@property
def version(self) -> AwesomeVersion:
"""Return version of add-on."""

View File

@ -332,6 +332,7 @@ ATTR_UUID = "uuid"
ATTR_VALID = "valid"
ATTR_VALUE = "value"
ATTR_VERSION = "version"
ATTR_VERSION_TIMESTAMP = "version_timestamp"
ATTR_VERSION_LATEST = "version_latest"
ATTR_VIDEO = "video"
ATTR_VLAN = "vlan"

View File

@ -1,6 +1,7 @@
"""A collection of tasks."""
import asyncio
from collections.abc import Awaitable
from datetime import timedelta
import logging
from ..addons.const import ADDON_UPDATE_CONDITIONS
@ -10,6 +11,7 @@ from ..exceptions import AddonsError, HomeAssistantError, ObserverError
from ..homeassistant.const import LANDINGPAGE
from ..jobs.decorator import Job, JobCondition
from ..plugins.const import PLUGIN_UPDATE_CONDITIONS
from ..utils.dt import utcnow
from ..utils.sentry import capture_exception
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -102,6 +104,8 @@ class Tasks(CoreSysAttributes):
addon.version,
addon.latest_version,
)
# Delay auto-updates for a day in case of issues
if utcnow() + timedelta(days=1) > addon.latest_version_timestamp:
continue
if not addon.test_update_schema():
_LOGGER.warning(

View File

@ -14,6 +14,8 @@ from ..const import (
ATTR_REPOSITORY,
ATTR_SLUG,
ATTR_TRANSLATIONS,
ATTR_VERSION,
ATTR_VERSION_TIMESTAMP,
FILE_SUFFIX_CONFIGURATION,
REPOSITORY_CORE,
REPOSITORY_LOCAL,
@ -22,6 +24,7 @@ from ..coresys import CoreSys, CoreSysAttributes
from ..exceptions import ConfigurationFileError
from ..resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
from ..utils.common import find_one_filetype, read_json_or_yaml_file
from ..utils.dt import utcnow
from ..utils.json import read_json_file
from .const import StoreType
from .utils import extract_hash_from_path
@ -135,6 +138,19 @@ class StoreData(CoreSysAttributes):
repositories[repo.slug] = repo.config
addons.update(await self._read_addons_folder(repo.path, repo.slug))
# Add a timestamp when we first see a new version
for slug, config in addons.items():
old_config = self.addons.get(slug)
if (
not old_config
or ATTR_VERSION_TIMESTAMP not in old_config
or old_config.get(ATTR_VERSION) != config.get(ATTR_VERSION)
):
config[ATTR_VERSION_TIMESTAMP] = utcnow().timestamp()
else:
config[ATTR_VERSION_TIMESTAMP] = old_config[ATTR_VERSION_TIMESTAMP]
self.repositories = repositories
self.addons = addons

View File

@ -243,3 +243,18 @@ async def test_reload(coresys: CoreSys):
await coresys.store.reload()
assert git_pull.call_count == 3
async def test_addon_version_timestamp(coresys: CoreSys, install_addon_example: Addon):
"""Test timestamp tracked for addon's version."""
# When unset, version timestamp set to utcnow on store load
assert (timestamp := install_addon_example.latest_version_timestamp)
# Reload of the store does not change timestamp unless version changes
await coresys.store.reload()
assert timestamp == install_addon_example.latest_version_timestamp
# If a new version is seen processing repo, reset to utc now
install_addon_example.data_store["version"] = "1.1.0"
await coresys.store.reload()
assert timestamp < install_addon_example.latest_version_timestamp