|
|
|
@ -36,6 +36,7 @@ try:
|
|
|
|
|
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
|
|
|
|
|
except ImportError, exc:
|
|
|
|
|
HAS_DOCKER_ERROR = str(exc)
|
|
|
|
|
HAS_DOCKER_PY = False
|
|
|
|
@ -114,6 +115,7 @@ class DockerBaseClass(object):
|
|
|
|
|
# log_file = open('docker.log', 'a')
|
|
|
|
|
# if pretty_print:
|
|
|
|
|
# log_file.write(json.dumps(msg, sort_keys=True, indent=4, separators=(',', ': ')))
|
|
|
|
|
# log_file.write(u'\n')
|
|
|
|
|
# else:
|
|
|
|
|
# log_file.write(msg + u'\n')
|
|
|
|
|
|
|
|
|
@ -166,11 +168,11 @@ class AnsibleDockerClient(Client):
|
|
|
|
|
|
|
|
|
|
def log(self, msg, pretty_print=False):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# if self.debug:
|
|
|
|
|
# log_file = open('docker.log', 'a')
|
|
|
|
|
# if pretty_print:
|
|
|
|
|
# log_file.write(json.dumps(msg, sort_keys=True, indent=4, separators=(',', ': ')))
|
|
|
|
|
# log_file.write(u'\n')
|
|
|
|
|
# else:
|
|
|
|
|
# log_file.write(msg + u'\n')
|
|
|
|
|
|
|
|
|
@ -392,40 +394,70 @@ class AnsibleDockerClient(Client):
|
|
|
|
|
if not name:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
lookup = name
|
|
|
|
|
if tag:
|
|
|
|
|
lookup = "%s:%s" % (name, tag)
|
|
|
|
|
|
|
|
|
|
self.log("Find image %s" % lookup)
|
|
|
|
|
try:
|
|
|
|
|
images = self.images(name=lookup)
|
|
|
|
|
except Exception, exc:
|
|
|
|
|
self.fail("Error getting image: %s" % str(exc))
|
|
|
|
|
self.log("Find image %s:%s" % (name, tag))
|
|
|
|
|
images = self._image_lookup(name, tag)
|
|
|
|
|
if len(images) == 0:
|
|
|
|
|
# In API <= 1.20 seeing 'docker.io/<name>' as the name of images pulled from docker hub
|
|
|
|
|
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
|
|
|
|
|
lookup = "docker.io/%s" % name
|
|
|
|
|
self.log("Check for docker.io image: %s" % lookup)
|
|
|
|
|
images = self._image_lookup(lookup, tag)
|
|
|
|
|
|
|
|
|
|
if len(images) > 1:
|
|
|
|
|
self.fail("Registry returned more than one result for %s" % lookup)
|
|
|
|
|
self.fail("Registry returned more than one result for %s:%s" % (name, tag))
|
|
|
|
|
|
|
|
|
|
if len(images) == 1:
|
|
|
|
|
try:
|
|
|
|
|
inspection = self.inspect_image(images[0]['Id'])
|
|
|
|
|
except Exception, exc:
|
|
|
|
|
self.fail("Error inspecting image %s - %s" % (lookup, str(exc)))
|
|
|
|
|
inspection['Name'] = lookup
|
|
|
|
|
self.fail("Error inspecting image %s:%s - %s" % (name, tag, str(exc)))
|
|
|
|
|
return inspection
|
|
|
|
|
self.log("Image %s not found." % lookup)
|
|
|
|
|
|
|
|
|
|
self.log("Image %s:%s not found." % (name, tag))
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
def _image_lookup(self, name, tag):
|
|
|
|
|
'''
|
|
|
|
|
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.
|
|
|
|
|
'''
|
|
|
|
|
try:
|
|
|
|
|
response = self.images(name=name)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
self.fail("Error searching for image %s - %s" % (name, str(exc)))
|
|
|
|
|
images = response
|
|
|
|
|
if tag:
|
|
|
|
|
lookup = "%s:%s" % (name, tag)
|
|
|
|
|
for image in response:
|
|
|
|
|
self.log(image, pretty_print=True)
|
|
|
|
|
if image.get('RepoTags') and lookup in image.get('RepoTags'):
|
|
|
|
|
images = [image]
|
|
|
|
|
break
|
|
|
|
|
return images
|
|
|
|
|
|
|
|
|
|
def pull_image(self, name, tag="latest"):
|
|
|
|
|
'''
|
|
|
|
|
Pull an image
|
|
|
|
|
'''
|
|
|
|
|
try:
|
|
|
|
|
self.log("Pulling image %s:%s" % (name, tag))
|
|
|
|
|
try:
|
|
|
|
|
for line in self.pull(name, tag=tag, stream=True):
|
|
|
|
|
response = json.loads(line)
|
|
|
|
|
self.log(response, pretty_print=True)
|
|
|
|
|
return self.find_image(name, tag)
|
|
|
|
|
line = json.loads(line)
|
|
|
|
|
self.log(line, pretty_print=True)
|
|
|
|
|
if line.get('error'):
|
|
|
|
|
if line.get('errorDetail'):
|
|
|
|
|
error_detail = line.get('errorDetail')
|
|
|
|
|
self.fail("Error pulling %s - code: %s message: %s" % (name,
|
|
|
|
|
error_detail.get('code'),
|
|
|
|
|
error_detail.get('message')))
|
|
|
|
|
else:
|
|
|
|
|
self.fail("Error pulling %s - %s" % (name, line.get('error')))
|
|
|
|
|
except Exception, exc:
|
|
|
|
|
self.fail("Error pulling image %s:%s - %s" % (name, tag, str(exc)))
|
|
|
|
|
|
|
|
|
|
return self.find_image(name, tag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|