mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-11-28 20:18:06 +00:00
Don't relay on latest with HA/Addons (#1175)
* Don't relay on latest with HA/Addons * Fix latest on install * Revert some options * Fix attach * migrate to new version handling * Fix thread * Fix is running * Allow wait * debug code * Fix debug value * Fix list * Fix regex * Some better log output * Fix logic * Improve cleanup handling * Fix bug * Cleanup old code * Improve version handling * Fix the way to attach
This commit is contained in:
@@ -68,11 +68,13 @@ class DockerInterface(CoreSysAttributes):
|
||||
return self.lock.locked()
|
||||
|
||||
@process_lock
|
||||
def install(self, tag: str, image: Optional[str] = None):
|
||||
def install(self, tag: str, image: Optional[str] = None, latest: bool = False):
|
||||
"""Pull docker image."""
|
||||
return self.sys_run_in_executor(self._install, tag, image)
|
||||
return self.sys_run_in_executor(self._install, tag, image, latest)
|
||||
|
||||
def _install(self, tag: str, image: Optional[str] = None) -> None:
|
||||
def _install(
|
||||
self, tag: str, image: Optional[str] = None, latest: bool = False
|
||||
) -> None:
|
||||
"""Pull Docker image.
|
||||
|
||||
Need run inside executor.
|
||||
@@ -80,12 +82,12 @@ class DockerInterface(CoreSysAttributes):
|
||||
image = image or self.image
|
||||
image = image.partition(":")[0] # remove potential tag
|
||||
|
||||
_LOGGER.info("Pull image %s tag %s.", image, tag)
|
||||
try:
|
||||
_LOGGER.info("Pull image %s tag %s.", image, tag)
|
||||
docker_image = self.sys_docker.images.pull(f"{image}:{tag}")
|
||||
|
||||
_LOGGER.info("Tag image %s with version %s as latest", image, tag)
|
||||
docker_image.tag(image, tag="latest")
|
||||
if latest:
|
||||
_LOGGER.info("Tag image %s with version %s as latest", image, tag)
|
||||
docker_image.tag(image, tag="latest")
|
||||
except docker.errors.APIError as err:
|
||||
_LOGGER.error("Can't install %s:%s -> %s.", image, tag, err)
|
||||
raise DockerAPIError() from None
|
||||
@@ -123,7 +125,6 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
docker_image = self.sys_docker.images.get(self.image)
|
||||
except docker.errors.DockerException:
|
||||
return False
|
||||
|
||||
@@ -131,28 +132,24 @@ class DockerInterface(CoreSysAttributes):
|
||||
if docker_container.status != "running":
|
||||
return False
|
||||
|
||||
# we run on an old image, stop and start it
|
||||
if docker_container.image.id != docker_image.id:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@process_lock
|
||||
def attach(self):
|
||||
def attach(self, tag: str):
|
||||
"""Attach to running Docker container."""
|
||||
return self.sys_run_in_executor(self._attach)
|
||||
return self.sys_run_in_executor(self._attach, tag)
|
||||
|
||||
def _attach(self) -> None:
|
||||
def _attach(self, tag: str) -> None:
|
||||
"""Attach to running docker container.
|
||||
|
||||
Need run inside executor.
|
||||
"""
|
||||
try:
|
||||
if self.image:
|
||||
self._meta = self.sys_docker.images.get(self.image).attrs
|
||||
with suppress(docker.errors.DockerException):
|
||||
self._meta = self.sys_docker.containers.get(self.name).attrs
|
||||
except docker.errors.DockerException:
|
||||
pass
|
||||
|
||||
with suppress(docker.errors.DockerException):
|
||||
if not self._meta and self.image:
|
||||
self._meta = self.sys_docker.images.get(f"{self.image}:{tag}").attrs
|
||||
|
||||
# Successfull?
|
||||
if not self._meta:
|
||||
@@ -250,11 +247,15 @@ class DockerInterface(CoreSysAttributes):
|
||||
self._meta = None
|
||||
|
||||
@process_lock
|
||||
def update(self, tag: str, image: Optional[str] = None) -> Awaitable[None]:
|
||||
def update(
|
||||
self, tag: str, image: Optional[str] = None, latest: bool = False
|
||||
) -> Awaitable[None]:
|
||||
"""Update a Docker image."""
|
||||
return self.sys_run_in_executor(self._update, tag, image)
|
||||
|
||||
def _update(self, tag: str, image: Optional[str] = None) -> None:
|
||||
def _update(
|
||||
self, tag: str, image: Optional[str] = None, latest: bool = False
|
||||
) -> None:
|
||||
"""Update a docker image.
|
||||
|
||||
Need run inside executor.
|
||||
@@ -266,14 +267,11 @@ class DockerInterface(CoreSysAttributes):
|
||||
)
|
||||
|
||||
# Update docker image
|
||||
self._install(tag, image)
|
||||
self._install(tag, image, latest)
|
||||
|
||||
# Stop container & cleanup
|
||||
with suppress(DockerAPIError):
|
||||
try:
|
||||
self._stop()
|
||||
finally:
|
||||
self._cleanup()
|
||||
self._stop()
|
||||
|
||||
def logs(self) -> Awaitable[bytes]:
|
||||
"""Return Docker logs of container.
|
||||
@@ -308,13 +306,13 @@ class DockerInterface(CoreSysAttributes):
|
||||
Need run inside executor.
|
||||
"""
|
||||
try:
|
||||
latest = self.sys_docker.images.get(self.image)
|
||||
origin = self.sys_docker.images.get(f"{self.image}:{self.version}")
|
||||
except docker.errors.DockerException:
|
||||
_LOGGER.warning("Can't find %s for cleanup", self.image)
|
||||
raise DockerAPIError() from None
|
||||
|
||||
for image in self.sys_docker.images.list(name=self.image):
|
||||
if latest.id == image.id:
|
||||
if origin.id == image.id:
|
||||
continue
|
||||
|
||||
with suppress(docker.errors.DockerException):
|
||||
|
||||
Reference in New Issue
Block a user