diff options
author | Felix Fontein <felix@fontein.de> | 2021-01-10 23:12:25 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-10 16:12:25 -0600 |
commit | 77ae0819f969f0700b9d849ec4a9720a259cee55 (patch) | |
tree | 29a7bf5b6b680279bdfb6d7a911209f250f323dd | |
parent | f7ac5ea8d62f16d427158e56d85c535e9922506c (diff) | |
download | ansible-77ae0819f969f0700b9d849ec4a9720a259cee55.tar.gz |
Backport of https://github.com/ansible-collections/community.docker/commit/5eef093e994ce4bb10529b1c5da38c4992f5b3c4 (#73067)
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 ############################################################ |