diff --git a/supervisor/addons/addon.py b/supervisor/addons/addon.py index b610a480a..34e2667f9 100644 --- a/supervisor/addons/addon.py +++ b/supervisor/addons/addon.py @@ -20,7 +20,7 @@ from typing import Any, Final, cast import aiohttp from awesomeversion import AwesomeVersion, AwesomeVersionCompareException from deepmerge import Merger -from securetar import AddFileError, atomic_contents_add, secure_path +from securetar import AddFileError, SecureTarFile, atomic_contents_add, secure_path import voluptuous as vol from voluptuous.humanize import humanize_error @@ -1308,7 +1308,7 @@ class Addon(AddonModel): on_condition=AddonsJobError, concurrency=JobConcurrency.GROUP_REJECT, ) - async def backup(self, tar_file: tarfile.TarFile) -> asyncio.Task | None: + async def backup(self, tar_file: SecureTarFile) -> asyncio.Task | None: """Backup state of an add-on. Returns a Task that completes when addon has state 'started' (see start) @@ -1414,7 +1414,7 @@ class Addon(AddonModel): on_condition=AddonsJobError, concurrency=JobConcurrency.GROUP_REJECT, ) - async def restore(self, tar_file: tarfile.TarFile) -> asyncio.Task | None: + async def restore(self, tar_file: SecureTarFile) -> asyncio.Task | None: """Restore state of an add-on. Returns a Task that completes when addon has state 'started' (see start) diff --git a/supervisor/addons/manager.py b/supervisor/addons/manager.py index 012f25967..132b6220b 100644 --- a/supervisor/addons/manager.py +++ b/supervisor/addons/manager.py @@ -4,10 +4,10 @@ import asyncio from collections.abc import Awaitable from contextlib import suppress import logging -import tarfile from typing import Self, Union from attr import evolve +from securetar import SecureTarFile from ..const import AddonBoot, AddonStartup, AddonState from ..coresys import CoreSys, CoreSysAttributes @@ -334,9 +334,7 @@ class AddonManager(CoreSysAttributes): ], on_condition=AddonsJobError, ) - async def restore( - self, slug: str, tar_file: tarfile.TarFile - ) -> asyncio.Task | None: + async def restore(self, slug: str, tar_file: SecureTarFile) -> asyncio.Task | None: """Restore state of an add-on. Returns a Task that completes when addon has state 'started' (see addon.start) diff --git a/supervisor/api/backups.py b/supervisor/api/backups.py index e3ce11e14..3fdc42fdb 100644 --- a/supervisor/api/backups.py +++ b/supervisor/api/backups.py @@ -310,7 +310,7 @@ class APIBackups(CoreSysAttributes): if background and not backup_task.done(): return {ATTR_JOB_ID: job_id} - backup: Backup = await backup_task + backup: Backup | None = await backup_task if backup: return {ATTR_JOB_ID: job_id, ATTR_SLUG: backup.slug} raise APIError( @@ -346,7 +346,7 @@ class APIBackups(CoreSysAttributes): if background and not backup_task.done(): return {ATTR_JOB_ID: job_id} - backup: Backup = await backup_task + backup: Backup | None = await backup_task if backup: return {ATTR_JOB_ID: job_id, ATTR_SLUG: backup.slug} raise APIError( diff --git a/supervisor/backups/backup.py b/supervisor/backups/backup.py index 7b3e38aa0..9a626aae9 100644 --- a/supervisor/backups/backup.py +++ b/supervisor/backups/backup.py @@ -170,21 +170,21 @@ class Backup(JobGroup): self._data[ATTR_REPOSITORIES] = value @property - def homeassistant_version(self) -> AwesomeVersion: + def homeassistant_version(self) -> AwesomeVersion | None: """Return backup Home Assistant version.""" if self.homeassistant is None: return None return self.homeassistant[ATTR_VERSION] @property - def homeassistant_exclude_database(self) -> bool: + def homeassistant_exclude_database(self) -> bool | None: """Return whether database was excluded from Home Assistant backup.""" if self.homeassistant is None: return None return self.homeassistant[ATTR_EXCLUDE_DATABASE] @property - def homeassistant(self) -> dict[str, Any]: + def homeassistant(self) -> dict[str, Any] | None: """Return backup Home Assistant data.""" return self._data[ATTR_HOMEASSISTANT] @@ -863,7 +863,7 @@ class Backup(JobGroup): await self.sys_homeassistant.backup(homeassistant_file, exclude_database) # Store size - self.homeassistant[ATTR_SIZE] = await self.sys_run_in_executor( + self._data[ATTR_HOMEASSISTANT][ATTR_SIZE] = await self.sys_run_in_executor( getattr, homeassistant_file, "size" ) diff --git a/supervisor/homeassistant/module.py b/supervisor/homeassistant/module.py index d3ca021a5..f2e35efd0 100644 --- a/supervisor/homeassistant/module.py +++ b/supervisor/homeassistant/module.py @@ -13,7 +13,7 @@ from typing import Any from uuid import UUID from awesomeversion import AwesomeVersion, AwesomeVersionException -from securetar import AddFileError, atomic_contents_add, secure_path +from securetar import AddFileError, SecureTarFile, atomic_contents_add, secure_path import voluptuous as vol from voluptuous.humanize import humanize_error @@ -410,7 +410,7 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes): @Job(name="home_assistant_module_backup") async def backup( - self, tar_file: tarfile.TarFile, exclude_database: bool = False + self, tar_file: SecureTarFile, exclude_database: bool = False ) -> None: """Backup Home Assistant Core config/directory.""" excludes = HOMEASSISTANT_BACKUP_EXCLUDE.copy() @@ -470,7 +470,7 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes): @Job(name="home_assistant_module_restore") async def restore( - self, tar_file: tarfile.TarFile, exclude_database: bool = False + self, tar_file: SecureTarFile, exclude_database: bool | None = False ) -> None: """Restore Home Assistant Core config/ directory.""" @@ -502,7 +502,7 @@ class HomeAssistant(FileConfiguration, CoreSysAttributes): temp_data = temp_path _LOGGER.info("Restore Home Assistant Core config folder") - if exclude_database: + if exclude_database is True: remove_folder_with_excludes( self.sys_config.path_homeassistant, excludes=HOMEASSISTANT_BACKUP_EXCLUDE_DATABASE,