mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-09 18:26:30 +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",
|
||||
"current": "CURRENT_VERSION",
|
||||
"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):
|
||||
"""Manage addons inside HassIO."""
|
||||
|
||||
def __init__(self, config, loop):
|
||||
def __init__(self, config, loop, dock):
|
||||
"""Initialize docker base wrapper."""
|
||||
self.config = config
|
||||
self.loop = loop
|
||||
self.dock = dock
|
||||
self.repo = AddonsRepo(config, loop)
|
||||
self.addons = AddonsConfig(config)
|
||||
self.dockers = {}
|
||||
|
@ -9,8 +9,8 @@ from voluptuous.humanize import humanize_error
|
||||
from ..const import (
|
||||
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_OPTIONS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE, BOOT_START,
|
||||
BOOT_STOP, BOOT_MANUAL)
|
||||
ATTR_OPTIONS, ATTR_PORTS, STARTUP_ONCE, STARTUP_AFTER, STARTUP_BEFORE,
|
||||
BOOT_AUTO, BOOT_MANUAL)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -25,7 +25,8 @@ SCHEMA_ADDON_CONFIG = vol.Schema({
|
||||
vol.Required(ATTR_STARTUP):
|
||||
vol.In([STARTUP_BEFORE, STARTUP_AFTER, STARTUP_ONCE]),
|
||||
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_SSL): vol.Boolean(),
|
||||
vol.Required(ATTR_MAP_DATA): vol.Boolean(),
|
||||
|
@ -39,10 +39,10 @@ ATTR_MAP_SSL = 'map_ssl'
|
||||
ATTR_MAP_DATA = 'map_data'
|
||||
ATTR_OPTIONS = 'options'
|
||||
ATTR_INSTALLED = 'installed'
|
||||
ATTR_STATE = 'state'
|
||||
|
||||
STARTUP_BEFORE = 'before'
|
||||
STARTUP_AFTER = 'after'
|
||||
STARTUP_ONCE = 'once'
|
||||
BOOT_START = 'start'
|
||||
BOOT_STOP = 'stop'
|
||||
BOOT_STOP = 'auto'
|
||||
BOOT_MANUAL = 'manual'
|
||||
|
@ -177,6 +177,30 @@ class DockerBase(object):
|
||||
|
||||
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):
|
||||
"""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):
|
||||
"""Update docker image."""
|
||||
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