Add landingpage / cleanup homeassistant core handling

This commit is contained in:
pvizeli 2017-07-11 12:26:58 +02:00
parent a14917e017
commit 02c8baef68
7 changed files with 121 additions and 97 deletions

View File

@ -15,54 +15,22 @@ from .validate import (
from ..const import (
FILE_HASSIO_ADDONS, ATTR_VERSION, ATTR_SLUG, ATTR_REPOSITORY, ATTR_LOCATON,
REPOSITORY_CORE, REPOSITORY_LOCAL, ATTR_USER, ATTR_SYSTEM)
from ..tools import read_json_file, write_json_file
from ..tools import JsonConfig
_LOGGER = logging.getLogger(__name__)
RE_VOLUME = re.compile(MAP_VOLUME)
class Data(object):
class Data(JsonConfig):
"""Hold data for addons inside HassIO."""
def __init__(self, config):
"""Initialize data holder."""
self._file = FILE_HASSIO_ADDONS
self._data = {}
super().__init__(FILE_HASSIO_ADDONS, SCHEMA_ADDON_FILE)
self.config = config
self._cache = {}
self._repositories = {}
# init or load data
if self._file.is_file():
try:
self._data = read_json_file(self._file)
except (OSError, json.JSONDecodeError):
_LOGGER.warning("Can't read %s", self._file)
self._data = {}
# validate
try:
self._data = SCHEMA_ADDON_FILE(self._data)
except vol.Invalid as ex:
_LOGGER.error("Can't parse addons.json -> %s",
humanize_error(self._data, ex))
def save(self):
"""Store data to config file."""
# validate
try:
self._data = SCHEMA_ADDON_FILE(self._data)
except vol.Invalid as ex:
_LOGGER.error("Can't parse addons data -> %s",
humanize_error(self._data, ex))
return False
if not write_json_file(self._file, self._data):
_LOGGER.error("Can't store config in %s", self._file)
return False
return True
@property
def user(self):
"""Return local addon user data."""

View File

@ -6,11 +6,9 @@ import os
from pathlib import Path, PurePath
import voluptuous as vol
from voluptuous.humanize import humanize_error
from .const import FILE_HASSIO_CONFIG, HASSIO_DATA
from .tools import (
fetch_last_versions, write_json_file, read_json_file, validate_timezone)
from .tools import fetch_last_versions, JsonConfig, validate_timezone
from .validate import HASS_DEVICES
_LOGGER = logging.getLogger(__name__)
@ -19,7 +17,6 @@ DATETIME_FORMAT = "%Y%m%d %H:%M:%S"
HOMEASSISTANT_CONFIG = PurePath("homeassistant")
HOMEASSISTANT_LAST = 'homeassistant_last'
HOMEASSISTANT_DEVICES = 'homeassistant_devices'
HASSIO_SSL = PurePath("ssl")
HASSIO_LAST = 'hassio_last'
@ -50,7 +47,6 @@ SCHEMA_CONFIG = vol.Schema({
vol.Optional(API_ENDPOINT): vol.Coerce(str),
vol.Optional(TIMEZONE, default='UTC'): validate_timezone,
vol.Optional(HOMEASSISTANT_LAST): vol.Coerce(str),
vol.Optional(HOMEASSISTANT_DEVICES, default=[]): HASS_DEVICES,
vol.Optional(HASSIO_LAST): vol.Coerce(str),
vol.Optional(ADDONS_CUSTOM_LIST, default=[]): [vol.Url()],
vol.Optional(SECURITY_INITIALIZE, default=False): vol.Boolean(),
@ -61,48 +57,13 @@ SCHEMA_CONFIG = vol.Schema({
}, extra=vol.REMOVE_EXTRA)
class CoreConfig(object):
class CoreConfig(JsonConfig):
"""Hold all core config data."""
def __init__(self):
"""Initialize config object."""
super().__init__(FILE_HASSIO_CONFIG, SCHEMA_CONFIG)
self.arch = None
self._file = FILE_HASSIO_CONFIG
self._data = {}
# init or load data
if self._file.is_file():
try:
self._data = read_json_file(self._file)
except (OSError, json.JSONDecodeError):
_LOGGER.warning("Can't read %s", self._file)
self._data = {}
# validate data
if not self._validate_config():
self._data = SCHEMA_CONFIG({})
def _validate_config(self):
"""Validate config and return True or False."""
# validate data
try:
self._data = SCHEMA_CONFIG(self._data)
except vol.Invalid as ex:
_LOGGER.warning(
"Invalid config %s", humanize_error(self._data, ex))
return False
return True
def save(self):
"""Store data to config file."""
if not self._validate_config():
return False
if not write_json_file(self._file, self._data):
_LOGGER.error("Can't store config in %s", self._file)
return False
return True
async def fetch_update_infos(self, websession):
"""Read current versions from web."""
@ -150,22 +111,6 @@ class CoreConfig(object):
self._data[TIMEZONE] = value
self.save()
@property
def homeassistant_devices(self):
"""Return list of special device to map into homeassistant."""
return self._data[HOMEASSISTANT_DEVICES]
@homeassistant_devices.setter
def homeassistant_devices(self, value):
"""Set list of special device."""
self._data[HOMEASSISTANT_DEVICES] = value
self.save()
@property
def homeassistant_image(self):
"""Return docker homeassistant repository."""
return os.environ['HOMEASSISTANT_REPOSITORY']
@property
def last_homeassistant(self):
"""Actual version of homeassistant."""

View File

@ -24,6 +24,7 @@ RESTART_EXIT_CODE = 100
FILE_HASSIO_ADDONS = Path(HASSIO_DATA, "addons.json")
FILE_HASSIO_CONFIG = Path(HASSIO_DATA, "config.json")
FILE_HASSIO_HOMEASSISTANT = Path(HASSIO_DATA, "homeassistant.json")
SOCKET_DOCKER = Path("/var/run/docker.sock")
SOCKET_HC = Path("/var/run/hassio-hc.sock")

View File

@ -13,9 +13,10 @@ HASS_DOCKER_NAME = 'homeassistant'
class DockerHomeAssistant(DockerBase):
"""Docker hassio wrapper for HomeAssistant."""
def __init__(self, config, loop, dock):
def __init__(self, config, loop, dock, data):
"""Initialize docker homeassistant wrapper."""
super().__init__(config, loop, dock, image=config.homeassistant_image)
super().__init__(config, loop, dock, image=data.image)
self.data = data
@property
def name(self):
@ -25,11 +26,11 @@ class DockerHomeAssistant(DockerBase):
@property
def devices(self):
"""Create list of special device to map into docker."""
if not self.config.homeassistant_devices:
if not self.data.devices:
return
devices = []
for device in self.config.homeassistant_devices:
for device in self.data.devices:
devices.append("/dev/{0}:/dev/{0}:rwm".format(device))
return devices

58
hassio/homeassistant.py Normal file
View File

@ -0,0 +1,58 @@
"""HomeAssistant control object."""
import logging
import os
from .const import FILE_HASSIO_HOMEASSISTANT, ATTR_DEVICES, ATTR_IMAGE
from .dock.homeassistant import DockerHomeAssistant
from .tools import JsonConfig
from .validate import SCHEMA_HASS_CONFIG
class HomeAssistant(JsonConfig):
"""Hass core object for handle it."""
def __init__(self, config, loop, dock):
"""Initialize hass object."""
super().__init__(FILE_HASSIO_HOMEASSISTANT, SCHEMA_HASS_CONFIG)
self.config = config
self.loop = loop
async def prepare(self):
"""Prepare HomeAssistant object."""
@property
def version(self):
"""Return version of running homeassistant."""
return self.docker.version
@property
def last_version(self):
"""Return last available version of homeassistant."""
return self.config.last_homeassistant
@property
def image(self):
"""Return image name of hass containter."""
if ATTR_IMAGE in self._data:
return self._data[ATTR_IMAGE]
return os.environ['HOMEASSISTANT_REPOSITORY']
@image.setter
def image(self, value):
"""Set image name of hass containter."""
if value is None:
self._data.pop(ATTR_IMAGE, None)
else:
self._data[ATTR_IMAGE] = value
self.save()
@property
def devices(self):
"""Return extend device mapping."""
return self._data[ATTR_DEVICES]
@devices.setter
def devices(self, value):
"""Set extend device mapping."""
self._data[ATTR_DEVICES] = value
self.save()

View File

@ -9,6 +9,7 @@ import aiohttp
import async_timeout
import pytz
import voluptuous as vol
from voluptuous.humanize import humanize_error
from .const import URL_HASSIO_VERSION, URL_HASSIO_VERSION_BETA
@ -98,3 +99,44 @@ async def fetch_timezone(websession):
data = await request.json()
return data.get('time_zone', 'UTC')
class JsonConfig(object):
"""Hass core object for handle it."""
def __init__(self, json_file, schema):
"""Initialize hass object."""
self._file = json_file
self._schema = schema
self._data = {}
# init or load data
if self._file.is_file():
try:
self._data = read_json_file(self._file)
except (OSError, json.JSONDecodeError):
_LOGGER.warning("Can't read %s", self._file)
self._data = {}
# validate
try:
self._data = self._schema(self._data)
except vol.Invalid as ex:
_LOGGER.error("Can't parse %s -> %s",
self._file, humanize_error(self._data, ex))
def save(self):
"""Store data to config file."""
# validate
try:
self._data = self._schema(self._data)
except vol.Invalid as ex:
_LOGGER.error("Can't parse data -> %s",
humanize_error(self._data, ex))
return False
# write
if not write_json_file(self._file, self._data):
_LOGGER.error("Can't store config in %s", self._file)
return False
return True

View File

@ -1,6 +1,9 @@
"""Validate functions."""
import voluptuous as vol
from .const import ATTR_DEVICES, ATTR_IMAGE
NETWORK_PORT = vol.All(vol.Coerce(int), vol.Range(min=1, max=65535))
HASS_DEVICES = [vol.Match(r"^[^/]*$")]
@ -30,3 +33,9 @@ DOCKER_PORTS = vol.Schema({
vol.All(vol.Coerce(str), vol.Match(r"^\d+(?:/tcp|/udp)?$")):
convert_to_docker_ports,
})
SCHEMA_HASS_CONFIG = vol.Schema({
vol.Optional(ATTR_DEVICES, default=[]): HASS_DEVICES,
vol.Optional(ATTR_IMAGE): vol.Coerce(str)
})