Ansible如何基于image_names遍历grouped_by_name获取最旧镜像
解决Ansible中基于镜像时间戳筛选旧镜像的问题
问题背景
你有两个JSON数据集:
- 包含镜像名称列表的
image_names:
{ "image_names": [ { "name": "sles-11-factory-os-ready" }, { "name": "sles-11-factory-base-vg00" }, { "name": "sles-11-factory-base" }, { "name": "rhel-7-factory-os-ready" }, { "name": "sles-12-factory-os-ready" }, { "name": "rhel-6-factory-os-ready" }, { "name": "rhel-7-factory-base-vg00" }, { "name": "sles-12-factory-base-vg00" }, { "name": "rhel-6-factory-base-vg00" }, { "name": "rhel-7-factory-base" }, { "name": "rhel-6-factory-base" }, { "name": "sles-12-factory-base" } ] }
- 以镜像名为键、对应镜像条目数组的
grouped_by_name:
{ "rhel-7-factory-os-ready" : [ { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" }, { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" }, { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" } ], "rhel-6-factory-os-ready" : [ { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" }, { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" }, { "id": "79334504-3e48-4411-b602-afe920e32e14", "updated": "2019-05-07T15:51:00Z" } ] }
你的需求是:遍历每个镜像,基于updated时间戳找出最旧的镜像,最终获取按rhel-6-factory-base的updated字段排序后,跳过最新项的旧镜像数据集。你尝试的Ansible代码没能成功,需要调整实现逻辑。
现有代码的问题
你之前的with_subelements用法有误,因为grouped_by_name是键值对结构,不是嵌套列表;另外代码没有对updated时间戳进行排序,也没有针对性地处理rhel-6-factory-base这个目标镜像。
修正后的解决方案
我们可以分步骤处理:先对目标镜像的条目按时间戳降序排序,再跳过第一个(最新)条目,最后循环输出旧镜像的ID。以下是完整的Ansible任务:
- name: Prepare sorted image entries for target image set_fact: sorted_target_images: >- {{ grouped_by_name['rhel-6-factory-base'] | default([]) | sort(attribute='updated', reverse=true) }} - name: Print the old images to delete debug: msg: "The images to be deleted are: {{ item.id }}" loop: "{{ sorted_target_images[1:] }}" when: sorted_target_images | length > 1
代码解释
set_fact任务:- 从
grouped_by_name中提取rhel-6-factory-base对应的镜像列表(用default([])避免键不存在时报错) - 使用
sort(attribute='updated', reverse=true)把列表按updated时间戳降序排列,这样第一个元素就是最新的镜像
- 从
debug任务:- 用
sorted_target_images[1:]获取除了第一个(最新)之外的所有旧镜像条目 - 添加
when条件,确保只有当镜像数量大于1时才执行(避免没有旧镜像时输出空内容)
- 用
如果需要遍历image_names中的所有镜像,而不仅仅是rhel-6-factory-base,可以调整为以下逻辑:
- name: Process each image name from image_names vars: current_image_entries: "{{ grouped_by_name[item.name] | default([]) | sort(attribute='updated', reverse=true) }}" debug: msg: "Old images for {{ item.name }}: {{ current_image_entries[1:] | map(attribute='id') | list }}" loop: "{{ image_names }}" when: current_image_entries | length > 1
这个版本会遍历image_names中的每个镜像名称,对每个存在的镜像条目排序后输出旧镜像ID列表。
内容的提问来源于stack exchange,提问作者harshavmb
相关产品推荐
相关产品推荐

