mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-19 07:06:30 +00:00
Clarify message when addon unavailable (#4098)
This commit is contained in:
parent
089635f4d3
commit
fed4a05003
@ -158,10 +158,7 @@ class AddonManager(CoreSysAttributes):
|
||||
if not store:
|
||||
raise AddonsError(f"Add-on {slug} does not exist", _LOGGER.error)
|
||||
|
||||
if not store.available:
|
||||
raise AddonsNotSupportedError(
|
||||
f"Add-on {slug} not supported on this platform", _LOGGER.error
|
||||
)
|
||||
store.validate_availability()
|
||||
|
||||
self.data.install(store)
|
||||
addon = Addon(self.coresys, slug)
|
||||
@ -263,10 +260,7 @@ class AddonManager(CoreSysAttributes):
|
||||
raise AddonsError(f"No update available for add-on {slug}", _LOGGER.warning)
|
||||
|
||||
# Check if available, Maybe something have changed
|
||||
if not store.available:
|
||||
raise AddonsNotSupportedError(
|
||||
f"Add-on {slug} not supported on that platform", _LOGGER.error
|
||||
)
|
||||
store.validate_availability()
|
||||
|
||||
if backup:
|
||||
await self.sys_backups.do_backup_partial(
|
||||
|
@ -1,6 +1,8 @@
|
||||
"""Init file for Supervisor add-ons."""
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Awaitable
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@ -78,10 +80,13 @@ from ..const import (
|
||||
)
|
||||
from ..coresys import CoreSys, CoreSysAttributes
|
||||
from ..docker.const import Capabilities
|
||||
from ..exceptions import AddonsNotSupportedError
|
||||
from .const import ATTR_BACKUP, ATTR_CODENOTARY, AddonBackupMode
|
||||
from .options import AddonOptions, UiOptions
|
||||
from .validate import RE_SERVICE, RE_VOLUME
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
Data = dict[str, Any]
|
||||
|
||||
|
||||
@ -595,30 +600,51 @@ class AddonModel(CoreSysAttributes, ABC):
|
||||
"""Return Signer email address for CAS."""
|
||||
return self.data.get(ATTR_CODENOTARY)
|
||||
|
||||
def validate_availability(self) -> None:
|
||||
"""Validate if addon is available for current system."""
|
||||
return self._validate_availability(self.data)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""Compaired add-on objects."""
|
||||
if not isinstance(other, AddonModel):
|
||||
return False
|
||||
return self.slug == other.slug
|
||||
|
||||
def _available(self, config) -> bool:
|
||||
"""Return True if this add-on is available on this platform."""
|
||||
def _validate_availability(self, config) -> None:
|
||||
"""Validate if addon is available for current system."""
|
||||
# Architecture
|
||||
if not self.sys_arch.is_supported(config[ATTR_ARCH]):
|
||||
return False
|
||||
raise AddonsNotSupportedError(
|
||||
f"Add-on {self.slug} not supported on this platform, supported architectures: {', '.join(config[ATTR_ARCH])}",
|
||||
_LOGGER.error,
|
||||
)
|
||||
|
||||
# Machine / Hardware
|
||||
machine = config.get(ATTR_MACHINE)
|
||||
if machine and f"!{self.sys_machine}" in machine:
|
||||
return False
|
||||
elif machine and self.sys_machine not in machine:
|
||||
return False
|
||||
if machine and (
|
||||
f"!{self.sys_machine}" in machine or self.sys_machine not in machine
|
||||
):
|
||||
raise AddonsNotSupportedError(
|
||||
f"Add-on {self.slug} not supported on this machine, supported machine types: {', '.join(machine)}",
|
||||
_LOGGER.error,
|
||||
)
|
||||
|
||||
# Home Assistant
|
||||
version: AwesomeVersion | None = config.get(ATTR_HOMEASSISTANT)
|
||||
with suppress(AwesomeVersionException, TypeError):
|
||||
if self.sys_homeassistant.version < version:
|
||||
raise AddonsNotSupportedError(
|
||||
f"Add-on {self.slug} not supported on this system, requires Home Assistant version {version} or greater",
|
||||
_LOGGER.error,
|
||||
)
|
||||
|
||||
def _available(self, config) -> bool:
|
||||
"""Return True if this add-on is available on this platform."""
|
||||
try:
|
||||
return self.sys_homeassistant.version >= version
|
||||
except (AwesomeVersionException, TypeError):
|
||||
self._validate_availability(config)
|
||||
except AddonsNotSupportedError:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _image(self, config) -> str:
|
||||
|
@ -8,6 +8,7 @@ from dbus_fast.introspection import Method, Property, Signal
|
||||
|
||||
from supervisor.dbus.interface import DBusInterface, DBusInterfaceProxy
|
||||
from supervisor.utils.dbus import DBUS_INTERFACE_PROPERTIES
|
||||
from supervisor.utils.yaml import read_yaml_file
|
||||
|
||||
|
||||
def get_dbus_name(intr_list: list[Method | Property | Signal], snake_case: str) -> str:
|
||||
@ -71,6 +72,12 @@ def load_json_fixture(filename: str) -> Any:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def load_yaml_fixture(filename: str) -> Any:
|
||||
"""Load a YAML fixture."""
|
||||
path = Path(Path(__file__).parent.joinpath("fixtures"), filename)
|
||||
return read_yaml_file(path)
|
||||
|
||||
|
||||
def load_fixture(filename: str) -> str:
|
||||
"""Load a fixture."""
|
||||
path = Path(Path(__file__).parent.joinpath("fixtures"), filename)
|
||||
|
@ -1,15 +1,24 @@
|
||||
"""Test store manager."""
|
||||
from typing import Any
|
||||
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.backups.manager import BackupManager
|
||||
from supervisor.bootstrap import migrate_system_env
|
||||
from supervisor.const import ATTR_ADDONS_CUSTOM_LIST
|
||||
from supervisor.coresys import CoreSys
|
||||
from supervisor.exceptions import StoreJobError
|
||||
from supervisor.exceptions import AddonsNotSupportedError, StoreJobError
|
||||
from supervisor.homeassistant.module import HomeAssistant
|
||||
from supervisor.store import StoreManager
|
||||
from supervisor.store.addon import AddonStore
|
||||
from supervisor.store.repository import Repository
|
||||
|
||||
from tests.common import load_yaml_fixture
|
||||
|
||||
|
||||
async def test_default_load(coresys: CoreSys):
|
||||
"""Test default load from config."""
|
||||
@ -111,3 +120,114 @@ async def test_reload_fails_if_out_of_date(coresys: CoreSys):
|
||||
type(coresys.supervisor), "need_update", new=PropertyMock(return_value=True)
|
||||
), pytest.raises(StoreJobError):
|
||||
await coresys.store.reload()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config,log",
|
||||
[
|
||||
(
|
||||
{"arch": ["i386"]},
|
||||
"Add-on local_ssh not supported on this platform, supported architectures: i386",
|
||||
),
|
||||
(
|
||||
{"machine": ["odroid-n2"]},
|
||||
"Add-on local_ssh not supported on this machine, supported machine types: odroid-n2",
|
||||
),
|
||||
(
|
||||
{"machine": ["!qemux86-64"]},
|
||||
"Add-on local_ssh not supported on this machine, supported machine types: !qemux86-64",
|
||||
),
|
||||
(
|
||||
{"homeassistant": AwesomeVersion("2023.1.1")},
|
||||
"Add-on local_ssh not supported on this system, requires Home Assistant version 2023.1.1 or greater",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_update_unavailable_addon(
|
||||
coresys: CoreSys,
|
||||
install_addon_ssh: Addon,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
config: dict[str, Any],
|
||||
log: str,
|
||||
):
|
||||
"""Test updating addon when new version not available for system."""
|
||||
addon_config = dict(
|
||||
load_yaml_fixture("addons/local/ssh/config.yaml"),
|
||||
version=AwesomeVersion("10.0.0"),
|
||||
**config,
|
||||
)
|
||||
|
||||
with patch.object(BackupManager, "do_backup_partial") as backup, patch.object(
|
||||
AddonStore, "data", new=PropertyMock(return_value=addon_config)
|
||||
), patch.object(
|
||||
CpuArch, "supported", new=PropertyMock(return_value=["amd64"])
|
||||
), patch.object(
|
||||
CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")
|
||||
), patch.object(
|
||||
HomeAssistant,
|
||||
"version",
|
||||
new=PropertyMock(return_value=AwesomeVersion("2022.1.1")),
|
||||
), patch(
|
||||
"shutil.disk_usage", return_value=(42, 42, (1024.0**3))
|
||||
):
|
||||
with pytest.raises(AddonsNotSupportedError):
|
||||
await coresys.addons.update("local_ssh", backup=True)
|
||||
|
||||
backup.assert_not_called()
|
||||
|
||||
assert log in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config,log",
|
||||
[
|
||||
(
|
||||
{"arch": ["i386"]},
|
||||
"Add-on local_ssh not supported on this platform, supported architectures: i386",
|
||||
),
|
||||
(
|
||||
{"machine": ["odroid-n2"]},
|
||||
"Add-on local_ssh not supported on this machine, supported machine types: odroid-n2",
|
||||
),
|
||||
(
|
||||
{"machine": ["!qemux86-64"]},
|
||||
"Add-on local_ssh not supported on this machine, supported machine types: !qemux86-64",
|
||||
),
|
||||
(
|
||||
{"homeassistant": AwesomeVersion("2023.1.1")},
|
||||
"Add-on local_ssh not supported on this system, requires Home Assistant version 2023.1.1 or greater",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_install_unavailable_addon(
|
||||
coresys: CoreSys,
|
||||
repository: Repository,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
config: dict[str, Any],
|
||||
log: str,
|
||||
):
|
||||
"""Test updating addon when new version not available for system."""
|
||||
addon_config = dict(
|
||||
load_yaml_fixture("addons/local/ssh/config.yaml"),
|
||||
version=AwesomeVersion("10.0.0"),
|
||||
**config,
|
||||
)
|
||||
|
||||
with patch.object(
|
||||
AddonStore, "data", new=PropertyMock(return_value=addon_config)
|
||||
), patch.object(
|
||||
CpuArch, "supported", new=PropertyMock(return_value=["amd64"])
|
||||
), patch.object(
|
||||
CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")
|
||||
), patch.object(
|
||||
HomeAssistant,
|
||||
"version",
|
||||
new=PropertyMock(return_value=AwesomeVersion("2022.1.1")),
|
||||
), patch(
|
||||
"shutil.disk_usage", return_value=(42, 42, (1024.0**3))
|
||||
), pytest.raises(
|
||||
AddonsNotSupportedError
|
||||
):
|
||||
await coresys.addons.install("local_ssh")
|
||||
|
||||
assert log in caplog.text
|
||||
|
Loading…
x
Reference in New Issue
Block a user