This commit is contained in:
Pascal Vizeli 2017-04-12 22:59:40 +02:00
parent 20856126c8
commit f340a19e40
10 changed files with 41 additions and 42 deletions

View File

@ -5,8 +5,8 @@ import shutil
from .data import AddonsData from .data import AddonsData
from .git import AddonsRepo from .git import AddonsRepo
from ..const import STATE_STOPED, STATE_STARTED from ..const import STATE_STOPPED, STATE_STARTED
from ..docker.addon import DockerAddon from ..dock.addon import DockerAddon
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -76,7 +76,7 @@ class AddonManager(AddonsData):
_LOGGER.error("No docker found for addon %s.", addon) _LOGGER.error("No docker found for addon %s.", addon)
return False return False
if not await self.dockers[addon].remove(version): if not await self.dockers[addon].remove():
return False return False
if os.path.isdir(self.path_data(addon)): if os.path.isdir(self.path_data(addon)):
@ -96,7 +96,7 @@ class AddonManager(AddonsData):
if await self.dockers[addon].is_running(): if await self.dockers[addon].is_running():
return STATE_STARTED return STATE_STARTED
return STATE_STOPED return STATE_STOPPED
async def start_addon(self, addon): async def start_addon(self, addon):
"""Set options and start addon.""" """Set options and start addon."""

View File

@ -7,9 +7,10 @@ from voluptuous.humanize import humanize_error
from ..const import ( from ..const import (
FILE_HASSIO_ADDONS, ATTR_NAME, ATTR_VERSION, ATTR_SLUG, ATTR_DESCRIPTON, FILE_HASSIO_ADDONS, ATTR_NAME, ATTR_VERSION, ATTR_SLUG, ATTR_DESCRIPTON,
ATTR_STARTUP, ATTR_BOOT, ATTR_MAP_SSL, ATTR_MAP_CONFIG, ATTR_MAP_DATA, ATTR_STARTUP, ATTR_BOOT, ATTR_MAP_SSL, ATTR_MAP_CONFIG, ATTR_OPTIONS,
ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE, BOOT_AUTO,
BOOT_AUTO, BOOT_MANUAL, DOCKER_REPO, ATTR_INSTALLED, ATTR_SCHEMA) BOOT_MANUAL, DOCKER_REPO, ATTR_INSTALLED, ATTR_SCHEMA)
from ..config import Config
from ..tools import read_json_file, write_json_file from ..tools import read_json_file, write_json_file
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -31,7 +32,7 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
vol.Required(ATTR_STARTUP): vol.Required(ATTR_STARTUP):
vol.In([STARTUP_BEFORE, STARTUP_AFTER, STARTUP_ONCE]), vol.In([STARTUP_BEFORE, STARTUP_AFTER, STARTUP_ONCE]),
vol.Required(ATTR_BOOT): vol.Required(ATTR_BOOT):
vol.IN([BOOT_AUTO, BOOT_MANUAL]), vol.In([BOOT_AUTO, BOOT_MANUAL]),
vol.Optional(ATTR_PORTS): dict, vol.Optional(ATTR_PORTS): dict,
vol.Required(ATTR_MAP_CONFIG): vol.Boolean(), vol.Required(ATTR_MAP_CONFIG): vol.Boolean(),
vol.Required(ATTR_MAP_SSL): vol.Boolean(), vol.Required(ATTR_MAP_SSL): vol.Boolean(),
@ -48,7 +49,7 @@ class AddonsData(Config):
def __init__(self, config): def __init__(self, config):
"""Initialize data holder.""" """Initialize data holder."""
super().__init__(FILE_HASSIO_ADDONS) super().__init__(FILE_HASSIO_ADDONS)
self.config self.config = config
self._addons_data = {} self._addons_data = {}
def read_addons_repo(self): def read_addons_repo(self):
@ -66,7 +67,7 @@ class AddonsData(Config):
_LOGGER.warning("Can't read %s", addon) _LOGGER.warning("Can't read %s", addon)
except vol.Invalid as ex: except vol.Invalid as ex:
_LOGGER.warnign("Can't read %s -> %s.", addon, _LOGGER.warning("Can't read %s -> %s.", addon,
humanize_error(addon_config, ex)) humanize_error(addon_config, ex))
@property @property
@ -83,7 +84,7 @@ class AddonsData(Config):
def list(self): def list(self):
"""Return a list of available addons.""" """Return a list of available addons."""
data = [] data = []
for addon, values in self._addons.items(): for addon, values in self._addons_data.items():
data.append({ data.append({
ATTR_NAME: values[ATTR_NAME], ATTR_NAME: values[ATTR_NAME],
ATTR_SLUG: values[ATTR_SLUG], ATTR_SLUG: values[ATTR_SLUG],
@ -114,7 +115,7 @@ class AddonsData(Config):
} }
self.save() self.save()
def set_uninstall_addon(self, addon, version): def set_uninstall_addon(self, addon):
"""Set addon as uninstalled.""" """Set addon as uninstalled."""
self._data.pop(addon, None) self._data.pop(addon, None)
self.save() self.save()
@ -172,10 +173,6 @@ class AddonsData(Config):
"""Return True if ssl map is needed.""" """Return True if ssl map is needed."""
return self._addons_data[addon][ATTR_MAP_SSL] return self._addons_data[addon][ATTR_MAP_SSL]
def need_data(self, addon):
"""Return True if data map is needed."""
return self._addons_data[addon][ATTR_MAP_DATA]
def path_data(self, addon): def path_data(self, addon):
"""Return addon data path inside supervisor.""" """Return addon data path inside supervisor."""
return "{}/{}".format( return "{}/{}".format(
@ -201,7 +198,7 @@ class AddonsData(Config):
def validate(struct): def validate(struct):
"""Validate schema.""" """Validate schema."""
validated = {} options = {}
for key, value in struct.items(): for key, value in struct.items():
if key not in raw_schema: if key not in raw_schema:
raise vol.Invalid("Unknown options {}.".format(key)) raise vol.Invalid("Unknown options {}.".format(key))
@ -209,18 +206,18 @@ class AddonsData(Config):
typ = raw_schema[key] typ = raw_schema[key]
try: try:
if typ == V_STR: if typ == V_STR:
validate[key] = str(value) options[key] = str(value)
elif typ == V_INT: elif typ == V_INT:
validate[key] = int(value) options[key] = int(value)
elif typ == V_FLOAT: elif typ == V_FLOAT:
validate[key] = float(value) options[key] = float(value)
elif typ == V_BOOL: elif typ == V_BOOL:
validate[key] = vol.Boolean()(value) options[key] = vol.Boolean()(value)
except TypeError: except TypeError:
raise vol.Invalid( raise vol.Invalid(
"Type error for {}.".format(key)) from None "Type error for {}.".format(key)) from None
return validated return options
schema = vol.Schema(vol.All(dict(), validate)) schema = vol.Schema(vol.All(dict(), validate))
return schema return schema

View File

@ -25,7 +25,7 @@ class AddonsRepo(object):
if not os.path.isdir(self.config.path_addons_repo): if not os.path.isdir(self.config.path_addons_repo):
return await self.clone() return await self.clone()
await with self._lock: async with self._lock:
try: try:
self.repo = await self.loop.run_in_executor( self.repo = await self.loop.run_in_executor(
None, git.Repo(self.config.path_addons_repo)) None, git.Repo(self.config.path_addons_repo))
@ -38,7 +38,7 @@ class AddonsRepo(object):
async def clone(self): async def clone(self):
"""Clone git addon repo.""" """Clone git addon repo."""
await with self._lock: async with self._lock:
try: try:
self.repo = await self.loop.run_in_executor( self.repo = await self.loop.run_in_executor(
None, git.Repo.clone_from, URL_HASSIO_ADDONS, None, git.Repo.clone_from, URL_HASSIO_ADDONS,
@ -56,9 +56,9 @@ class AddonsRepo(object):
_LOGGER.warning("It is already a task in progress.") _LOGGER.warning("It is already a task in progress.")
return False return False
await with self._lock: async with self._lock:
try: try:
yield from self.loop.run_in_executor( await self.loop.run_in_executor(
None, self.repo.remotes.origin.pull) None, self.repo.remotes.origin.pull)
except (git.InvalidGitRepositoryError, git.NoSuchPathError) as err: except (git.InvalidGitRepositoryError, git.NoSuchPathError) as err:

View File

@ -3,7 +3,7 @@ import logging
from aiohttp import web from aiohttp import web
from .addons import APIAddonManager from .addons import APIAddons
from .homeassistant import APIHomeAssistant from .homeassistant import APIHomeAssistant
from .host import APIHost from .host import APIHost
from .network import APINetwork from .network import APINetwork

View File

@ -6,7 +6,8 @@ import voluptuous as vol
from .util import api_process, api_validate from .util import api_process, api_validate
from ..const import ( from ..const import (
ATTR_VERSION, ATTR_CURRENT, ATTR_STATE, ATTR_BOOT, ATTR_OPTIONS) ATTR_VERSION, ATTR_CURRENT, ATTR_STATE, ATTR_BOOT, ATTR_OPTIONS,
STATE_STOPPED, STATE_STARTED)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -69,7 +70,7 @@ class APIAddons(object):
ATTR_VERSION, self.addons.get_version(addon)) ATTR_VERSION, self.addons.get_version(addon))
return await asyncio.shield( return await asyncio.shield(
self.addons.addon_install(addon, version)) self.addons.addon_install(addon, version), loop=self.loop)
@api_process @api_process
async def uninstall(self, request): async def uninstall(self, request):
@ -77,7 +78,7 @@ class APIAddons(object):
addon = self._extract_addon(request) addon = self._extract_addon(request)
return await asyncio.shield( return await asyncio.shield(
self.addons.addon_uninstall(addon)) self.addons.addon_uninstall(addon), loop=self.loop)
@api_process @api_process
async def start(self, request): async def start(self, request):
@ -88,18 +89,18 @@ class APIAddons(object):
raise RuntimeError("Addon is already running.") raise RuntimeError("Addon is already running.")
return await asyncio.shield( return await asyncio.shield(
self.addons.addon_start(addon)) self.addons.addon_start(addon), loop=self.loop)
@api_process @api_process
async def stop(self, request): async def stop(self, request):
"""Stop addon.""" """Stop addon."""
addon = self._extract_addon(request) addon = self._extract_addon(request)
if await self.addons.state_addon(addon) == STATE_STOPED: if await self.addons.state_addon(addon) == STATE_STOPPED:
raise RuntimeError("Addon is already stoped.") raise RuntimeError("Addon is already stoped.")
return await asyncio.shield( return await asyncio.shield(
self.addons.addon_stop(addon)) self.addons.addon_stop(addon), loop=self.loop)
@api_process @api_process
async def update(self, request): async def update(self, request):
@ -113,4 +114,4 @@ class APIAddons(object):
raise RuntimeError("Version is already in use.") raise RuntimeError("Version is already in use.")
return await asyncio.shield( return await asyncio.shield(
self.addons.addon_update(addon, version)) self.addons.addon_update(addon, version), loop=self.loop)

View File

@ -45,4 +45,5 @@ class APIHomeAssistant(object):
if version == self.dock_hass.version: if version == self.dock_hass.version:
raise RuntimeError("%s is already in use.", version) raise RuntimeError("%s is already in use.", version)
return await asyncio.shield(self.dock_hass.update(version)) return await asyncio.shield(
self.dock_hass.update(version), loop=self.loop)

View File

@ -1,5 +1,4 @@
"""Bootstrap HassIO.""" """Bootstrap HassIO."""
import json
import logging import logging
import os import os
@ -40,7 +39,7 @@ class Config(object):
def save(self): def save(self):
"""Store data to config file.""" """Store data to config file."""
if not write_json_file(self._filename, self._data) if not write_json_file(self._filename, self._data):
_LOGGER.exception("Can't store config in %s", self._filename) _LOGGER.exception("Can't store config in %s", self._filename)
return False return False
return True return True
@ -53,7 +52,7 @@ class CoreConfig(Config):
"""Initialize config object.""" """Initialize config object."""
self.websession = websession self.websession = websession
super().__ini__(FILE_HASSIO_CONFIG) super().__init__(FILE_HASSIO_CONFIG)
# init data # init data
if not self._data: if not self._data:

View File

@ -43,11 +43,12 @@ ATTR_MAP_SSL = 'map_ssl'
ATTR_OPTIONS = 'options' ATTR_OPTIONS = 'options'
ATTR_INSTALLED = 'installed' ATTR_INSTALLED = 'installed'
ATTR_STATE = 'state' ATTR_STATE = 'state'
ATTR_SCHEMA = 'schema'
STARTUP_BEFORE = 'before' STARTUP_BEFORE = 'before'
STARTUP_AFTER = 'after' STARTUP_AFTER = 'after'
STARTUP_ONCE = 'once' STARTUP_ONCE = 'once'
BOOT_STOP = 'auto' BOOT_AUTO = 'auto'
BOOT_MANUAL = 'manual' BOOT_MANUAL = 'manual'
STATE_STARTED = 'started' STATE_STARTED = 'started'
STATE_STOPED = 'stoped' STATE_STOPPED = 'stopped'

View File

@ -19,7 +19,7 @@ class DockerAddon(DockerBase):
super().__init__( super().__init__(
config, loop, dock, image=addons_data.get_image(addon)) config, loop, dock, image=addons_data.get_image(addon))
self.addon = addon self.addon = addon
self.addons_data self.addons_data = addons_data
@property @property
def docker_name(self): def docker_name(self):

View File

@ -28,6 +28,6 @@ class DockerSupervisor(DockerBase):
"""Update docker image.""" """Update docker image."""
raise RuntimeError("Not support on supervisor docker container!") raise RuntimeError("Not support on supervisor docker container!")
async def remove(self, tag): async def remove(self):
"""Remove docker image.""" """Remove docker image."""
raise RuntimeError("Not support on supervisor docker container!") raise RuntimeError("Not support on supervisor docker container!")