Catch requests with docker exceptions (#1926)

This commit is contained in:
Pascal Vizeli 2020-08-15 23:01:10 +02:00 committed by GitHub
parent 22a7931a7c
commit fe6634551a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 60 additions and 57 deletions

View File

@ -8,6 +8,7 @@ from typing import Any, Dict, Optional
import attr import attr
import docker import docker
from packaging import version as pkg_version from packaging import version as pkg_version
import requests
from ..const import DNS_SUFFIX, DOCKER_IMAGE_DENYLIST, SOCKET_DOCKER from ..const import DNS_SUFFIX, DOCKER_IMAGE_DENYLIST, SOCKET_DOCKER
from ..exceptions import DockerAPIError from ..exceptions import DockerAPIError
@ -128,7 +129,7 @@ class DockerAPI:
container = self.docker.containers.create( container = self.docker.containers.create(
f"{image}:{version}", use_config_proxy=False, **kwargs f"{image}:{version}", use_config_proxy=False, **kwargs
) )
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't create container from %s: %s", name, err) _LOGGER.error("Can't create container from %s: %s", name, err)
raise DockerAPIError() raise DockerAPIError()
@ -146,12 +147,12 @@ class DockerAPI:
# Run container # Run container
try: try:
container.start() container.start()
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't start %s: %s", name, err) _LOGGER.error("Can't start %s: %s", name, err)
raise DockerAPIError() raise DockerAPIError()
# Update metadata # Update metadata
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
container.reload() container.reload()
return container return container
@ -184,13 +185,13 @@ class DockerAPI:
result = container.wait() result = container.wait()
output = container.logs(stdout=stdout, stderr=stderr) output = container.logs(stdout=stdout, stderr=stderr)
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't execute command: %s", err) _LOGGER.error("Can't execute command: %s", err)
raise DockerAPIError() raise DockerAPIError()
finally: finally:
# cleanup container # cleanup container
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
container.remove(force=True) container.remove(force=True)
return CommandReturn(result.get("StatusCode"), output) return CommandReturn(result.get("StatusCode"), output)

View File

@ -334,8 +334,7 @@ class DockerAddon(DockerInterface):
_LOGGER.warning("%s run with disabled protected mode!", self.addon.name) _LOGGER.warning("%s run with disabled protected mode!", self.addon.name)
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(
@ -396,7 +395,7 @@ class DockerAddon(DockerInterface):
# Update meta data # Update meta data
self._meta = image.attrs self._meta = image.attrs
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't build %s:%s: %s", self.image, tag, err) _LOGGER.error("Can't build %s:%s: %s", self.image, tag, err)
raise DockerAPIError() raise DockerAPIError()
@ -414,7 +413,7 @@ class DockerAddon(DockerInterface):
""" """
try: try:
image = self.sys_docker.api.get_image(f"{self.image}:{self.version}") image = self.sys_docker.api.get_image(f"{self.image}:{self.version}")
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't fetch image %s: %s", self.image, err) _LOGGER.error("Can't fetch image %s: %s", self.image, err)
raise DockerAPIError() raise DockerAPIError()
@ -423,7 +422,7 @@ class DockerAddon(DockerInterface):
with tar_file.open("wb") as write_tar: with tar_file.open("wb") as write_tar:
for chunk in image: for chunk in image:
write_tar.write(chunk) write_tar.write(chunk)
except (OSError, requests.exceptions.ReadTimeout) as err: except (OSError, requests.RequestException) as err:
_LOGGER.error("Can't write tar file %s: %s", tar_file, err) _LOGGER.error("Can't write tar file %s: %s", tar_file, err)
raise DockerAPIError() raise DockerAPIError()
@ -471,7 +470,7 @@ class DockerAddon(DockerInterface):
# Load needed docker objects # Load needed docker objects
container = self.sys_docker.containers.get(self.name) container = self.sys_docker.containers.get(self.name)
socket = container.attach_socket(params={"stdin": 1, "stream": 1}) socket = container.attach_socket(params={"stdin": 1, "stream": 1})
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't attach to %s stdin: %s", self.name, err) _LOGGER.error("Can't attach to %s stdin: %s", self.name, err)
raise DockerAPIError() raise DockerAPIError()

View File

@ -1,12 +1,10 @@
"""Audio docker object.""" """Audio docker object."""
from contextlib import suppress
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Dict from typing import Dict
from ..const import ENV_TIME, MACHINE_ID from ..const import ENV_TIME, MACHINE_ID
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import DockerAPIError
from .interface import DockerInterface from .interface import DockerInterface
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -56,8 +54,7 @@ class DockerAudio(DockerInterface, CoreSysAttributes):
return return
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(

View File

@ -1,10 +1,8 @@
"""HA Cli docker object.""" """HA Cli docker object."""
from contextlib import suppress
import logging import logging
from ..const import ENV_TIME, ENV_TOKEN from ..const import ENV_TIME, ENV_TOKEN
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import DockerAPIError
from .interface import DockerInterface from .interface import DockerInterface
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -34,8 +32,7 @@ class DockerCli(DockerInterface, CoreSysAttributes):
return return
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(

View File

@ -1,10 +1,8 @@
"""DNS docker object.""" """DNS docker object."""
from contextlib import suppress
import logging import logging
from ..const import ENV_TIME from ..const import ENV_TIME
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import DockerAPIError
from .interface import DockerInterface from .interface import DockerInterface
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -34,8 +32,7 @@ class DockerDNS(DockerInterface, CoreSysAttributes):
return return
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(

View File

@ -1,10 +1,10 @@
"""Init file for Supervisor Docker object.""" """Init file for Supervisor Docker object."""
from contextlib import suppress
from ipaddress import IPv4Address from ipaddress import IPv4Address
import logging import logging
from typing import Awaitable, Dict, Optional from typing import Awaitable, Dict, Optional
import docker import docker
import requests
from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_OLD, LABEL_MACHINE, MACHINE_ID from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_OLD, LABEL_MACHINE, MACHINE_ID
from ..exceptions import DockerAPIError from ..exceptions import DockerAPIError
@ -98,8 +98,7 @@ class DockerHomeAssistant(DockerInterface):
return return
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(
@ -167,8 +166,10 @@ class DockerHomeAssistant(DockerInterface):
docker_image = self.sys_docker.images.get( docker_image = self.sys_docker.images.get(
f"{self.image}:{self.sys_homeassistant.version}" f"{self.image}:{self.sys_homeassistant.version}"
) )
except docker.errors.DockerException: except docker.errors.NotFound:
return False return False
except (docker.errors.DockerException, requests.RequestException):
return DockerAPIError()
# we run on an old image, stop and start it # we run on an old image, stop and start it
if docker_container.image.id != docker_image.id: if docker_container.image.id != docker_image.id:

View File

@ -5,6 +5,7 @@ import logging
from typing import Any, Awaitable, Dict, List, Optional from typing import Any, Awaitable, Dict, List, Optional
import docker import docker
import requests
from . import CommandReturn from . import CommandReturn
from ..const import LABEL_ARCH, LABEL_VERSION from ..const import LABEL_ARCH, LABEL_VERSION
@ -107,6 +108,10 @@ class DockerInterface(CoreSysAttributes):
free_space, free_space,
) )
raise DockerAPIError() raise DockerAPIError()
except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Unknown error with %s:%s -> %s", image, tag, err)
self.sys_capture_exception(err)
raise DockerAPIError()
else: else:
self._meta = docker_image.attrs self._meta = docker_image.attrs
@ -119,7 +124,7 @@ class DockerInterface(CoreSysAttributes):
Need run inside executor. Need run inside executor.
""" """
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
self.sys_docker.images.get(f"{self.image}:{self.version}") self.sys_docker.images.get(f"{self.image}:{self.version}")
return True return True
return False return False
@ -138,8 +143,10 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except docker.errors.NotFound:
return False return False
except (docker.errors.DockerException, requests.RequestException):
raise DockerAPIError()
return docker_container.status == "running" return docker_container.status == "running"
@ -153,10 +160,10 @@ class DockerInterface(CoreSysAttributes):
Need run inside executor. Need run inside executor.
""" """
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
self._meta = self.sys_docker.containers.get(self.name).attrs self._meta = self.sys_docker.containers.get(self.name).attrs
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
if not self._meta and self.image: if not self._meta and self.image:
self._meta = self.sys_docker.images.get(f"{self.image}:{tag}").attrs self._meta = self.sys_docker.images.get(f"{self.image}:{tag}").attrs
@ -189,16 +196,18 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except docker.errors.NotFound:
return
except (docker.errors.DockerException, requests.RequestException):
raise DockerAPIError() raise DockerAPIError()
if docker_container.status == "running": if docker_container.status == "running":
_LOGGER.info("Stop %s application", self.name) _LOGGER.info("Stop %s application", self.name)
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
docker_container.stop(timeout=self.timeout) docker_container.stop(timeout=self.timeout)
if remove_container: if remove_container:
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
_LOGGER.info("Clean %s application", self.name) _LOGGER.info("Clean %s application", self.name)
docker_container.remove(force=True) docker_container.remove(force=True)
@ -214,13 +223,14 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
_LOGGER.error("%s not found for starting up", self.name)
raise DockerAPIError() raise DockerAPIError()
_LOGGER.info("Start %s", self.name) _LOGGER.info("Start %s", self.name)
try: try:
docker_container.start() docker_container.start()
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't start %s: %s", self.name, err) _LOGGER.error("Can't start %s: %s", self.name, err)
raise DockerAPIError() raise DockerAPIError()
@ -249,7 +259,7 @@ class DockerInterface(CoreSysAttributes):
image=f"{self.image}:{self.version}", force=True image=f"{self.image}:{self.version}", force=True
) )
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.warning("Can't remove image %s: %s", self.image, err) _LOGGER.warning("Can't remove image %s: %s", self.image, err)
raise DockerAPIError() raise DockerAPIError()
@ -296,12 +306,12 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
return b"" return b""
try: try:
return docker_container.logs(tail=100, stdout=True, stderr=True) return docker_container.logs(tail=100, stdout=True, stderr=True)
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.warning("Can't grep logs from %s: %s", self.image, err) _LOGGER.warning("Can't grep logs from %s: %s", self.image, err)
return b"" return b""
@ -318,7 +328,7 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
origin = self.sys_docker.images.get(f"{self.image}:{self.version}") origin = self.sys_docker.images.get(f"{self.image}:{self.version}")
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
_LOGGER.warning("Can't find %s for cleanup", self.image) _LOGGER.warning("Can't find %s for cleanup", self.image)
raise DockerAPIError() raise DockerAPIError()
@ -327,7 +337,7 @@ class DockerInterface(CoreSysAttributes):
if origin.id == image.id: if origin.id == image.id:
continue continue
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
_LOGGER.info("Cleanup images: %s", image.tags) _LOGGER.info("Cleanup images: %s", image.tags)
self.sys_docker.images.remove(image.id, force=True) self.sys_docker.images.remove(image.id, force=True)
@ -336,7 +346,7 @@ class DockerInterface(CoreSysAttributes):
return return
for image in self.sys_docker.images.list(name=old_image): for image in self.sys_docker.images.list(name=old_image):
with suppress(docker.errors.DockerException): with suppress(docker.errors.DockerException, requests.RequestException):
_LOGGER.info("Cleanup images: %s", image.tags) _LOGGER.info("Cleanup images: %s", image.tags)
self.sys_docker.images.remove(image.id, force=True) self.sys_docker.images.remove(image.id, force=True)
@ -352,13 +362,13 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
container = self.sys_docker.containers.get(self.name) container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
raise DockerAPIError() raise DockerAPIError()
_LOGGER.info("Restart %s", self.image) _LOGGER.info("Restart %s", self.image)
try: try:
container.restart(timeout=self.timeout) container.restart(timeout=self.timeout)
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.warning("Can't restart %s: %s", self.image, err) _LOGGER.warning("Can't restart %s: %s", self.image, err)
raise DockerAPIError() raise DockerAPIError()
@ -385,13 +395,13 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
raise DockerAPIError() raise DockerAPIError()
try: try:
stats = docker_container.stats(stream=False) stats = docker_container.stats(stream=False)
return DockerStats(stats) return DockerStats(stats)
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't read stats from %s: %s", self.name, err) _LOGGER.error("Can't read stats from %s: %s", self.name, err)
raise DockerAPIError() raise DockerAPIError()
@ -409,7 +419,7 @@ class DockerInterface(CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
return False return False
# container is not running # container is not running

View File

@ -1,10 +1,8 @@
"""HA Cli docker object.""" """HA Cli docker object."""
from contextlib import suppress
import logging import logging
from ..const import ENV_TIME from ..const import ENV_TIME
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import DockerAPIError
from .interface import DockerInterface from .interface import DockerInterface
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -34,8 +32,7 @@ class DockerMulticast(DockerInterface, CoreSysAttributes):
return return
# Cleanup # Cleanup
with suppress(DockerAPIError): self._stop()
self._stop()
# Create & Run container # Create & Run container
docker_container = self.sys_docker.run( docker_container = self.sys_docker.run(

View File

@ -5,6 +5,7 @@ import logging
from typing import List, Optional from typing import List, Optional
import docker import docker
import requests
from ..const import DOCKER_NETWORK, DOCKER_NETWORK_MASK, DOCKER_NETWORK_RANGE from ..const import DOCKER_NETWORK, DOCKER_NETWORK_MASK, DOCKER_NETWORK_RANGE
from ..exceptions import DockerAPIError from ..exceptions import DockerAPIError
@ -35,9 +36,11 @@ class DockerNetwork:
for cid, data in self.network.attrs.get("Containers", {}).items(): for cid, data in self.network.attrs.get("Containers", {}).items():
try: try:
containers.append(self.docker.containers.get(cid)) containers.append(self.docker.containers.get(cid))
except docker.errors.APIError as err: except docker.errors.NotFound:
_LOGGER.warning("Docker network is corrupt! %s - run autofix", err) _LOGGER.warning("Docker network is corrupt! %s - run autofix", cid)
self.stale_cleanup(data.get("Name", cid)) self.stale_cleanup(data.get("Name", cid))
except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Unknown error with container lookup %s", err)
return containers return containers
@ -132,5 +135,5 @@ class DockerNetwork:
Fix: https://github.com/moby/moby/issues/23302 Fix: https://github.com/moby/moby/issues/23302
""" """
with suppress(docker.errors.APIError): with suppress(docker.errors.DockerException, requests.RequestException):
self.network.disconnect(container_name, force=True) self.network.disconnect(container_name, force=True)

View File

@ -5,6 +5,7 @@ import os
from typing import Awaitable from typing import Awaitable
import docker import docker
import requests
from ..coresys import CoreSysAttributes from ..coresys import CoreSysAttributes
from ..exceptions import DockerAPIError from ..exceptions import DockerAPIError
@ -38,7 +39,7 @@ class DockerSupervisor(DockerInterface, CoreSysAttributes):
""" """
try: try:
docker_container = self.sys_docker.containers.get(self.name) docker_container = self.sys_docker.containers.get(self.name)
except docker.errors.DockerException: except (docker.errors.DockerException, requests.RequestException):
raise DockerAPIError() raise DockerAPIError()
self._meta = docker_container.attrs self._meta = docker_container.attrs
@ -74,7 +75,7 @@ class DockerSupervisor(DockerInterface, CoreSysAttributes):
docker_container.image.tag(self.image, tag=self.version) docker_container.image.tag(self.image, tag=self.version)
docker_container.image.tag(self.image, tag="latest") docker_container.image.tag(self.image, tag="latest")
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't retag supervisor version: %s", err) _LOGGER.error("Can't retag supervisor version: %s", err)
raise DockerAPIError() raise DockerAPIError()
@ -101,6 +102,6 @@ class DockerSupervisor(DockerInterface, CoreSysAttributes):
continue continue
docker_image.tag(start_image, start_tag) docker_image.tag(start_image, start_tag)
except docker.errors.DockerException as err: except (docker.errors.DockerException, requests.RequestException) as err:
_LOGGER.error("Can't fix start tag: %s", err) _LOGGER.error("Can't fix start tag: %s", err)
raise DockerAPIError() raise DockerAPIError()