mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-12-20 02:18:59 +00:00
Improve CpuArch type safety across codebase (#6372)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ from ..const import (
|
|||||||
FILE_SUFFIX_CONFIGURATION,
|
FILE_SUFFIX_CONFIGURATION,
|
||||||
META_ADDON,
|
META_ADDON,
|
||||||
SOCKET_DOCKER,
|
SOCKET_DOCKER,
|
||||||
|
CpuArch,
|
||||||
)
|
)
|
||||||
from ..coresys import CoreSys, CoreSysAttributes
|
from ..coresys import CoreSys, CoreSysAttributes
|
||||||
from ..docker.const import DOCKER_HUB
|
from ..docker.const import DOCKER_HUB
|
||||||
@@ -67,7 +68,7 @@ class AddonBuild(FileConfiguration, CoreSysAttributes):
|
|||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def arch(self) -> str:
|
def arch(self) -> CpuArch:
|
||||||
"""Return arch of the add-on."""
|
"""Return arch of the add-on."""
|
||||||
return self.sys_arch.match([self.addon.arch])
|
return self.sys_arch.match([self.addon.arch])
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ from ..const import (
|
|||||||
AddonBootConfig,
|
AddonBootConfig,
|
||||||
AddonStage,
|
AddonStage,
|
||||||
AddonStartup,
|
AddonStartup,
|
||||||
|
CpuArch,
|
||||||
)
|
)
|
||||||
from ..coresys import CoreSys
|
from ..coresys import CoreSys
|
||||||
from ..docker.const import Capabilities
|
from ..docker.const import Capabilities
|
||||||
@@ -548,7 +549,7 @@ class AddonModel(JobGroup, ABC):
|
|||||||
return self.data.get(ATTR_MACHINE, [])
|
return self.data.get(ATTR_MACHINE, [])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def arch(self) -> str:
|
def arch(self) -> CpuArch:
|
||||||
"""Return architecture to use for the addon's image."""
|
"""Return architecture to use for the addon's image."""
|
||||||
if ATTR_IMAGE in self.data:
|
if ATTR_IMAGE in self.data:
|
||||||
return self.sys_arch.match(self.data[ATTR_ARCH])
|
return self.sys_arch.match(self.data[ATTR_ARCH])
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import logging
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
|
from .const import CpuArch
|
||||||
from .coresys import CoreSys, CoreSysAttributes
|
from .coresys import CoreSys, CoreSysAttributes
|
||||||
from .exceptions import ConfigurationFileError, HassioArchNotFound
|
from .exceptions import ConfigurationFileError, HassioArchNotFound
|
||||||
from .utils.json import read_json_file
|
from .utils.json import read_json_file
|
||||||
@@ -12,38 +13,40 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
ARCH_JSON: Path = Path(__file__).parent.joinpath("data/arch.json")
|
ARCH_JSON: Path = Path(__file__).parent.joinpath("data/arch.json")
|
||||||
|
|
||||||
MAP_CPU = {
|
MAP_CPU: dict[str, CpuArch] = {
|
||||||
"armv7": "armv7",
|
"armv7": CpuArch.ARMV7,
|
||||||
"armv6": "armhf",
|
"armv6": CpuArch.ARMHF,
|
||||||
"armv8": "aarch64",
|
"armv8": CpuArch.AARCH64,
|
||||||
"aarch64": "aarch64",
|
"aarch64": CpuArch.AARCH64,
|
||||||
"i686": "i386",
|
"i686": CpuArch.I386,
|
||||||
"x86_64": "amd64",
|
"x86_64": CpuArch.AMD64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CpuArch(CoreSysAttributes):
|
class CpuArchManager(CoreSysAttributes):
|
||||||
"""Manage available architectures."""
|
"""Manage available architectures."""
|
||||||
|
|
||||||
def __init__(self, coresys: CoreSys) -> None:
|
def __init__(self, coresys: CoreSys) -> None:
|
||||||
"""Initialize CPU Architecture handler."""
|
"""Initialize CPU Architecture handler."""
|
||||||
self.coresys = coresys
|
self.coresys = coresys
|
||||||
self._supported_arch: list[str] = []
|
self._supported_arch: list[CpuArch] = []
|
||||||
self._supported_set: set[str] = set()
|
self._supported_set: set[CpuArch] = set()
|
||||||
self._default_arch: str
|
self._default_arch: CpuArch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default(self) -> str:
|
def default(self) -> CpuArch:
|
||||||
"""Return system default arch."""
|
"""Return system default arch."""
|
||||||
return self._default_arch
|
return self._default_arch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supervisor(self) -> str:
|
def supervisor(self) -> CpuArch:
|
||||||
"""Return supervisor arch."""
|
"""Return supervisor arch."""
|
||||||
return self.sys_supervisor.arch or self._default_arch
|
if self.sys_supervisor.arch:
|
||||||
|
return CpuArch(self.sys_supervisor.arch)
|
||||||
|
return self._default_arch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported(self) -> list[str]:
|
def supported(self) -> list[CpuArch]:
|
||||||
"""Return support arch by CPU/Machine."""
|
"""Return support arch by CPU/Machine."""
|
||||||
return self._supported_arch
|
return self._supported_arch
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ class CpuArch(CoreSysAttributes):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Use configs from arch.json
|
# Use configs from arch.json
|
||||||
self._supported_arch.extend(arch_data[self.sys_machine])
|
self._supported_arch.extend(CpuArch(a) for a in arch_data[self.sys_machine])
|
||||||
self._default_arch = self.supported[0]
|
self._default_arch = self.supported[0]
|
||||||
|
|
||||||
# Make sure native support is in supported list
|
# Make sure native support is in supported list
|
||||||
@@ -78,14 +81,14 @@ class CpuArch(CoreSysAttributes):
|
|||||||
"""Return True if there is a supported arch by this platform."""
|
"""Return True if there is a supported arch by this platform."""
|
||||||
return not self._supported_set.isdisjoint(arch_list)
|
return not self._supported_set.isdisjoint(arch_list)
|
||||||
|
|
||||||
def match(self, arch_list: list[str]) -> str:
|
def match(self, arch_list: list[str]) -> CpuArch:
|
||||||
"""Return best match for this CPU/Platform."""
|
"""Return best match for this CPU/Platform."""
|
||||||
for self_arch in self.supported:
|
for self_arch in self.supported:
|
||||||
if self_arch in arch_list:
|
if self_arch in arch_list:
|
||||||
return self_arch
|
return self_arch
|
||||||
raise HassioArchNotFound()
|
raise HassioArchNotFound()
|
||||||
|
|
||||||
def detect_cpu(self) -> str:
|
def detect_cpu(self) -> CpuArch:
|
||||||
"""Return the arch type of local CPU."""
|
"""Return the arch type of local CPU."""
|
||||||
cpu = platform.machine()
|
cpu = platform.machine()
|
||||||
for check, value in MAP_CPU.items():
|
for check, value in MAP_CPU.items():
|
||||||
@@ -96,9 +99,10 @@ class CpuArch(CoreSysAttributes):
|
|||||||
"Unknown CPU architecture %s, falling back to Supervisor architecture.",
|
"Unknown CPU architecture %s, falling back to Supervisor architecture.",
|
||||||
cpu,
|
cpu,
|
||||||
)
|
)
|
||||||
return self.sys_supervisor.arch
|
return CpuArch(self.sys_supervisor.arch)
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Unknown CPU architecture %s, assuming CPU architecture equals Supervisor architecture.",
|
"Unknown CPU architecture %s, assuming CPU architecture equals Supervisor architecture.",
|
||||||
cpu,
|
cpu,
|
||||||
)
|
)
|
||||||
return cpu
|
# Return the cpu string as-is, wrapped in CpuArch (may fail if invalid)
|
||||||
|
return CpuArch(cpu)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from colorlog import ColoredFormatter
|
|||||||
|
|
||||||
from .addons.manager import AddonManager
|
from .addons.manager import AddonManager
|
||||||
from .api import RestAPI
|
from .api import RestAPI
|
||||||
from .arch import CpuArch
|
from .arch import CpuArchManager
|
||||||
from .auth import Auth
|
from .auth import Auth
|
||||||
from .backups.manager import BackupManager
|
from .backups.manager import BackupManager
|
||||||
from .bus import Bus
|
from .bus import Bus
|
||||||
@@ -71,7 +71,7 @@ async def initialize_coresys() -> CoreSys:
|
|||||||
coresys.jobs = await JobManager(coresys).load_config()
|
coresys.jobs = await JobManager(coresys).load_config()
|
||||||
coresys.core = await Core(coresys).post_init()
|
coresys.core = await Core(coresys).post_init()
|
||||||
coresys.plugins = await PluginManager(coresys).load_config()
|
coresys.plugins = await PluginManager(coresys).load_config()
|
||||||
coresys.arch = CpuArch(coresys)
|
coresys.arch = CpuArchManager(coresys)
|
||||||
coresys.auth = await Auth(coresys).load_config()
|
coresys.auth = await Auth(coresys).load_config()
|
||||||
coresys.updater = await Updater(coresys).load_config()
|
coresys.updater = await Updater(coresys).load_config()
|
||||||
coresys.api = RestAPI(coresys)
|
coresys.api = RestAPI(coresys)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ from .const import (
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .addons.manager import AddonManager
|
from .addons.manager import AddonManager
|
||||||
from .api import RestAPI
|
from .api import RestAPI
|
||||||
from .arch import CpuArch
|
from .arch import CpuArchManager
|
||||||
from .auth import Auth
|
from .auth import Auth
|
||||||
from .backups.manager import BackupManager
|
from .backups.manager import BackupManager
|
||||||
from .bus import Bus
|
from .bus import Bus
|
||||||
@@ -78,7 +78,7 @@ class CoreSys:
|
|||||||
# Internal objects pointers
|
# Internal objects pointers
|
||||||
self._docker: DockerAPI | None = None
|
self._docker: DockerAPI | None = None
|
||||||
self._core: Core | None = None
|
self._core: Core | None = None
|
||||||
self._arch: CpuArch | None = None
|
self._arch: CpuArchManager | None = None
|
||||||
self._auth: Auth | None = None
|
self._auth: Auth | None = None
|
||||||
self._homeassistant: HomeAssistant | None = None
|
self._homeassistant: HomeAssistant | None = None
|
||||||
self._supervisor: Supervisor | None = None
|
self._supervisor: Supervisor | None = None
|
||||||
@@ -266,17 +266,17 @@ class CoreSys:
|
|||||||
self._plugins = value
|
self._plugins = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def arch(self) -> CpuArch:
|
def arch(self) -> CpuArchManager:
|
||||||
"""Return CpuArch object."""
|
"""Return CpuArchManager object."""
|
||||||
if self._arch is None:
|
if self._arch is None:
|
||||||
raise RuntimeError("CpuArch not set!")
|
raise RuntimeError("CpuArchManager not set!")
|
||||||
return self._arch
|
return self._arch
|
||||||
|
|
||||||
@arch.setter
|
@arch.setter
|
||||||
def arch(self, value: CpuArch) -> None:
|
def arch(self, value: CpuArchManager) -> None:
|
||||||
"""Set a CpuArch object."""
|
"""Set a CpuArchManager object."""
|
||||||
if self._arch:
|
if self._arch:
|
||||||
raise RuntimeError("CpuArch already set!")
|
raise RuntimeError("CpuArchManager already set!")
|
||||||
self._arch = value
|
self._arch = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -733,8 +733,8 @@ class CoreSysAttributes:
|
|||||||
return self.coresys.plugins
|
return self.coresys.plugins
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sys_arch(self) -> CpuArch:
|
def sys_arch(self) -> CpuArchManager:
|
||||||
"""Return CpuArch object."""
|
"""Return CpuArchManager object."""
|
||||||
return self.coresys.arch
|
return self.coresys.arch
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ from .stats import DockerStats
|
|||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
MAP_ARCH: dict[CpuArch | str, str] = {
|
MAP_ARCH: dict[CpuArch, str] = {
|
||||||
CpuArch.ARMV7: "linux/arm/v7",
|
CpuArch.ARMV7: "linux/arm/v7",
|
||||||
CpuArch.ARMHF: "linux/arm/v6",
|
CpuArch.ARMHF: "linux/arm/v6",
|
||||||
CpuArch.AARCH64: "linux/arm64",
|
CpuArch.AARCH64: "linux/arm64",
|
||||||
@@ -366,7 +366,7 @@ class DockerInterface(JobGroup, ABC):
|
|||||||
if not image:
|
if not image:
|
||||||
raise ValueError("Cannot pull without an image!")
|
raise ValueError("Cannot pull without an image!")
|
||||||
|
|
||||||
image_arch = str(arch) if arch else self.sys_arch.supervisor
|
image_arch = arch or self.sys_arch.supervisor
|
||||||
listener: EventListener | None = None
|
listener: EventListener | None = None
|
||||||
|
|
||||||
_LOGGER.info("Downloading docker image %s with tag %s.", image, version)
|
_LOGGER.info("Downloading docker image %s with tag %s.", image, version)
|
||||||
@@ -603,9 +603,7 @@ class DockerInterface(JobGroup, ABC):
|
|||||||
expected_cpu_arch: CpuArch | None = None,
|
expected_cpu_arch: CpuArch | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Check we have expected image with correct arch."""
|
"""Check we have expected image with correct arch."""
|
||||||
expected_image_cpu_arch = (
|
arch = expected_cpu_arch or self.sys_arch.supervisor
|
||||||
str(expected_cpu_arch) if expected_cpu_arch else self.sys_arch.supervisor
|
|
||||||
)
|
|
||||||
image_name = f"{expected_image}:{version!s}"
|
image_name = f"{expected_image}:{version!s}"
|
||||||
if self.image == expected_image:
|
if self.image == expected_image:
|
||||||
try:
|
try:
|
||||||
@@ -623,7 +621,7 @@ class DockerInterface(JobGroup, ABC):
|
|||||||
# If we have an image and its the right arch, all set
|
# If we have an image and its the right arch, all set
|
||||||
# It seems that newer Docker version return a variant for arm64 images.
|
# It seems that newer Docker version return a variant for arm64 images.
|
||||||
# Make sure we match linux/arm64 and linux/arm64/v8.
|
# Make sure we match linux/arm64 and linux/arm64/v8.
|
||||||
expected_image_arch = MAP_ARCH[expected_image_cpu_arch]
|
expected_image_arch = MAP_ARCH[arch]
|
||||||
if image_arch.startswith(expected_image_arch):
|
if image_arch.startswith(expected_image_arch):
|
||||||
return
|
return
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
@@ -636,7 +634,7 @@ class DockerInterface(JobGroup, ABC):
|
|||||||
# We're missing the image we need. Stop and clean up what we have then pull the right one
|
# We're missing the image we need. Stop and clean up what we have then pull the right one
|
||||||
with suppress(DockerError):
|
with suppress(DockerError):
|
||||||
await self.remove()
|
await self.remove()
|
||||||
await self.install(version, expected_image, arch=expected_image_cpu_arch)
|
await self.install(version, expected_image, arch=arch)
|
||||||
|
|
||||||
@Job(
|
@Job(
|
||||||
name="docker_interface_update",
|
name="docker_interface_update",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from awesomeversion import AwesomeVersion
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.addons.addon import Addon
|
from supervisor.addons.addon import Addon
|
||||||
from supervisor.arch import CpuArch
|
from supervisor.arch import CpuArchManager
|
||||||
from supervisor.config import CoreConfig
|
from supervisor.config import CoreConfig
|
||||||
from supervisor.const import AddonBoot, AddonStartup, AddonState, BusEvent
|
from supervisor.const import AddonBoot, AddonStartup, AddonState, BusEvent
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
@@ -54,7 +54,9 @@ async def fixture_mock_arch_disk() -> AsyncGenerator[None]:
|
|||||||
"""Mock supported arch and disk space."""
|
"""Mock supported arch and disk space."""
|
||||||
with (
|
with (
|
||||||
patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0**3))),
|
patch("shutil.disk_usage", return_value=(42, 42, 2 * (1024.0**3))),
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
):
|
):
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import pytest
|
|||||||
|
|
||||||
from supervisor.addons.addon import Addon
|
from supervisor.addons.addon import Addon
|
||||||
from supervisor.addons.build import AddonBuild
|
from supervisor.addons.build import AddonBuild
|
||||||
from supervisor.arch import CpuArch
|
from supervisor.arch import CpuArchManager
|
||||||
from supervisor.const import AddonState
|
from supervisor.const import AddonState
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.docker.addon import DockerAddon
|
from supervisor.docker.addon import DockerAddon
|
||||||
@@ -236,7 +236,9 @@ async def test_api_addon_rebuild_healthcheck(
|
|||||||
patch.object(AddonBuild, "is_valid", return_value=True),
|
patch.object(AddonBuild, "is_valid", return_value=True),
|
||||||
patch.object(DockerAddon, "is_running", return_value=False),
|
patch.object(DockerAddon, "is_running", return_value=False),
|
||||||
patch.object(Addon, "need_build", new=PropertyMock(return_value=True)),
|
patch.object(Addon, "need_build", new=PropertyMock(return_value=True)),
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
patch.object(DockerAddon, "run", new=container_events_task),
|
patch.object(DockerAddon, "run", new=container_events_task),
|
||||||
patch.object(
|
patch.object(
|
||||||
coresys.docker,
|
coresys.docker,
|
||||||
@@ -308,7 +310,9 @@ async def test_api_addon_rebuild_force(
|
|||||||
patch.object(
|
patch.object(
|
||||||
Addon, "need_build", new=PropertyMock(return_value=False)
|
Addon, "need_build", new=PropertyMock(return_value=False)
|
||||||
), # Image-based
|
), # Image-based
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
):
|
):
|
||||||
resp = await api_client.post("/addons/local_ssh/rebuild")
|
resp = await api_client.post("/addons/local_ssh/rebuild")
|
||||||
|
|
||||||
@@ -326,7 +330,9 @@ async def test_api_addon_rebuild_force(
|
|||||||
patch.object(
|
patch.object(
|
||||||
Addon, "need_build", new=PropertyMock(return_value=False)
|
Addon, "need_build", new=PropertyMock(return_value=False)
|
||||||
), # Image-based
|
), # Image-based
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
patch.object(DockerAddon, "run", new=container_events_task),
|
patch.object(DockerAddon, "run", new=container_events_task),
|
||||||
patch.object(
|
patch.object(
|
||||||
coresys.docker,
|
coresys.docker,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from awesomeversion import AwesomeVersion
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.addons.addon import Addon
|
from supervisor.addons.addon import Addon
|
||||||
from supervisor.arch import CpuArch
|
from supervisor.arch import CpuArchManager
|
||||||
from supervisor.backups.manager import BackupManager
|
from supervisor.backups.manager import BackupManager
|
||||||
from supervisor.config import CoreConfig
|
from supervisor.config import CoreConfig
|
||||||
from supervisor.const import AddonState, CoreState
|
from supervisor.const import AddonState, CoreState
|
||||||
@@ -191,7 +191,9 @@ async def test_api_store_update_healthcheck(
|
|||||||
patch.object(DockerAddon, "run", new=container_events_task),
|
patch.object(DockerAddon, "run", new=container_events_task),
|
||||||
patch.object(DockerInterface, "install"),
|
patch.object(DockerInterface, "install"),
|
||||||
patch.object(DockerAddon, "is_running", return_value=False),
|
patch.object(DockerAddon, "is_running", return_value=False),
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
):
|
):
|
||||||
resp = await api_client.post(f"/store/addons/{TEST_ADDON_SLUG}/update")
|
resp = await api_client.post(f"/store/addons/{TEST_ADDON_SLUG}/update")
|
||||||
|
|
||||||
@@ -548,7 +550,9 @@ async def test_api_store_addons_addon_availability_arch_not_supported(
|
|||||||
coresys.addons.data.user[addon_obj.slug] = {"version": AwesomeVersion("0.0.1")}
|
coresys.addons.data.user[addon_obj.slug] = {"version": AwesomeVersion("0.0.1")}
|
||||||
|
|
||||||
# Mock the system architecture to be different
|
# Mock the system architecture to be different
|
||||||
with patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])):
|
with patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
):
|
||||||
resp = await api_client.request(
|
resp = await api_client.request(
|
||||||
api_method, f"/store/addons/{addon_obj.slug}/{api_action}"
|
api_method, f"/store/addons/{addon_obj.slug}/{api_action}"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from awesomeversion import AwesomeVersion
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.addons.addon import Addon
|
from supervisor.addons.addon import Addon
|
||||||
from supervisor.arch import CpuArch
|
from supervisor.arch import CpuArchManager
|
||||||
from supervisor.backups.manager import BackupManager
|
from supervisor.backups.manager import BackupManager
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
from supervisor.exceptions import AddonNotSupportedError, StoreJobError
|
from supervisor.exceptions import AddonNotSupportedError, StoreJobError
|
||||||
@@ -163,7 +163,9 @@ async def test_update_unavailable_addon(
|
|||||||
with (
|
with (
|
||||||
patch.object(BackupManager, "do_backup_partial") as backup,
|
patch.object(BackupManager, "do_backup_partial") as backup,
|
||||||
patch.object(AddonStore, "data", new=PropertyMock(return_value=addon_config)),
|
patch.object(AddonStore, "data", new=PropertyMock(return_value=addon_config)),
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
patch.object(CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")),
|
patch.object(CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")),
|
||||||
patch.object(
|
patch.object(
|
||||||
HomeAssistant,
|
HomeAssistant,
|
||||||
@@ -219,7 +221,9 @@ async def test_install_unavailable_addon(
|
|||||||
|
|
||||||
with (
|
with (
|
||||||
patch.object(AddonStore, "data", new=PropertyMock(return_value=addon_config)),
|
patch.object(AddonStore, "data", new=PropertyMock(return_value=addon_config)),
|
||||||
patch.object(CpuArch, "supported", new=PropertyMock(return_value=["amd64"])),
|
patch.object(
|
||||||
|
CpuArchManager, "supported", new=PropertyMock(return_value=["amd64"])
|
||||||
|
),
|
||||||
patch.object(CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")),
|
patch.object(CoreSys, "machine", new=PropertyMock(return_value="qemux86-64")),
|
||||||
patch.object(
|
patch.object(
|
||||||
HomeAssistant,
|
HomeAssistant,
|
||||||
|
|||||||
Reference in New Issue
Block a user