mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-04-02 00:07:16 +01:00
Handle certain OSError in get_latest_mtime during directory walk (#6632)
Besides file not found also catch "Too many levels of symbolic links" which can happen when there are symbolic link loops in the add-on/apps repository. Also improve error handling in the repository update process to catch OSError when checking for local modifications and raise a specific error that can be handled appropriately. Fixes SUPERVISOR-1FJ0 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -219,11 +219,18 @@ class RepositoryLocal(RepositoryBuiltin):
|
||||
super().__init__(coresys, BuiltinRepository.LOCAL.value, local_path, slug)
|
||||
self._latest_mtime: float | None = None
|
||||
|
||||
async def _get_latest_mtime(self) -> tuple[float, Path]:
|
||||
"""Get latest modification time of repository."""
|
||||
try:
|
||||
return await self.sys_run_in_executor(get_latest_mtime, self.local_path)
|
||||
except OSError as err:
|
||||
self.coresys.resolution.check_oserror(err)
|
||||
_LOGGER.error("Can't check local repository for modifications: %s", err)
|
||||
raise StoreRepositoryUnknownError(repo=self.slug) from err
|
||||
|
||||
async def load(self) -> None:
|
||||
"""Load addon repository."""
|
||||
self._latest_mtime, _ = await self.sys_run_in_executor(
|
||||
get_latest_mtime, self.local_path
|
||||
)
|
||||
self._latest_mtime, _ = await self._get_latest_mtime()
|
||||
|
||||
async def update(self) -> bool:
|
||||
"""Update add-on repository.
|
||||
@@ -231,9 +238,8 @@ class RepositoryLocal(RepositoryBuiltin):
|
||||
Returns True if the repository was updated.
|
||||
"""
|
||||
# Check local modifications
|
||||
latest_mtime, modified_path = await self.sys_run_in_executor(
|
||||
get_latest_mtime, self.local_path
|
||||
)
|
||||
latest_mtime, modified_path = await self._get_latest_mtime()
|
||||
|
||||
if self._latest_mtime != latest_mtime:
|
||||
_LOGGER.debug(
|
||||
"Local modifications detected in %s repository: %s",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Tools file for Supervisor."""
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
from functools import lru_cache
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
@@ -146,10 +147,11 @@ def get_latest_mtime(directory: Path) -> tuple[float, Path]:
|
||||
if mtime > latest_mtime:
|
||||
latest_mtime = mtime
|
||||
latest_path = path
|
||||
except FileNotFoundError:
|
||||
# File might disappear between listing and stat. Parent
|
||||
# directory modification date will flag such a change.
|
||||
continue
|
||||
except OSError as err:
|
||||
if err.errno in (errno.ENOENT, errno.ELOOP):
|
||||
_LOGGER.debug("Could not stat %s, skipping", path)
|
||||
continue
|
||||
raise
|
||||
return latest_mtime, latest_path
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user