diff --git a/supervisor/addons/validate.py b/supervisor/addons/validate.py index 02bdc2761..096275cf7 100644 --- a/supervisor/addons/validate.py +++ b/supervisor/addons/validate.py @@ -122,6 +122,7 @@ SCHEMA_ELEMENT = vol.Match(RE_SCHEMA_ELEMENT) RE_MACHINE = re.compile( r"^!?(?:" r"|intel-nuc" + r"|generic-x86-64" r"|odroid-c2" r"|odroid-c4" r"|odroid-n2" diff --git a/supervisor/data/arch.json b/supervisor/data/arch.json index 4894dd526..0c5be8d31 100644 --- a/supervisor/data/arch.json +++ b/supervisor/data/arch.json @@ -14,5 +14,6 @@ "qemux86-64": ["amd64", "i386"], "qemuarm": ["armhf"], "qemuarm-64": ["aarch64"], - "intel-nuc": ["amd64", "i386"] + "intel-nuc": ["amd64", "i386"], + "generic-x86-64": ["amd64", "i386"] } diff --git a/supervisor/hassos.py b/supervisor/hassos.py index 0831296b1..756f052f6 100644 --- a/supervisor/hassos.py +++ b/supervisor/hassos.py @@ -55,15 +55,23 @@ class HassOS(CoreSysAttributes): """Return board name.""" return self._board - async def _download_raucb(self, version: AwesomeVersion) -> Path: - """Download rauc bundle (OTA) from github.""" + def _get_download_url(self, version: AwesomeVersion) -> str: raw_url = self.sys_updater.ota_url if raw_url is None: raise HassOSUpdateError("Don't have an URL for OTA updates!", _LOGGER.error) - url = raw_url.format(version=str(version), board=self.board) + update_board = self.board + + # OS version 6 and later renamed intel-nuc to generic-x86-64... + if update_board == "intel-nuc" and version >= 6.0: + update_board = "generic-x86-64" + + url = raw_url.format(version=str(version), board=update_board) + return url + + async def _download_raucb(self, url: str, raucb: Path) -> None: + """Download rauc bundle (OTA) from URL.""" _LOGGER.info("Fetch OTA update from %s", url) - raucb = Path(self.sys_config.path_tmp, f"hassos-{version!s}.raucb") try: timeout = aiohttp.ClientTimeout(total=60 * 60, connect=180) async with self.sys_websession.get(url, timeout=timeout) as request: @@ -82,7 +90,6 @@ class HassOS(CoreSysAttributes): ota_file.write(chunk) _LOGGER.info("Completed download of OTA update file %s", raucb) - return raucb except (aiohttp.ClientError, asyncio.TimeoutError) as err: self.sys_supervisor.connectivity = False @@ -154,7 +161,9 @@ class HassOS(CoreSysAttributes): ) # Fetch files from internet - int_ota = await self._download_raucb(version) + ota_url = self._get_download_url(version) + int_ota = Path(self.sys_config.path_tmp, f"hassos-{version!s}.raucb") + await self._download_raucb(ota_url, int_ota) ext_ota = Path(self.sys_config.path_extern_tmp, int_ota.name) try: diff --git a/tests/conftest.py b/tests/conftest.py index f0ca3c17a..b157d4190 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,6 @@ """Common test functions.""" +from functools import partial +from inspect import unwrap from pathlib import Path import re from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch @@ -161,6 +163,11 @@ async def coresys(loop, docker, network_manager, aiohttp_client) -> CoreSys: ha_version=AwesomeVersion("2021.2.4") ) + # Remove rate limiting decorator from fetch_data + coresys_obj.updater.fetch_data = partial( + unwrap(coresys_obj.updater.fetch_data), coresys_obj.updater + ) + yield coresys_obj await coresys_obj.websession.close() diff --git a/tests/test_hassos.py b/tests/test_hassos.py new file mode 100644 index 000000000..648aef641 --- /dev/null +++ b/tests/test_hassos.py @@ -0,0 +1,22 @@ +"""Test Home Assistant OS functionality.""" + +from awesomeversion import AwesomeVersion +import pytest + +from supervisor.coresys import CoreSys + +# pylint: disable=protected-access + + +@pytest.mark.asyncio +async def test_ota_url_generic_x86_64_rename(coresys: CoreSys) -> None: + """Test download URL generated.""" + + coresys.hassos._board = "intel-nuc" + coresys.hassos._version = AwesomeVersion("5.13") + await coresys.updater.fetch_data() + + version6 = AwesomeVersion("6.0") + url = coresys.updater.ota_url.format(version=str(version6), board="generic-x86-64") + + assert coresys.hassos._get_download_url(version6) == url