mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-08 17:56:33 +00:00
Fix addon image changed on update (#3971)
This commit is contained in:
parent
4c5d54b7a3
commit
5f04e4fb6a
@ -467,6 +467,11 @@ class Addon(AddonModel):
|
|||||||
"""Return True if this add-on need a local build."""
|
"""Return True if this add-on need a local build."""
|
||||||
return ATTR_IMAGE not in self.data
|
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
|
@property
|
||||||
def path_data(self) -> Path:
|
def path_data(self) -> Path:
|
||||||
"""Return add-on data path inside Supervisor."""
|
"""Return add-on data path inside Supervisor."""
|
||||||
|
@ -523,18 +523,42 @@ class DockerAddon(DockerInterface):
|
|||||||
BusEvent.HARDWARE_NEW_DEVICE, self._hardware_events
|
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(
|
def _install(
|
||||||
self,
|
self,
|
||||||
version: AwesomeVersion,
|
version: AwesomeVersion,
|
||||||
image: str | None = None,
|
image: str | None = None,
|
||||||
latest: bool = False,
|
latest: bool = False,
|
||||||
arch: CpuArch | None = None,
|
arch: CpuArch | None = None,
|
||||||
|
*,
|
||||||
|
need_build: bool | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Pull Docker image or build it.
|
"""Pull Docker image or build it.
|
||||||
|
|
||||||
Need run inside executor.
|
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)
|
self._build(version)
|
||||||
else:
|
else:
|
||||||
super()._install(version, image, latest, arch)
|
super()._install(version, image, latest, arch)
|
||||||
|
67
tests/addons/test_manager.py
Normal file
67
tests/addons/test_manager.py
Normal 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()
|
46
tests/fixtures/addon-config-add-image.json
vendored
Normal file
46
tests/fixtures/addon-config-add-image.json
vendored
Normal 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"
|
||||||
|
}
|
45
tests/fixtures/addon-config-remove-image.json
vendored
Normal file
45
tests/fixtures/addon-config-remove-image.json
vendored
Normal 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"]
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user