Merge pull request #1291 from home-assistant/dev

Release 187
This commit is contained in:
Pascal Vizeli 2019-09-12 23:30:53 +02:00 committed by GitHub
commit 69a7ed8a5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 35 deletions

View File

@ -345,11 +345,14 @@ class Addon(AddonModel):
"""Save data of add-on."""
self.sys_addons.data.save_data()
def write_options(self):
async def write_options(self):
"""Return True if add-on options is written to data."""
schema = self.schema
options = self.options
# Update secrets for validation
await self.sys_secrets.reload()
try:
options = schema(options)
write_json_file(self.path_options, options)
@ -467,7 +470,7 @@ class Addon(AddonModel):
self.save_persist()
# Options
self.write_options()
await self.write_options()
# Sound
if self.with_audio:

View File

@ -5,7 +5,6 @@ from typing import Any, Awaitable, Dict, List
from aiohttp import web
import voluptuous as vol
from voluptuous.humanize import humanize_error
from ..addons import AnyAddon
from ..docker.stats import DockerStats
@ -266,13 +265,16 @@ class APIAddons(CoreSysAttributes):
"""Store user options for add-on."""
addon: AnyAddon = self._extract_addon(request)
# Update secrets for validation
await self.sys_secrets.reload()
# Extend schema with add-on specific validation
addon_schema = SCHEMA_OPTIONS.extend(
{vol.Optional(ATTR_OPTIONS): vol.Any(None, addon.schema)}
)
body: Dict[str, Any] = await api_validate(
addon_schema, request, origin=[ATTR_OPTIONS]
)
# Validate/Process Body
body = await api_validate(addon_schema, request, origin=[ATTR_OPTIONS])
if ATTR_OPTIONS in body:
addon.options = body[ATTR_OPTIONS]
if ATTR_BOOT in body:
@ -336,14 +338,6 @@ class APIAddons(CoreSysAttributes):
def start(self, request: web.Request) -> Awaitable[None]:
"""Start add-on."""
addon: AnyAddon = self._extract_addon(request)
# check options
options = addon.options
try:
addon.schema(options)
except vol.Invalid as ex:
raise APIError(humanize_error(options, ex)) from None
return asyncio.shield(addon.start())
@api_process

View File

@ -1,26 +1,26 @@
"""Init file for Hass.io util for RESTful API."""
import json
import logging
from typing import Optional, List
from typing import Any, Dict, List, Optional
from aiohttp import web
import voluptuous as vol
from voluptuous.humanize import humanize_error
from ..const import (
JSON_RESULT,
CONTENT_TYPE_BINARY,
JSON_DATA,
JSON_MESSAGE,
RESULT_OK,
JSON_RESULT,
RESULT_ERROR,
CONTENT_TYPE_BINARY,
RESULT_OK,
)
from ..exceptions import HassioError, APIError, APIForbidden
from ..exceptions import APIError, APIForbidden, HassioError
_LOGGER: logging.Logger = logging.getLogger(__name__)
def json_loads(data):
def json_loads(data: Any) -> Dict[str, Any]:
"""Extract json from string with support for '' and None."""
if not data:
return {}
@ -78,23 +78,23 @@ def api_process_raw(content):
return wrap_method
def api_return_error(message=None):
def api_return_error(message: Optional[str] = None) -> web.Response:
"""Return an API error message."""
return web.json_response(
{JSON_RESULT: RESULT_ERROR, JSON_MESSAGE: message}, status=400
)
def api_return_ok(data=None):
def api_return_ok(data: Optional[Dict[str, Any]] = None) -> web.Response:
"""Return an API ok answer."""
return web.json_response({JSON_RESULT: RESULT_OK, JSON_DATA: data or {}})
async def api_validate(
schema: vol.Schema, request: web.Request, origin: Optional[List[str]] = None
):
) -> Dict[str, Any]:
"""Validate request data with schema."""
data = await request.json(loads=json_loads)
data: Dict[str, Any] = await request.json(loads=json_loads)
try:
data_validated = schema(data)
except vol.Invalid as ex:

View File

@ -2,7 +2,7 @@
from pathlib import Path
from ipaddress import ip_network
HASSIO_VERSION = "186"
HASSIO_VERSION = "187"
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"

View File

@ -127,7 +127,9 @@ class DockerHomeAssistant(DockerInterface):
"""
try:
docker_container = self.sys_docker.containers.get(self.name)
docker_image = self.sys_docker.images.get(self.image)
docker_image = self.sys_docker.images.get(
f"{self.image}:{self.sys_homeassistant.version}"
)
except docker.errors.DockerException:
return False

View File

@ -1,11 +1,13 @@
"""Handle Home Assistant secrets to add-ons."""
from typing import Dict
from pathlib import Path
from datetime import timedelta
import logging
from pathlib import Path
from typing import Dict
from ruamel.yaml import YAML, YAMLError
from .coresys import CoreSys, CoreSysAttributes
from .utils import AsyncThrottle
_LOGGER: logging.Logger = logging.getLogger(__name__)
@ -38,6 +40,7 @@ class SecretsManager(CoreSysAttributes):
"""Reload secrets."""
await self._read_secrets()
@AsyncThrottle(timedelta(seconds=60))
async def _read_secrets(self):
"""Read secrets.yaml into memory."""
if not self.path_secrets.exists():

View File

@ -16,10 +16,9 @@ RUN_UPDATE_DNS = 30100
RUN_RELOAD_ADDONS = 10800
RUN_RELOAD_SNAPSHOTS = 72000
RUN_RELOAD_HOST = 72000
RUN_RELOAD_HOST = 7600
RUN_RELOAD_UPDATER = 7200
RUN_RELOAD_INGRESS = 930
RUN_RELOAD_SECRETS = 940
RUN_WATCHDOG_HOMEASSISTANT_DOCKER = 15
RUN_WATCHDOG_HOMEASSISTANT_API = 300
@ -78,11 +77,6 @@ class Tasks(CoreSysAttributes):
self.sys_ingress.reload, RUN_RELOAD_INGRESS
)
)
self.jobs.add(
self.sys_scheduler.register_task(
self.sys_secrets.reload, RUN_RELOAD_SECRETS
)
)
# Watchdog
self.jobs.add(