community.docker
community.docker copied to clipboard
Perma diff in check mode when referencing image tag + digest
SUMMARY
Executing the module docker_container in check mode always reports a change when referencing a tag and digest for an image at the same time, e.g
- docker_container:
image: "nginx:1.25.3@sha256:d02f9b9db4d759ef27dc26b426b842ff2fb881c5c6079612d27ec36e36b132dd"
The same module executed in normal mode doesn't report a change.
ISSUE TYPE
- Bug Report
COMPONENT NAME
module: docker_container
ANSIBLE VERSION
ansible [core 2.16.2]
python version = 3.11.3 (main, May 15 2023, 14:35:06) [Clang 14.0.3 (clang-1403.0.22.14.1)]
jinja version = 3.1.2
libyaml = True
COLLECTION VERSION
/Users/user/Library/Caches/pypoetry/virtualenvs/infra-vKVwe6_N-py3.11/lib/python3.11/site-packages/ansible_collections
Collection Version
----------------- -------
community.general 8.1.0
OS / ENVIRONMENT
Linux Debian 4.19.289-2
STEPS TO REPRODUCE
- Run the following task once to create the container on the host
- name: "Create Nginx container"
docker_container:
image: "nginx:1.25.3@sha256:d02f9b9db4d759ef27dc26b426b842ff2fb881c5c6079612d27ec36e36b132dd"
name: "nginx"
state: "started"
- Re-run the previous task with
--checkoption;
EXPECTED RESULTS
The task should not report a change as the container configuration didn't change.
ACTUAL RESULTS
The recap displays the task as changed:
TASK [Create Nginx container] ****************************************************************************************
changed: [localhost]
With --diff option, the task doesn't report any hint on the diff:
"diff": {
"after": {},
"before": {}
},
What happens is that the module things the image does not exists, and tries to pull it. Outside of check mode, it notices that after pulling the image equals the image before pulling, and reports changed=false. With check mode, it doesn't know what happens after pulling and thus reports it as changed.
The main problem here is that having both a tag and a digest is not really supported by the module. It only handles either having the tag or the digest.
BTW, please note that if you specify both tag + digest, that Docker pretty much ignores the tag. If you for example run docker pull nginx:foobar@sha256:d02f9b9db4d759ef27dc26b426b842ff2fb881c5c6079612d27ec36e36b132dd it will pull exactly the same image as if you would have specified any other value for the tag. Also after pulling you don't have a local image nginx with that tag (also not if you specify the "real" one). If you specify both tag and digest, Docker basically ignores the tag completely and only uses the digest.
I guess this is also something we can implement for this collection, though I very much dislike this behavior since you can forgot to update the tag after updating the digest without noticing, which makes having the tag specified rather worthless.
Hey @felixfontein,
Thanks for your explanations!
BTW, please note that if you specify both tag + digest, that Docker pretty much ignores the tag.
I am aware that Docker ignores the tag when the digest is specified. For me, it's simply a matter of ease when handling dependency updates. Digests don't give a clue about which version they reference, and it's easy to mismatch them.
I have also discovered another behavior, I suspect is a bug. Adding *: strict comparisons to the task above will make the module recreate the container each time the task is run:
- name: "Create Nginx container"
docker_container:
comparisons:
"*": "strict"
image: "nginx:1.25.3@sha256:d02f9b9db4d759ef27dc26b426b842ff2fb881c5c6079612d27ec36e36b132dd"
name: "nginx"
state: "started"
See the task recap:
TASK [Create Nginx container] ******************************************************************************************
--- before
+++ after
@@ -1,12 +1,5 @@
{
- "env": [
- "NGINX_VERSION=1.25.3",
- "NJS_VERSION=0.8.2",
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
- "PKG_RELEASE=1~bookworm"
- ],
- "exposed_ports": [
- "80/tcp"
- ],
+ "env": [],
+ "exposed_ports": [],
"running": true
}
changed: [locahost]
I would have expected the container not to be re-created every run, the same as when you specify either the tag or the digest.