summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fontein <felix@fontein.de>2021-01-10 23:12:25 +0100
committerGitHub <noreply@github.com>2021-01-10 16:12:25 -0600
commit77ae0819f969f0700b9d849ec4a9720a259cee55 (patch)
tree29a7bf5b6b680279bdfb6d7a911209f250f323dd
parentf7ac5ea8d62f16d427158e56d85c535e9922506c (diff)
downloadansible-77ae0819f969f0700b9d849ec4a9720a259cee55.tar.gz
Backport of https://github.com/ansible-collections/community.docker/commit/5eef093e994ce4bb10529b1c5da38c4992f5b3c4 (#73067)
-rw-r--r--changelogs/fragments/community.docker-55-docker_image-loading.yml3
-rw-r--r--lib/ansible/modules/cloud/docker/docker_image.py36
-rw-r--r--test/integration/targets/docker_image/tasks/tests/options.yml28
3 files changed, 62 insertions, 5 deletions
diff --git a/changelogs/fragments/community.docker-55-docker_image-loading.yml b/changelogs/fragments/community.docker-55-docker_image-loading.yml
new file mode 100644
index 0000000000..c7694f0594
--- /dev/null
+++ b/changelogs/fragments/community.docker-55-docker_image-loading.yml
@@ -0,0 +1,3 @@
+bugfixes:
+- "docker_image - report error when loading a broken archive that contains no image (https://github.com/ansible-collections/community.docker/issues/46, https://github.com/ansible-collections/community.docker/pull/55)."
+- "docker_image - report error when the loaded archive does not contain the specified image (https://github.com/ansible-collections/community.docker/issues/41, https://github.com/ansible-collections/community.docker/pull/55)."
diff --git a/lib/ansible/modules/cloud/docker/docker_image.py b/lib/ansible/modules/cloud/docker/docker_image.py
index 0599ae509c..52992007b0 100644
--- a/lib/ansible/modules/cloud/docker/docker_image.py
+++ b/lib/ansible/modules/cloud/docker/docker_image.py
@@ -786,17 +786,45 @@ class ImageManager(DockerBaseClass):
:return: image dict
'''
+ # Load image(s) from file
+ load_output = []
try:
self.log("Opening image %s" % self.load_path)
with open(self.load_path, 'rb') as image_tar:
self.log("Loading image from %s" % self.load_path)
- self.client.load_image(image_tar)
+ for line in self.client.load_image(image_tar):
+ self.log(line, pretty_print=True)
+ if "stream" in line or "status" in line:
+ load_line = line.get("stream") or line.get("status") or ''
+ load_output.append(load_line)
except EnvironmentError as exc:
if exc.errno == errno.ENOENT:
- self.fail("Error opening image %s - %s" % (self.load_path, str(exc)))
- self.fail("Error loading image %s - %s" % (self.name, str(exc)))
+ self.client.fail("Error opening image %s - %s" % (self.load_path, str(exc)))
+ self.client.fail("Error loading image %s - %s" % (self.name, str(exc)), stdout='\n'.join(load_output))
except Exception as exc:
- self.fail("Error loading image %s - %s" % (self.name, str(exc)))
+ self.client.fail("Error loading image %s - %s" % (self.name, str(exc)), stdout='\n'.join(load_output))
+
+ # Collect loaded images
+ loaded_images = set()
+ for line in load_output:
+ if line.startswith('Loaded image:'):
+ loaded_images.add(line[len('Loaded image:'):].strip())
+
+ if not loaded_images:
+ self.client.fail("Detected no loaded images. Archive potentially corrupt?", stdout='\n'.join(load_output))
+
+ expected_image = '%s:%s' % (self.name, self.tag)
+ if expected_image not in loaded_images:
+ self.client.fail(
+ "The archive did not contain image '%s'. Instead, found %s." % (
+ expected_image, ', '.join(["'%s'" % image for image in sorted(loaded_images)])),
+ stdout='\n'.join(load_output))
+ loaded_images.remove(expected_image)
+
+ if loaded_images:
+ self.client.module.warn(
+ "The archive contained more images than specified: %s" % (
+ ', '.join(["'%s'" % image for image in sorted(loaded_images)]), ))
return self.client.find_image(self.name, self.tag)
diff --git a/test/integration/targets/docker_image/tasks/tests/options.yml b/test/integration/targets/docker_image/tasks/tests/options.yml
index 5564a38c93..1c045b9a28 100644
--- a/test/integration/targets/docker_image/tasks/tests/options.yml
+++ b/test/integration/targets/docker_image/tasks/tests/options.yml
@@ -182,6 +182,11 @@
source: pull
register: archive_image
+- name: Create invalid archive
+ copy:
+ dest: "{{ output_dir }}/image-invalid.tar"
+ content: "this is not a valid image"
+
- name: remove image
docker_image:
name: "quay.io/ansible/docker-test-containers:hello-world"
@@ -202,11 +207,32 @@
source: load
register: load_image_1
+- name: load image (wrong name)
+ docker_image:
+ name: foo:bar
+ load_path: "{{ output_dir }}/image.tar"
+ source: load
+ register: load_image_2
+ ignore_errors: true
+
+- name: load image (invalid image)
+ docker_image:
+ name: foo:bar
+ load_path: "{{ output_dir }}/image-invalid.tar"
+ source: load
+ register: load_image_3
+ ignore_errors: true
+
- assert:
that:
- load_image is changed
- - load_image_1 is not changed
- archive_image['image']['Id'] == load_image['image']['Id']
+ - load_image_1 is not changed
+ - load_image_2 is failed
+ - >-
+ "The archive did not contain image 'foo:bar'. Instead, found 'quay.io/ansible/docker-test-containers:hello-world'." == load_image_2.msg
+ - load_image_3 is failed
+ - '"Detected no loaded images. Archive potentially corrupt?" == load_image_3.msg'
####################################################################
## path ############################################################