mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-28 11:36:32 +00:00
Support OTA url over version files (#2324)
* Support OTA url over version files * Fix new schema
This commit is contained in:
parent
59102afd45
commit
80763c4bbf
@ -9,11 +9,6 @@ URL_HASSIO_ADDONS = "https://github.com/home-assistant/addons"
|
|||||||
URL_HASSIO_APPARMOR = "https://version.home-assistant.io/apparmor.txt"
|
URL_HASSIO_APPARMOR = "https://version.home-assistant.io/apparmor.txt"
|
||||||
URL_HASSIO_VERSION = "https://version.home-assistant.io/{channel}.json"
|
URL_HASSIO_VERSION = "https://version.home-assistant.io/{channel}.json"
|
||||||
|
|
||||||
URL_HASSOS_OTA = (
|
|
||||||
"https://github.com/home-assistant/operating-system/releases/download/"
|
|
||||||
"{version}/hassos_{board}-{version}.raucb"
|
|
||||||
)
|
|
||||||
|
|
||||||
SUPERVISOR_DATA = Path("/data")
|
SUPERVISOR_DATA = Path("/data")
|
||||||
|
|
||||||
FILE_HASSIO_ADDONS = Path(SUPERVISOR_DATA, "addons.json")
|
FILE_HASSIO_ADDONS = Path(SUPERVISOR_DATA, "addons.json")
|
||||||
@ -290,6 +285,7 @@ ATTR_MAC = "mac"
|
|||||||
ATTR_FREQUENCY = "frequency"
|
ATTR_FREQUENCY = "frequency"
|
||||||
ATTR_ACCESSPOINTS = "accesspoints"
|
ATTR_ACCESSPOINTS = "accesspoints"
|
||||||
ATTR_UNHEALTHY = "unhealthy"
|
ATTR_UNHEALTHY = "unhealthy"
|
||||||
|
ATTR_OTA = "ota"
|
||||||
|
|
||||||
PROVIDE_SERVICE = "provide"
|
PROVIDE_SERVICE = "provide"
|
||||||
NEED_SERVICE = "need"
|
NEED_SERVICE = "need"
|
||||||
|
@ -8,7 +8,6 @@ import aiohttp
|
|||||||
from cpe import CPE
|
from cpe import CPE
|
||||||
from packaging.version import parse as pkg_parse
|
from packaging.version import parse as pkg_parse
|
||||||
|
|
||||||
from .const import URL_HASSOS_OTA
|
|
||||||
from .coresys import CoreSys, CoreSysAttributes
|
from .coresys import CoreSys, CoreSysAttributes
|
||||||
from .dbus.rauc import RaucState
|
from .dbus.rauc import RaucState
|
||||||
from .exceptions import DBusError, HassOSNotSupportedError, HassOSUpdateError
|
from .exceptions import DBusError, HassOSNotSupportedError, HassOSUpdateError
|
||||||
@ -64,10 +63,14 @@ class HassOS(CoreSysAttributes):
|
|||||||
|
|
||||||
async def _download_raucb(self, version: str) -> Path:
|
async def _download_raucb(self, version: str) -> Path:
|
||||||
"""Download rauc bundle (OTA) from github."""
|
"""Download rauc bundle (OTA) from github."""
|
||||||
url = URL_HASSOS_OTA.format(version=version, board=self.board)
|
raw_url = self.sys_updater.ota_url
|
||||||
raucb = Path(self.sys_config.path_tmp, f"hassos-{version}.raucb")
|
if raw_url is None:
|
||||||
|
_LOGGER.error("Don't have an URL for OTA updates!")
|
||||||
|
raise HassOSNotSupportedError()
|
||||||
|
url = raw_url.format(version=version, board=self.board)
|
||||||
|
|
||||||
_LOGGER.info("Fetch OTA update from %s", url)
|
_LOGGER.info("Fetch OTA update from %s", url)
|
||||||
|
raucb = Path(self.sys_config.path_tmp, f"hassos-{version}.raucb")
|
||||||
try:
|
try:
|
||||||
timeout = aiohttp.ClientTimeout(total=60 * 60, connect=180)
|
timeout = aiohttp.ClientTimeout(total=60 * 60, connect=180)
|
||||||
async with self.sys_websession.get(url, timeout=timeout) as request:
|
async with self.sys_websession.get(url, timeout=timeout) as request:
|
||||||
|
@ -18,6 +18,7 @@ from .const import (
|
|||||||
ATTR_IMAGE,
|
ATTR_IMAGE,
|
||||||
ATTR_MULTICAST,
|
ATTR_MULTICAST,
|
||||||
ATTR_OBSERVER,
|
ATTR_OBSERVER,
|
||||||
|
ATTR_OTA,
|
||||||
ATTR_SUPERVISOR,
|
ATTR_SUPERVISOR,
|
||||||
FILE_HASSIO_UPDATER,
|
FILE_HASSIO_UPDATER,
|
||||||
URL_HASSIO_VERSION,
|
URL_HASSIO_VERSION,
|
||||||
@ -93,7 +94,7 @@ class Updater(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def image_homeassistant(self) -> Optional[str]:
|
def image_homeassistant(self) -> Optional[str]:
|
||||||
"""Return latest version of Home Assistant."""
|
"""Return image of Home Assistant docker."""
|
||||||
if ATTR_HOMEASSISTANT not in self._data[ATTR_IMAGE]:
|
if ATTR_HOMEASSISTANT not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_HOMEASSISTANT].format(
|
return self._data[ATTR_IMAGE][ATTR_HOMEASSISTANT].format(
|
||||||
@ -102,7 +103,7 @@ class Updater(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def image_supervisor(self) -> Optional[str]:
|
def image_supervisor(self) -> Optional[str]:
|
||||||
"""Return latest version of Supervisor."""
|
"""Return image of Supervisor docker."""
|
||||||
if ATTR_SUPERVISOR not in self._data[ATTR_IMAGE]:
|
if ATTR_SUPERVISOR not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_SUPERVISOR].format(
|
return self._data[ATTR_IMAGE][ATTR_SUPERVISOR].format(
|
||||||
@ -111,28 +112,28 @@ class Updater(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def image_cli(self) -> Optional[str]:
|
def image_cli(self) -> Optional[str]:
|
||||||
"""Return latest version of CLI."""
|
"""Return image of CLI docker."""
|
||||||
if ATTR_CLI not in self._data[ATTR_IMAGE]:
|
if ATTR_CLI not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_CLI].format(arch=self.sys_arch.supervisor)
|
return self._data[ATTR_IMAGE][ATTR_CLI].format(arch=self.sys_arch.supervisor)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_dns(self) -> Optional[str]:
|
def image_dns(self) -> Optional[str]:
|
||||||
"""Return latest version of DNS."""
|
"""Return image of DNS docker."""
|
||||||
if ATTR_DNS not in self._data[ATTR_IMAGE]:
|
if ATTR_DNS not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_DNS].format(arch=self.sys_arch.supervisor)
|
return self._data[ATTR_IMAGE][ATTR_DNS].format(arch=self.sys_arch.supervisor)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_audio(self) -> Optional[str]:
|
def image_audio(self) -> Optional[str]:
|
||||||
"""Return latest version of Audio."""
|
"""Return image of Audio docker."""
|
||||||
if ATTR_AUDIO not in self._data[ATTR_IMAGE]:
|
if ATTR_AUDIO not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_AUDIO].format(arch=self.sys_arch.supervisor)
|
return self._data[ATTR_IMAGE][ATTR_AUDIO].format(arch=self.sys_arch.supervisor)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_observer(self) -> Optional[str]:
|
def image_observer(self) -> Optional[str]:
|
||||||
"""Return latest version of Observer."""
|
"""Return image of Observer docker."""
|
||||||
if ATTR_OBSERVER not in self._data[ATTR_IMAGE]:
|
if ATTR_OBSERVER not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_OBSERVER].format(
|
return self._data[ATTR_IMAGE][ATTR_OBSERVER].format(
|
||||||
@ -141,13 +142,18 @@ class Updater(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def image_multicast(self) -> Optional[str]:
|
def image_multicast(self) -> Optional[str]:
|
||||||
"""Return latest version of Multicast."""
|
"""Return image of Multicast docker."""
|
||||||
if ATTR_MULTICAST not in self._data[ATTR_IMAGE]:
|
if ATTR_MULTICAST not in self._data[ATTR_IMAGE]:
|
||||||
return None
|
return None
|
||||||
return self._data[ATTR_IMAGE][ATTR_MULTICAST].format(
|
return self._data[ATTR_IMAGE][ATTR_MULTICAST].format(
|
||||||
arch=self.sys_arch.supervisor
|
arch=self.sys_arch.supervisor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ota_url(self) -> Optional[str]:
|
||||||
|
"""Return OTA url for OS."""
|
||||||
|
return self._data.get(ATTR_OTA)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def channel(self) -> UpdateChannel:
|
def channel(self) -> UpdateChannel:
|
||||||
"""Return upstream channel of Supervisor instance."""
|
"""Return upstream channel of Supervisor instance."""
|
||||||
@ -196,6 +202,7 @@ class Updater(JsonConfig, CoreSysAttributes):
|
|||||||
# Update HassOS version
|
# Update HassOS version
|
||||||
if self.sys_hassos.board:
|
if self.sys_hassos.board:
|
||||||
self._data[ATTR_HASSOS] = data["hassos"][self.sys_hassos.board]
|
self._data[ATTR_HASSOS] = data["hassos"][self.sys_hassos.board]
|
||||||
|
self._data[ATTR_OTA] = data["ota"]
|
||||||
|
|
||||||
# Update Home Assistant plugins
|
# Update Home Assistant plugins
|
||||||
self._data[ATTR_CLI] = data["cli"]
|
self._data[ATTR_CLI] = data["cli"]
|
||||||
|
@ -27,6 +27,7 @@ from .const import (
|
|||||||
ATTR_LOGGING,
|
ATTR_LOGGING,
|
||||||
ATTR_MULTICAST,
|
ATTR_MULTICAST,
|
||||||
ATTR_OBSERVER,
|
ATTR_OBSERVER,
|
||||||
|
ATTR_OTA,
|
||||||
ATTR_PASSWORD,
|
ATTR_PASSWORD,
|
||||||
ATTR_PORT,
|
ATTR_PORT,
|
||||||
ATTR_PORTS,
|
ATTR_PORTS,
|
||||||
@ -135,6 +136,7 @@ SCHEMA_HASS_CONFIG = vol.Schema(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=no-value-for-parameter
|
||||||
SCHEMA_UPDATER_CONFIG = vol.Schema(
|
SCHEMA_UPDATER_CONFIG = vol.Schema(
|
||||||
{
|
{
|
||||||
vol.Optional(ATTR_CHANNEL, default=UpdateChannel.STABLE): vol.Coerce(
|
vol.Optional(ATTR_CHANNEL, default=UpdateChannel.STABLE): vol.Coerce(
|
||||||
@ -160,6 +162,7 @@ SCHEMA_UPDATER_CONFIG = vol.Schema(
|
|||||||
},
|
},
|
||||||
extra=vol.REMOVE_EXTRA,
|
extra=vol.REMOVE_EXTRA,
|
||||||
),
|
),
|
||||||
|
vol.Optional(ATTR_OTA): vol.Url(),
|
||||||
},
|
},
|
||||||
extra=vol.REMOVE_EXTRA,
|
extra=vol.REMOVE_EXTRA,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user