Validate hassio backup settings (#138880)
* Validate hassio backup settings * Add snapshots * Don't reset addon and folder settings * Adapt to changes in BackupConfig.updatepull/138941/head
parent
fb57284561
commit
0d8c449ff4
|
@ -16,7 +16,7 @@ from .agent import (
|
|||
BackupAgentPlatformProtocol,
|
||||
LocalBackupAgent,
|
||||
)
|
||||
from .config import BackupConfig
|
||||
from .config import BackupConfig, CreateBackupParametersDict
|
||||
from .const import DATA_MANAGER, DOMAIN
|
||||
from .http import async_register_http_views
|
||||
from .manager import (
|
||||
|
@ -55,6 +55,7 @@ __all__ = [
|
|||
"BackupReaderWriter",
|
||||
"BackupReaderWriterError",
|
||||
"CreateBackupEvent",
|
||||
"CreateBackupParametersDict",
|
||||
"CreateBackupStage",
|
||||
"CreateBackupState",
|
||||
"Folder",
|
||||
|
|
|
@ -33,6 +33,7 @@ from homeassistant.components.backup import (
|
|||
BackupReaderWriter,
|
||||
BackupReaderWriterError,
|
||||
CreateBackupEvent,
|
||||
CreateBackupParametersDict,
|
||||
CreateBackupStage,
|
||||
CreateBackupState,
|
||||
Folder,
|
||||
|
@ -635,7 +636,25 @@ class SupervisorBackupReaderWriter(BackupReaderWriter):
|
|||
unsub()
|
||||
|
||||
async def async_validate_config(self, *, config: BackupConfig) -> None:
|
||||
"""Validate backup config."""
|
||||
"""Validate backup config.
|
||||
|
||||
Replace the core backup agent with the hassio default agent.
|
||||
"""
|
||||
core_agent_id = "backup.local"
|
||||
create_backup = config.data.create_backup
|
||||
if core_agent_id not in create_backup.agent_ids:
|
||||
_LOGGER.debug("Backup settings don't need to be adjusted")
|
||||
return
|
||||
|
||||
default_agent = await _default_agent(self._client)
|
||||
_LOGGER.info("Adjusting backup settings to not include core backup location")
|
||||
automatic_agents = [
|
||||
agent_id if agent_id != core_agent_id else default_agent
|
||||
for agent_id in create_backup.agent_ids
|
||||
]
|
||||
config.update(
|
||||
create_backup=CreateBackupParametersDict(agent_ids=automatic_agents)
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_listen_job_events(
|
||||
|
|
|
@ -625,7 +625,7 @@
|
|||
}),
|
||||
'create_backup': dict({
|
||||
'agent_ids': list([
|
||||
'backup.local',
|
||||
'hassio.local',
|
||||
'test-agent',
|
||||
]),
|
||||
'include_addons': None,
|
||||
|
|
|
@ -529,6 +529,7 @@ def resolution_suggestions_for_issue_fixture(supervisor_client: AsyncMock) -> As
|
|||
def supervisor_client() -> Generator[AsyncMock]:
|
||||
"""Mock the supervisor client."""
|
||||
mounts_info_mock = AsyncMock(spec_set=["default_backup_mount", "mounts"])
|
||||
mounts_info_mock.default_backup_mount = None
|
||||
mounts_info_mock.mounts = []
|
||||
supervisor_client = AsyncMock()
|
||||
supervisor_client.addons = AsyncMock()
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
# serializer version: 1
|
||||
# name: test_config_load_config_info[storage_data0]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': dict({
|
||||
'config': dict({
|
||||
'agents': dict({
|
||||
}),
|
||||
'create_backup': dict({
|
||||
'agent_ids': list([
|
||||
]),
|
||||
'include_addons': None,
|
||||
'include_all_addons': False,
|
||||
'include_database': True,
|
||||
'include_folders': None,
|
||||
'name': None,
|
||||
'password': None,
|
||||
}),
|
||||
'last_attempted_automatic_backup': None,
|
||||
'last_completed_automatic_backup': None,
|
||||
'next_automatic_backup': None,
|
||||
'next_automatic_backup_additional': False,
|
||||
'retention': dict({
|
||||
'copies': None,
|
||||
'days': None,
|
||||
}),
|
||||
'schedule': dict({
|
||||
'days': list([
|
||||
]),
|
||||
'recurrence': 'never',
|
||||
'time': None,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_config_load_config_info[storage_data1]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': dict({
|
||||
'config': dict({
|
||||
'agents': dict({
|
||||
}),
|
||||
'create_backup': dict({
|
||||
'agent_ids': list([
|
||||
'test-agent1',
|
||||
'hassio.local',
|
||||
'test-agent2',
|
||||
]),
|
||||
'include_addons': list([
|
||||
'addon1',
|
||||
'addon2',
|
||||
]),
|
||||
'include_all_addons': True,
|
||||
'include_database': True,
|
||||
'include_folders': list([
|
||||
'media',
|
||||
'share',
|
||||
]),
|
||||
'name': None,
|
||||
'password': None,
|
||||
}),
|
||||
'last_attempted_automatic_backup': None,
|
||||
'last_completed_automatic_backup': None,
|
||||
'next_automatic_backup': None,
|
||||
'next_automatic_backup_additional': False,
|
||||
'retention': dict({
|
||||
'copies': None,
|
||||
'days': None,
|
||||
}),
|
||||
'schedule': dict({
|
||||
'days': list([
|
||||
]),
|
||||
'recurrence': 'never',
|
||||
'time': None,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_config_load_config_info[storage_data2]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': dict({
|
||||
'config': dict({
|
||||
'agents': dict({
|
||||
}),
|
||||
'create_backup': dict({
|
||||
'agent_ids': list([
|
||||
'test-agent1',
|
||||
'hassio.local',
|
||||
'test-agent2',
|
||||
]),
|
||||
'include_addons': list([
|
||||
'addon1',
|
||||
'addon2',
|
||||
]),
|
||||
'include_all_addons': False,
|
||||
'include_database': True,
|
||||
'include_folders': list([
|
||||
'media',
|
||||
'share',
|
||||
]),
|
||||
'name': None,
|
||||
'password': None,
|
||||
}),
|
||||
'last_attempted_automatic_backup': None,
|
||||
'last_completed_automatic_backup': None,
|
||||
'next_automatic_backup': None,
|
||||
'next_automatic_backup_additional': False,
|
||||
'retention': dict({
|
||||
'copies': None,
|
||||
'days': None,
|
||||
}),
|
||||
'schedule': dict({
|
||||
'days': list([
|
||||
]),
|
||||
'recurrence': 'never',
|
||||
'time': None,
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
|
@ -30,6 +30,7 @@ from aiohasupervisor.models.backups import LOCATION_CLOUD_BACKUP, LOCATION_LOCAL
|
|||
from aiohasupervisor.models.mounts import MountsInfo
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.backup import (
|
||||
DOMAIN as BACKUP_DOMAIN,
|
||||
|
@ -38,6 +39,7 @@ from homeassistant.components.backup import (
|
|||
BackupAgent,
|
||||
BackupAgentPlatformProtocol,
|
||||
Folder,
|
||||
store as backup_store,
|
||||
)
|
||||
from homeassistant.components.hassio import DOMAIN
|
||||
from homeassistant.components.hassio.backup import RESTORE_JOB_ID_ENV
|
||||
|
@ -2466,3 +2468,94 @@ async def test_restore_progress_after_restart_unknown_job(
|
|||
assert response["success"]
|
||||
assert response["result"]["last_non_idle_event"] is None
|
||||
assert response["result"]["state"] == "idle"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"storage_data",
|
||||
[
|
||||
{},
|
||||
{
|
||||
"backup": {
|
||||
"data": {
|
||||
"backups": [],
|
||||
"config": {
|
||||
"agents": {},
|
||||
"create_backup": {
|
||||
"agent_ids": ["test-agent1", "hassio.local", "test-agent2"],
|
||||
"include_addons": ["addon1", "addon2"],
|
||||
"include_all_addons": True,
|
||||
"include_database": True,
|
||||
"include_folders": ["media", "share"],
|
||||
"name": None,
|
||||
"password": None,
|
||||
},
|
||||
"retention": {"copies": None, "days": None},
|
||||
"last_attempted_automatic_backup": None,
|
||||
"last_completed_automatic_backup": None,
|
||||
"schedule": {
|
||||
"days": [],
|
||||
"recurrence": "never",
|
||||
"state": "never",
|
||||
"time": None,
|
||||
},
|
||||
},
|
||||
},
|
||||
"key": DOMAIN,
|
||||
"version": backup_store.STORAGE_VERSION,
|
||||
"minor_version": backup_store.STORAGE_VERSION_MINOR,
|
||||
},
|
||||
},
|
||||
{
|
||||
"backup": {
|
||||
"data": {
|
||||
"backups": [],
|
||||
"config": {
|
||||
"agents": {},
|
||||
"create_backup": {
|
||||
"agent_ids": ["test-agent1", "backup.local", "test-agent2"],
|
||||
"include_addons": ["addon1", "addon2"],
|
||||
"include_all_addons": False,
|
||||
"include_database": True,
|
||||
"include_folders": ["media", "share"],
|
||||
"name": None,
|
||||
"password": None,
|
||||
},
|
||||
"retention": {"copies": None, "days": None},
|
||||
"last_attempted_automatic_backup": None,
|
||||
"last_completed_automatic_backup": None,
|
||||
"schedule": {
|
||||
"days": [],
|
||||
"recurrence": "never",
|
||||
"state": "never",
|
||||
"time": None,
|
||||
},
|
||||
},
|
||||
},
|
||||
"key": DOMAIN,
|
||||
"version": backup_store.STORAGE_VERSION,
|
||||
"minor_version": backup_store.STORAGE_VERSION_MINOR,
|
||||
},
|
||||
},
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("hassio_client")
|
||||
async def test_config_load_config_info(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
snapshot: SnapshotAssertion,
|
||||
hass_storage: dict[str, Any],
|
||||
storage_data: dict[str, Any] | None,
|
||||
) -> None:
|
||||
"""Test loading stored backup config and reading it via config/info."""
|
||||
client = await hass_ws_client(hass)
|
||||
await hass.config.async_set_time_zone("Europe/Amsterdam")
|
||||
freezer.move_to("2024-11-13T12:01:00+01:00")
|
||||
|
||||
hass_storage.update(storage_data)
|
||||
|
||||
assert await async_setup_component(hass, BACKUP_DOMAIN, {BACKUP_DOMAIN: {}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
await client.send_json_auto_id({"type": "backup/config/info"})
|
||||
assert await client.receive_json() == snapshot
|
||||
|
|
Loading…
Reference in New Issue