mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-13 20:26:29 +00:00
Create backup of add-ons and core before update (#3369)
* Create backup of addons and core before update * Move responsibility
This commit is contained in:
parent
22238c9c0e
commit
e0fd31c390
@ -252,7 +252,7 @@ class AddonManager(CoreSysAttributes):
|
||||
],
|
||||
on_condition=AddonsJobError,
|
||||
)
|
||||
async def update(self, slug: str) -> None:
|
||||
async def update(self, slug: str, backup: Optional[bool] = False) -> None:
|
||||
"""Update add-on."""
|
||||
if slug not in self.local:
|
||||
raise AddonsError(f"Add-on {slug} is not installed", _LOGGER.error)
|
||||
@ -273,6 +273,13 @@ class AddonManager(CoreSysAttributes):
|
||||
f"Add-on {slug} not supported on that platform", _LOGGER.error
|
||||
)
|
||||
|
||||
if backup:
|
||||
await self.sys_backups.do_backup_partial(
|
||||
name=f"addon_{addon.slug}_{addon.version}",
|
||||
homeassistant=False,
|
||||
addons=[addon.slug],
|
||||
)
|
||||
|
||||
# Update instance
|
||||
last_state: AddonState = addon.state
|
||||
old_image = addon.image
|
||||
|
@ -622,9 +622,9 @@ class AddonModel(CoreSysAttributes, ABC):
|
||||
"""Uninstall this add-on."""
|
||||
return self.sys_addons.uninstall(self.slug)
|
||||
|
||||
def update(self) -> Awaitable[None]:
|
||||
def update(self, backup: Optional[bool] = False) -> Awaitable[None]:
|
||||
"""Update this add-on."""
|
||||
return self.sys_addons.update(self.slug)
|
||||
return self.sys_addons.update(self.slug, backup=backup)
|
||||
|
||||
def rebuild(self) -> Awaitable[None]:
|
||||
"""Rebuild this add-on."""
|
||||
|
@ -10,6 +10,7 @@ from ..const import (
|
||||
ATTR_ARCH,
|
||||
ATTR_AUDIO_INPUT,
|
||||
ATTR_AUDIO_OUTPUT,
|
||||
ATTR_BACKUP,
|
||||
ATTR_BLK_READ,
|
||||
ATTR_BLK_WRITE,
|
||||
ATTR_BOOT,
|
||||
@ -54,7 +55,12 @@ SCHEMA_OPTIONS = vol.Schema(
|
||||
}
|
||||
)
|
||||
|
||||
SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): version_tag})
|
||||
SCHEMA_UPDATE = vol.Schema(
|
||||
{
|
||||
vol.Optional(ATTR_VERSION): version_tag,
|
||||
vol.Optional(ATTR_BACKUP): bool,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class APIHomeAssistant(CoreSysAttributes):
|
||||
@ -137,10 +143,14 @@ class APIHomeAssistant(CoreSysAttributes):
|
||||
@api_process
|
||||
async def update(self, request: web.Request) -> None:
|
||||
"""Update Home Assistant."""
|
||||
body = await api_validate(SCHEMA_VERSION, request)
|
||||
version = body.get(ATTR_VERSION, self.sys_homeassistant.latest_version)
|
||||
body = await api_validate(SCHEMA_UPDATE, request)
|
||||
|
||||
await asyncio.shield(self.sys_homeassistant.core.update(version))
|
||||
await asyncio.shield(
|
||||
self.sys_homeassistant.core.update(
|
||||
version=body.get(ATTR_VERSION, self.sys_homeassistant.latest_version),
|
||||
backup=body.get(ATTR_BACKUP),
|
||||
)
|
||||
)
|
||||
|
||||
@api_process
|
||||
def stop(self, request: web.Request) -> Awaitable[None]:
|
||||
|
@ -3,13 +3,15 @@ import asyncio
|
||||
from typing import Any, Awaitable
|
||||
|
||||
from aiohttp import web
|
||||
import voluptuous as vol
|
||||
|
||||
from ..addons import AnyAddon
|
||||
from ..api.utils import api_process
|
||||
from ..api.utils import api_process, api_validate
|
||||
from ..const import (
|
||||
ATTR_ADDONS,
|
||||
ATTR_ADVANCED,
|
||||
ATTR_AVAILABLE,
|
||||
ATTR_BACKUP,
|
||||
ATTR_BUILD,
|
||||
ATTR_DESCRIPTON,
|
||||
ATTR_HOMEASSISTANT,
|
||||
@ -34,6 +36,12 @@ from ..exceptions import APIError, APIForbidden
|
||||
from ..store.addon import AddonStore
|
||||
from ..store.repository import Repository
|
||||
|
||||
SCHEMA_UPDATE = vol.Schema(
|
||||
{
|
||||
vol.Optional(ATTR_BACKUP): bool,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class APIStore(CoreSysAttributes):
|
||||
"""Handle RESTful API for store functions."""
|
||||
@ -134,12 +142,15 @@ class APIStore(CoreSysAttributes):
|
||||
return asyncio.shield(addon.install())
|
||||
|
||||
@api_process
|
||||
def addons_addon_update(self, request: web.Request) -> Awaitable[None]:
|
||||
async def addons_addon_update(self, request: web.Request) -> None:
|
||||
"""Update add-on."""
|
||||
addon = self._extract_addon(request, installed=True)
|
||||
if addon == request.get(REQUEST_FROM):
|
||||
raise APIForbidden(f"Add-on {addon.slug} can't update itself!")
|
||||
return asyncio.shield(addon.update())
|
||||
|
||||
body = await api_validate(SCHEMA_UPDATE, request)
|
||||
|
||||
return await asyncio.shield(addon.update(backup=body.get(ATTR_BACKUP)))
|
||||
|
||||
@api_process
|
||||
async def addons_addon_info(self, request: web.Request) -> dict[str, Any]:
|
||||
|
@ -114,6 +114,7 @@ ATTR_AUTH = "auth"
|
||||
ATTR_AUTH_API = "auth_api"
|
||||
ATTR_AUTO_UPDATE = "auto_update"
|
||||
ATTR_AVAILABLE = "available"
|
||||
ATTR_BACKUP = "backup"
|
||||
ATTR_BACKUP_EXCLUDE = "backup_exclude"
|
||||
ATTR_BACKUP_POST = "backup_post"
|
||||
ATTR_BACKUP_PRE = "backup_pre"
|
||||
|
@ -12,6 +12,8 @@ from typing import Awaitable, Optional
|
||||
import attr
|
||||
from awesomeversion import AwesomeVersion, AwesomeVersionException
|
||||
|
||||
from supervisor.const import ATTR_HOMEASSISTANT
|
||||
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..docker.homeassistant import DockerHomeAssistant
|
||||
from ..docker.stats import DockerStats
|
||||
@ -173,7 +175,11 @@ class HomeAssistantCore(CoreSysAttributes):
|
||||
],
|
||||
on_condition=HomeAssistantJobError,
|
||||
)
|
||||
async def update(self, version: Optional[AwesomeVersion] = None) -> None:
|
||||
async def update(
|
||||
self,
|
||||
version: Optional[AwesomeVersion] = None,
|
||||
backup: Optional[bool] = False,
|
||||
) -> None:
|
||||
"""Update HomeAssistant version."""
|
||||
version = version or self.sys_homeassistant.latest_version
|
||||
old_image = self.sys_homeassistant.image
|
||||
@ -186,6 +192,13 @@ class HomeAssistantCore(CoreSysAttributes):
|
||||
f"Version {version!s} is already installed", _LOGGER.warning
|
||||
)
|
||||
|
||||
if backup:
|
||||
await self.sys_backups.do_backup_partial(
|
||||
name=f"core_{self.instance.version}",
|
||||
homeassistant=True,
|
||||
folders=[ATTR_HOMEASSISTANT],
|
||||
)
|
||||
|
||||
# process an update
|
||||
async def _update(to_version: AwesomeVersion) -> None:
|
||||
"""Run Home Assistant update."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user