mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-12 11:46:31 +00:00
Add first version of docker for addons
This commit is contained in:
parent
530f17d502
commit
ae003e5b76
10
API.md
10
API.md
@ -69,7 +69,15 @@ On success
|
|||||||
"version": "INSTALL_VERSION",
|
"version": "INSTALL_VERSION",
|
||||||
"current": "CURRENT_VERSION",
|
"current": "CURRENT_VERSION",
|
||||||
"beta": "true|false",
|
"beta": "true|false",
|
||||||
"addons": {}
|
"addons": [
|
||||||
|
{
|
||||||
|
"name": "xy bla",
|
||||||
|
"slug": "xy",
|
||||||
|
"version": "CURRENT_VERSION",
|
||||||
|
"installed": "none|INSTALL_VERSION",
|
||||||
|
"description": "description"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class AddonsManager(object):
|
class AddonsManager(object):
|
||||||
"""Manage addons inside HassIO."""
|
"""Manage addons inside HassIO."""
|
||||||
|
|
||||||
def __init__(self, config, loop):
|
def __init__(self, config, loop, dock):
|
||||||
"""Initialize docker base wrapper."""
|
"""Initialize docker base wrapper."""
|
||||||
self.config = config
|
self.config = config
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
|
self.dock = dock
|
||||||
self.repo = AddonsRepo(config, loop)
|
self.repo = AddonsRepo(config, loop)
|
||||||
self.addons = AddonsConfig(config)
|
self.addons = AddonsConfig(config)
|
||||||
self.dockers = {}
|
self.dockers = {}
|
||||||
|
@ -9,8 +9,8 @@ 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_MAP_DATA,
|
||||||
ATTR_OPTIONS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE, BOOT_START,
|
ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE,
|
||||||
BOOT_STOP, BOOT_MANUAL)
|
BOOT_AUTO, BOOT_MANUAL)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -25,7 +25,8 @@ 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_START, BOOT_STOP, BOOT_MANUAL]),
|
vol.IN([BOOT_AUTO, BOOT_MANUAL]),
|
||||||
|
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(),
|
||||||
vol.Required(ATTR_MAP_DATA): vol.Boolean(),
|
vol.Required(ATTR_MAP_DATA): vol.Boolean(),
|
||||||
|
@ -39,10 +39,10 @@ ATTR_MAP_SSL = 'map_ssl'
|
|||||||
ATTR_MAP_DATA = 'map_data'
|
ATTR_MAP_DATA = 'map_data'
|
||||||
ATTR_OPTIONS = 'options'
|
ATTR_OPTIONS = 'options'
|
||||||
ATTR_INSTALLED = 'installed'
|
ATTR_INSTALLED = 'installed'
|
||||||
|
ATTR_STATE = 'state'
|
||||||
|
|
||||||
STARTUP_BEFORE = 'before'
|
STARTUP_BEFORE = 'before'
|
||||||
STARTUP_AFTER = 'after'
|
STARTUP_AFTER = 'after'
|
||||||
STARTUP_ONCE = 'once'
|
STARTUP_ONCE = 'once'
|
||||||
BOOT_START = 'start'
|
BOOT_STOP = 'auto'
|
||||||
BOOT_STOP = 'stop'
|
|
||||||
BOOT_MANUAL = 'manual'
|
BOOT_MANUAL = 'manual'
|
||||||
|
@ -177,6 +177,30 @@ class DockerBase(object):
|
|||||||
|
|
||||||
self.container = None
|
self.container = None
|
||||||
|
|
||||||
|
async def remove(self):
|
||||||
|
"""Remove docker container."""
|
||||||
|
if self._lock.locked():
|
||||||
|
_LOGGER.error("Can't excute remove while a task is in progress")
|
||||||
|
return False
|
||||||
|
|
||||||
|
async with self._lock:
|
||||||
|
await self.loop.run_in_executor(None, self._remove)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _stop(self):
|
||||||
|
"""Stop/remove and remove docker container.
|
||||||
|
|
||||||
|
Need run inside executor.
|
||||||
|
"""
|
||||||
|
if self.container:
|
||||||
|
self._stop()
|
||||||
|
|
||||||
|
image = "{}:latest".format(self.image)
|
||||||
|
try:
|
||||||
|
self.dock.images.remove(image=image, force=True)
|
||||||
|
except docker.errors.DockerException as err:
|
||||||
|
_LOGGER.warning("Can't remove image %s -> %s.", image, err)
|
||||||
|
|
||||||
async def update(self, tag):
|
async def update(self, tag):
|
||||||
"""Update a docker image.
|
"""Update a docker image.
|
||||||
|
|
||||||
|
63
hassio/dock/addon.py
Normal file
63
hassio/dock/addon.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
"""Init file for HassIO addon docker object."""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import docker
|
||||||
|
|
||||||
|
from . import DockerBase
|
||||||
|
from ..const import ATTR_SLUG, ATTR_PORTS
|
||||||
|
from ..tools import get_version_from_env
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
HASS_DOCKER_NAME = 'homeassistant'
|
||||||
|
|
||||||
|
|
||||||
|
class DockerHomeAssistant(DockerBase):
|
||||||
|
"""Docker hassio wrapper for HomeAssistant."""
|
||||||
|
|
||||||
|
def __init__(self, config, loop, dock, addon_config, image):
|
||||||
|
"""Initialize docker homeassistant wrapper."""
|
||||||
|
super().__init__(config, loop, dock, image=image)
|
||||||
|
self.addon_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def docker_name(self):
|
||||||
|
"""Return name of docker container."""
|
||||||
|
return "addon_{}".format(self.addon_config[ATTR_SLUG])
|
||||||
|
|
||||||
|
def _run(self):
|
||||||
|
"""Run docker image.
|
||||||
|
|
||||||
|
Need run inside executor.
|
||||||
|
"""
|
||||||
|
if self._is_running():
|
||||||
|
return
|
||||||
|
|
||||||
|
# cleanup old container
|
||||||
|
self._stop()
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.container = self.dock.containers.run(
|
||||||
|
self.image,
|
||||||
|
name=self.docker_name,
|
||||||
|
detach=True,
|
||||||
|
network_mode='bridge',
|
||||||
|
ports=self.addon_config[ATTR_PORTS],
|
||||||
|
restart_policy={
|
||||||
|
"Name": "on-failure",
|
||||||
|
"MaximumRetryCount": 10,
|
||||||
|
},
|
||||||
|
volumes={
|
||||||
|
self.config.path_config_docker:
|
||||||
|
{'bind': '/config', 'mode': 'rw'},
|
||||||
|
self.config.path_ssl_docker:
|
||||||
|
{'bind': '/ssl', 'mode': 'rw'},
|
||||||
|
})
|
||||||
|
|
||||||
|
self.version = get_version_from_env(
|
||||||
|
self.container.attrs['Config']['Env'])
|
||||||
|
except docker.errors.DockerException as err:
|
||||||
|
_LOGGER.error("Can't run %s -> %s.", self.image, err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
@ -27,3 +27,7 @@ class DockerSupervisor(DockerBase):
|
|||||||
async def update(self, tag):
|
async def update(self, tag):
|
||||||
"""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):
|
||||||
|
"""Remove docker image."""
|
||||||
|
raise RuntimeError("Not support on supervisor docker container!")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user