detect native arch (#1114)

This commit is contained in:
Pascal Vizeli 2019-06-05 16:59:43 +02:00 committed by GitHub
parent 0a0d97b084
commit 5e8007453f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 16 deletions

View File

@ -1,14 +1,24 @@
"""Handle Arch for underlay maschine/platforms.""" """Handle Arch for underlay maschine/platforms."""
import logging import logging
from typing import List
from pathlib import Path from pathlib import Path
import platform
from typing import List
from .coresys import CoreSysAttributes, CoreSys from .coresys import CoreSys, CoreSysAttributes
from .exceptions import HassioArchNotFound, JsonFileError from .exceptions import HassioArchNotFound, JsonFileError
from .utils.json import read_json_file from .utils.json import read_json_file
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
MAP_CPU = {
"armv7": "armv7",
"armv6": "armhf",
"armv8": "aarch64",
"aarch64": "aarch64",
"i686": "i386",
"x86_64": "amd64",
}
class CpuArch(CoreSysAttributes): class CpuArch(CoreSysAttributes):
"""Manage available architectures.""" """Manage available architectures."""
@ -42,10 +52,12 @@ class CpuArch(CoreSysAttributes):
_LOGGER.warning("Can't read arch json") _LOGGER.warning("Can't read arch json")
return return
native_support = self.detect_cpu()
# Evaluate current CPU/Platform # Evaluate current CPU/Platform
if not self.sys_machine or self.sys_machine not in arch_data: if not self.sys_machine or self.sys_machine not in arch_data:
_LOGGER.warning("Can't detect underlay machine type!") _LOGGER.warning("Can't detect underlay machine type!")
self._default_arch = self.sys_supervisor.arch self._default_arch = native_support
self._supported_arch.append(self.default) self._supported_arch.append(self.default)
return return
@ -53,6 +65,10 @@ class CpuArch(CoreSysAttributes):
self._supported_arch.extend(arch_data[self.sys_machine]) self._supported_arch.extend(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
if native_support not in self._supported_arch:
self._supported_arch.append(native_support)
def is_supported(self, arch_list: List[str]) -> bool: def is_supported(self, arch_list: List[str]) -> bool:
"""Return True if there is a supported arch by this platform.""" """Return True if there is a supported arch by this platform."""
return not set(self.supported).isdisjoint(set(arch_list)) return not set(self.supported).isdisjoint(set(arch_list))
@ -63,3 +79,11 @@ class CpuArch(CoreSysAttributes):
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:
"""Return the arch type of local CPU."""
cpu = platform.machine()
for check, value in MAP_CPU.items():
if cpu.startswith(check):
return value
return self.sys_supervisor.arch

View File

@ -1,4 +1,15 @@
"""Test arch object.""" """Test arch object."""
from unittest.mock import patch
import pytest
@pytest.fixture(autouse=True)
def mock_detect_cpu():
"""Mock cpu detection."""
with patch("platform.machine") as detect_mock:
detect_mock.return_value = "Unknown"
yield detect_mock
async def test_machine_not_exits(coresys, sys_machine, sys_supervisor): async def test_machine_not_exits(coresys, sys_machine, sys_supervisor):
@ -32,118 +43,144 @@ async def test_supervisor_arch(coresys, sys_machine, sys_supervisor):
assert coresys.arch.supervisor == "amd64" assert coresys.arch.supervisor == "amd64"
async def test_raspberrypi_arch(coresys, sys_machine): async def test_raspberrypi_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for raspberrypi.""" """Test arch for raspberrypi."""
sys_machine.return_value = "raspberrypi" sys_machine.return_value = "raspberrypi"
sys_supervisor.arch = "armhf"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armhf" assert coresys.arch.default == "armhf"
assert coresys.arch.supported == ["armhf"] assert coresys.arch.supported == ["armhf"]
async def test_raspberrypi2_arch(coresys, sys_machine): async def test_raspberrypi2_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for raspberrypi2.""" """Test arch for raspberrypi2."""
sys_machine.return_value = "raspberrypi2" sys_machine.return_value = "raspberrypi2"
sys_supervisor.arch = "armv7"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armv7" assert coresys.arch.default == "armv7"
assert coresys.arch.supported == ["armv7", "armhf"] assert coresys.arch.supported == ["armv7", "armhf"]
async def test_raspberrypi3_arch(coresys, sys_machine): async def test_raspberrypi3_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for raspberrypi3.""" """Test arch for raspberrypi3."""
sys_machine.return_value = "raspberrypi3" sys_machine.return_value = "raspberrypi3"
sys_supervisor.arch = "armv7"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armv7" assert coresys.arch.default == "armv7"
assert coresys.arch.supported == ["armv7", "armhf"] assert coresys.arch.supported == ["armv7", "armhf"]
async def test_raspberrypi3_64_arch(coresys, sys_machine): async def test_raspberrypi3_64_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for raspberrypi3_64.""" """Test arch for raspberrypi3_64."""
sys_machine.return_value = "raspberrypi3-64" sys_machine.return_value = "raspberrypi3-64"
sys_supervisor.arch = "aarch64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "aarch64" assert coresys.arch.default == "aarch64"
assert coresys.arch.supported == ["aarch64", "armv7", "armhf"] assert coresys.arch.supported == ["aarch64", "armv7", "armhf"]
async def test_tinker_arch(coresys, sys_machine): async def test_tinker_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for tinker.""" """Test arch for tinker."""
sys_machine.return_value = "tinker" sys_machine.return_value = "tinker"
sys_supervisor.arch = "armv7"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armv7" assert coresys.arch.default == "armv7"
assert coresys.arch.supported == ["armv7", "armhf"] assert coresys.arch.supported == ["armv7", "armhf"]
async def test_odroid_c2_arch(coresys, sys_machine): async def test_odroid_c2_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for odroid-c2.""" """Test arch for odroid-c2."""
sys_machine.return_value = "odroid-c2" sys_machine.return_value = "odroid-c2"
sys_supervisor.arch = "aarch64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "aarch64" assert coresys.arch.default == "aarch64"
assert coresys.arch.supported == ["aarch64"] assert coresys.arch.supported == ["aarch64"]
async def test_odroid_xu_arch(coresys, sys_machine): async def test_odroid_xu_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for odroid-xu.""" """Test arch for odroid-xu."""
sys_machine.return_value = "odroid-xu" sys_machine.return_value = "odroid-xu"
sys_supervisor.arch = "armv7"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armv7" assert coresys.arch.default == "armv7"
assert coresys.arch.supported == ["armv7", "armhf"] assert coresys.arch.supported == ["armv7", "armhf"]
async def test_orangepi_prime_arch(coresys, sys_machine): async def test_orangepi_prime_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for orangepi_prime.""" """Test arch for orangepi_prime."""
sys_machine.return_value = "orangepi-prime" sys_machine.return_value = "orangepi-prime"
sys_supervisor.arch = "aarch64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "aarch64" assert coresys.arch.default == "aarch64"
assert coresys.arch.supported == ["aarch64"] assert coresys.arch.supported == ["aarch64"]
async def test_intel_nuc_arch(coresys, sys_machine): async def test_intel_nuc_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for intel-nuc.""" """Test arch for intel-nuc."""
sys_machine.return_value = "intel-nuc" sys_machine.return_value = "intel-nuc"
sys_supervisor.arch = "amd64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "amd64" assert coresys.arch.default == "amd64"
assert coresys.arch.supported == ["amd64", "i386"] assert coresys.arch.supported == ["amd64", "i386"]
async def test_qemux86_arch(coresys, sys_machine): async def test_qemux86_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for qemux86.""" """Test arch for qemux86."""
sys_machine.return_value = "qemux86" sys_machine.return_value = "qemux86"
sys_supervisor.arch = "i386"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "i386" assert coresys.arch.default == "i386"
assert coresys.arch.supported == ["i386"] assert coresys.arch.supported == ["i386"]
async def test_qemux86_64_arch(coresys, sys_machine): async def test_qemux86_64_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for qemux86-64.""" """Test arch for qemux86-64."""
sys_machine.return_value = "qemux86-64" sys_machine.return_value = "qemux86-64"
sys_supervisor.arch = "amd64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "amd64" assert coresys.arch.default == "amd64"
assert coresys.arch.supported == ["amd64", "i386"] assert coresys.arch.supported == ["amd64", "i386"]
async def test_qemuarm_arch(coresys, sys_machine): async def test_qemuarm_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for qemuarm.""" """Test arch for qemuarm."""
sys_machine.return_value = "qemuarm" sys_machine.return_value = "qemuarm"
sys_supervisor.arch = "armhf"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "armhf" assert coresys.arch.default == "armhf"
assert coresys.arch.supported == ["armhf"] assert coresys.arch.supported == ["armhf"]
async def test_qemuarm_64_arch(coresys, sys_machine): async def test_qemuarm_64_arch(coresys, sys_machine, sys_supervisor):
"""Test arch for qemuarm-64.""" """Test arch for qemuarm-64."""
sys_machine.return_value = "qemuarm-64" sys_machine.return_value = "qemuarm-64"
sys_supervisor.arch = "aarch64"
await coresys.arch.load() await coresys.arch.load()
assert coresys.arch.default == "aarch64" assert coresys.arch.default == "aarch64"
assert coresys.arch.supported == ["aarch64"] assert coresys.arch.supported == ["aarch64"]
async def test_qemuarm_arch_native_armv7(
coresys, sys_machine, mock_detect_cpu, sys_supervisor
):
"""Test arch for qemuarm."""
sys_machine.return_value = "qemuarm"
sys_supervisor.arch = "armhf"
mock_detect_cpu.return_value = "armv7l"
await coresys.arch.load()
assert coresys.arch.default == "armhf"
assert coresys.arch.supported == ["armhf", "armv7"]