diff --git a/scripts/test_env.sh b/scripts/test_env.sh index fface59b2..fb2b93567 100755 --- a/scripts/test_env.sh +++ b/scripts/test_env.sh @@ -96,7 +96,7 @@ function setup_test_env() { -e SUPERVISOR_SHARE="/workspaces/test_supervisor" \ -e SUPERVISOR_NAME=hassio_supervisor \ -e SUPERVISOR_DEV=1 \ - -e HOMEASSISTANT_REPOSITORY="homeassistant/qemux86-64-homeassistant" \ + -e SUPERVISOR_MACHINE="qemux86-64" \ homeassistant/amd64-hassio-supervisor:latest } diff --git a/supervisor/api/supervisor.py b/supervisor/api/supervisor.py index 33b71613b..241466036 100644 --- a/supervisor/api/supervisor.py +++ b/supervisor/api/supervisor.py @@ -38,11 +38,12 @@ from ..const import ( CONTENT_TYPE_BINARY, SUPERVISOR_VERSION, UpdateChannels, + LogLevel, ) from ..coresys import CoreSysAttributes from ..exceptions import APIError from ..utils.validate import validate_timezone -from ..validate import log_level, repositories, wait_boot +from ..validate import repositories, wait_boot from .utils import api_process, api_process_raw, api_validate _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -54,7 +55,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, + vol.Optional(ATTR_LOGGING): vol.Coerce(LogLevel), vol.Optional(ATTR_DEBUG): vol.Boolean(), vol.Optional(ATTR_DEBUG_BLOCK): vol.Boolean(), } diff --git a/supervisor/bootstrap.py b/supervisor/bootstrap.py index 932180ca4..74bbcfc1d 100644 --- a/supervisor/bootstrap.py +++ b/supervisor/bootstrap.py @@ -12,12 +12,13 @@ from .api import RestAPI from .arch import CpuArch from .auth import Auth from .const import ( - SOCKET_DOCKER, - UpdateChannels, - ENV_SUPERVISOR_SHARE, - ENV_SUPERVISOR_NAME, ENV_HOMEASSISTANT_REPOSITORY, ENV_SUPERVISOR_MACHINE, + ENV_SUPERVISOR_NAME, + ENV_SUPERVISOR_SHARE, + SOCKET_DOCKER, + LogLevel, + UpdateChannels, ) from .core import Core from .coresys import CoreSys @@ -28,14 +29,14 @@ from .homeassistant import HomeAssistant from .host import HostManager from .hwmon import HwMonitor from .ingress import Ingress +from .plugins import PluginManager +from .secrets import SecretsManager from .services import ServiceManager from .snapshots import SnapshotManager from .store import StoreManager from .supervisor import Supervisor from .tasks import Tasks from .updater import Updater -from .secrets import SecretsManager -from .plugins import PluginManager from .utils.dt import fetch_timezone _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -163,7 +164,7 @@ def initialize_system_data(coresys: CoreSys): if bool(os.environ.get("SUPERVISOR_DEV", 0)): _LOGGER.warning("SUPERVISOR_DEV is set") coresys.updater.channel = UpdateChannels.DEV - coresys.config.logging = "debug" + coresys.config.logging = LogLevel.DEBUG coresys.config.debug = True diff --git a/supervisor/config.py b/supervisor/config.py index e4fb771d5..3354bf467 100644 --- a/supervisor/config.py +++ b/supervisor/config.py @@ -15,6 +15,7 @@ from .const import ( ENV_SUPERVISOR_SHARE, FILE_HASSIO_CONFIG, SUPERVISOR_DATA, + LogLevel, ) from .utils.dt import parse_datetime from .utils.json import JsonConfig @@ -89,19 +90,19 @@ class CoreConfig(JsonConfig): self._data[ATTR_DEBUG_BLOCK] = value @property - def logging(self) -> str: + def logging(self) -> LogLevel: """Return log level of system.""" return self._data[ATTR_LOGGING] @logging.setter - def logging(self, value: str): + def logging(self, value: LogLevel): """Set system log level.""" self._data[ATTR_LOGGING] = value self.modify_log_level() def modify_log_level(self) -> None: """Change log level.""" - lvl = getattr(logging, self.logging.upper()) + lvl = getattr(logging, str(self.logging.value).upper()) logging.getLogger("supervisor").setLevel(lvl) @property diff --git a/supervisor/const.py b/supervisor/const.py index 513ba6c1f..5b92de955 100644 --- a/supervisor/const.py +++ b/supervisor/const.py @@ -361,3 +361,13 @@ class CoreStates(str, Enum): STARTUP = "startup" RUNNING = "running" FREEZE = "freeze" + + +class LogLevel(str, Enum): + """Logging level of system.""" + + DEBUG = "debug" + INFO = "info" + WARNING = "warning" + ERROR = "error" + CRITICAL = "critical" diff --git a/supervisor/data/coredns.tmpl b/supervisor/data/coredns.tmpl index 50b6dc540..33e3bbdaa 100644 --- a/supervisor/data/coredns.tmpl +++ b/supervisor/data/coredns.tmpl @@ -2,26 +2,29 @@ log errors loop + {% if debug %}debug{% endif %} hosts /config/hosts { fallthrough } template ANY AAAA local.hass.io hassio { rcode NOERROR } - forward . {{ locals | join(" ") }} dns://127.0.0.1:5353 { + mdns + forward . {{ locals | join(" ") }} dns://127.0.0.1:5553 { except local.hass.io policy sequential health_check 5s } - fallback REFUSED . dns://127.0.0.1:5353 - fallback SERVFAIL . dns://127.0.0.1:5353 - fallback NXDOMAIN . dns://127.0.0.1:5353 + fallback REFUSED . dns://127.0.0.1:5553 + fallback SERVFAIL . dns://127.0.0.1:5553 + fallback NXDOMAIN . dns://127.0.0.1:5553 cache 10 } -.:5353 { +.:5553 { log errors + {% if debug %}debug{% endif %} forward . tls://1.1.1.1 tls://1.0.0.1 { tls_servername cloudflare-dns.com except local.hass.io diff --git a/supervisor/plugins/__init__.py b/supervisor/plugins/__init__.py index c41c7cebf..0c0d91614 100644 --- a/supervisor/plugins/__init__.py +++ b/supervisor/plugins/__init__.py @@ -3,6 +3,7 @@ import asyncio import logging from ..coresys import CoreSys, CoreSysAttributes +from ..exceptions import HassioError from .audio import Audio from .cli import HaCli from .dns import CoreDNS @@ -14,6 +15,11 @@ _LOGGER: logging.Logger = logging.getLogger(__name__) class PluginManager(CoreSysAttributes): """Manage supported function for plugins.""" + required_cli: int = 24 + required_dns: int = 5 + required_audio: int = 14 + required_multicast: int = 2 + def __init__(self, coresys: CoreSys): """Initialize plugin manager.""" self.coresys: CoreSys = coresys @@ -49,6 +55,37 @@ class PluginManager(CoreSysAttributes): [self.dns.load(), self.audio.load(), self.cli.load(), self.multicast.load()] ) + # Check requirements + for plugin, required_version in ( + (self._audio, self.required_audio), + (self._dns, self.required_dns), + (self._cli, self.required_cli), + (self._multicast, self.required_multicast), + ): + # Check if need an update + try: + if int(plugin.version) >= required_version: + continue + except TypeError: + _LOGGER.warning( + "Somethings going wrong with requirements on %s", + type(plugin).__name__, + ) + + _LOGGER.info( + "Requirement need update for %s - %i", + type(plugin).__name__, + required_version, + ) + try: + await plugin.update(version=str(required_version)) + except HassioError: + _LOGGER.error( + "Can't update %s to %i but it's a reuirement, the Supervisor is not health now!", + type(plugin).__name__, + required_version, + ) + async def repair(self): """Repair Supervisor plugins.""" await asyncio.wait( diff --git a/supervisor/plugins/dns.py b/supervisor/plugins/dns.py index f7c8abd63..0922cb182 100644 --- a/supervisor/plugins/dns.py +++ b/supervisor/plugins/dns.py @@ -13,15 +13,22 @@ import attr import jinja2 import voluptuous as vol -from ..const import ATTR_IMAGE, ATTR_SERVERS, ATTR_VERSION, DNS_SUFFIX, FILE_HASSIO_DNS +from ..const import ( + ATTR_IMAGE, + ATTR_SERVERS, + ATTR_VERSION, + DNS_SUFFIX, + FILE_HASSIO_DNS, + LogLevel, +) from ..coresys import CoreSys, CoreSysAttributes from ..docker.dns import DockerDNS from ..docker.stats import DockerStats from ..exceptions import CoreDNSError, CoreDNSUpdateError, DockerAPIError from ..misc.forwarder import DNSForward from ..utils.json import JsonConfig -from .validate import SCHEMA_DNS_CONFIG from ..validate import dns_url +from .validate import SCHEMA_DNS_CONFIG _LOGGER: logging.Logger = logging.getLogger(__name__) @@ -301,7 +308,9 @@ class CoreDNS(JsonConfig, CoreSysAttributes): _LOGGER.warning("Ignore invalid DNS Server: %s", server) # Generate config file - data = self.coredns_template.render(locals=dns_servers) + data = self.coredns_template.render( + locals=dns_servers, debug=self.sys_config.logging == LogLevel.DEBUG + ) try: self.corefile.write_text(data) diff --git a/supervisor/validate.py b/supervisor/validate.py index 4e502073b..cfe3c9e22 100644 --- a/supervisor/validate.py +++ b/supervisor/validate.py @@ -34,6 +34,7 @@ from .const import ( ATTR_VERSION, ATTR_WAIT_BOOT, ATTR_WATCHDOG, + LogLevel, UpdateChannels, ) from .utils.validate import validate_timezone @@ -48,7 +49,6 @@ docker_image = vol.Match(r"^[\w{}]+/[\-\w{}]+$") 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 dns_url(url: str) -> str: @@ -156,7 +156,7 @@ SCHEMA_SUPERVISOR_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, + vol.Optional(ATTR_LOGGING, default=LogLevel.INFO): vol.Coerce(LogLevel), vol.Optional(ATTR_DEBUG, default=False): vol.Boolean(), vol.Optional(ATTR_DEBUG_BLOCK, default=False): vol.Boolean(), },