Fix addon image changed on update (#3971)

This commit is contained in:
Mike Degatano 2022-11-03 09:21:57 -04:00 committed by GitHub
parent 4c5d54b7a3
commit 5f04e4fb6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 188 additions and 1 deletions

View File

@ -467,6 +467,11 @@ class Addon(AddonModel):
"""Return True if this add-on need a local build."""
return ATTR_IMAGE not in self.data
@property
def latest_need_build(self) -> bool:
"""Return True if the latest version of the addon needs a local build."""
return ATTR_IMAGE not in self.data_store
@property
def path_data(self) -> Path:
"""Return add-on data path inside Supervisor."""

View File

@ -523,18 +523,42 @@ class DockerAddon(DockerInterface):
BusEvent.HARDWARE_NEW_DEVICE, self._hardware_events
)
def _update(
self, version: AwesomeVersion, image: str | None = None, latest: bool = False
) -> None:
"""Update a docker image.
Need run inside executor.
"""
image = image or self.image
_LOGGER.info(
"Updating image %s:%s to %s:%s", self.image, self.version, image, version
)
# Update docker image
self._install(
version, image=image, latest=latest, need_build=self.addon.latest_need_build
)
# Stop container & cleanup
with suppress(DockerError):
self._stop()
def _install(
self,
version: AwesomeVersion,
image: str | None = None,
latest: bool = False,
arch: CpuArch | None = None,
*,
need_build: bool | None = None,
) -> None:
"""Pull Docker image or build it.
Need run inside executor.
"""
if self.addon.need_build:
if need_build is None and self.addon.need_build or need_build:
self._build(version)
else:
super()._install(version, image, latest, arch)

View File

@ -0,0 +1,67 @@
"""Test addon manager."""
from unittest.mock import PropertyMock, patch
from awesomeversion import AwesomeVersion
import pytest
from supervisor.addons.addon import Addon
from supervisor.arch import CpuArch
from supervisor.coresys import CoreSys
from supervisor.docker.addon import DockerAddon
from supervisor.docker.interface import DockerInterface
from tests.common import load_json_fixture
from tests.const import TEST_ADDON_SLUG
@pytest.fixture(autouse=True)
async def fixture_mock_arch_disk() -> None:
"""Mock supported arch and disk space."""
with patch(
"shutil.disk_usage", return_value=(42, 42, 2 * (1024.0**3))
), patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])):
yield
async def test_image_added_removed_on_update(
coresys: CoreSys, install_addon_ssh: Addon
):
"""Test image added or removed from addon config on update."""
assert install_addon_ssh.need_update is False
with patch(
"supervisor.store.data.read_json_or_yaml_file",
return_value=load_json_fixture("addon-config-add-image.json"),
):
await coresys.store.data.update()
assert install_addon_ssh.need_update is True
assert install_addon_ssh.image == "local/amd64-addon-ssh"
assert coresys.addons.store.get(TEST_ADDON_SLUG).image == "test/amd64-my-ssh-addon"
with patch.object(DockerInterface, "_install") as install, patch.object(
DockerAddon, "_build"
) as build:
await install_addon_ssh.update()
build.assert_not_called()
install.assert_called_once_with(
AwesomeVersion("10.0.0"), "test/amd64-my-ssh-addon", False, None
)
assert install_addon_ssh.need_update is False
with patch(
"supervisor.store.data.read_json_or_yaml_file",
return_value=load_json_fixture("addon-config-remove-image.json"),
):
await coresys.store.data.update()
assert install_addon_ssh.need_update is True
assert install_addon_ssh.image == "test/amd64-my-ssh-addon"
assert coresys.addons.store.get(TEST_ADDON_SLUG).image == "local/amd64-addon-ssh"
with patch.object(DockerInterface, "_install") as install, patch.object(
DockerAddon, "_build"
) as build:
await install_addon_ssh.update()
build.assert_called_once_with(AwesomeVersion("11.0.0"))
install.assert_not_called()

View File

@ -0,0 +1,46 @@
{
"name": "Terminal & SSH",
"version": "10.0.0",
"slug": "ssh",
"description": "Allow logging in remotely to Home Assistant using SSH",
"url": "https://github.com/home-assistant/hassio-addons/tree/master/ssh",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"init": false,
"advanced": true,
"host_dbus": true,
"ingress": true,
"panel_icon": "mdi:console",
"panel_title": "Terminal",
"hassio_api": true,
"hassio_role": "manager",
"audio": true,
"uart": true,
"ports": {
"22/tcp": null
},
"map": [
"config:rw",
"ssl:rw",
"addons:rw",
"share:rw",
"backup:rw",
"media:rw"
],
"options": {
"authorized_keys": [],
"apks": [],
"password": "",
"server": {
"tcp_forwarding": false
}
},
"schema": {
"authorized_keys": ["str"],
"password": "password",
"server": {
"tcp_forwarding": "bool"
},
"apks": ["str"]
},
"image": "test/{arch}-my-ssh-addon"
}

View File

@ -0,0 +1,45 @@
{
"name": "Terminal & SSH",
"version": "11.0.0",
"slug": "ssh",
"description": "Allow logging in remotely to Home Assistant using SSH",
"url": "https://github.com/home-assistant/hassio-addons/tree/master/ssh",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"init": false,
"advanced": true,
"host_dbus": true,
"ingress": true,
"panel_icon": "mdi:console",
"panel_title": "Terminal",
"hassio_api": true,
"hassio_role": "manager",
"audio": true,
"uart": true,
"ports": {
"22/tcp": null
},
"map": [
"config:rw",
"ssl:rw",
"addons:rw",
"share:rw",
"backup:rw",
"media:rw"
],
"options": {
"authorized_keys": [],
"apks": [],
"password": "",
"server": {
"tcp_forwarding": false
}
},
"schema": {
"authorized_keys": ["str"],
"password": "password",
"server": {
"tcp_forwarding": "bool"
},
"apks": ["str"]
}
}