docker_container, docker_image_facts: allow to use image IDs (#46324)

* Allow to specify images by hash for docker_container and docker_image_facts.

* flake8

* More sanity checks.

* Added changelog.

* Added test.

* Make compatible with Python < 3.4.

* Remove out-commented imports.
This commit is contained in:
Felix Fontein 2018-10-06 15:50:31 +02:00 committed by John R Barker
parent 895019c59b
commit a520ca3298
7 changed files with 143 additions and 39 deletions

View file

@ -18,9 +18,6 @@
import os
import re
import json
import sys
import copy
from distutils.version import LooseVersion
from ansible.module_utils.basic import AnsibleModule, env_fallback
@ -35,22 +32,18 @@ HAS_DOCKER_ERROR = None
try:
from requests.exceptions import SSLError
from docker import __version__ as docker_version
from docker.errors import APIError, TLSParameterError, NotFound
from docker.errors import APIError, TLSParameterError
from docker.tls import TLSConfig
from docker.constants import DEFAULT_DOCKER_API_VERSION
from docker import auth
if LooseVersion(docker_version) >= LooseVersion('3.0.0'):
HAS_DOCKER_PY_3 = True
from docker import APIClient as Client
from docker.types import Ulimit, LogConfig
elif 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)
@ -62,14 +55,14 @@ except ImportError as exc:
# installed, as they utilize the same namespace are are incompatible
try:
# docker
import docker.models
import docker.models # noqa: F401
HAS_DOCKER_MODELS = True
except ImportError:
HAS_DOCKER_MODELS = False
try:
# docker-py
import docker.ssladapter
import docker.ssladapter # noqa: F401
HAS_DOCKER_SSLADAPTER = True
except ImportError:
HAS_DOCKER_SSLADAPTER = False
@ -112,14 +105,21 @@ BYTE_SUFFIXES = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
if not HAS_DOCKER_PY:
# No docker-py. Create a place holder client to allow
# instantiation of AnsibleModule and proper error handing
class Client(object):
class Client(object): # noqa: F811
def __init__(self, **kwargs):
pass
class APIError(Exception):
class APIError(Exception): # noqa: F811
pass
def is_image_name_id(name):
"""Checks whether the given image name is in fact an image ID (hash)."""
if re.match('^sha256:[0-9a-fA-F]{64}$', name):
return True
return False
def sanitize_result(data):
"""Sanitize data object for return to Ansible.
@ -428,7 +428,7 @@ class AnsibleDockerClient(Client):
def find_image(self, name, tag):
'''
Lookup an image and return the inspection results.
Lookup an image (by name and tag) and return the inspection results.
'''
if not name:
return None
@ -457,6 +457,20 @@ class AnsibleDockerClient(Client):
self.log("Image %s:%s not found." % (name, tag))
return None
def find_image_by_id(self, id):
'''
Lookup an image (by ID) and return the inspection results.
'''
if not id:
return None
self.log("Find image %s (by ID)" % id)
try:
inspection = self.inspect_image(id)
except Exception as exc:
self.fail("Error inspecting image ID %s - %s" % (id, str(exc)))
return inspection
def _image_lookup(self, name, tag):
'''
Including a tag in the name parameter sent to the docker-py images method does not