Add first part of api

This commit is contained in:
Pascal Vizeli 2017-04-12 00:06:17 +02:00
parent 14500d3ac4
commit 3ef76a4ada
7 changed files with 126 additions and 8 deletions

View File

@ -112,3 +112,19 @@ class AddonManager(object):
return False return False
return True return True
async def update_addon(self, addon, version=None):
"""Update addon."""
if self.addons.is_installed(addon):
_LOGGER.error("Addon %s is not installed.", addon)
return False
if addon not in self.dockers:
_LOGGER.error("No docker found for addon %s.", addon)
return False
version = version or self.addons.get_version(addon)
if not await self.dockers[addon].update(version):
return False
return True

View File

@ -9,7 +9,7 @@ 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_MAP_DATA,
ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE, ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE,
BOOT_AUTO, BOOT_MANUAL, DOCKER_REPO) BOOT_AUTO, BOOT_MANUAL, DOCKER_REPO, ATTR_INSTALLED)
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__)
@ -65,6 +65,26 @@ class AddonsConfig(Config):
"""Return a list of installed addons.""" """Return a list of installed addons."""
return self._data.keys() return self._data.keys()
@property
def list_all(self):
"""Return a list of available addons."""
return self._addons_data.keys()
@property
def list(self):
"""Return a list of available addons."""
data = []
for addon, values in self._addons.items():
data.append({
ATTR_NAME: values[ATTR_NAME],
ATTR_SLUG: values[ATTR_SLUG],
ATTR_DESCRIPTON: values[ATTR_DESCRIPTON],
ATTR_VERSION: values[ATTR_VERSION],
ATTR_INSTALLED: self._data.get(addon, {}).get(ATTR_VERSION),
})
return data
def exists_addon(self, addon): def exists_addon(self, addon):
"""Return True if a addon exists.""" """Return True if a addon exists."""
return addon in self._addons_data return addon in self._addons_data
@ -73,6 +93,10 @@ class AddonsConfig(Config):
"""Return True if a addon is installed.""" """Return True if a addon is installed."""
return addon in self._data return addon in self._data
def version_installed(self, addon):
"""Return installed version."""
return self._data[addon][ATTR_VERSION]
def set_install_addon(self, addon, version): def set_install_addon(self, addon, version):
"""Set addon as installed.""" """Set addon as installed."""
self._data[addon] = { self._data[addon] = {
@ -93,12 +117,27 @@ class AddonsConfig(Config):
opt.update(self._data[addon][ATTR_OPTIONS]) opt.update(self._data[addon][ATTR_OPTIONS])
return opt return opt
def get_boot(self, addon):
"""Return boot config with prio local settings."""
if ATTR_BOOT in self._data[addon]:
return self._data[addon][ATTR_BOOT]
return self._addons_data[addon][ATTR_BOOT]
def get_image(self, addon): def get_image(self, addon):
"""Return name of addon docker image.""" """Return name of addon docker image."""
return "{}/{}-addon-{}".format( return "{}/{}-addon-{}".format(
DOCKER_REPO, self.config.hassio_arch, DOCKER_REPO, self.config.hassio_arch,
self._addons_data[addon][ATTR_SLUG]) self._addons_data[addon][ATTR_SLUG])
def get_name(self, addon):
"""Return name of addon."""
return self._addons_data[addon][ATTR_NAME]
def get_description(self, addon):
"""Return description of addon."""
return self._addons_data[addon][ATTR_DESCRIPTON]
def get_version(self, addon): def get_version(self, addon):
"""Return version of addon.""" """Return version of addon."""
return self._addons_data[addon][ATTR_VERSION] return self._addons_data[addon][ATTR_VERSION]

View File

@ -3,10 +3,11 @@ import logging
from aiohttp import web from aiohttp import web
from .addons import APIAddonManager
from .homeassistant import APIHomeAssistant
from .host import APIHost from .host import APIHost
from .network import APINetwork from .network import APINetwork
from .supervisor import APISupervisor from .supervisor import APISupervisor
from .homeassistant import APIHomeAssistant
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -40,9 +41,10 @@ class RestAPI(object):
self.webapp.router.add_get('/network/info', api_net.info) self.webapp.router.add_get('/network/info', api_net.info)
self.webapp.router.add_get('/network/options', api_net.options) self.webapp.router.add_get('/network/options', api_net.options)
def register_supervisor(self, host_controll): def register_supervisor(self, host_controll, addon_manager):
"""Register supervisor function.""" """Register supervisor function."""
api_supervisor = APISupervisor(self.config, self.loop, host_controll) api_supervisor = APISupervisor(
self.config, self.loop, host_controll, addon_manager)
self.webapp.router.add_get('/supervisor/ping', api_supervisor.ping) self.webapp.router.add_get('/supervisor/ping', api_supervisor.ping)
self.webapp.router.add_get('/supervisor/info', api_supervisor.info) self.webapp.router.add_get('/supervisor/info', api_supervisor.info)
@ -57,6 +59,21 @@ class RestAPI(object):
self.webapp.router.add_get('/homeassistant/info', api_hass.info) self.webapp.router.add_get('/homeassistant/info', api_hass.info)
self.webapp.router.add_get('/homeassistant/update', api_hass.update) self.webapp.router.add_get('/homeassistant/update', api_hass.update)
def register_addons(self, addon_manager):
"""Register homeassistant function."""
api_addons = APIAddons(self.config, self.loop, addon_manager)
self.webapp.router.add_get('/addons/{addon}/info', api_addons.info)
self.webapp.router.add_get(
'/addons/{addon}/install', api_addons.install)
self.webapp.router.add_get(
'/addons/{addon}/uninstall', api_addons.uninstall)
self.webapp.router.add_get('/addons/{addon}/start', api_addons.start)
self.webapp.router.add_get('/addons/{addon}/stop', api_addons.stop)
self.webapp.router.add_get('/addons/{addon}/update', api_addons.update)
self.webapp.router.add_get(
'/addons/{addon}/options', api_addons.options)
async def start(self): async def start(self):
"""Run rest api webserver.""" """Run rest api webserver."""
self._handler = self.webapp.make_handler(loop=self.loop) self._handler = self.webapp.make_handler(loop=self.loop)

42
hassio/api/addons.py Normal file
View File

@ -0,0 +1,42 @@
"""Init file for HassIO homeassistant rest api."""
import asyncio
import logging
import voluptuous as vol
from .util import api_process, api_validate
from ..const import ATTR_VERSION, ATTR_CURRENT
_LOGGER = logging.getLogger(__name__)
SCHEMA_VERSION = vol.Schema({
vol.Optional(ATTR_VERSION): vol.Coerce(str),
})
class APIAddons(object):
"""Handle rest api for addons functions."""
def __init__(self, config, loop, addon_manager):
"""Initialize homeassistant rest api part."""
self.config = config
self.loop = loop
self.addon_manager = addon_manager
@api_process
async def info(self, request):
"""Return host information."""
@api_process
async def update(self, request):
"""Update host OS."""
body = await api_validate(SCHEMA_VERSION, request)
version = body.get(ATTR_VERSION, self.config.current_homeassistant)
if self.dock_hass.in_progress:
raise RuntimeError("Other task is in progress.")
if version == self.dock_hass.version:
raise RuntimeError("%s is already in use.", version)
return await asyncio.shield(self.dock_hass.update(version))

View File

@ -4,7 +4,8 @@ import logging
import voluptuous as vol import voluptuous as vol
from .util import api_process, api_process_hostcontroll, api_validate from .util import api_process, api_process_hostcontroll, api_validate
from ..const import ATTR_VERSION, ATTR_CURRENT, ATTR_BETA, HASSIO_VERSION from ..const import (
ATTR_ADDONS, ATTR_VERSION, ATTR_CURRENT, ATTR_BETA, HASSIO_VERSION)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -21,11 +22,12 @@ SCHEMA_VERSION = vol.Schema({
class APISupervisor(object): class APISupervisor(object):
"""Handle rest api for supervisor functions.""" """Handle rest api for supervisor functions."""
def __init__(self, config, loop, host_controll): def __init__(self, config, loop, host_controll, addon_manager):
"""Initialize supervisor rest api part.""" """Initialize supervisor rest api part."""
self.config = config self.config = config
self.loop = loop self.loop = loop
self.host_controll = host_controll self.host_controll = host_controll
self.addon_manager = addon_manager
@api_process @api_process
async def ping(self, request): async def ping(self, request):
@ -39,8 +41,8 @@ class APISupervisor(object):
ATTR_VERSION: HASSIO_VERSION, ATTR_VERSION: HASSIO_VERSION,
ATTR_CURRENT: self.config.current_hassio, ATTR_CURRENT: self.config.current_hassio,
ATTR_BETA: self.config.upstream_beta, ATTR_BETA: self.config.upstream_beta,
ATTR_ADDONS: self.addon_manager.addons.list,
} }
return info return info
@api_process @api_process

View File

@ -27,6 +27,7 @@ JSON_MESSAGE = 'message'
RESULT_ERROR = 'error' RESULT_ERROR = 'error'
RESULT_OK = 'ok' RESULT_OK = 'ok'
ATTR_ADDONS = 'addons'
ATTR_VERSION = 'version' ATTR_VERSION = 'version'
ATTR_CURRENT = 'current' ATTR_CURRENT = 'current'
ATTR_BETA = 'beta' ATTR_BETA = 'beta'

View File

@ -60,8 +60,9 @@ class HassIO(object):
# rest api views # rest api views
self.api.register_host(self.host_controll) self.api.register_host(self.host_controll)
self.api.register_network(self.host_controll) self.api.register_network(self.host_controll)
self.api.register_supervisor(self.host_controll) self.api.register_supervisor(self.host_controll, self.addon_manager)
self.api.register_homeassistant(self.homeassistant) self.api.register_homeassistant(self.homeassistant)
self.api.register_addons(self.addon_manager)
# schedule update info tasks # schedule update info tasks
self.scheduler.register_task( self.scheduler.register_task(