From 5855df4f0fff8030df34930c55c1023f54ab037b Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 8 Mar 2021 10:05:08 +0100 Subject: [PATCH] Backport of bugfix parts of https://github.com/ansible-collections/community.docker/pull/87/ to stable-2.9. (#73817) --- ...community.docker-87-docker_image-load-image-ids.yml | 5 +++++ lib/ansible/module_utils/docker/common.py | 10 +++++++++- lib/ansible/modules/cloud/docker/docker_image.py | 9 +++++++-- lib/ansible/modules/cloud/docker/docker_image_info.py | 6 ++++-- 4 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/community.docker-87-docker_image-load-image-ids.yml diff --git a/changelogs/fragments/community.docker-87-docker_image-load-image-ids.yml b/changelogs/fragments/community.docker-87-docker_image-load-image-ids.yml new file mode 100644 index 00000000000000..7433f69ab83b57 --- /dev/null +++ b/changelogs/fragments/community.docker-87-docker_image-load-image-ids.yml @@ -0,0 +1,5 @@ +bugfixes: +- "docker_image - prevent module failure when removing image that is removed between inspection and removal (https://github.com/ansible-collections/community.docker/pull/87)." +- "docker_image - prevent module failure when removing non-existant image by ID (https://github.com/ansible-collections/community.docker/pull/87)." +- "docker_image_info - prevent module failure when image vanishes between listing and inspection (https://github.com/ansible-collections/community.docker/pull/87)." +- "docker_image_info - prevent module failure when querying non-existant image by ID (https://github.com/ansible-collections/community.docker/pull/87)." diff --git a/lib/ansible/module_utils/docker/common.py b/lib/ansible/module_utils/docker/common.py index 03307250d692bf..dcbedaaa13c62e 100644 --- a/lib/ansible/module_utils/docker/common.py +++ b/lib/ansible/module_utils/docker/common.py @@ -636,6 +636,9 @@ def find_image(self, name, tag): if len(images) == 1: try: inspection = self.inspect_image(images[0]['Id']) + except NotFound: + self.log("Image %s:%s not found." % (name, tag)) + return None except Exception as exc: self.fail("Error inspecting image %s:%s - %s" % (name, tag, str(exc))) return inspection @@ -643,7 +646,7 @@ def find_image(self, name, tag): self.log("Image %s:%s not found." % (name, tag)) return None - def find_image_by_id(self, image_id): + def find_image_by_id(self, image_id, accept_missing_image=False): ''' Lookup an image (by ID) and return the inspection results. ''' @@ -653,6 +656,11 @@ def find_image_by_id(self, image_id): self.log("Find image %s (by ID)" % image_id) try: inspection = self.inspect_image(image_id) + except NotFound as exc: + if not accept_missing_image: + self.fail("Error inspecting image ID %s - %s" % (image_id, str(exc))) + self.log("Image %s not found." % image_id) + return None except Exception as exc: self.fail("Error inspecting image ID %s - %s" % (image_id, str(exc))) return inspection diff --git a/lib/ansible/modules/cloud/docker/docker_image.py b/lib/ansible/modules/cloud/docker/docker_image.py index b5beec19c9d038..8ae3e7977a2687 100644 --- a/lib/ansible/modules/cloud/docker/docker_image.py +++ b/lib/ansible/modules/cloud/docker/docker_image.py @@ -451,7 +451,7 @@ else: from docker.auth.auth import resolve_repository_name from docker.utils.utils import parse_repository_tag - from docker.errors import DockerException + from docker.errors import DockerException, NotFound except ImportError: # missing Docker SDK for Python handled in module_utils.docker.common pass @@ -557,6 +557,8 @@ def present(self): self.client.fail('Cannot find the image %s locally.' % name) if not self.check_mode and image and image['Id'] == self.results['image']['Id']: self.results['changed'] = False + else: + self.results['image'] = image if self.archive_path: self.archive_image(self.name, self.tag) @@ -574,7 +576,7 @@ def absent(self): ''' name = self.name if is_image_name_id(name): - image = self.client.find_image_by_id(name) + image = self.client.find_image_by_id(name, accept_missing_image=True) else: image = self.client.find_image(name, self.tag) if self.tag: @@ -583,6 +585,9 @@ def absent(self): if not self.check_mode: try: self.client.remove_image(name, force=self.force_absent) + except NotFound: + # If the image vanished while we were trying to remove it, don't fail + pass except Exception as exc: self.fail("Error removing image %s - %s" % (name, str(exc))) diff --git a/lib/ansible/modules/cloud/docker/docker_image_info.py b/lib/ansible/modules/cloud/docker/docker_image_info.py index 57912f961ac589..1650259d8f8bb2 100644 --- a/lib/ansible/modules/cloud/docker/docker_image_info.py +++ b/lib/ansible/modules/cloud/docker/docker_image_info.py @@ -172,7 +172,7 @@ try: from docker import utils - from docker.errors import DockerException + from docker.errors import DockerException, NotFound except ImportError: # missing Docker SDK for Python handled in ansible.module_utils.docker.common pass @@ -220,7 +220,7 @@ def get_facts(self): for name in names: if is_image_name_id(name): self.log('Fetching image %s (ID)' % (name)) - image = self.client.find_image_by_id(name) + image = self.client.find_image_by_id(name, accept_missing_image=True) else: repository, tag = utils.parse_repository_tag(name) if not tag: @@ -237,6 +237,8 @@ def get_all_images(self): for image in images: try: inspection = self.client.inspect_image(image['Id']) + except NotFound: + pass except Exception as exc: self.fail("Error inspecting image %s - %s" % (image['Id'], str(exc))) results.append(inspection)