diff --git a/hassio/config.py b/hassio/config.py index 8f47f6079..85fc51c4a 100644 --- a/hassio/config.py +++ b/hassio/config.py @@ -14,6 +14,7 @@ HOMEASSISTANT_CURRENT = 'homeassistant_current' HASSIO_SSL = "{}/ssl" HASSIO_CURRENT = 'hassio_current' +HASSIO_CLEANUP = 'hassio_cleanup' ADDONS_REPO = "{}/addons" ADDONS_DATA = "{}/addons_data" @@ -87,6 +88,20 @@ class CoreConfig(Config): """Set beta upstream mode.""" self._data[UPSTREAM_BETA] = bool(value) + @property + def cleanup_hassio(self): + """Return Version they need to cleanup.""" + return self._data.get(HASSIO_CLEANUP) + + @cleanup_hassio.setter + def cleanup_hassio(self, version): + """Set or remove cleanup flag.""" + if version is None: + self._data.pop(HASSIO_CLEANUP, None) + else: + self._data[HASSIO_CLEANUP] = version + self.save() + @property def homeassistant_image(self): """Return docker homeassistant repository.""" diff --git a/hassio/core.py b/hassio/core.py index a833ac720..2587a7bb2 100644 --- a/hassio/core.py +++ b/hassio/core.py @@ -50,6 +50,7 @@ class HassIO(object): """Setup HassIO orchestration.""" # supervisor await self.supervisor.attach() + await self.supervisor.cleanup() # hostcontroll host_info = await self.host_controll.info() diff --git a/hassio/dock/__init__.py b/hassio/dock/__init__.py index e4401fb74..07b25108a 100644 --- a/hassio/dock/__init__.py +++ b/hassio/dock/__init__.py @@ -209,10 +209,7 @@ class DockerBase(object): return True async def update(self, tag): - """Update a docker image. - - Return a Future. - """ + """Update a docker image.""" if self._lock.locked(): _LOGGER.error("Can't excute update while a task is in progress") return False diff --git a/hassio/dock/supervisor.py b/hassio/dock/supervisor.py index c456b85d5..18a900fce 100644 --- a/hassio/dock/supervisor.py +++ b/hassio/dock/supervisor.py @@ -1,6 +1,8 @@ """Init file for HassIO docker object.""" import os +import docker + from . import DockerBase @@ -19,27 +21,43 @@ class DockerSupervisor(DockerBase): return os.environ['SUPERVISOR_NAME'] async def update(self, tag): - """Update a supervisor docker image. - - Return a Future. - """ + """Update a supervisor docker image.""" if self._lock.locked(): _LOGGER.error("Can't excute update while a task is in progress") return False + _LOGGER.info("Update supervisor docker to %s:%s", self.image, tag) + old_version = self.version + async with self._lock: - if await self.loop.run_in_executor(None, self._update, tag): + if await self.loop.run_in_executor(None, self._install, tag): + self.config.hassio_cleanup = old_version self.loop.create_task(self.hassio.stop(RESTART_EXIT_CODE)) - def _update(self, tag): - """Update a docker image. + async def cleanup(self): + """Check if old supervisor version exists and cleanup.""" + if not self.config.hassio_cleanup: + return + + async with self._lock: + if await self.loop.run_in_executor(None, self._cleanup): + self.config.hassio_cleanup = None + + def _cleanup(self): + """Remove old image. Need run inside executor. """ - _LOGGER.info("Update supervisor docker to %s:%s", self.image, tag) + old_image = "{}:{}".format(self.image, self.config.hassio_cleanup) - # update docker image - return self._install(tag) + _LOGGER.info("Old supervisor docker found %s", old_image) + 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) + return False + + return True async def run(self): """Run docker image."""