diff --git a/hassio_api/hassio/config.py b/hassio_api/hassio/config.py index f79efdd69..873a7eadd 100644 --- a/hassio_api/hassio/config.py +++ b/hassio_api/hassio/config.py @@ -6,6 +6,7 @@ import os from .const import ( FILE_HASSIO_CONFIG, HOMEASSISTANT_TAG, HOMEASSISTANT_IMAGE, HOMEASSISTANT_SSL, HOMEASSISTANT_CONFIG, HASSIO_SHARE) +from .tools import fetch_current_versions _LOGGER = logging.getLogger(__name__) @@ -15,8 +16,8 @@ class CoreConfig(object): def __init__(self, config_file=FILE_HASSIO_CONFIG): """Initialize config object.""" - self._data = {} self._filename = config_file + self._data = {} # init or load data if os.path.isfile(self._filename): diff --git a/hassio_api/hassio/dock/__init__.py b/hassio_api/hassio/dock/__init__.py index 8e3751558..5ff030d34 100644 --- a/hassio_api/hassio/dock/__init__.py +++ b/hassio_api/hassio/dock/__init__.py @@ -1,4 +1,5 @@ """Init file for HassIO docker object.""" +from contextlib import suppress import logging import docker @@ -25,14 +26,14 @@ class DockerBase(object): """Return name of docker container.""" return None - def install(self, tag='latest'): + def install(self, tag): """Pull docker image. Return a Future. """ return self.loop.run_in_executor(None, self._install, tag) - def _install(self, tag='latest'): + def _install(self, tag): """Pull docker image. Need run inside executor. @@ -41,8 +42,8 @@ class DockerBase(object): _LOGGER.info("Pull image %s tag %s.", self.image, tag) image = self.dock.images.pull("{}:{}".format(self.image, tag)) - if tag != 'latest': - image.tag(self.image, tag='latest') + image.tag(self.image, tag='latest') + self.version = get_version_from_env(image.attrs['Config']['Env']) except docker.errors.APIError as err: _LOGGER.error("Can't install %s:%s -> %s.", self.image, tag, err) return False @@ -67,6 +68,8 @@ class DockerBase(object): self.container.attrs['Config']['Env']) except docker.errors.DockerException: return False + + self.container.reload() return self.container.status == 'running' def attach(self): @@ -103,3 +106,51 @@ class DockerBase(object): Need run inside executor. """ raise NotImplementedError() + + def stop(self): + """Stop/remove docker container. + + Return a Future. + """ + return self.loop.run_in_executor(None, self._stop) + + def _stop(self): + """Stop/remove and remove docker container. + + Need run inside executor. + """ + if not self.container: + return + + self.container.reload() + if self.container.status == 'running' + with suppress(docker.errors.DockerException): + self.container.stop() + + with suppress(docker.errors.DockerException): + self.container.remove(force=True) + + self.container = None + + def update(self, tag): + """Update a docker image. + + Return a Future. + """ + return self.loop.run_in_executor(None, self._update, tag) + + def _update(self, tag): + """Update a docker image. + + Need run inside executor. + """ + if self.container: + self._stop() + + old_image = "{}:{}".format(self.image, self.version) + if self._install(tag): + try: + self.dock.images.remove(image=old_image, force=True) + except docker.errors.DockerException as err: + _LOGGER.warning( + "Can't remove old image %s -> %s.", old_image, err) diff --git a/hassio_api/hassio/dock/supervisor.py b/hassio_api/hassio/dock/supervisor.py index 72a45a538..c932e9d04 100644 --- a/hassio_api/hassio/dock/supervisor.py +++ b/hassio_api/hassio/dock/supervisor.py @@ -16,6 +16,14 @@ class DockerSupervisor(DockerBase): """Run docker image.""" raise RuntimeError("Not support on supervisor docker container!") - async def install(self, tag='latest'): + async def install(self, tag): """Pull docker image.""" raise RuntimeError("Not support on supervisor docker container!") + + async def stop(self): + """Stop/remove docker container.""" + raise RuntimeError("Not support on supervisor docker container!") + + async def update(self, tag): + """Update docker image.""" + raise RuntimeError("Not support on supervisor docker container!")