Always stop the addon before restoring it (#4492)

* Always stop the addon before restoring it

* patch ingress refresh to avoid timeout
This commit is contained in:
Mike Degatano 2023-08-15 07:08:45 -04:00 committed by GitHub
parent bd2c99a455
commit 61288559b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 4 deletions

View File

@ -962,6 +962,11 @@ class Addon(AddonModel):
self.slug, data[ATTR_USER], data[ATTR_SYSTEM], restore_image self.slug, data[ATTR_USER], data[ATTR_SYSTEM], restore_image
) )
# Stop it first if its running
if await self.instance.is_running():
with suppress(DockerError):
await self.instance.stop()
# Check version / restore image # Check version / restore image
version = data[ATTR_VERSION] version = data[ATTR_VERSION]
if not await self.instance.exists(): if not await self.instance.exists():
@ -979,9 +984,6 @@ class Addon(AddonModel):
_LOGGER.info("Restore/Update of image for addon %s", self.slug) _LOGGER.info("Restore/Update of image for addon %s", self.slug)
with suppress(DockerError): with suppress(DockerError):
await self.instance.update(version, restore_image) await self.instance.update(version, restore_image)
else:
with suppress(DockerError):
await self.instance.stop()
# Restore data # Restore data
def _restore_data(): def _restore_data():

View File

@ -18,6 +18,7 @@ from supervisor.docker.addon import DockerAddon
from supervisor.docker.const import ContainerState from supervisor.docker.const import ContainerState
from supervisor.docker.monitor import DockerContainerStateEvent from supervisor.docker.monitor import DockerContainerStateEvent
from supervisor.exceptions import AddonsError, AddonsJobError, AudioUpdateError from supervisor.exceptions import AddonsError, AddonsJobError, AudioUpdateError
from supervisor.ingress import Ingress
from supervisor.store.repository import Repository from supervisor.store.repository import Repository
from supervisor.utils.dt import utcnow from supervisor.utils.dt import utcnow
@ -530,12 +531,37 @@ async def test_restore(
tarfile = SecureTarFile(get_fixture_path(f"backup_local_ssh_{status}.tar.gz"), "r") tarfile = SecureTarFile(get_fixture_path(f"backup_local_ssh_{status}.tar.gz"), "r")
with patch.object(DockerAddon, "is_running", return_value=False), patch.object( with patch.object(DockerAddon, "is_running", return_value=False), patch.object(
CpuArch, "supported", new=PropertyMock(return_value=["aarch64"]) CpuArch, "supported", new=PropertyMock(return_value=["aarch64"])
): ), patch.object(Ingress, "update_hass_panel") as update_hass_panel:
start_task = await coresys.addons.restore(TEST_ADDON_SLUG, tarfile) start_task = await coresys.addons.restore(TEST_ADDON_SLUG, tarfile)
update_hass_panel.assert_called_once()
assert bool(start_task) is (status == "running") assert bool(start_task) is (status == "running")
async def test_restore_while_running(
coresys: CoreSys,
install_addon_ssh: Addon,
container: MagicMock,
tmp_supervisor_data,
path_extern,
):
"""Test restore of a running addon."""
container.status = "running"
coresys.hardware.disk.get_disk_free_space = lambda x: 5000
install_addon_ssh.path_data.mkdir()
await install_addon_ssh.load()
tarfile = SecureTarFile(get_fixture_path("backup_local_ssh_stopped.tar.gz"), "r")
with patch.object(DockerAddon, "is_running", return_value=True), patch.object(
CpuArch, "supported", new=PropertyMock(return_value=["aarch64"])
), patch.object(Ingress, "update_hass_panel"):
start_task = await coresys.addons.restore(TEST_ADDON_SLUG, tarfile)
assert bool(start_task) is False
container.stop.assert_called_once()
async def test_start_when_running( async def test_start_when_running(
coresys: CoreSys, coresys: CoreSys,
install_addon_ssh: Addon, install_addon_ssh: Addon,