From e2a1ce2916e9b87fe1ad4a1011c04ef8d2faf046 Mon Sep 17 00:00:00 2001 From: dariko Date: Tue, 20 Dec 2016 14:55:03 +0100 Subject: [PATCH] [docker] Add compatibility with docker-py v2.0 --- lib/ansible/module_utils/docker_common.py | 23 ++++++++++++------- .../modules/cloud/docker/docker_container.py | 5 +++- .../modules/cloud/docker/docker_image.py | 5 +++- .../modules/cloud/docker/docker_network.py | 16 ++++++++++--- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/lib/ansible/module_utils/docker_common.py b/lib/ansible/module_utils/docker_common.py index b931701f93..13bc7a6af6 100644 --- a/lib/ansible/module_utils/docker_common.py +++ b/lib/ansible/module_utils/docker_common.py @@ -27,17 +27,24 @@ from urlparse import urlparse from ansible.module_utils.basic import * HAS_DOCKER_PY = True +HAS_DOCKER_PY_2 = False HAS_DOCKER_ERROR = None try: from requests.exceptions import SSLError - from docker import Client from docker import __version__ as docker_version from docker.errors import APIError, TLSParameterError, NotFound from docker.tls import TLSConfig from docker.constants import DEFAULT_TIMEOUT_SECONDS, DEFAULT_DOCKER_API_VERSION - from docker.utils.types import Ulimit, LogConfig from docker import auth + if LooseVersion(docker_version) >= LooseVersion('2.0.0'): + HAS_DOCKER_PY_2 = True + from docker import APIClient as Client + from docker.types import Ulimit, LogConfig + else: + from docker import Client + from docker.utils.types import Ulimit, LogConfig + except ImportError as exc: HAS_DOCKER_ERROR = str(exc) HAS_DOCKER_PY = False @@ -135,7 +142,7 @@ class AnsibleDockerClient(Client): MIN_DOCKER_VERSION)) self.debug = self.module.params.get('debug') - self.check_mode = self.module.check_mode + self.check_mode = self.module.check_mode self._connect_params = self._get_connect_params() try: @@ -377,9 +384,9 @@ class AnsibleDockerClient(Client): images = self._image_lookup(name, tag) if len(images) == 0: # In API <= 1.20 seeing 'docker.io/' as the name of images pulled from docker hub - registry, repo_name = auth.resolve_repository_name(name) + registry, repo_name = auth.resolve_repository_name(name) if registry == 'docker.io': - # the name does not contain a registry, so let's see if docker.io works + # the name does not contain a registry, so let's see if docker.io works lookup = "docker.io/%s" % name self.log("Check for docker.io image: %s" % lookup) images = self._image_lookup(lookup, tag) @@ -397,9 +404,9 @@ class AnsibleDockerClient(Client): self.log("Image %s:%s not found." % (name, tag)) return None - def _image_lookup(self, name, tag): + def _image_lookup(self, name, tag): ''' - Including a tag in the name parameter sent to the docker-py images method does not + Including a tag in the name parameter sent to the docker-py images method does not work consistently. Instead, get the result set for name and manually check if the tag exists. ''' @@ -408,7 +415,7 @@ class AnsibleDockerClient(Client): except Exception as exc: self.fail("Error searching for image %s - %s" % (name, str(exc))) images = response - if tag: + if tag: lookup = "%s:%s" % (name, tag) images = [] for image in response: diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index 2acba8388a..8eb4b36060 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -656,7 +656,10 @@ from ansible.module_utils.docker_common import * try: from docker import utils - from docker.utils.types import Ulimit + if HAS_DOCKER_PY_2: + from docker.types import Ulimit + else: + from docker.utils.types import Ulimit except: # missing docker-py handled in ansible.module_utils.docker pass diff --git a/lib/ansible/modules/cloud/docker/docker_image.py b/lib/ansible/modules/cloud/docker/docker_image.py index 0c6c691348..4643c63ed6 100644 --- a/lib/ansible/modules/cloud/docker/docker_image.py +++ b/lib/ansible/modules/cloud/docker/docker_image.py @@ -250,7 +250,10 @@ image: from ansible.module_utils.docker_common import * try: - from docker.auth.auth import resolve_repository_name + if HAS_DOCKER_PY_2: + from docker.auth import resolve_repository_name + else: + from docker.auth.auth import resolve_repository_name from docker.utils.utils import parse_repository_tag except ImportError: # missing docker-py handled in docker_common diff --git a/lib/ansible/modules/cloud/docker/docker_network.py b/lib/ansible/modules/cloud/docker/docker_network.py index 3c7f46bfc0..867907b4a5 100644 --- a/lib/ansible/modules/cloud/docker/docker_network.py +++ b/lib/ansible/modules/cloud/docker/docker_network.py @@ -164,7 +164,10 @@ from ansible.module_utils.docker_common import * try: from docker import utils - from docker.utils.types import Ulimit + if HAS_DOCKER_PY_2: + from docker.types import Ulimit, IPAMPool, IPAMConfig + else: + from docker.utils.types import Ulimit except: # missing docker-py handled in ansible.module_utils.docker pass @@ -275,9 +278,16 @@ class DockerNetworkManager(object): if not self.existing_network: ipam_pools = [] if self.parameters.ipam_options: - ipam_pools.append(utils.create_ipam_pool(**self.parameters.ipam_options)) + if HAS_DOCKER_PY_2: + ipam_pools.append(IPAMPool(**self.parameters.ipam_options)) + else: + ipam_pools.append(utils.create_ipam_pool(**self.parameters.ipam_options)) - ipam_config = utils.create_ipam_config(driver=self.parameters.ipam_driver, + if HAS_DOCKER_PY_2: + ipam_config = IPAMConfig(driver=self.parameters.ipam_driver, + pool_configs=ipam_pools) + else: + ipam_config = utils.create_ipam_config(driver=self.parameters.ipam_driver, pool_configs=ipam_pools) if not self.check_mode: