Partial backup v1 bugfix (#3463)

* Fix compatibility to v1 partial backups

* Add test

* migrate folder list

* add test
This commit is contained in:
Pascal Vizeli 2022-02-24 20:27:50 +01:00 committed by GitHub
parent 71903d906b
commit 3edfaa1ee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 12 deletions

View File

@ -122,7 +122,9 @@ class Backup(CoreSysAttributes):
@property
def homeassistant_version(self):
"""Return backupbackup Home Assistant version."""
return self._data[ATTR_HOMEASSISTANT].get(ATTR_VERSION)
if self.homeassistant is None:
return None
return self._data[ATTR_HOMEASSISTANT][ATTR_VERSION]
@property
def homeassistant(self):

View File

@ -234,10 +234,10 @@ class BackupManager(CoreSysAttributes):
# Version 1
if FOLDER_HOMEASSISTANT in folder_list:
folder_list.remove(FOLDER_HOMEASSISTANT)
homeassistant = True
homeassistant = backup.homeassistant_version is not None
try:
task_hass = None
task_hass: asyncio.Task | None = None
async with backup:
# Restore docker config
_LOGGER.info("Restoring %s Docker config", backup.slug)

View File

@ -1,4 +1,8 @@
"""Validate some things around restore."""
from __future__ import annotations
from typing import Any
import voluptuous as vol
from ..backups.const import BackupType
@ -44,6 +48,26 @@ def unique_addons(addons_list):
return addons_list
def v1_homeassistant(
homeassistant_data: dict[str, Any] | None
) -> dict[str, Any] | None:
"""Cleanup homeassistant artefacts from v1."""
if not homeassistant_data:
return None
if homeassistant_data.get(ATTR_VERSION) is None:
return None
return homeassistant_data
def v1_folderlist(folder_data: list[str]) -> list[str]:
"""Cleanup folder artefacts from v1."""
if FOLDER_HOMEASSISTANT in folder_data:
folder_data.remove(FOLDER_HOMEASSISTANT)
return folder_data
# pylint: disable=no-value-for-parameter
SCHEMA_BACKUP = vol.Schema(
{
@ -55,18 +79,21 @@ SCHEMA_BACKUP = vol.Schema(
vol.Optional(ATTR_COMPRESSED, default=True): vol.Boolean(),
vol.Optional(ATTR_PROTECTED, default=False): vol.Boolean(),
vol.Optional(ATTR_CRYPTO, default=None): vol.Maybe(CRYPTO_AES128),
vol.Optional(ATTR_HOMEASSISTANT, default=None): vol.Maybe(
vol.Schema(
{
vol.Required(ATTR_VERSION): version_tag,
vol.Optional(ATTR_SIZE, default=0): vol.Coerce(float),
},
extra=vol.REMOVE_EXTRA,
)
vol.Optional(ATTR_HOMEASSISTANT, default=None): vol.All(
v1_homeassistant,
vol.Maybe(
vol.Schema(
{
vol.Required(ATTR_VERSION): version_tag,
vol.Optional(ATTR_SIZE, default=0): vol.Coerce(float),
},
extra=vol.REMOVE_EXTRA,
)
),
),
vol.Optional(ATTR_DOCKER, default=dict): SCHEMA_DOCKER_CONFIG,
vol.Optional(ATTR_FOLDERS, default=list): vol.All(
[vol.In(ALL_FOLDERS)], vol.Unique()
v1_folderlist, [vol.In(ALL_FOLDERS)], vol.Unique()
),
vol.Optional(ATTR_ADDONS, default=list): vol.All(
[

View File

@ -0,0 +1,43 @@
"""Test Backup schema validation."""
from supervisor.backups import validate
VALID_DEFAULT = {
validate.ATTR_NAME: "Test Backup",
validate.ATTR_SLUG: "test",
validate.ATTR_DATE: "2021-12-01 00:00:00",
}
def test_v1_homeassistant_migration():
"""Test v1 homeassistant validation migration."""
data = validate.SCHEMA_BACKUP(
{
**VALID_DEFAULT,
**{
validate.ATTR_HOMEASSISTANT: {validate.ATTR_VERSION: None},
validate.ATTR_TYPE: validate.BackupType.PARTIAL,
},
}
)
assert data[validate.ATTR_HOMEASSISTANT] is None
def test_v1_folder_migration():
"""Test v1 folder validation migration."""
data = validate.SCHEMA_BACKUP(
{
**VALID_DEFAULT,
**{
validate.ATTR_TYPE: validate.BackupType.PARTIAL,
validate.ATTR_FOLDERS: [
validate.FOLDER_ADDONS,
validate.ATTR_HOMEASSISTANT,
],
},
}
)
assert data[validate.ATTR_FOLDERS] == [validate.FOLDER_ADDONS]