mirror of
https://github.com/home-assistant/core.git
synced 2025-08-10 16:15:08 +02:00
Merge remote-tracking branch 'upstream/allthebackupchanges' into backup_hassio
This commit is contained in:
@@ -20,7 +20,7 @@ from .manager import (
|
|||||||
CoreBackupReaderWriter,
|
CoreBackupReaderWriter,
|
||||||
NewBackup,
|
NewBackup,
|
||||||
)
|
)
|
||||||
from .models import BackupUploadMetadata, BaseBackup
|
from .models import BaseBackup
|
||||||
from .websocket import async_register_websocket_handlers
|
from .websocket import async_register_websocket_handlers
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@@ -30,7 +30,6 @@ __all__ = [
|
|||||||
"BackupPlatformProtocol",
|
"BackupPlatformProtocol",
|
||||||
"BackupProgress",
|
"BackupProgress",
|
||||||
"BackupReaderWriter",
|
"BackupReaderWriter",
|
||||||
"BackupUploadMetadata",
|
|
||||||
"BaseBackup",
|
"BaseBackup",
|
||||||
"LocalBackupAgent",
|
"LocalBackupAgent",
|
||||||
"NewBackup",
|
"NewBackup",
|
||||||
|
@@ -9,7 +9,7 @@ from typing import Any, Protocol
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from .models import BackupUploadMetadata, BaseBackup
|
from .models import BaseBackup
|
||||||
|
|
||||||
|
|
||||||
class BackupAgentError(HomeAssistantError):
|
class BackupAgentError(HomeAssistantError):
|
||||||
@@ -46,13 +46,15 @@ class BackupAgent(abc.ABC):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
path: Path,
|
path: Path,
|
||||||
metadata: BackupUploadMetadata,
|
homeassistant_version: str,
|
||||||
|
backup: BaseBackup,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup.
|
"""Upload a backup.
|
||||||
|
|
||||||
:param path: The full file path to the backup that should be uploaded.
|
:param path: The full file path to the backup that should be uploaded.
|
||||||
:param metadata: Metadata about the backup that should be uploaded.
|
:param backup: Metadata about the backup that should be uploaded.
|
||||||
|
:param homeassistant_version: The version of Home Assistant that created the backup
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@@ -12,7 +12,7 @@ from homeassistant.helpers.hassio import is_hassio
|
|||||||
|
|
||||||
from .agent import BackupAgent, LocalBackupAgent
|
from .agent import BackupAgent, LocalBackupAgent
|
||||||
from .const import LOGGER
|
from .const import LOGGER
|
||||||
from .models import BackupUploadMetadata, BaseBackup
|
from .models import BaseBackup
|
||||||
from .util import read_backup
|
from .util import read_backup
|
||||||
|
|
||||||
|
|
||||||
@@ -78,17 +78,11 @@ class CoreLocalBackupAgent(LocalBackupAgent):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
path: Path,
|
path: Path,
|
||||||
metadata: BackupUploadMetadata,
|
backup: BaseBackup,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup."""
|
"""Upload a backup."""
|
||||||
self._backups[metadata.backup_id] = BaseBackup(
|
self._backups[backup.backup_id] = backup
|
||||||
backup_id=metadata.backup_id,
|
|
||||||
date=metadata.date,
|
|
||||||
name=metadata.name,
|
|
||||||
protected=metadata.protected,
|
|
||||||
size=round(path.stat().st_size / 1_048_576, 2),
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
|
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
|
||||||
"""List backups."""
|
"""List backups."""
|
||||||
|
@@ -43,7 +43,7 @@ from .const import (
|
|||||||
EXCLUDE_FROM_BACKUP,
|
EXCLUDE_FROM_BACKUP,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
)
|
)
|
||||||
from .models import BackupUploadMetadata, BaseBackup
|
from .models import BaseBackup
|
||||||
from .util import read_backup
|
from .util import read_backup
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ from .util import read_backup
|
|||||||
class NewBackup:
|
class NewBackup:
|
||||||
"""New backup class."""
|
"""New backup class."""
|
||||||
|
|
||||||
backup_id: str
|
backup_job_id: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
@@ -226,20 +226,15 @@ class BackupManager:
|
|||||||
path: Path,
|
path: Path,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup to selected agents."""
|
"""Upload a backup to selected agents."""
|
||||||
|
LOGGER.warning("Uploading backup %s to agents %s", backup.backup_id, agent_ids)
|
||||||
self.syncing = True
|
self.syncing = True
|
||||||
try:
|
try:
|
||||||
sync_backup_results = await asyncio.gather(
|
sync_backup_results = await asyncio.gather(
|
||||||
*(
|
*(
|
||||||
self.backup_agents[agent_id].async_upload_backup(
|
self.backup_agents[agent_id].async_upload_backup(
|
||||||
path=path,
|
path=path,
|
||||||
metadata=BackupUploadMetadata(
|
backup=backup,
|
||||||
backup_id=backup.backup_id,
|
homeassistant_version=HAVERSION,
|
||||||
date=backup.date,
|
|
||||||
homeassistant=HAVERSION,
|
|
||||||
name=backup.name,
|
|
||||||
protected=backup.protected,
|
|
||||||
size=backup.size,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
for agent_id in agent_ids
|
for agent_id in agent_ids
|
||||||
),
|
),
|
||||||
@@ -320,7 +315,7 @@ class BackupManager:
|
|||||||
protected=result.protected,
|
protected=result.protected,
|
||||||
size=result.size,
|
size=result.size,
|
||||||
)
|
)
|
||||||
backup.agent_ids.append(agent_ids[idx])
|
backup.agent_ids.append(agent_ids[idx])
|
||||||
|
|
||||||
return (backup, agent_errors)
|
return (backup, agent_errors)
|
||||||
|
|
||||||
@@ -563,7 +558,7 @@ class CoreBackupReaderWriter(BackupReaderWriter):
|
|||||||
eager_start=False, # To ensure the task is not started before we return
|
eager_start=False, # To ensure the task is not started before we return
|
||||||
)
|
)
|
||||||
|
|
||||||
return (NewBackup(backup_id=backup_id), backup_task)
|
return (NewBackup(backup_job_id=backup_id), backup_task)
|
||||||
|
|
||||||
async def _async_create_backup(
|
async def _async_create_backup(
|
||||||
self,
|
self,
|
||||||
|
@@ -16,15 +16,3 @@ class BaseBackup:
|
|||||||
def as_dict(self) -> dict:
|
def as_dict(self) -> dict:
|
||||||
"""Return a dict representation of this backup."""
|
"""Return a dict representation of this backup."""
|
||||||
return asdict(self)
|
return asdict(self)
|
||||||
|
|
||||||
|
|
||||||
@dataclass()
|
|
||||||
class BackupUploadMetadata:
|
|
||||||
"""Backup upload metadata."""
|
|
||||||
|
|
||||||
backup_id: str # The ID of the backup
|
|
||||||
date: str # The date the backup was created
|
|
||||||
homeassistant: str # The version of Home Assistant that created the backup
|
|
||||||
name: str # The name of the backup
|
|
||||||
protected: bool # If the backup is protected
|
|
||||||
size: float # The size of the backup (in bytes)
|
|
||||||
|
@@ -13,7 +13,6 @@ from homeassistant.components.backup import (
|
|||||||
BackupAgent,
|
BackupAgent,
|
||||||
BackupProgress,
|
BackupProgress,
|
||||||
BackupReaderWriter,
|
BackupReaderWriter,
|
||||||
BackupUploadMetadata,
|
|
||||||
BaseBackup,
|
BaseBackup,
|
||||||
LocalBackupAgent,
|
LocalBackupAgent,
|
||||||
NewBackup,
|
NewBackup,
|
||||||
@@ -57,7 +56,8 @@ class SupervisorLocalBackupAgent(LocalBackupAgent):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
path: Path,
|
path: Path,
|
||||||
metadata: BackupUploadMetadata,
|
backup: BaseBackup,
|
||||||
|
homeassistant_version: str,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup."""
|
"""Upload a backup."""
|
||||||
@@ -141,7 +141,7 @@ class SupervisorBackupReaderWriter(BackupReaderWriter):
|
|||||||
eager_start=False, # To ensure the task is not started before we return
|
eager_start=False, # To ensure the task is not started before we return
|
||||||
)
|
)
|
||||||
|
|
||||||
return (NewBackup(backup_id=backup.job_id), backup_task)
|
return (NewBackup(backup_job_id=backup.job_id), backup_task)
|
||||||
|
|
||||||
async def _async_wait_for_backup(
|
async def _async_wait_for_backup(
|
||||||
self, backup: supervisor_backups.NewBackup
|
self, backup: supervisor_backups.NewBackup
|
||||||
|
@@ -6,11 +6,7 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.backup import (
|
from homeassistant.components.backup import BackupAgent, BaseBackup
|
||||||
BackupAgent,
|
|
||||||
BackupUploadMetadata,
|
|
||||||
BaseBackup,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
@@ -54,20 +50,13 @@ class KitchenSinkBackupAgent(BackupAgent):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
path: Path,
|
path: Path,
|
||||||
metadata: BackupUploadMetadata,
|
backup: BaseBackup,
|
||||||
|
homeassistant_version: str,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup."""
|
"""Upload a backup."""
|
||||||
LOGGER.info("Uploading backup %s %s", path.name, metadata)
|
LOGGER.info("Uploading backup %s %s", path.name, backup)
|
||||||
self._uploads.append(
|
self._uploads.append(backup)
|
||||||
BaseBackup(
|
|
||||||
backup_id=metadata.backup_id,
|
|
||||||
date=metadata.date,
|
|
||||||
name=metadata.name,
|
|
||||||
protected=metadata.protected,
|
|
||||||
size=metadata.size,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_delete_backup(
|
async def async_delete_backup(
|
||||||
self,
|
self,
|
||||||
|
@@ -10,7 +10,6 @@ from homeassistant.components.backup import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
BackupAgent,
|
BackupAgent,
|
||||||
BackupAgentPlatformProtocol,
|
BackupAgentPlatformProtocol,
|
||||||
BackupUploadMetadata,
|
|
||||||
BaseBackup,
|
BaseBackup,
|
||||||
)
|
)
|
||||||
from homeassistant.components.backup.const import DATA_MANAGER
|
from homeassistant.components.backup.const import DATA_MANAGER
|
||||||
@@ -75,17 +74,12 @@ class BackupAgentTest(BackupAgent):
|
|||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
path: Path,
|
path: Path,
|
||||||
metadata: BackupUploadMetadata,
|
backup: BaseBackup,
|
||||||
|
homeassistant_version: str,
|
||||||
**kwargs: Any,
|
**kwargs: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Upload a backup."""
|
"""Upload a backup."""
|
||||||
self._backups[metadata.backup_id] = BaseBackup(
|
self._backups[backup.backup_id] = backup
|
||||||
backup_id=metadata.backup_id,
|
|
||||||
date=metadata.date,
|
|
||||||
name=metadata.name,
|
|
||||||
protected=metadata.protected,
|
|
||||||
size=metadata.size,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
|
async def async_list_backups(self, **kwargs: Any) -> list[BaseBackup]:
|
||||||
"""List backups."""
|
"""List backups."""
|
||||||
|
@@ -982,6 +982,7 @@
|
|||||||
'backup': dict({
|
'backup': dict({
|
||||||
'agent_ids': list([
|
'agent_ids': list([
|
||||||
'test.remote',
|
'test.remote',
|
||||||
|
'backup.local',
|
||||||
]),
|
]),
|
||||||
'backup_id': 'abc123',
|
'backup_id': 'abc123',
|
||||||
'date': '1970-01-01T00:00:00.000Z',
|
'date': '1970-01-01T00:00:00.000Z',
|
||||||
@@ -1064,7 +1065,7 @@
|
|||||||
dict({
|
dict({
|
||||||
'id': 1,
|
'id': 1,
|
||||||
'result': dict({
|
'result': dict({
|
||||||
'backup_id': '27f5c632',
|
'backup_job_id': '27f5c632',
|
||||||
}),
|
}),
|
||||||
'success': True,
|
'success': True,
|
||||||
'type': 'result',
|
'type': 'result',
|
||||||
@@ -1085,7 +1086,7 @@
|
|||||||
dict({
|
dict({
|
||||||
'id': 1,
|
'id': 1,
|
||||||
'result': dict({
|
'result': dict({
|
||||||
'backup_id': '27f5c632',
|
'backup_job_id': '27f5c632',
|
||||||
}),
|
}),
|
||||||
'success': True,
|
'success': True,
|
||||||
'type': 'result',
|
'type': 'result',
|
||||||
@@ -1106,7 +1107,7 @@
|
|||||||
dict({
|
dict({
|
||||||
'id': 1,
|
'id': 1,
|
||||||
'result': dict({
|
'result': dict({
|
||||||
'backup_id': '27f5c632',
|
'backup_job_id': '27f5c632',
|
||||||
}),
|
}),
|
||||||
'success': True,
|
'success': True,
|
||||||
'type': 'result',
|
'type': 'result',
|
||||||
@@ -1127,7 +1128,7 @@
|
|||||||
dict({
|
dict({
|
||||||
'id': 1,
|
'id': 1,
|
||||||
'result': dict({
|
'result': dict({
|
||||||
'backup_id': 'abc123',
|
'backup_job_id': 'abc123',
|
||||||
}),
|
}),
|
||||||
'success': True,
|
'success': True,
|
||||||
'type': 'result',
|
'type': 'result',
|
||||||
@@ -1137,7 +1138,7 @@
|
|||||||
dict({
|
dict({
|
||||||
'id': 1,
|
'id': 1,
|
||||||
'result': dict({
|
'result': dict({
|
||||||
'backup_id': 'abc123',
|
'backup_job_id': 'abc123',
|
||||||
}),
|
}),
|
||||||
'success': True,
|
'success': True,
|
||||||
'type': 'result',
|
'type': 'result',
|
||||||
|
@@ -426,7 +426,7 @@ async def test_not_loading_bad_platforms(
|
|||||||
assert "Loaded 0 platforms" in caplog.text
|
assert "Loaded 0 platforms" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
async def test_exception_plaform_pre(
|
async def test_exception_platform_pre(
|
||||||
hass: HomeAssistant, mocked_json_bytes: Mock, mocked_tarfile: Mock
|
hass: HomeAssistant, mocked_json_bytes: Mock, mocked_tarfile: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test exception in pre step."""
|
"""Test exception in pre step."""
|
||||||
@@ -449,7 +449,7 @@ async def test_exception_plaform_pre(
|
|||||||
await _mock_backup_generation(hass, manager, mocked_json_bytes, mocked_tarfile)
|
await _mock_backup_generation(hass, manager, mocked_json_bytes, mocked_tarfile)
|
||||||
|
|
||||||
|
|
||||||
async def test_exception_plaform_post(
|
async def test_exception_platform_post(
|
||||||
hass: HomeAssistant, mocked_json_bytes: Mock, mocked_tarfile: Mock
|
hass: HomeAssistant, mocked_json_bytes: Mock, mocked_tarfile: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test exception in post step."""
|
"""Test exception in post step."""
|
||||||
|
Reference in New Issue
Block a user