diff --git a/API.md b/API.md index 030599729..87226f6c4 100644 --- a/API.md +++ b/API.md @@ -44,6 +44,8 @@ The addons from `addons` are only installed one. "logging": "debug|info|warning|error|critical", "ip_address": "ip address", "wait_boot": "int", + "debug": "bool", + "debug_block": "bool", "addons": [ { "name": "xy bla", @@ -80,6 +82,8 @@ Optional: "channel": "stable|beta|dev", "timezone": "TIMEZONE", "wait_boot": "int", + "debug": "bool", + "debug_block": "bool", "logging": "debug|info|warning|error|critical", "addons_repositories": [ "REPO_URL" diff --git a/Dockerfile b/Dockerfile index 20239d44b..3f9cbebb5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ ARG BUILD_FROM FROM $BUILD_FROM +ARG BUILD_ARCH + # Install base RUN apk add --no-cache \ openssl \ @@ -15,13 +17,10 @@ RUN apk add --no-cache \ # Install requirements COPY requirements.txt /usr/src/ RUN apk add --no-cache --virtual .build-dependencies \ - make \ - g++ \ - openssl-dev \ - libffi-dev \ - musl-dev \ + build-base \ && export MAKEFLAGS="-j$(nproc)" \ - && pip3 install --no-cache-dir -r /usr/src/requirements.txt \ + && pip3 install --no-cache-dir --find-links https://wheels.hass.io/alpine-3.9/${BUILD_ARCH}/ \ + -r /usr/src/requirements.txt \ && apk del .build-dependencies \ && rm -f /usr/src/requirements.txt diff --git a/README.md b/README.md index 963f91c04..c2428cc77 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://dev.azure.com/home-assistant/Home%20Assistant/_apis/build/status/home-assistant.hassio?branchName=dev)](https://dev.azure.com/home-assistant/Home%20Assistant/_build/latest?definitionId=2&branchName=dev) +[![Build Status](https://dev.azure.com/home-assistant/Hass.io/_apis/build/status/hassio?branchName=dev)](https://dev.azure.com/home-assistant/Hass.io/_build/latest?definitionId=2&branchName=dev) # Hass.io diff --git a/hassio/__main__.py b/hassio/__main__.py index 31596d318..1962a6d86 100644 --- a/hassio/__main__.py +++ b/hassio/__main__.py @@ -40,6 +40,7 @@ if __name__ == "__main__": coresys = loop.run_until_complete(bootstrap.initialize_coresys()) bootstrap.migrate_system_env(coresys) + bootstrap.supervisor_debugger(coresys) _LOGGER.info("Setup HassIO") loop.run_until_complete(coresys.core.setup()) diff --git a/hassio/api/supervisor.py b/hassio/api/supervisor.py index f153780e8..ec883a315 100644 --- a/hassio/api/supervisor.py +++ b/hassio/api/supervisor.py @@ -14,6 +14,8 @@ from ..const import ( ATTR_BLK_WRITE, ATTR_CHANNEL, ATTR_CPU_PERCENT, + ATTR_DEBUG, + ATTR_DEBUG_BLOCK, ATTR_DESCRIPTON, ATTR_ICON, ATTR_INSTALLED, @@ -43,6 +45,7 @@ from .utils import api_process, api_process_raw, api_validate _LOGGER = logging.getLogger(__name__) +# pylint: disable=no-value-for-parameter SCHEMA_OPTIONS = vol.Schema( { vol.Optional(ATTR_CHANNEL): CHANNELS, @@ -50,6 +53,8 @@ SCHEMA_OPTIONS = vol.Schema( vol.Optional(ATTR_TIMEZONE): validate_timezone, vol.Optional(ATTR_WAIT_BOOT): WAIT_BOOT, vol.Optional(ATTR_LOGGING): LOG_LEVEL, + vol.Optional(ATTR_DEBUG): vol.Boolean(), + vol.Optional(ATTR_DEBUG_BLOCK): vol.Boolean(), } ) @@ -111,6 +116,12 @@ class APISupervisor(CoreSysAttributes): if ATTR_WAIT_BOOT in body: self.sys_config.wait_boot = body[ATTR_WAIT_BOOT] + if ATTR_DEBUG in body: + self.sys_config.debug = body[ATTR_DEBUG] + + if ATTR_DEBUG_BLOCK in body: + self.sys_config.debug_block = body[ATTR_DEBUG_BLOCK] + if ATTR_LOGGING in body: self.sys_config.logging = body[ATTR_LOGGING] diff --git a/hassio/bootstrap.py b/hassio/bootstrap.py index 8b37525b7..726ce5484 100644 --- a/hassio/bootstrap.py +++ b/hassio/bootstrap.py @@ -67,7 +67,7 @@ async def initialize_coresys(): return coresys -def initialize_system_data(coresys): +def initialize_system_data(coresys: CoreSys): """Set up the default configuration and create folders.""" config = coresys.config @@ -124,7 +124,7 @@ def initialize_system_data(coresys): coresys.config.modify_log_level() -def migrate_system_env(coresys): +def migrate_system_env(coresys: CoreSys): """Cleanup some stuff after update.""" config = coresys.config @@ -207,3 +207,16 @@ def reg_signal(loop): loop.add_signal_handler(signal.SIGINT, lambda: loop.call_soon(loop.stop)) except (ValueError, RuntimeError): _LOGGER.warning("Could not bind to SIGINT") + + +def supervisor_debugger(coresys: CoreSys) -> None: + """Setup debugger if needed.""" + if not coresys.config.debug or not coresys.dev: + return + import ptvsd + + _LOGGER.info("Initialize Hass.io debugger") + + ptvsd.enable_attach(address=('0.0.0.0', 33333), redirect_output=True) + if coresys.config.debug_block: + ptvsd.wait_for_attach() diff --git a/hassio/config.py b/hassio/config.py index ca386a7b8..eb569beb5 100644 --- a/hassio/config.py +++ b/hassio/config.py @@ -2,19 +2,21 @@ from datetime import datetime import logging import os -import re from pathlib import Path, PurePath +import re import pytz from .const import ( + ATTR_ADDONS_CUSTOM_LIST, + ATTR_DEBUG, + ATTR_DEBUG_BLOCK, + ATTR_LAST_BOOT, + ATTR_LOGGING, + ATTR_TIMEZONE, + ATTR_WAIT_BOOT, FILE_HASSIO_CONFIG, HASSIO_DATA, - ATTR_TIMEZONE, - ATTR_ADDONS_CUSTOM_LIST, - ATTR_LAST_BOOT, - ATTR_WAIT_BOOT, - ATTR_LOGGING, ) from .utils.dt import parse_datetime from .utils.json import JsonConfig @@ -82,6 +84,26 @@ class CoreConfig(JsonConfig): """Set wait boot time.""" self._data[ATTR_WAIT_BOOT] = value + @property + def debug(self) -> bool: + """Return True if ptvsd is enabled.""" + return self._data[ATTR_DEBUG] + + @debug.setter + def debug(self, value: bool): + """Set debug mode.""" + self._data[ATTR_DEBUG] = value + + @property + def debug_block(self) -> bool: + """Return True if ptvsd should waiting.""" + return self._data[ATTR_DEBUG_BLOCK] + + @debug_block.setter + def debug_block(self, value: bool): + """Set debug wait mode.""" + self._data[ATTR_DEBUG_BLOCK] = value + @property def logging(self) -> str: """Return log level of system.""" diff --git a/hassio/const.py b/hassio/const.py index 01b2582de..df19e30ac 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -208,6 +208,8 @@ ATTR_IP_ADDRESS = "ip_address" ATTR_SESSION = "session" ATTR_ADMIN = "admin" ATTR_PANELS = "panels" +ATTR_DEBUG = "debug" +ATTR_DEBUG_BLOCK = "debug_block" PROVIDE_SERVICE = "provide" NEED_SERVICE = "need" diff --git a/hassio/coresys.py b/hassio/coresys.py index 190d79801..0512ea5d3 100644 --- a/hassio/coresys.py +++ b/hassio/coresys.py @@ -78,7 +78,7 @@ class CoreSys: return None @property - def dev(self) -> str: + def dev(self) -> bool: """Return True if we run dev mode.""" return self._updater.channel == CHANNEL_DEV diff --git a/hassio/validate.py b/hassio/validate.py index e29affae2..4df3b06a7 100644 --- a/hassio/validate.py +++ b/hassio/validate.py @@ -9,6 +9,8 @@ from .const import ( ATTR_ADDONS_CUSTOM_LIST, ATTR_BOOT, ATTR_CHANNEL, + ATTR_DEBUG, + ATTR_DEBUG_BLOCK, ATTR_HASSIO, ATTR_HASSOS, ATTR_HASSOS_CLI, @@ -120,6 +122,8 @@ SCHEMA_HASSIO_CONFIG = vol.Schema( ): REPOSITORIES, vol.Optional(ATTR_WAIT_BOOT, default=5): WAIT_BOOT, vol.Optional(ATTR_LOGGING, default="info"): LOG_LEVEL, + vol.Optional(ATTR_DEBUG, default=False): vol.Boolean(), + vol.Optional(ATTR_DEBUG_BLOCK, default=False): vol.Boolean(), }, extra=vol.REMOVE_EXTRA, ) diff --git a/requirements.txt b/requirements.txt index 18d8d7bbb..04a32bb2d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ pytz==2019.1 pyudev==0.21.0 uvloop==0.12.2 voluptuous==0.11.5 +ptvsd==4.2.8