mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-24 09:36:31 +00:00
Catch requests with docker exceptions (#1926)
This commit is contained in:
parent
22a7931a7c
commit
fe6634551a
@ -8,6 +8,7 @@ from typing import Any, Dict, Optional
|
||||
import attr
|
||||
import docker
|
||||
from packaging import version as pkg_version
|
||||
import requests
|
||||
|
||||
from ..const import DNS_SUFFIX, DOCKER_IMAGE_DENYLIST, SOCKET_DOCKER
|
||||
from ..exceptions import DockerAPIError
|
||||
@ -128,7 +129,7 @@ class DockerAPI:
|
||||
container = self.docker.containers.create(
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -146,12 +147,12 @@ class DockerAPI:
|
||||
# Run container
|
||||
try:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
# Update metadata
|
||||
with suppress(docker.errors.DockerException):
|
||||
with suppress(docker.errors.DockerException, requests.RequestException):
|
||||
container.reload()
|
||||
|
||||
return container
|
||||
@ -184,13 +185,13 @@ class DockerAPI:
|
||||
result = container.wait()
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
finally:
|
||||
# cleanup container
|
||||
with suppress(docker.errors.DockerException):
|
||||
with suppress(docker.errors.DockerException, requests.RequestException):
|
||||
container.remove(force=True)
|
||||
|
||||
return CommandReturn(result.get("StatusCode"), output)
|
||||
|
@ -334,8 +334,7 @@ class DockerAddon(DockerInterface):
|
||||
_LOGGER.warning("%s run with disabled protected mode!", self.addon.name)
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
@ -396,7 +395,7 @@ class DockerAddon(DockerInterface):
|
||||
# Update meta data
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -414,7 +413,7 @@ class DockerAddon(DockerInterface):
|
||||
"""
|
||||
try:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -423,7 +422,7 @@ class DockerAddon(DockerInterface):
|
||||
with tar_file.open("wb") as write_tar:
|
||||
for chunk in image:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -471,7 +470,7 @@ class DockerAddon(DockerInterface):
|
||||
# Load needed docker objects
|
||||
container = self.sys_docker.containers.get(self.name)
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
"""Audio docker object."""
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from ..const import ENV_TIME, MACHINE_ID
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import DockerAPIError
|
||||
from .interface import DockerInterface
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@ -56,8 +54,7 @@ class DockerAudio(DockerInterface, CoreSysAttributes):
|
||||
return
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
|
@ -1,10 +1,8 @@
|
||||
"""HA Cli docker object."""
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
|
||||
from ..const import ENV_TIME, ENV_TOKEN
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import DockerAPIError
|
||||
from .interface import DockerInterface
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@ -34,8 +32,7 @@ class DockerCli(DockerInterface, CoreSysAttributes):
|
||||
return
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
|
@ -1,10 +1,8 @@
|
||||
"""DNS docker object."""
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
|
||||
from ..const import ENV_TIME
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import DockerAPIError
|
||||
from .interface import DockerInterface
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@ -34,8 +32,7 @@ class DockerDNS(DockerInterface, CoreSysAttributes):
|
||||
return
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
|
@ -1,10 +1,10 @@
|
||||
"""Init file for Supervisor Docker object."""
|
||||
from contextlib import suppress
|
||||
from ipaddress import IPv4Address
|
||||
import logging
|
||||
from typing import Awaitable, Dict, Optional
|
||||
|
||||
import docker
|
||||
import requests
|
||||
|
||||
from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_OLD, LABEL_MACHINE, MACHINE_ID
|
||||
from ..exceptions import DockerAPIError
|
||||
@ -98,8 +98,7 @@ class DockerHomeAssistant(DockerInterface):
|
||||
return
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
@ -167,8 +166,10 @@ class DockerHomeAssistant(DockerInterface):
|
||||
docker_image = self.sys_docker.images.get(
|
||||
f"{self.image}:{self.sys_homeassistant.version}"
|
||||
)
|
||||
except docker.errors.DockerException:
|
||||
except docker.errors.NotFound:
|
||||
return False
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
return DockerAPIError()
|
||||
|
||||
# we run on an old image, stop and start it
|
||||
if docker_container.image.id != docker_image.id:
|
||||
|
@ -5,6 +5,7 @@ import logging
|
||||
from typing import Any, Awaitable, Dict, List, Optional
|
||||
|
||||
import docker
|
||||
import requests
|
||||
|
||||
from . import CommandReturn
|
||||
from ..const import LABEL_ARCH, LABEL_VERSION
|
||||
@ -107,6 +108,10 @@ class DockerInterface(CoreSysAttributes):
|
||||
free_space,
|
||||
)
|
||||
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:
|
||||
self._meta = docker_image.attrs
|
||||
|
||||
@ -119,7 +124,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
|
||||
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}")
|
||||
return True
|
||||
return False
|
||||
@ -138,8 +143,10 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except docker.errors.NotFound:
|
||||
return False
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
raise DockerAPIError()
|
||||
|
||||
return docker_container.status == "running"
|
||||
|
||||
@ -153,10 +160,10 @@ class DockerInterface(CoreSysAttributes):
|
||||
|
||||
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
|
||||
|
||||
with suppress(docker.errors.DockerException):
|
||||
with suppress(docker.errors.DockerException, requests.RequestException):
|
||||
if not self._meta and self.image:
|
||||
self._meta = self.sys_docker.images.get(f"{self.image}:{tag}").attrs
|
||||
|
||||
@ -189,16 +196,18 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
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()
|
||||
|
||||
if docker_container.status == "running":
|
||||
_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)
|
||||
|
||||
if remove_container:
|
||||
with suppress(docker.errors.DockerException):
|
||||
with suppress(docker.errors.DockerException, requests.RequestException):
|
||||
_LOGGER.info("Clean %s application", self.name)
|
||||
docker_container.remove(force=True)
|
||||
|
||||
@ -214,13 +223,14 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
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()
|
||||
|
||||
_LOGGER.info("Start %s", self.name)
|
||||
try:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -249,7 +259,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -296,12 +306,12 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
return b""
|
||||
|
||||
try:
|
||||
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)
|
||||
|
||||
return b""
|
||||
@ -318,7 +328,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -327,7 +337,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
if origin.id == image.id:
|
||||
continue
|
||||
|
||||
with suppress(docker.errors.DockerException):
|
||||
with suppress(docker.errors.DockerException, requests.RequestException):
|
||||
_LOGGER.info("Cleanup images: %s", image.tags)
|
||||
self.sys_docker.images.remove(image.id, force=True)
|
||||
|
||||
@ -336,7 +346,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
return
|
||||
|
||||
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)
|
||||
self.sys_docker.images.remove(image.id, force=True)
|
||||
|
||||
@ -352,13 +362,13 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
raise DockerAPIError()
|
||||
|
||||
_LOGGER.info("Restart %s", self.image)
|
||||
try:
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -385,13 +395,13 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
raise DockerAPIError()
|
||||
|
||||
try:
|
||||
stats = docker_container.stats(stream=False)
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -409,7 +419,7 @@ class DockerInterface(CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
return False
|
||||
|
||||
# container is not running
|
||||
|
@ -1,10 +1,8 @@
|
||||
"""HA Cli docker object."""
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
|
||||
from ..const import ENV_TIME
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import DockerAPIError
|
||||
from .interface import DockerInterface
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
@ -34,8 +32,7 @@ class DockerMulticast(DockerInterface, CoreSysAttributes):
|
||||
return
|
||||
|
||||
# Cleanup
|
||||
with suppress(DockerAPIError):
|
||||
self._stop()
|
||||
self._stop()
|
||||
|
||||
# Create & Run container
|
||||
docker_container = self.sys_docker.run(
|
||||
|
@ -5,6 +5,7 @@ import logging
|
||||
from typing import List, Optional
|
||||
|
||||
import docker
|
||||
import requests
|
||||
|
||||
from ..const import DOCKER_NETWORK, DOCKER_NETWORK_MASK, DOCKER_NETWORK_RANGE
|
||||
from ..exceptions import DockerAPIError
|
||||
@ -35,9 +36,11 @@ class DockerNetwork:
|
||||
for cid, data in self.network.attrs.get("Containers", {}).items():
|
||||
try:
|
||||
containers.append(self.docker.containers.get(cid))
|
||||
except docker.errors.APIError as err:
|
||||
_LOGGER.warning("Docker network is corrupt! %s - run autofix", err)
|
||||
except docker.errors.NotFound:
|
||||
_LOGGER.warning("Docker network is corrupt! %s - run autofix", 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
|
||||
|
||||
@ -132,5 +135,5 @@ class DockerNetwork:
|
||||
|
||||
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)
|
||||
|
@ -5,6 +5,7 @@ import os
|
||||
from typing import Awaitable
|
||||
|
||||
import docker
|
||||
import requests
|
||||
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import DockerAPIError
|
||||
@ -38,7 +39,7 @@ class DockerSupervisor(DockerInterface, CoreSysAttributes):
|
||||
"""
|
||||
try:
|
||||
docker_container = self.sys_docker.containers.get(self.name)
|
||||
except docker.errors.DockerException:
|
||||
except (docker.errors.DockerException, requests.RequestException):
|
||||
raise DockerAPIError()
|
||||
|
||||
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="latest")
|
||||
except docker.errors.DockerException as err:
|
||||
except (docker.errors.DockerException, requests.RequestException) as err:
|
||||
_LOGGER.error("Can't retag supervisor version: %s", err)
|
||||
raise DockerAPIError()
|
||||
|
||||
@ -101,6 +102,6 @@ class DockerSupervisor(DockerInterface, CoreSysAttributes):
|
||||
continue
|
||||
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)
|
||||
raise DockerAPIError()
|
||||
|
Loading…
x
Reference in New Issue
Block a user