diff --git a/API.md b/API.md index fd9ab0a73..0d4679e42 100644 --- a/API.md +++ b/API.md @@ -41,6 +41,7 @@ The addons from `addons` are only installed one. "arch": "armhf|aarch64|i386|amd64", "channel": "stable|beta|dev", "timezone": "TIMEZONE", + "logging": "debug|info|warning|error|critical", "ip_address": "ip address", "wait_boot": "int", "addons": [ @@ -79,6 +80,7 @@ Optional: "channel": "stable|beta|dev", "timezone": "TIMEZONE", "wait_boot": "int", + "logging": "debug|info|warning|error|critical", "addons_repositories": [ "REPO_URL" ] @@ -704,7 +706,8 @@ return: "machine": "type", "arch": "arch", "supported_arch": ["arch1", "arch2"], - "channel": "stable|beta|dev" + "channel": "stable|beta|dev", + "logging": "debug|info|warning|error|critical" } ``` diff --git a/hassio/api/info.py b/hassio/api/info.py index f5c07a51b..527397946 100644 --- a/hassio/api/info.py +++ b/hassio/api/info.py @@ -1,9 +1,20 @@ """Init file for Hass.io info RESTful API.""" import logging +from typing import Any, Dict -from ..const import (ATTR_ARCH, ATTR_CHANNEL, ATTR_HASSOS, ATTR_HOMEASSISTANT, - ATTR_HOSTNAME, ATTR_MACHINE, ATTR_SUPERVISOR, - ATTR_SUPPORTED_ARCH) +from aiohttp import web + +from ..const import ( + ATTR_ARCH, + ATTR_CHANNEL, + ATTR_HASSOS, + ATTR_HOMEASSISTANT, + ATTR_HOSTNAME, + ATTR_LOGGING, + ATTR_MACHINE, + ATTR_SUPERVISOR, + ATTR_SUPPORTED_ARCH, +) from ..coresys import CoreSysAttributes from .utils import api_process @@ -14,7 +25,7 @@ class APIInfo(CoreSysAttributes): """Handle RESTful API for info functions.""" @api_process - async def info(self, request): + async def info(self, request: web.Request) -> Dict[str, Any]: """Show system info.""" return { ATTR_SUPERVISOR: self.sys_supervisor.version, @@ -25,4 +36,5 @@ class APIInfo(CoreSysAttributes): ATTR_ARCH: self.sys_arch.default, ATTR_SUPPORTED_ARCH: self.sys_arch.supported, ATTR_CHANNEL: self.sys_updater.channel, + ATTR_LOGGING: self.sys_config.logging, } diff --git a/hassio/api/supervisor.py b/hassio/api/supervisor.py index ff42fd6cb..f153780e8 100644 --- a/hassio/api/supervisor.py +++ b/hassio/api/supervisor.py @@ -17,7 +17,9 @@ from ..const import ( ATTR_DESCRIPTON, ATTR_ICON, ATTR_INSTALLED, + ATTR_IP_ADDRESS, ATTR_LAST_VERSION, + ATTR_LOGGING, ATTR_LOGO, ATTR_MEMORY_LIMIT, ATTR_MEMORY_USAGE, @@ -30,14 +32,13 @@ from ..const import ( ATTR_TIMEZONE, ATTR_VERSION, ATTR_WAIT_BOOT, - ATTR_IP_ADDRESS, CONTENT_TYPE_BINARY, HASSIO_VERSION, ) from ..coresys import CoreSysAttributes from ..exceptions import APIError from ..utils.validate import validate_timezone -from ..validate import CHANNELS, REPOSITORIES, WAIT_BOOT +from ..validate import CHANNELS, LOG_LEVEL, REPOSITORIES, WAIT_BOOT from .utils import api_process, api_process_raw, api_validate _LOGGER = logging.getLogger(__name__) @@ -48,6 +49,7 @@ SCHEMA_OPTIONS = vol.Schema( vol.Optional(ATTR_ADDONS_REPOSITORIES): REPOSITORIES, vol.Optional(ATTR_TIMEZONE): validate_timezone, vol.Optional(ATTR_WAIT_BOOT): WAIT_BOOT, + vol.Optional(ATTR_LOGGING): LOG_LEVEL, } ) @@ -90,6 +92,7 @@ class APISupervisor(CoreSysAttributes): ATTR_IP_ADDRESS: str(self.sys_supervisor.ip_address), ATTR_WAIT_BOOT: self.sys_config.wait_boot, ATTR_TIMEZONE: self.sys_config.timezone, + ATTR_LOGGING: self.sys_config.logging, ATTR_ADDONS: list_addons, ATTR_ADDONS_REPOSITORIES: self.sys_config.addons_repositories, } @@ -108,6 +111,9 @@ class APISupervisor(CoreSysAttributes): if ATTR_WAIT_BOOT in body: self.sys_config.wait_boot = body[ATTR_WAIT_BOOT] + if ATTR_LOGGING in body: + self.sys_config.logging = body[ATTR_LOGGING] + if ATTR_ADDONS_REPOSITORIES in body: new = set(body[ATTR_ADDONS_REPOSITORIES]) await asyncio.shield(self.sys_addons.load_repositories(new)) diff --git a/hassio/config.py b/hassio/config.py index 6232e9eb8..4fc4b819d 100644 --- a/hassio/config.py +++ b/hassio/config.py @@ -8,15 +8,21 @@ from pathlib import Path, PurePath import pytz from .const import ( - FILE_HASSIO_CONFIG, HASSIO_DATA, ATTR_TIMEZONE, ATTR_ADDONS_CUSTOM_LIST, - ATTR_LAST_BOOT, 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 from .validate import SCHEMA_HASSIO_CONFIG _LOGGER = logging.getLogger(__name__) -HOMEASSISTANT_CONFIG = PurePath('homeassistant') +HOMEASSISTANT_CONFIG = PurePath("homeassistant") HASSIO_SSL = PurePath("ssl") @@ -45,7 +51,7 @@ class CoreConfig(JsonConfig): @property def timezone(self): """Return system timezone.""" - config_file = Path(self.path_homeassistant, 'configuration.yaml') + config_file = Path(self.path_homeassistant, "configuration.yaml") try: assert config_file.exists() configuration = config_file.read_text() @@ -53,7 +59,7 @@ class CoreConfig(JsonConfig): data = RE_TIMEZONE.search(configuration) assert data - timezone = data.group('timezone') + timezone = data.group("timezone") pytz.timezone(timezone) except (pytz.exceptions.UnknownTimeZoneError, OSError, AssertionError): _LOGGER.debug("Can't parse Home Assistant timezone") @@ -67,15 +73,25 @@ class CoreConfig(JsonConfig): self._data[ATTR_TIMEZONE] = value @property - def wait_boot(self): + def wait_boot(self) -> int: """Return wait time for auto boot stages.""" return self._data[ATTR_WAIT_BOOT] @wait_boot.setter - def wait_boot(self, value): + def wait_boot(self, value: int): """Set wait boot time.""" self._data[ATTR_WAIT_BOOT] = value + @property + def logging(self) -> str: + """Return log level of system.""" + return self._data[ATTR_LOGGING] + + @logging.setter + def logging(self, value: str): + """Set system log level.""" + self._data[ATTR_LOGGING] = value + @property def last_boot(self): """Return last boot datetime.""" @@ -99,7 +115,7 @@ class CoreConfig(JsonConfig): @property def path_extern_hassio(self): """Return Hass.io data path external for Docker.""" - return PurePath(os.environ['SUPERVISOR_SHARE']) + return PurePath(os.environ["SUPERVISOR_SHARE"]) @property def path_extern_homeassistant(self): diff --git a/hassio/const.py b/hassio/const.py index 75ab80846..b034f7523 100644 --- a/hassio/const.py +++ b/hassio/const.py @@ -67,6 +67,7 @@ ATTR_WAIT_BOOT = "wait_boot" ATTR_DEPLOYMENT = "deployment" ATTR_WATCHDOG = "watchdog" ATTR_CHANGELOG = "changelog" +ATTR_LOGGING = "logging" ATTR_DATE = "date" ATTR_ARCH = "arch" ATTR_LONG_DESCRIPTION = "long_description" diff --git a/hassio/validate.py b/hassio/validate.py index 71b85c9d3..e29affae2 100644 --- a/hassio/validate.py +++ b/hassio/validate.py @@ -16,6 +16,7 @@ from .const import ( ATTR_IMAGE, ATTR_LAST_BOOT, ATTR_LAST_VERSION, + ATTR_LOGGING, ATTR_PASSWORD, ATTR_PORT, ATTR_PORTS, @@ -42,6 +43,7 @@ CHANNELS = vol.In([CHANNEL_STABLE, CHANNEL_BETA, CHANNEL_DEV]) UUID_MATCH = vol.Match(r"^[0-9a-f]{32}$") SHA256 = vol.Match(r"^[0-9a-f]{64}$") TOKEN = vol.Match(r"^[0-9a-f]{32,256}$") +LOG_LEVEL = vol.In(["debug", "info", "warning", "error", "critical"]) def validate_repository(repository): @@ -117,6 +119,7 @@ SCHEMA_HASSIO_CONFIG = vol.Schema( default=["https://github.com/hassio-addons/repository"], ): REPOSITORIES, vol.Optional(ATTR_WAIT_BOOT, default=5): WAIT_BOOT, + vol.Optional(ATTR_LOGGING, default="info"): LOG_LEVEL, }, extra=vol.REMOVE_EXTRA, )