From 1e1a843ff399eacbc039f26e8a865e76e03118ef Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 8 Mar 2021 08:37:04 +0100 Subject: [PATCH] Backport of https://github.com/ansible-collections/community.docker/pull/87 to stable-1. (#1983) --- ...community.docker-87-docker_image-load-image-ids.yml | 5 +++++ plugins/module_utils/docker/common.py | 10 +++++++++- plugins/modules/cloud/docker/docker_image.py | 9 +++++++-- plugins/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 0000000000..7433f69ab8 --- /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/plugins/module_utils/docker/common.py b/plugins/module_utils/docker/common.py index 03307250d6..dcbedaaa13 100644 --- a/plugins/module_utils/docker/common.py +++ b/plugins/module_utils/docker/common.py @@ -636,6 +636,9 @@ class AnsibleDockerClient(Client): 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 @@ class AnsibleDockerClient(Client): 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 @@ class AnsibleDockerClient(Client): 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/plugins/modules/cloud/docker/docker_image.py b/plugins/modules/cloud/docker/docker_image.py index 1e2976bede..6c930b7074 100644 --- a/plugins/modules/cloud/docker/docker_image.py +++ b/plugins/modules/cloud/docker/docker_image.py @@ -433,7 +433,7 @@ if docker_version is not None: 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 @@ -540,6 +540,8 @@ class ImageManager(DockerBaseClass): 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) @@ -557,7 +559,7 @@ class ImageManager(DockerBaseClass): ''' 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: @@ -566,6 +568,9 @@ class ImageManager(DockerBaseClass): 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/plugins/modules/cloud/docker/docker_image_info.py b/plugins/modules/cloud/docker/docker_image_info.py index 8cf08ef08e..b083976699 100644 --- a/plugins/modules/cloud/docker/docker_image_info.py +++ b/plugins/modules/cloud/docker/docker_image_info.py @@ -167,7 +167,7 @@ import traceback 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 @@ -215,7 +215,7 @@ class ImageManager(DockerBaseClass): 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: @@ -232,6 +232,8 @@ class ImageManager(DockerBaseClass): 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)