Skip to content

Commit

Permalink
Add image_name_mismatch option. (#488)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein authored Nov 1, 2022
1 parent 4e1bb64 commit 5b31f17
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/488-docker_container-image-name.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- "docker_container - added ``image_name_mismatch`` option which allows to control the behavior if the container uses the image specified, but the container's configuration uses a different name for the image than the one provided to the module (https://github.com/ansible-collections/community.docker/issues/485, https://github.com/ansible-collections/community.docker/pull/488)."
4 changes: 4 additions & 0 deletions plugins/module_utils/module_container/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ def get_container_id(self, container):
def get_image_from_container(self, container):
pass

@abc.abstractmethod
def get_image_name_from_container(self, container):
pass

@abc.abstractmethod
def is_container_removing(self, container):
pass
Expand Down
3 changes: 3 additions & 0 deletions plugins/module_utils/module_container/docker_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ def get_container_id(self, container):
def get_image_from_container(self, container):
return container['Image']

def get_image_name_from_container(self, container):
return container['Config'].get('Image')

def is_container_removing(self, container):
if container.get('State'):
return container['State'].get('Status') == 'removing'
Expand Down
7 changes: 7 additions & 0 deletions plugins/module_utils/module_container/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ def __init__(self, container, engine_driver):
self.raw = container
self.id = None
self.image = None
self.image_name = None
self.container = container
self.engine_driver = engine_driver
if container:
self.id = engine_driver.get_container_id(container)
self.image = engine_driver.get_image_from_container(container)
self.image_name = engine_driver.get_image_name_from_container(container)
self.log(self.container, pretty_print=True)

@property
Expand Down Expand Up @@ -68,6 +70,7 @@ def __init__(self, module, engine_driver, client, active_options):
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_image_name_mismatch = self.module.params['image_name_mismatch']
self.param_keep_volumes = self.module.params['keep_volumes']
self.param_kill_signal = self.module.params['kill_signal']
self.param_name = self.module.params['name']
Expand Down Expand Up @@ -302,6 +305,9 @@ def present(self, state):
image_different = False
if self.all_options['image'].comparison == 'strict':
image_different = self._image_is_different(image, container)
if self.param_image_name_mismatch == 'recreate' and self.param_image is not None and self.param_image != container.image_name:
different = True
self.diff_tracker.add('image_name', parameter=self.param_image, active=container.image_name)
if image_different or different or self.param_recreate:
self.diff_tracker.merge(differences)
self.diff['differences'] = differences.get_legacy_docker_container_diffs()
Expand Down Expand Up @@ -810,6 +816,7 @@ def run_module(engine_driver):
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'),
image_name_mismatch=dict(type='str', choices=['ignore', 'recreate'], default='ignore'),
keep_volumes=dict(type='bool', default=True),
kill_signal=dict(type='str'),
name=dict(type='str', required=True),
Expand Down
14 changes: 14 additions & 0 deletions plugins/modules/docker_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,20 @@
- 'fail'
default: ignore
version_added: 2.6.0
image_name_mismatch:
description:
- Determines what the module does if the image matches, but the image name in the container's configuration
does not match the image name provided to the module.
- "This is ignored if C(image: ignore) is set in I(comparisons)."
- If set to C(recreate) the container will be recreated.
- If set to C(ignore) the container will not be recreated because of this. It might still get recreated for other reasons.
This has been the default behavior of the module for a long time, but might not be what users expect.
type: str
choices:
- recreate
- ignore
default: ignore
version_added: 3.2.0
init:
description:
- Run an init inside the container that forwards signals and reaps processes.
Expand Down
149 changes: 149 additions & 0 deletions tests/integration/targets/docker_container/tasks/tests/options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,155 @@
- image_label_mismatch_10 is not changed
- image_label_mismatch_11 is changed

####################################################################
## image_name_mismatch #############################################
####################################################################

- name: Pull images to make sure ignore_image test succeeds
# If the image isn't there, it will pull it and return 'changed'.
docker_image:
name: "{{ item }}"
source: pull
loop:
- "{{ docker_test_image_hello_world }}"
- "{{ docker_test_image_registry_nginx }}"

- name: image
docker_container:
image: "{{ docker_test_image_alpine }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
register: image_1

- name: image (idempotency)
docker_container:
image: "{{ docker_test_image_alpine }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
register: image_2
diff: true

- name: ignore_image
docker_container:
image: "{{ docker_test_image_hello_world }}"
ignore_image: yes
name: "{{ cname }}"
state: started
register: ignore_image
diff: true

- 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
diff: true

- 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
diff: true

- name: image change
docker_container:
image: "{{ docker_test_image_hello_world }}"
name: "{{ cname }}"
state: started
force_kill: yes
register: image_change
diff: true

- name: cleanup
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no

- assert:
that:
- 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

####################################################################
## image_name_mismatch #############################################
####################################################################

- name: Registering image name
set_fact:
iname_name_mismatch: "{{ cname_prefix ~ '-image-name' }}"
- name: Registering image name
set_fact:
inames: "{{ inames + [iname_name_mismatch] }}"

- name: Tag hello world image (pulled earlier) with new name
docker_image:
name: "{{ docker_test_image_registry_nginx }}"
source: local
repository: "{{ iname_name_mismatch }}:latest"

- name: image_name_mismatch
docker_container:
image: "{{ docker_test_image_registry_nginx }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
state: started
register: image_name_mismatch_1

- name: image_name_mismatch (ignore)
docker_container:
image: "{{ iname_name_mismatch }}:latest"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
image_name_mismatch: ignore
state: started
register: image_name_mismatch_2

- name: image_name_mismatch (recreate)
docker_container:
image: "{{ iname_name_mismatch }}:latest"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
image_name_mismatch: recreate
state: started
force_kill: yes
register: image_name_mismatch_3

- name: Cleanup container
docker_container:
name: "{{ cname }}"
state: absent
force_kill: yes
diff: no

- name: Cleanup image
docker_image:
name: "{{ iname_name_mismatch }}"
state: absent
diff: no

- assert:
that:
- image_name_mismatch_1 is changed
- image_name_mismatch_2 is not changed
- image_name_mismatch_3 is changed
- image_name_mismatch_3.container.Image == image_name_mismatch_2.container.Image

####################################################################
## ipc_mode ########################################################
####################################################################
Expand Down

0 comments on commit 5b31f17

Please sign in to comment.