diff options
Diffstat (limited to 'compose/cli/errors.py')
-rw-r--r-- | compose/cli/errors.py | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/compose/cli/errors.py b/compose/cli/errors.py index 5af3ede9..1506aa66 100644 --- a/compose/cli/errors.py +++ b/compose/cli/errors.py @@ -4,8 +4,10 @@ from __future__ import unicode_literals import contextlib import logging import socket +from distutils.spawn import find_executable from textwrap import dedent +import six from docker.errors import APIError from requests.exceptions import ConnectionError as RequestsConnectionError from requests.exceptions import ReadTimeout @@ -13,10 +15,10 @@ from requests.exceptions import SSLError from requests.packages.urllib3.exceptions import ReadTimeoutError from ..const import API_VERSION_TO_ENGINE_VERSION -from .utils import call_silently from .utils import is_docker_for_mac_installed from .utils import is_mac from .utils import is_ubuntu +from .utils import is_windows log = logging.getLogger(__name__) @@ -53,8 +55,28 @@ def handle_connection_errors(client): log_api_error(e, client.api_version) raise ConnectionError() except (ReadTimeout, socket.timeout) as e: - log_timeout_error() + log_timeout_error(client.timeout) raise ConnectionError() + except Exception as e: + if is_windows(): + import pywintypes + if isinstance(e, pywintypes.error): + log_windows_pipe_error(e) + raise ConnectionError() + raise + + +def log_windows_pipe_error(exc): + if exc.winerror == 232: # https://github.com/docker/compose/issues/5005 + log.error( + "The current Compose file version is not compatible with your engine version. " + "Please upgrade your Compose file to a more recent version, or set " + "a COMPOSE_API_VERSION in your environment." + ) + else: + log.error( + "Windows named pipe error: {} (code: {})".format(exc.strerror, exc.winerror) + ) def log_timeout_error(timeout): @@ -67,14 +89,18 @@ def log_timeout_error(timeout): def log_api_error(e, client_version): - if b'client is newer than server' not in e.explanation: - log.error(e.explanation) + explanation = e.explanation + if isinstance(explanation, six.binary_type): + explanation = explanation.decode('utf-8') + + if 'client is newer than server' not in explanation: + log.error(explanation) return version = API_VERSION_TO_ENGINE_VERSION.get(client_version) if not version: # They've set a custom API version - log.error(e.explanation) + log.error(explanation) return log.error( @@ -89,38 +115,35 @@ def exit_with_error(msg): def get_conn_error_message(url): - if call_silently(['which', 'docker']) != 0: - if is_mac(): - return docker_not_found_mac - if is_ubuntu(): - return docker_not_found_ubuntu - return docker_not_found_generic + if find_executable('docker') is None: + return docker_not_found_msg("Couldn't connect to Docker daemon.") if is_docker_for_mac_installed(): return conn_error_docker_for_mac - if call_silently(['which', 'docker-machine']) == 0: + if find_executable('docker-machine') is not None: return conn_error_docker_machine return conn_error_generic.format(url=url) -docker_not_found_mac = """ - Couldn't connect to Docker daemon. You might need to install Docker: - - https://docs.docker.com/engine/installation/mac/ -""" +def docker_not_found_msg(problem): + return "{} You might need to install Docker:\n\n{}".format( + problem, docker_install_url()) -docker_not_found_ubuntu = """ - Couldn't connect to Docker daemon. You might need to install Docker: +def docker_install_url(): + if is_mac(): + return docker_install_url_mac + elif is_ubuntu(): + return docker_install_url_ubuntu + elif is_windows(): + return docker_install_url_windows + else: + return docker_install_url_generic - https://docs.docker.com/engine/installation/ubuntulinux/ -""" - -docker_not_found_generic = """ - Couldn't connect to Docker daemon. You might need to install Docker: - - https://docs.docker.com/engine/installation/ -""" +docker_install_url_mac = "https://docs.docker.com/engine/installation/mac/" +docker_install_url_ubuntu = "https://docs.docker.com/engine/installation/ubuntulinux/" +docker_install_url_windows = "https://docs.docker.com/engine/installation/windows/" +docker_install_url_generic = "https://docs.docker.com/engine/installation/" conn_error_docker_machine = """ |