我有一组名为“db”的主机,其节点数可能会有所不同。每个节点都有一个事实(“seqno”),它是一个整数。
我需要在所有主机中比较这个事实并选择最大值,然后在具有此最大值的一个(且仅一个)主机上运行一些操作。如果多个节点具有相同的值,则应选择第一个节点。
我试过这种方法:
- name: find max seqno value
set_fact: seqno_max={{ [hostvars[groups['db'][0]]['seqno'], hostvars[groups['db'][1]]['seqno']] | max }}
- name: find single hostname to use as a node with max seqno
set_fact: seqno_max_host={{ hostvars[item]['inventory_hostname'] }}
with_items: groups['db'][::-1] # reverse list. if two nodes have the same seqno, use first node as starting point.
when: hostvars[item]['seqno'] == seqno_max
- name: Some actions based on a result of previous tasks
action: # Run some actions
when: seqno_max_host == inventory_hostname
但由于某种原因,“max”运算符始终返回第二个值。此方法只有在您拥有任意指定数量的主机时才有效 - 我希望有一个适用于任意数量主机的解决方案。
编辑:事实证明,hostvars将整数转换回字符串,因此比较它们会产生意外结果。对int
过滤器内的每个hostvars参考重新应用max
过滤器有帮助。不过,问题仍然是如何修复上面的代码以使其适用于任意数量的主机 - 是否可以不编写自定义过滤器或创建临时模板?
答案 0 :(得分:0)
我最终得到的解决方案不是很漂亮,但很有效。
- shell: "if [ {{ hostvars[inventory_hostname]['seqno'] }} -lt {{ hostvars[item]['seqno'] }} ]; then echo {{ hostvars[item]['seqno'] }}; fi"
with_items: groups['db']
register: result_c
- set_fact: seqno_max={{ hostvars[inventory_hostname]['seqno'] }}
when: result_c.results | map(attribute='stdout') | join('') == ""