我需要一些看起来微不足道但我无法处理的东西
"ansible_mounts": [
{
"device": "/device1",
"mount": "/"
},
{
"device": "/device1",
"mount": "/home"
},
{
"device": "/device2",
"mount": "/boot"
}
]
我需要一本以设备为键、以挂载为值的字典。我不知道如何获得列表作为值,我只知道如何获得单个项目(因此在每个循环中,最后一个项目都被覆盖(:
- name: Getting all the mounted filesystems (by device)
ansible.builtin.set_fact:
filesystems_by_device: "{{ item }}"
with_items:
- "{{ ansible_mounts | items2dict(key_name='device', value_name='mount') }}"
输出为:
"filesystems_by_device": {
"device2": "/boot",
"device1": "/home"
}
我需要:
"filesystems_by_device": {
"device2": [ "/boot" ],
"device1": [ "/", "/home" ]
}
例如,我了解如何从过滤后的列表中构建列表,我可能需要应用类似于我的字典的东西:
- name: List from filtered one
set_fact:
foo: "{{ foo + [item] }}"
with_items:
- "{{ ansible_mounts }}"
when: item.mount in another_list
vars:
foo: []
我尝试了很多东西,但我对这种语法感到困惑。
感谢的任何帮助
这实际上并不像看上去那么微不足道,我认为除非开发自定义过滤器,否则没有一个解决方案不在任务中循环(正如您已经尝试过的那样(。以下是我如何在简单的标准ansible中实现这一点。
- 在列表中设备的唯一名称上创建一个循环
- 每个项目的set_fact提取该设备的装载点的值
演示剧本:
---
- hosts: localhost
gather_facts: false
vars:
"ansible_mounts": [
{
"device": "/device1",
"mount": "/"
},
{
"device": "/device1",
"mount": "/home"
},
{
"device": "/device2",
"mount": "/boot"
}
]
tasks:
- name: Construct the needed datastructure
set_fact:
filesystems_by_device: >-
{{
filesystems_by_device | default({})
| combine({
item: ansible_mounts | selectattr('device', 'eq', item) | map(attribute='mount') | list
})
}}
loop: "{{ ansible_mounts | map(attribute='device') | unique | sort }}"
- name: Show result
debug:
var: filesystems_by_device
结果:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Construct the needed datastructure] **********************************************************************************************************************************************************************************************
ok: [localhost] => (item=/device1)
ok: [localhost] => (item=/device2)
TASK [Show result] *********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"filesystems_by_device": {
"/device1": [
"/",
"/home"
],
"/device2": [
"/boot"
]
}
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0