Split out sync functions in backup manager (#67428)

This commit is contained in:
Joakim Sørensen 2022-03-12 05:32:05 +01:00 committed by GitHub
parent d3deae6288
commit c5800d6103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -8,6 +8,7 @@ from pathlib import Path
import tarfile import tarfile
from tarfile import TarError from tarfile import TarError
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import Any
from securetar import SecureTarFile, atomic_contents_add from securetar import SecureTarFile, atomic_contents_add
@ -47,9 +48,14 @@ class BackupManager:
async def load_backups(self) -> None: async def load_backups(self) -> None:
"""Load data of stored backup files.""" """Load data of stored backup files."""
backups = {} backups = await self.hass.async_add_executor_job(self._read_backups)
LOGGER.debug("Loaded %s backups", len(backups))
self.backups = backups
self.loaded = True
def _read_backups() -> None: def _read_backups(self) -> dict[str, Backup]:
"""Read backups from disk."""
backups: dict[str, Backup] = {}
for backup_path in self.backup_dir.glob("*.tar"): for backup_path in self.backup_dir.glob("*.tar"):
try: try:
with tarfile.open(backup_path, "r:") as backup_file: with tarfile.open(backup_path, "r:") as backup_file:
@ -65,11 +71,7 @@ class BackupManager:
backups[backup.slug] = backup backups[backup.slug] = backup
except (OSError, TarError, json.JSONDecodeError) as err: except (OSError, TarError, json.JSONDecodeError) as err:
LOGGER.warning("Unable to read backup %s: %s", backup_path, err) LOGGER.warning("Unable to read backup %s: %s", backup_path, err)
return backups
await self.hass.async_add_executor_job(_read_backups)
LOGGER.debug("Loaded %s backups", len(backups))
self.backups = backups
self.loaded = True
async def get_backups(self) -> dict[str, Backup]: async def get_backups(self) -> dict[str, Backup]:
"""Return backups.""" """Return backups."""
@ -126,33 +128,17 @@ class BackupManager:
"homeassistant": {"version": HAVERSION}, "homeassistant": {"version": HAVERSION},
"compressed": True, "compressed": True,
} }
tar_file_path = Path(self.backup_dir, f"{slug}.tar") tar_file_path = Path(self.backup_dir, f"{backup_data['slug']}.tar")
if not self.backup_dir.exists(): if not self.backup_dir.exists():
LOGGER.debug("Creating backup directory") LOGGER.debug("Creating backup directory")
self.hass.async_add_executor_job(self.backup_dir.mkdir) self.hass.async_add_executor_job(self.backup_dir.mkdir)
def _create_backup() -> None: await self.hass.async_add_executor_job(
with TemporaryDirectory() as tmp_dir: self._generate_backup_contents,
tmp_dir_path = Path(tmp_dir) tar_file_path,
json_util.save_json(
tmp_dir_path.joinpath("./backup.json").as_posix(),
backup_data, backup_data,
) )
with SecureTarFile(tar_file_path, "w", gzip=False) as tar_file:
with SecureTarFile(
tmp_dir_path.joinpath("./homeassistant.tar.gz").as_posix(),
"w",
) as core_tar:
atomic_contents_add(
tar_file=core_tar,
origin_path=Path(self.hass.config.path()),
excludes=EXCLUDE_FROM_BACKUP,
arcname="data",
)
tar_file.add(tmp_dir_path, arcname=".")
await self.hass.async_add_executor_job(_create_backup)
backup = Backup( backup = Backup(
slug=slug, slug=slug,
name=backup_name, name=backup_name,
@ -167,6 +153,32 @@ class BackupManager:
finally: finally:
self.backing_up = False self.backing_up = False
def _generate_backup_contents(
self,
tar_file_path: Path,
backup_data: dict[str, Any],
) -> None:
"""Generate backup contents."""
with TemporaryDirectory() as tmp_dir, SecureTarFile(
tar_file_path, "w", gzip=False
) as tar_file:
tmp_dir_path = Path(tmp_dir)
json_util.save_json(
tmp_dir_path.joinpath("./backup.json").as_posix(),
backup_data,
)
with SecureTarFile(
tmp_dir_path.joinpath("./homeassistant.tar.gz").as_posix(),
"w",
) as core_tar:
atomic_contents_add(
tar_file=core_tar,
origin_path=Path(self.hass.config.path()),
excludes=EXCLUDE_FROM_BACKUP,
arcname="data",
)
tar_file.add(tmp_dir_path, arcname=".")
def _generate_slug(date: str, name: str) -> str: def _generate_slug(date: str, name: str) -> str:
"""Generate a backup slug.""" """Generate a backup slug."""