Support plugin requirements & mdns (#1638)

* Support plugin requirements & mdns

* better error handling

* Use debug from LogLevel

* fix lint

* fix logger

* fix test env

* Use new style

* fix typo
This commit is contained in:
Pascal Vizeli 2020-04-07 12:08:29 +02:00 committed by GitHub
parent e787e59b49
commit e2dc1a4471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 85 additions and 23 deletions

View File

@ -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
}

View File

@ -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(),
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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(

View File

@ -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)

View File

@ -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(),
},