diff --git a/API.md b/API.md index 8c7a4d40a..4bd2d0f5a 100644 --- a/API.md +++ b/API.md @@ -8,8 +8,8 @@ On error / Code 400: ```json { - "result": "error", - "message": "" + "result": "error", + "message": "" } ``` @@ -17,8 +17,8 @@ On success / Code 200: ```json { - "result": "ok", - "data": { } + "result": "ok", + "data": {} } ``` @@ -36,32 +36,30 @@ The addons from `addons` are only installed one. ```json { - "version": "INSTALL_VERSION", - "last_version": "LAST_VERSION", - "arch": "armhf|aarch64|i386|amd64", - "channel": "stable|beta|dev", - "timezone": "TIMEZONE", - "logging": "debug|info|warning|error|critical", - "ip_address": "ip address", - "wait_boot": "int", - "debug": "bool", - "debug_block": "bool", - "addons": [ - { - "name": "xy bla", - "slug": "xy", - "description": "description", - "repository": "12345678|null", - "version": "LAST_VERSION", - "installed": "INSTALL_VERSION", - "icon": "bool", - "logo": "bool", - "state": "started|stopped", - } - ], - "addons_repositories": [ - "REPO_URL" - ] + "version": "INSTALL_VERSION", + "last_version": "LAST_VERSION", + "arch": "armhf|aarch64|i386|amd64", + "channel": "stable|beta|dev", + "timezone": "TIMEZONE", + "logging": "debug|info|warning|error|critical", + "ip_address": "ip address", + "wait_boot": "int", + "debug": "bool", + "debug_block": "bool", + "addons": [ + { + "name": "xy bla", + "slug": "xy", + "description": "description", + "repository": "12345678|null", + "version": "LAST_VERSION", + "installed": "INSTALL_VERSION", + "icon": "bool", + "logo": "bool", + "state": "started|stopped" + } + ], + "addons_repositories": ["REPO_URL"] } ``` @@ -71,7 +69,7 @@ Optional: ```json { - "version": "VERSION" + "version": "VERSION" } ``` @@ -79,15 +77,13 @@ Optional: ```json { - "channel": "stable|beta|dev", - "timezone": "TIMEZONE", - "wait_boot": "int", - "debug": "bool", - "debug_block": "bool", - "logging": "debug|info|warning|error|critical", - "addons_repositories": [ - "REPO_URL" - ] + "channel": "stable|beta|dev", + "timezone": "TIMEZONE", + "wait_boot": "int", + "debug": "bool", + "debug_block": "bool", + "logging": "debug|info|warning|error|critical", + "addons_repositories": ["REPO_URL"] } ``` @@ -100,16 +96,17 @@ Reload addons/version. Output is the raw docker log. - GET `/supervisor/stats` + ```json { - "cpu_percent": 0.0, - "memory_usage": 283123, - "memory_limit": 329392, - "memory_percent": 1.4, - "network_tx": 0, - "network_rx": 0, - "blk_read": 0, - "blk_write": 0 + "cpu_percent": 0.0, + "memory_usage": 283123, + "memory_limit": 329392, + "memory_percent": 1.4, + "network_tx": 0, + "network_rx": 0, + "blk_read": 0, + "blk_write": 0 } ``` @@ -123,15 +120,15 @@ Repair overlayfs issue and restore lost images ```json { - "snapshots": [ - { - "slug": "SLUG", - "date": "ISO", - "name": "Custom name", - "type": "full|partial", - "protected": "bool" - } - ] + "snapshots": [ + { + "slug": "SLUG", + "date": "ISO", + "name": "Custom name", + "type": "full|partial", + "protected": "bool" + } + ] } ``` @@ -140,9 +137,10 @@ Repair overlayfs issue and restore lost images - POST `/snapshots/new/upload` return: + ```json { - "slug": "" + "slug": "" } ``` @@ -150,15 +148,16 @@ return: ```json { - "name": "Optional", - "password": "Optional" + "name": "Optional", + "password": "Optional" } ``` return: + ```json { - "slug": "" + "slug": "" } ``` @@ -166,17 +165,18 @@ return: ```json { - "name": "Optional", - "addons": ["ADDON_SLUG"], - "folders": ["FOLDER_NAME"], - "password": "Optional" + "name": "Optional", + "addons": ["ADDON_SLUG"], + "folders": ["FOLDER_NAME"], + "password": "Optional" } ``` return: + ```json { - "slug": "" + "slug": "" } ``` @@ -186,23 +186,23 @@ return: ```json { - "slug": "SNAPSHOT ID", - "type": "full|partial", - "name": "custom snapshot name / description", - "date": "ISO", - "size": "SIZE_IN_MB", - "protected": "bool", - "homeassistant": "version", - "addons": [ - { - "slug": "ADDON_SLUG", - "name": "NAME", - "version": "INSTALLED_VERSION", - "size": "SIZE_IN_MB" - } - ], - "repositories": ["URL"], - "folders": ["NAME"] + "slug": "SNAPSHOT ID", + "type": "full|partial", + "name": "custom snapshot name / description", + "date": "ISO", + "size": "SIZE_IN_MB", + "protected": "bool", + "homeassistant": "version", + "addons": [ + { + "slug": "ADDON_SLUG", + "name": "NAME", + "version": "INSTALLED_VERSION", + "size": "SIZE_IN_MB" + } + ], + "repositories": ["URL"], + "folders": ["NAME"] } ``` @@ -214,7 +214,7 @@ return: ```json { - "password": "Optional" + "password": "Optional" } ``` @@ -222,10 +222,10 @@ return: ```json { - "homeassistant": "bool", - "addons": ["ADDON_SLUG"], - "folders": ["FOLDER_NAME"], - "password": "Optional" + "homeassistant": "bool", + "addons": ["ADDON_SLUG"], + "folders": ["FOLDER_NAME"], + "password": "Optional" } ``` @@ -241,13 +241,13 @@ return: ```json { - "hostname": "hostname|null", - "features": ["shutdown", "reboot", "hostname", "services", "hassos"], - "operating_system": "HassOS XY|Ubuntu 16.4|null", - "kernel": "4.15.7|null", - "chassis": "specific|null", - "deployment": "stable|beta|dev|null", - "cpe": "xy|null", + "hostname": "hostname|null", + "features": ["shutdown", "reboot", "hostname", "services", "hassos"], + "operating_system": "HassOS XY|Ubuntu 16.4|null", + "kernel": "4.15.7|null", + "chassis": "specific|null", + "deployment": "stable|beta|dev|null", + "cpe": "xy|null" } ``` @@ -255,7 +255,7 @@ return: ```json { - "hostname": "", + "hostname": "" } ``` @@ -264,15 +264,16 @@ return: #### Services - GET `/host/services` + ```json { - "services": [ - { - "name": "xy.service", - "description": "XY ...", - "state": "active|" - } - ] + "services": [ + { + "name": "xy.service", + "description": "XY ...", + "state": "active|" + } + ] } ``` @@ -285,27 +286,31 @@ return: ### HassOS - GET `/hassos/info` + ```json { - "version": "2.3", - "version_cli": "7", - "version_latest": "2.4", - "version_cli_latest": "8", - "board": "ova|rpi" + "version": "2.3", + "version_cli": "7", + "version_latest": "2.4", + "version_cli_latest": "8", + "board": "ova|rpi", + "boot": "rauc boot slot" } ``` - POST `/hassos/update` + ```json { - "version": "optional" + "version": "optional" } ``` - POST `/hassos/update/cli` + ```json { - "version": "optional" + "version": "optional" } ``` @@ -316,6 +321,7 @@ Load host configs from a USB stick. ### Hardware - GET `/hardware/info` + ```json { "serial": ["/dev/xy"], @@ -336,17 +342,18 @@ Load host configs from a USB stick. ``` - GET `/hardware/audio` + ```json { - "audio": { - "input": { - "0,0": "Mic" - }, - "output": { - "1,0": "Jack", - "1,1": "HDMI" - } + "audio": { + "input": { + "0,0": "Mic" + }, + "output": { + "1,0": "Jack", + "1,1": "HDMI" } + } } ``` @@ -360,18 +367,18 @@ Trigger an udev reload ```json { - "version": "INSTALL_VERSION", - "last_version": "LAST_VERSION", - "arch": "arch", - "machine": "Image machine type", - "ip_address": "ip address", - "image": "str", - "custom": "bool -> if custom image", - "boot": "bool", - "port": 8123, - "ssl": "bool", - "watchdog": "bool", - "wait_boot": 600 + "version": "INSTALL_VERSION", + "last_version": "LAST_VERSION", + "arch": "arch", + "machine": "Image machine type", + "ip_address": "ip address", + "image": "str", + "custom": "bool -> if custom image", + "boot": "bool", + "port": 8123, + "ssl": "bool", + "watchdog": "bool", + "wait_boot": 600 } ``` @@ -381,7 +388,7 @@ Optional: ```json { - "version": "VERSION" + "version": "VERSION" } ``` @@ -399,14 +406,14 @@ Output is the raw Docker log. ```json { - "image": "Optional|null", - "last_version": "Optional for custom image|null", - "port": "port for access hass", - "ssl": "bool", - "password": "", - "refresh_token": "", - "watchdog": "bool", - "wait_boot": 600 + "image": "Optional|null", + "last_version": "Optional for custom image|null", + "port": "port for access hass", + "ssl": "bool", + "password": "", + "refresh_token": "", + "watchdog": "bool", + "wait_boot": 600 } ``` @@ -421,16 +428,17 @@ Proxy to real home-assistant instance. Proxy to real websocket instance. - GET `/homeassistant/stats` + ```json { - "cpu_percent": 0.0, - "memory_usage": 283123, - "memory_limit": 329392, - "memory_percent": 1.4, - "network_tx": 0, - "network_rx": 0, - "blk_read": 0, - "blk_write": 0 + "cpu_percent": 0.0, + "memory_usage": 283123, + "memory_limit": 329392, + "memory_percent": 1.4, + "network_tx": 0, + "network_rx": 0, + "blk_read": 0, + "blk_write": 0 } ``` @@ -444,31 +452,31 @@ Get all available addons. ```json { - "addons": [ - { - "name": "xy bla", - "slug": "xy", - "description": "description", - "repository": "core|local|REP_ID", - "version": "LAST_VERSION", - "installed": "none|INSTALL_VERSION", - "detached": "bool", - "available": "bool", - "build": "bool", - "url": "null|url", - "icon": "bool", - "logo": "bool" - } - ], - "repositories": [ - { - "slug": "12345678", - "name": "Repitory Name|unknown", - "source": "URL_OF_REPOSITORY", - "url": "WEBSITE|REPOSITORY", - "maintainer": "BLA BLU |unknown" - } - ] + "addons": [ + { + "name": "xy bla", + "slug": "xy", + "description": "description", + "repository": "core|local|REP_ID", + "version": "LAST_VERSION", + "installed": "none|INSTALL_VERSION", + "detached": "bool", + "available": "bool", + "build": "bool", + "url": "null|url", + "icon": "bool", + "logo": "bool" + } + ], + "repositories": [ + { + "slug": "12345678", + "name": "Repitory Name|unknown", + "source": "URL_OF_REPOSITORY", + "url": "WEBSITE|REPOSITORY", + "maintainer": "BLA BLU |unknown" + } + ] } ``` @@ -477,64 +485,64 @@ Get all available addons. ```json { - "name": "xy bla", - "slug": "xdssd_xybla", - "hostname": "xdssd-xybla", - "dns": [], - "description": "description", - "long_description": "null|markdown", - "auto_update": "bool", - "url": "null|url of addon", - "detached": "bool", - "available": "bool", - "arch": ["armhf", "aarch64", "i386", "amd64"], - "machine": "[raspberrypi2, tinker]", - "homeassistant": "null|min Home Assistant version", - "repository": "12345678|null", - "version": "null|VERSION_INSTALLED", - "last_version": "LAST_VERSION", - "state": "none|started|stopped", - "boot": "auto|manual", - "build": "bool", - "options": "{}", - "network": "{}|null", - "network_description": "{}|null", - "host_network": "bool", - "host_pid": "bool", - "host_ipc": "bool", - "host_dbus": "bool", - "privileged": ["NET_ADMIN", "SYS_ADMIN"], - "apparmor": "disable|default|profile", - "devices": ["/dev/xy"], - "udev": "bool", - "auto_uart": "bool", - "icon": "bool", - "logo": "bool", - "changelog": "bool", - "hassio_api": "bool", - "hassio_role": "default|homeassistant|manager|admin", - "homeassistant_api": "bool", - "auth_api": "bool", - "full_access": "bool", - "protected": "bool", - "rating": "1-6", - "stdin": "bool", - "webui": "null|http(s)://[HOST]:port/xy/zx", - "gpio": "bool", - "kernel_modules": "bool", - "devicetree": "bool", - "docker_api": "bool", - "audio": "bool", - "audio_input": "null|0,0", - "audio_output": "null|0,0", - "services_role": "['service:access']", - "discovery": "['service']", - "ip_address": "ip address", - "ingress": "bool", - "ingress_entry": "null|/api/hassio_ingress/slug", - "ingress_url": "null|/api/hassio_ingress/slug/entry.html", - "ingress_port": "null|int", - "ingress_panel": "null|bool" + "name": "xy bla", + "slug": "xdssd_xybla", + "hostname": "xdssd-xybla", + "dns": [], + "description": "description", + "long_description": "null|markdown", + "auto_update": "bool", + "url": "null|url of addon", + "detached": "bool", + "available": "bool", + "arch": ["armhf", "aarch64", "i386", "amd64"], + "machine": "[raspberrypi2, tinker]", + "homeassistant": "null|min Home Assistant version", + "repository": "12345678|null", + "version": "null|VERSION_INSTALLED", + "last_version": "LAST_VERSION", + "state": "none|started|stopped", + "boot": "auto|manual", + "build": "bool", + "options": "{}", + "network": "{}|null", + "network_description": "{}|null", + "host_network": "bool", + "host_pid": "bool", + "host_ipc": "bool", + "host_dbus": "bool", + "privileged": ["NET_ADMIN", "SYS_ADMIN"], + "apparmor": "disable|default|profile", + "devices": ["/dev/xy"], + "udev": "bool", + "auto_uart": "bool", + "icon": "bool", + "logo": "bool", + "changelog": "bool", + "hassio_api": "bool", + "hassio_role": "default|homeassistant|manager|admin", + "homeassistant_api": "bool", + "auth_api": "bool", + "full_access": "bool", + "protected": "bool", + "rating": "1-6", + "stdin": "bool", + "webui": "null|http(s)://[HOST]:port/xy/zx", + "gpio": "bool", + "kernel_modules": "bool", + "devicetree": "bool", + "docker_api": "bool", + "audio": "bool", + "audio_input": "null|0,0", + "audio_output": "null|0,0", + "services_role": "['service:access']", + "discovery": "['service']", + "ip_address": "ip address", + "ingress": "bool", + "ingress_entry": "null|/api/hassio_ingress/slug", + "ingress_url": "null|/api/hassio_ingress/slug/entry.html", + "ingress_port": "null|int", + "ingress_panel": "null|bool" } ``` @@ -548,15 +556,15 @@ Get all available addons. ```json { - "boot": "auto|manual", - "auto_update": "bool", - "network": { - "CONTAINER": "port|[ip, port]" - }, - "options": {}, - "audio_output": "null|0,0", - "audio_input": "null|0,0", - "ingress_panel": "bool" + "boot": "auto|manual", + "auto_update": "bool", + "network": { + "CONTAINER": "port|[ip, port]" + }, + "options": {}, + "audio_output": "null|0,0", + "audio_input": "null|0,0", + "ingress_panel": "bool" } ``` @@ -568,7 +576,7 @@ This function is not callable by itself. ```json { - "protected": "bool", + "protected": "bool" } ``` @@ -597,16 +605,17 @@ Only supported for local build addons Write data to add-on stdin - GET `/addons/{addon}/stats` + ```json { - "cpu_percent": 0.0, - "memory_usage": 283123, - "memory_limit": 329392, - "memory_percent": 1.4, - "network_tx": 0, - "network_rx": 0, - "blk_read": 0, - "blk_write": 0 + "cpu_percent": 0.0, + "memory_usage": 283123, + "memory_limit": 329392, + "memory_percent": 1.4, + "network_tx": 0, + "network_rx": 0, + "blk_read": 0, + "blk_write": 0 } ``` @@ -618,7 +627,7 @@ Create a new Session for access to ingress service. ```json { - "session": "token" + "session": "token" } ``` @@ -628,14 +637,14 @@ Return a list of enabled panels. ```json { - "panels": { - "addon_slug": { - "enable": "boolean", - "icon": "mdi:...", - "title": "title", - "admin": "boolean" - } + "panels": { + "addon_slug": { + "enable": "boolean", + "icon": "mdi:...", + "title": "title", + "admin": "boolean" } + } } ``` @@ -647,41 +656,45 @@ Need ingress session as cookie. ### discovery - GET `/discovery` + ```json { - "discovery": [ - { - "addon": "slug", - "service": "name", - "uuid": "uuid", - "config": {} - } - ] + "discovery": [ + { + "addon": "slug", + "service": "name", + "uuid": "uuid", + "config": {} + } + ] } ``` - GET `/discovery/{UUID}` + ```json { - "addon": "slug", - "service": "name", - "uuid": "uuid", - "config": {} + "addon": "slug", + "service": "name", + "uuid": "uuid", + "config": {} } ``` - POST `/discovery` + ```json { - "service": "name", - "config": {} + "service": "name", + "config": {} } ``` return: + ```json { - "uuid": "uuid" + "uuid": "uuid" } ``` @@ -690,42 +703,45 @@ return: ### Services - GET `/services` + ```json { - "services": [ - { - "slug": "name", - "available": "bool", - "providers": "list" - } - ] + "services": [ + { + "slug": "name", + "available": "bool", + "providers": "list" + } + ] } ``` #### MQTT - GET `/services/mqtt` + ```json { - "addon": "name", - "host": "xy", - "port": "8883", - "ssl": "bool", - "username": "optional", - "password": "optional", - "protocol": "3.1.1" + "addon": "name", + "host": "xy", + "port": "8883", + "ssl": "bool", + "username": "optional", + "password": "optional", + "protocol": "3.1.1" } ``` - POST `/services/mqtt` + ```json { - "host": "xy", - "port": "8883", - "ssl": "bool|optional", - "username": "optional", - "password": "optional", - "protocol": "3.1.1" + "host": "xy", + "port": "8883", + "ssl": "bool|optional", + "username": "optional", + "password": "optional", + "protocol": "3.1.1" } ``` @@ -734,45 +750,49 @@ return: ### Misc - GET `/info` + ```json { - "supervisor": "version", - "homeassistant": "version", - "hassos": "null|version", - "hostname": "name", - "machine": "type", - "arch": "arch", - "supported_arch": ["arch1", "arch2"], - "channel": "stable|beta|dev", - "logging": "debug|info|warning|error|critical", - "timezone": "Europe/Zurich" + "supervisor": "version", + "homeassistant": "version", + "hassos": "null|version", + "hostname": "name", + "machine": "type", + "arch": "arch", + "supported_arch": ["arch1", "arch2"], + "channel": "stable|beta|dev", + "logging": "debug|info|warning|error|critical", + "timezone": "Europe/Zurich" } ``` ### DNS - GET `/dns/info` + ```json { - "host": "ip-address", - "version": "1", - "latest_version": "2", - "servers": ["dns://8.8.8.8"], - "locals": ["dns://xy"] + "host": "ip-address", + "version": "1", + "latest_version": "2", + "servers": ["dns://8.8.8.8"], + "locals": ["dns://xy"] } ``` - POST `/dns/options` + ```json { - "servers": ["dns://8.8.8.8"] + "servers": ["dns://8.8.8.8"] } ``` - POST `/dns/update` + ```json { - "version": "VERSION" + "version": "VERSION" } ``` @@ -781,16 +801,17 @@ return: - GET `/dns/logs` - GET `/dns/stats` + ```json { - "cpu_percent": 0.0, - "memory_usage": 283123, - "memory_limit": 329392, - "memory_percent": 1.4, - "network_tx": 0, - "network_rx": 0, - "blk_read": 0, - "blk_write": 0 + "cpu_percent": 0.0, + "memory_usage": 283123, + "memory_limit": 329392, + "memory_percent": 1.4, + "network_tx": 0, + "network_rx": 0, + "blk_read": 0, + "blk_write": 0 } ``` @@ -802,6 +823,7 @@ supervisor. You can call post `/auth` We support: + - Json `{ "user|name": "...", "password": "..." }` - application/x-www-form-urlencoded `user|name=...&password=...` - BasicAuth diff --git a/hassio/api/hassos.py b/hassio/api/hassos.py index 78e853707..ef5153cb6 100644 --- a/hassio/api/hassos.py +++ b/hassio/api/hassos.py @@ -3,11 +3,12 @@ import asyncio import logging from typing import Any, Awaitable, Dict -import voluptuous as vol from aiohttp import web +import voluptuous as vol from ..const import ( ATTR_BOARD, + ATTR_BOOT, ATTR_VERSION, ATTR_VERSION_CLI, ATTR_VERSION_CLI_LATEST, @@ -33,6 +34,7 @@ class APIHassOS(CoreSysAttributes): ATTR_VERSION_LATEST: self.sys_hassos.version_latest, ATTR_VERSION_CLI_LATEST: self.sys_hassos.version_cli_latest, ATTR_BOARD: self.sys_hassos.board, + ATTR_BOOT: self.sys_dbus.rauc.boot_slot, } @api_process diff --git a/hassio/core.py b/hassio/core.py index 572d21d4e..8f2d7cd7e 100644 --- a/hassio/core.py +++ b/hassio/core.py @@ -79,7 +79,11 @@ class HassIO(CoreSysAttributes): """Start Hass.io orchestration.""" await self.sys_api.start() - # on release channel, try update itself + # Mark booted partition as healthy + if self.sys_hassos.available: + await self.sys_hassos.mark_healthy() + + # On release channel, try update itself if self.sys_supervisor.need_update: try: if self.sys_dev: @@ -92,7 +96,7 @@ class HassIO(CoreSysAttributes): "future version of Home Assistant!" ) - # start addon mark as initialize + # Start addon mark as initialize await self.sys_addons.boot(STARTUP_INITIALIZE) try: diff --git a/hassio/dbus/rauc.py b/hassio/dbus/rauc.py index cb713addd..901d2c199 100644 --- a/hassio/dbus/rauc.py +++ b/hassio/dbus/rauc.py @@ -1,6 +1,7 @@ """D-Bus interface for rauc.""" import logging from typing import Optional +from enum import Enum from .interface import DBusInterface from .utils import dbus_connected @@ -13,6 +14,14 @@ DBUS_NAME = "de.pengutronix.rauc" DBUS_OBJECT = "/" +class RaucState(str, Enum): + """Rauc slot states.""" + + GOOD = "good" + BAD = "bad" + ACTIVE = "active" + + class Rauc(DBusInterface): """Handle D-Bus interface for rauc.""" @@ -82,6 +91,14 @@ class Rauc(DBusInterface): """ return self.dbus.wait_signal(f"{DBUS_NAME}.Installer.Completed") + @dbus_connected + def mark(self, state: RaucState, slot_identifier: str): + """Get slot status. + + Return a coroutine. + """ + return self.dbus.Installer.Mark(state, slot_identifier) + @dbus_connected async def update(self): """Update Properties.""" diff --git a/hassio/docker/interface.py b/hassio/docker/interface.py index fe3cd4332..dddaf5524 100644 --- a/hassio/docker/interface.py +++ b/hassio/docker/interface.py @@ -427,9 +427,10 @@ class DockerInterface(CoreSysAttributes): continue available_version.append(version) - assert available_version + if not available_version: + raise ValueError() - except (docker.errors.DockerException, AssertionError): + except (docker.errors.DockerException, ValueError): _LOGGER.debug("No version found for %s", self.image) raise DockerAPIError() else: diff --git a/hassio/hassos.py b/hassio/hassos.py index d0add98b1..d05a902e0 100644 --- a/hassio/hassos.py +++ b/hassio/hassos.py @@ -17,6 +17,7 @@ from .exceptions import ( HassOSUpdateError, DockerAPIError, ) +from .dbus.rauc import RaucState _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -111,20 +112,19 @@ class HassOS(CoreSysAttributes): async def load(self) -> None: """Load HassOS data.""" try: - # Check needed host functions - assert self.sys_dbus.rauc.is_connected - assert self.sys_dbus.systemd.is_connected - assert self.sys_dbus.hostname.is_connected - - assert self.sys_host.info.cpe is not None + if self.sys_host.info.cpe is None: + raise TypeError() cpe = CPE(self.sys_host.info.cpe) - assert cpe.get_product()[0] == "hassos" - except (AssertionError, NotImplementedError): + + if cpe.get_product()[0] != "hassos": + raise TypeError() + except TypeError: _LOGGER.debug("Found no HassOS") return + else: + self._available = True # Store meta data - self._available = True self._version = cpe.get_version()[0] self._board = cpe.get_target_hardware()[0] @@ -210,3 +210,12 @@ class HassOS(CoreSysAttributes): await self.instance.install(self.version_cli, latest=True) except DockerAPIError: _LOGGER.error("Repairing of HassOS CLI fails") + + async def mark_healthy(self): + """Set booted partition as good for rauc.""" + try: + response = await self.sys_dbus.rauc.mark(RaucState.GOOD, "booted") + except DBusError: + _LOGGER.error("Can't mark booted partition as healty!") + else: + _LOGGER.info("Rauc: %s - %s", self.sys_dbus.rauc.boot_slot, response[1]) diff --git a/hassio/utils/tar.py b/hassio/utils/tar.py index 0ffd97cf9..2648c0fea 100644 --- a/hassio/utils/tar.py +++ b/hassio/utils/tar.py @@ -124,9 +124,10 @@ def secure_path(tar: tarfile.TarFile) -> Generator[tarfile.TarInfo, None, None]: for member in tar: file_path = Path(member.name) try: - assert not file_path.is_absolute() + if file_path.is_absolute(): + raise ValueError() Path("/fake", file_path).resolve().relative_to("/fake") - except (ValueError, RuntimeError, AssertionError): + except (ValueError, RuntimeError): _LOGGER.warning("Issue with file %s", file_path) continue else: