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 <module>
    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 f9a179f770)
This commit is contained in:
Will Thames 2017-09-11 12:06:57 +10:00 committed by Toshio Kuratomi
parent b62c60ef86
commit 51a9875cfd

View file

@ -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.')