I'm rather newish to ansible and podman, and don't have a full grasp of python. So, I came up to a bit of a block on how to gather a list of container images on a system, and remove them. However only remove the image if no running container is using that image.
My initial tasks, which does work, looks like this:
- name: Gather facts about all container images
containers.podman.podman_image_info:
register: image_info
- name: remove images no longer used
containers.podman.podman_image:
name: "{{ item.Id }}"
state: absent
loop: "{{ image_info.images }}"
loop_control:
label: "{{ item.Id }}"
ignore_errors: true
However, This is not perfect, as the task will fail once it gets to an image that is in use, this is why ignore_errors: true
is set. I also do not want the large block of error output (about 200+ lines) this provides when it does fail. Overall this does what I intended it to.
My next step in this "evolution" of code is how to remove the large error output without using no_log: true
or anything similar, if possible. My thought is to compare a list of the image IDs I'm all ready gathering, to that of the running containers images. I updated the code to gather information on the containers on the system.
- name: Gather facts about all container images
containers.podman.podman_image_info:
register: image_info
- name: gather container info
containers.podman.podman_container_info:
register: container_info
- name: remove images no longer used
containers.podman.podman_image:
name: "{{ item.Id }}"
state: absent
loop: "{{ image_info.images }}"
loop_control:
label: "{{ item.Id }}"
ignore_errors: true
Then debugging the output of the container_info
variable I do see the image ID, which ends up something like container_info.containers[0].Image
as a variable I can use. My thought now is that I can use this to remove the image IDs that are in use from the list of images I have.
Here is my block, I'm not sure how I can, create this new image list with the info I have. I know I'll have to use set_facts
for this, but is it possible to loop though two different lists in a task? Or am I overthinking this and a simpler way exists that I'm not aware of. All I really want to do is avoid needing to use ignore_errors
in my code.
Update: I have setting the facts down. which looks like the following in my playbook:
- name: Setting facts for image IDs
set_fact:
image_id: "{{ image_info.images | json_query('[].Id') }}"
- name: Setting fact for Container image ID
set_fact:
container_id: "{{ container_info.containers | json_query('[].Image') }}"
This ends up giving me the following info when debuged.
TASK [docker-host : debug image_id] ***********************************************************************************************************************************************************************
ok: [dtest05] =>
image_id:
- 4bc0467496b6c7a60543069c570ef0e1be4565d25cb2bc7d524600a5fe0d3b8f
- c223664c734cbbc7213a4312af596b37a5bf5e55f93526bcb34e527efc9c4d5b
- dbcefaa52e7009f5d9b6179a256e70890d29148add0f77741ca4550ba2e2ffa6
- e911c149c0ca46a11a8b6eb604439e972685ec25abfde07eb1cdb272a9c0d1a9
- eb40451959b6c5f4aebb2b687a589a58370faab9b15faa43c0aea8d711155b9e
TASK [docker-host : debug container_id] *******************************************************************************************************************************************************************
ok: [dtest05] =>
container_id:
- dbcefaa52e7009f5d9b6179a256e70890d29148add0f77741ca4550ba2e2ffa6
I think I just need to set another fact that will remove duplicates.
Update2: Created another fact to "merge" the two other facts. Full playbook looks like this:
- name: Gather facts about all container images
containers.podman.podman_image_info:
register: image_info
- name: gather container info
containers.podman.podman_container_info:
register: container_info
- name: Setting Facts for Image IDs
set_fact:
image_id: "{{ image_info.images | json_query('[].Id') }}"
container_id: "{{ container_info.containers | json_query('[].Image') }}"
- name: Merging facts
set_fact:
merged_ids: "{{ image_id }} + {{ container_id }}"
Then the merged_id
variable outputs the following:
merged_ids:
- 4bc0467496b6c7a60543069c570ef0e1be4565d25cb2bc7d524600a5fe0d3b8f
- c223664c734cbbc7213a4312af596b37a5bf5e55f93526bcb34e527efc9c4d5b
- dbcefaa52e7009f5d9b6179a256e70890d29148add0f77741ca4550ba2e2ffa6
- e911c149c0ca46a11a8b6eb604439e972685ec25abfde07eb1cdb272a9c0d1a9
- eb40451959b6c5f4aebb2b687a589a58370faab9b15faa43c0aea8d711155b9e
- dbcefaa52e7009f5d9b6179a256e70890d29148add0f77741ca4550ba2e2ffa6
I can see the duplicate IDs in the list. How do I remove the duplicate IDs from the merged_ids
variable list?
There's a problem with your "Merging facts" tasks. You're not creating a merged list of values; you are in fact concatenating two strings. You want:
- name: Merging facts
set_fact:
merged_ids: "{{ image_id + container_id }}"
There is a unique
filter you can use to unique-ify a list:
- name: Merging facts
set_fact:
merged_ids: "{{ image_id + container_id | unique }}"