From 51a9875cfd10bb906bf8329bb986b69900a26dd8 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Mon, 11 Sep 2017 12:06:57 +1000 Subject: [PATCH] Handle missing docker-py better (#27540) * Update docker inventory to use APIClient docker-py has been updated, and the `Client` class no longer exists. We use the new `APIClient` class. To provide graceful failure when docker-py is not installed, we need to create a dummy `Client` class so that the inventory script will get as far as displaying a useful error message Before ``` $ contrib/inventory/docker.py --pretty Traceback (most recent call last): File "contrib/inventory/docker.py", line 418, in class AnsibleDockerClient(Client): NameError: name 'Client' is not defined ``` After ``` $ contrib/inventory/docker.py --pretty Failed to import docker-py. Try `pip install docker-py` - cannot import name Client ``` * docker inventory configuration file location Allow docker.yml to live next to docker.py, as well as in the current directory (cherry picked from commit f9a179f77089692a1988fac802a89389b72fbbfc) --- contrib/inventory/docker.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/contrib/inventory/docker.py b/contrib/inventory/docker.py index 2cba94ab658..461e0d68173 100755 --- a/contrib/inventory/docker.py +++ b/contrib/inventory/docker.py @@ -371,7 +371,6 @@ HAS_DOCKER_PY = True HAS_DOCKER_ERROR = False try: - from docker import Client from docker.errors import APIError, TLSParameterError from docker.tls import TLSConfig from docker.constants import DEFAULT_TIMEOUT_SECONDS, DEFAULT_DOCKER_API_VERSION @@ -379,6 +378,19 @@ except ImportError as exc: HAS_DOCKER_ERROR = str(exc) HAS_DOCKER_PY = False +# Client has recently been split into DockerClient and APIClient +try: + from docker import Client +except ImportError as exc: + try: + from docker import APIClient as Client + except ImportError as exc: + HAS_DOCKER_ERROR = str(exc) + HAS_DOCKER_PY = False + + class Client: + pass + DEFAULT_DOCKER_HOST = 'unix://var/run/docker.sock' DEFAULT_TLS = False DEFAULT_TLS_VERIFY = False @@ -779,6 +791,10 @@ class DockerInventory(object): if config_path: try: config_file = os.path.abspath(config_path) + # default config path is docker.yml in same directory as this script + # old behaviour is docker.yml in current directory. Handle both. + if not os.path.exists(config_file): + config_file = os.path.abspath(os.path.basename(config_path)) except: config_file = None @@ -813,7 +829,7 @@ class DockerInventory(object): # Parse command line arguments basename = os.path.splitext(os.path.basename(__file__))[0] - default_config = basename + '.yml' + default_config = os.path.join(os.path.dirname(__file__), basename + '.yml') parser = argparse.ArgumentParser( description='Return Ansible inventory for one or more Docker hosts.')