docker_container: add image_comparison parameter (#428)

* Add image_comparison parameter.

* Forgot version_added.
This commit is contained in:
Felix Fontein 2022-07-15 17:14:40 +02:00 committed by GitHub
parent 37c868e192
commit 5d0a036819
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 7 deletions

View File

@ -0,0 +1,2 @@
minor_changes:
- "docker_container - add a new parameter ``image_comparison`` to control the behavior for which image will be used for idempotency checks (https://github.com/ansible-collections/community.docker/issues/421, https://github.com/ansible-collections/community.docker/pull/428)."

View File

@ -65,6 +65,7 @@ class ContainerManager(DockerBaseClass):
self.param_debug = self.module.params['debug']
self.param_force_kill = self.module.params['force_kill']
self.param_image = self.module.params['image']
self.param_image_comparison = self.module.params['image_comparison']
self.param_image_label_mismatch = self.module.params['image_label_mismatch']
self.param_keep_volumes = self.module.params['keep_volumes']
self.param_kill_signal = self.module.params['kill_signal']
@ -276,7 +277,7 @@ class ContainerManager(DockerBaseClass):
# the container already runs or not; in the former case, in case the
# container needs to be restarted, we use the existing container's
# image ID.
image = self._get_image()
image, comparison_image = self._get_image(container)
self.log(image, pretty_print=True)
if not container.exists or container.removing:
# New container
@ -297,7 +298,7 @@ class ContainerManager(DockerBaseClass):
container_created = True
else:
# Existing container
different, differences = self.has_different_configuration(container, image)
different, differences = self.has_different_configuration(container, comparison_image)
image_different = False
if self.all_options['image'].comparison == 'strict':
image_different = self._image_is_different(image, container)
@ -323,9 +324,10 @@ class ContainerManager(DockerBaseClass):
if new_container:
container = new_container
container_created = True
comparison_image = image
if container and container.exists:
container = self.update_limits(container, image)
container = self.update_limits(container, comparison_image)
container = self.update_networks(container, container_created)
if state == 'started' and not container.running:
@ -377,11 +379,24 @@ class ContainerManager(DockerBaseClass):
container = self.engine_driver.inspect_container_by_name(self.client, container)
return Container(container, self.engine_driver)
def _get_image(self):
def _get_container_image(self, container, fallback=None):
if not container.exists or container.removing:
return fallback
image = container.image
if is_image_name_id(image):
image = self.engine_driver.inspect_image_by_id(self.client, image)
else:
repository, tag = parse_repository_tag(image)
if not tag:
tag = "latest"
image = self.engine_driver.inspect_image_by_name(self.client, repository, tag)
return image or fallback
def _get_image(self, container):
image_parameter = self.param_image
if not image_parameter:
self.log('No image specified')
return None
return None, self._get_container_image(container)
if is_image_name_id(image_parameter):
image = self.engine_driver.inspect_image_by_id(self.client, image_parameter)
else:
@ -406,7 +421,15 @@ class ContainerManager(DockerBaseClass):
self.log("image")
self.log(image, pretty_print=True)
return image
comparison_image = image
if self.param_image_comparison == 'current-image':
comparison_image = self._get_container_image(container, image)
if comparison_image != image:
self.log("current image")
self.log(image, pretty_print=True)
return image, comparison_image
def _image_is_different(self, image, container):
if image and image.get('Id'):
@ -776,6 +799,7 @@ def run_module(engine_driver):
force_kill=dict(type='bool', default=False, aliases=['forcekill']),
ignore_image=dict(type='bool', default=False),
image=dict(type='str'),
image_comparison=dict(type='str', choices=['desired-image', 'current-image'], default='desired-image'),
image_label_mismatch=dict(type='str', choices=['ignore', 'fail'], default='ignore'),
keep_volumes=dict(type='bool', default=True),
kill_signal=dict(type='str'),

View File

@ -404,6 +404,19 @@ options:
- Can also be an image ID. If this is the case, the image is assumed to be available locally.
The I(pull) option is ignored for this case.
type: str
image_comparison:
description:
- Determines which image to use for idempotency checks that depend on image parameters.
- The default, C(desired-image), will use the image that is provided to the module via the I(image) parameter.
- C(current-image) will use the image that the container is currently using, if the container exists. It
falls back to the image that is provided in case the container does not yet exist.
- This affects the I(env), I(env_file), I(exposed_ports), I(labels), and I(volumes) options.
type: str
choices:
- desired-image
- current-image
default: desired-image
version_added: 3.0.0
image_label_mismatch:
description:
- How to handle labels inherited from the image that are not set explicitly.

View File

@ -2101,7 +2101,7 @@
- interactive_3 is changed
####################################################################
## image / ignore_image ############################################
## image / image_comparison / ignore_image #########################
####################################################################
- name: Pull {{ docker_test_image_hello_world }} image to make sure ignore_image test succeeds
@ -2134,6 +2134,25 @@
state: started
register: ignore_image
- name: ignore_image (labels and env differ in image, image_comparison=current-image)
docker_container:
image: "{{ docker_test_image_registry_nginx }}"
ignore_image: yes
image_comparison: current-image
name: "{{ cname }}"
state: started
register: ignore_image_2
- name: ignore_image (labels and env differ in image, image_comparison=desired-image)
docker_container:
image: "{{ docker_test_image_registry_nginx }}"
ignore_image: yes
image_comparison: desired-image
name: "{{ cname }}"
state: started
force_kill: yes
register: ignore_image_3
- name: image change
docker_container:
image: "{{ docker_test_image_hello_world }}"
@ -2154,6 +2173,8 @@
- image_1 is changed
- image_2 is not changed
- ignore_image is not changed
- ignore_image_2 is not changed
- ignore_image_3 is changed
- image_change is changed
####################################################################