我正在使用列表,列表字典等,但我对此一无所知。
从功能上讲,我试图了解输入列表中的安装是否都安装在其他设备上。
因此在输入中,我有一个在变量中定义的安装列表,即:
mounts:
- '/'
- '/home'
- '/foo'
诸如此类的事实
"ansible_mounts": [
{
"device": "/device1",
"mount": "/"
},
{
"device": "/device1",
"mount": "/home"
},
{
"device": "/device2",
"mount": "/boot"
},
{
"device": "/device2",
"mount": "/bar"
},
{
"device": "/device3",
"mount": "/foo"
}
]
因此,我需要构建一个在此示例中失败的任务,因为'/'
和'/home'
都安装在'/device1'
上(并且我们并不关心'/bar'
像'/device2'
一样安装在'/boot'
上,因为'/bar'
不在输入列表中。
我想出了以下元素:一个以设备为键,所有相关的坐骑为值的字典:
"filesystems_by_device": {
"/device1": [
"/",
"/home"
],
"/device2": [
"/boot",
"/bar"
],
"/device3": [
"/foo"
]
}
还有一个以mount为键,设备为值的字典(它确实可以是单个值而不是列表):
"filesystems_by_mount": {
"/": [
"/device1"
],
"/home": [
"/device1"
],
"/boot": [
"/device2"
],
"/bar": [
"/device2"
],
"/foo": [
"/device3"
]
}
我不知道如何混合这些数据来构建适当的任务。我已经尝试了几种解决方案,进行了很多测试,但是现在我需要重新审视这个问题。我迷失了这种语法。
任何帮助表示赞赏
注意:这可以轻松地以静态方式完成,也可以通过相应模块调用的bash脚本轻松完成,但是我真的想避免这种情况,并保持这种“动态”的方式进行
答案 0 :(得分:1)
您有安装列表。这个有length
个X挂接,您要检查。
您有一本字典,其中安装点为键,而相应的设备为值。
从那里,为每个安装点提取设备列表的值(如果是单个字符串,会更容易...),将它们放在展平的列表中,使该列表唯一,并获取其长度。如果此列表的长度与安装点的长度不同,则您将使任务失败。
一个例子总是比漫长的演讲更好:
- name: Fail if my mounts are not on separate devices
vars:
mount_num: "{{ mounts | length }}"
mount_devices: "{{ mounts | map('extract', filesystems_by_mount) | list | flatten | unique }}"
device_num: "{{ mount_devices | length }}"
fail:
msg: "Two or more mount are on the same device"
when: mount_num != device_num
答案 1 :(得分:1)
Q:“输入列表中的安装都安装在不同的设备上...失败,因为'/'和'/ home'都安装在'/ device1'上。” >
A:下面的任务
- assert:
that: my_mounts|intersect(mounts)|length <= 1
fail_msg: "[ERR] Too many mounts {{ my_mounts }} on {{ item.0 }}"
loop: "{{ ansible_mounts|groupby('device') }}"
vars:
my_mounts: "{{ item.1|map(attribute='mount')|list }}"
给予(删节)
failed: ...
ansible_loop_var: item
assertion: my_mounts|intersect(mounts)|length <= 1
evaluated_to: false
item:
- /device1
- - device: /device1
mount: /
- device: /device1
mount: /home
msg: '[ERR] Too many mounts [''/'', ''/home''] on /device1'
ansible_loop_var: item
item:
- /device2
- - device: /device2
mount: /boot
- device: /device2
mount: /bar
msg: All assertions passed
ansible_loop_var: item
item:
- /device3
- - device: /device3
mount: /foo
msg: All assertions passed