【问题标题】:How to list hosts with larger than average RAM?如何列出具有大于平均 RAM 的主机?
【发布时间】:2021-11-12 18:53:00
【问题描述】:

Ansible 已经完成了“事实收集”,hostvars 中的每个主机都已经设置了 ansible_memory_mb.real.total

如何选择数量高于平均水平的主机?一定有一个 Jinja 过滤单线,我想不通...

【问题讨论】:

    标签: ansible jinja2 json-query


    【解决方案1】:

    例如,提取你想要的变量

      mems: "{{ ansible_play_hosts|
                map('extract', hostvars, 'ansible_memfree_mb')|
                list }}"
    
      mems:
      - 99
      - 84
      - 86
    

    注意:要提取ansible_memory_mb.real.total试试

      mems: "{{ ansible_play_hosts|
                map('extract', hostvars, ['ansible_memmory_mb','real','total'])|
                list }}"
    

    并创建字典

      hosts_mems: "{{ dict(ansible_play_hosts|zip(mems)) }}"
    
      hosts_mems:
        host01: 99
        host02: 84
        host03: 86
    

    计算平均值

      mems_average: "{{ hosts_mems.values()|sum / hosts_mems.values()|length }}"
    
      mems_average: '89.66666666666667'
    

    并选择内存大于平均水平的主机

      hosts_mems_high: "{{ hosts_mems|dict2items|
                           selectattr('value', 'gt', mems_average|int)|items2dict }}"
    
      hosts_mems_high:
        host01: 99
    

    如果您想要“Jinja 过滤单线”,即如果您想减少变量的数量,请随意替换。

    【讨论】:

    • 谢谢,@弗拉基米尔。但是这种方法有效,但会将字典转换为列表 - 然后将其压缩回字典 - 多次。没有什么更短——更快?比如说hostvars | json_query(......)?
    • 如果你找到任何告诉我。
    【解决方案2】:

    这就是我最终如何做到的。不完全是 one-liner - 我需要先计算平均 RAM,我所做的非常像 @Vladimir-Botka 在他的回答中建议的那样。

    我的方法避免了dict2itemszip,但是,在我看来,这使它更胜一筹:

    - name: Figure out, if there is a business server with spare RAM
      set_fact:
        spareserver: >-
          {{ (groups.business |
            map('extract', hostvars) |
            selectattr('ansible_memory_mb.real.total', 'gt', avgram | float) |
            first).ansible_hostname }}
      vars:
        ramsizes: >-
          {{ groups.business |
            map('extract', hostvars, [
                'ansible_memory_mb', 'real', 'total'
            ]) |
            list }}
        avgram: '{{ (ramsizes | sum) / (ramsizes | length) }}'
    

    观察:

    1. 需要显式转换为float 要么是一个错误,要么是一个非常烦人的“功能”。 avgram 的值是算术表达式的结果——为什么临时任务变量记录为 string,必须再次强制返回 float?还可能损失精度?
    2. 我向hostvars 申请了两次map('extract') -- 我不喜欢这样,但我不知道如何避免 -- 欢迎提出建议。
    3. 我还是不明白,为什么json_query 不起作用。下面没有产生任何错误 - 但spareserver
    - set_fact:
        spareserver: >-
          {{ hostvars | json_query('[?ansible_memory_mb.real.total > `{{ avgram }}`]') }}
    
    1. 谁因为我向 Vladimir 寻求更好的解决方案而降级了我的问题,应该停止使用 StackOverflow。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      相关资源
      最近更新 更多