mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-19 15:16:33 +00:00
Auto updates to new version delay for 24 hours (#4838)
This commit is contained in:
parent
88d718271d
commit
140b769a42
@ -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."""
|
||||
|
@ -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."""
|
||||
|
@ -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"
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user