summaryrefslogtreecommitdiff
path: root/compose/cli/errors.py
diff options
context:
space:
mode:
Diffstat (limited to 'compose/cli/errors.py')
-rw-r--r--compose/cli/errors.py77
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 = """