首页 > 解决方案 > 抑制 Ansible 中的断言输出

问题描述

我有一个 Ansible 脚本,它检查 Linux 文件系统的容量,如果超过某个阈值,就会发出一条消息。

- hosts: all
  gather_facts: yes
  tasks:
     - name: Collect only facts about hardware
       setup:
         gather_subset:
           - 'hardware'

     - name: Test for available disk space
       setup: filter=ansible_mounts
       
     - name: Ensure that free space on the tested volume is greater than 15%
       assert:
         that:
           - mount.size_available > mount.size_total|float * 0.05
         fail_msg: Disk space on {{ item.mount }} has reached 95% threshold. Total size is {{ mount.size_total }} bytes and the available size is {{ mount.size_available }} 
         quiet: yes
       vars:
         mount: "{{ ansible_mounts | selectattr('mount','equalto',item.mount) | list | first }}"
       with_items:
         - "{{ ansible_mounts }}"

问题是,即使我添加了,quiet: yes我仍然可以在正常的驱动器上将此作为输出:

{
    "changed": false,
    "msg": "All assertions passed",
    "_ansible_no_log": false,
    "item": {
        "mount": "/boot",
        "device": "/dev/sda2",
        "fstype": "ext4",
        "options": "rw,nodev,relatime,data=ordered",
        "size_total": 1023303680,
        "size_available": 729440256,
        "block_size": 4096,
        "block_total": 249830,
        "block_available": 178086,
        "block_used": 71744,
        "inode_total": 65536,
        "inode_available": 65223,
        "inode_used": 313,
        "uuid": "75c887d9-e8a9-45a6-9bb8-8e7ffe4b9e68"
    },
    "ansible_loop_var": "item",
    "_ansible_item_label": {
        "mount": "/boot",
        "device": "/dev/sda2",
        "fstype": "ext4",
        "options": "rw,nodev,relatime,data=ordered",
        "size_total": 1023303680,
        "size_available": 729440256,
        "block_size": 4096,
        "block_total": 249830,
        "block_available": 178086,
        "block_used": 71744,
        "inode_total": 65536,
        "inode_available": 65223,
        "inode_used": 313,
        "uuid": "75c887d9-e8a9-45a6-9bb8-8e7ffe4b9e68"
    }
} 

而这失败了:

{
    "evaluated_to": false,
    "assertion": "mount.size_available > mount.size_total|float * 0.05",
    "msg": "Disk space on /snap/core/8268 has reached 95% threshold. Size 0 Total size 93454336",
    "_ansible_no_log": false,
    "changed": false,
    "item": {
        "mount": "/snap/core/8268",
        "device": "/dev/loop0",
        "fstype": "squashfs",
        "options": "ro,nodev,relatime",
        "size_total": 93454336,
        "size_available": 0,
        "block_size": 131072,
        "block_total": 713,
        "block_available": 0,
        "block_used": 713,
        "inode_total": 12842,
        "inode_available": 0,
        "inode_used": 12842,
        "uuid": "N/A"
    },
    "ansible_loop_var": "item",
    "_ansible_item_label": {
        "mount": "/snap/core/8268",
        "device": "/dev/loop0",
        "fstype": "squashfs",
        "options": "ro,nodev,relatime",
        "size_total": 93454336,
        "size_available": 0,
        "block_size": 131072,
        "block_total": 713,
        "block_available": 0,
        "block_used": 713,
        "inode_total": 12842,
        "inode_available": 0,
        "inode_used": 12842,
        "uuid": "N/A"
    }
}

我想压制除断言失败消息之外的所有内容。

标签: ansible

解决方案


简短的回答是labelloop_control指令中设置显式,这将抑制为每次循环迭代输出整个循环变量的默认行为。

但是你也在vars你的任务部分做一些奇怪的事情。

如果我们同时解决这两个问题,我们会得到:

- hosts: all
  gather_facts: false
  tasks:
    - name: Collect only facts about hardware
      setup:
        gather_subset:
          - hardware

    - name: Test for available disk space
      setup:
        filter: ansible_mounts

    - name: Ensure that free space on the tested volume is greater than 15%
      assert:
        that:
          - item.size_available|float > item.size_total|float * 0.05
        fail_msg: Disk space on {{ item.mount }} has reached 95% threshold. Total size is {{ item.size_total }} bytes and the available size is {{ item.size_available }} 
        quiet: yes
      loop: "{{ ansible_mounts }}"
      loop_control:
        label: "{{ item.mount }}"

这将为健康的文件系统输出如下内容:

ok: [host0] => (item=/)

对于您的断言失败的文件系统,类似这样的事情:

failed: [host1] (item=/vol/failed) => {"ansible_loop_var": "item", "assertion": "item.size_available|float > item.size_total|float * 0.05", "changed": false, "evaluated_to": false, "item": {"block_available": 0, "block_size": 131072, "block_total": 444, "block_used": 444, "device": "/dev/loop4", "fstype": "squashfs", "inode_available": 0, "inode_total": 10809, "inode_used": 10809, "mount": "/vol/failed", "options": "ro,nodev,relatime", "size_available": 0, "size_total": 58195968, "uuid": "N/A"}, "msg": "Disk space on /vol/failed has reached 95% threshold. Total size is 58195968 bytes and the available size is 0"}

请注意, 的内容ansible_mounts可能包含合法没有可用空间的文件系统(例如,只读 squashfs 或 isofs 挂载),或者没有size_totalsize_available键。您可能希望在任务中添加过滤器,例如:

    - name: Ensure that free space on the tested volume is greater than 15%
      assert:
        that:
          - item.size_available|float > item.size_total|float * 0.05
        fail_msg: Disk space on {{ item.mount }} has reached 95% threshold. Total size is {{ item.size_total }} bytes and the available size is {{ item.size_available }} 
        quiet: yes
      when: >
        "size_total" in item and item.fstype in ['xfs', 'ext4']
      loop: "{{ ansible_mounts }}"
      loop_control:
        label: "{{ item.mount }}"

使用该过滤器,我的系统上的输出是:

TASK [Ensure that free space on the tested volume is greater than 15%] **************************************
ok: [localhost] => (item=/)
skipping: [localhost] => (item=/var/lib/snapd/snap/mame/2287)
ok: [localhost] => (item=/boot)
skipping: [localhost] => (item=/var/lib/snapd/snap/gtk-common-themes/1514)
ok: [localhost] => (item=/home)
skipping: [localhost] => (item=/var/lib/snapd/snap/kde-frameworks-5-core18/32)
skipping: [localhost] => (item=/var/lib/snapd/snap/snapd/10707)
skipping: [localhost] => (item=/var/lib/snapd/snap/core18/1944)
skipping: [localhost] => (item=/var/lib/snapd/snap/mame/2235)
ok: [localhost] => (item=/var/lib/libvirt)
ok: [localhost] => (item=/var/lib/containers)
ok: [localhost] => (item=/var/lib/packages)
ok: [localhost] => (item=/var/lib/mock)
ok: [localhost] => (item=/vol/log)
ok: [localhost] => (item=/scratch)
ok: [localhost] => (item=/var/cache)
skipping: [localhost] => (item=/var/lib/containers/storage/overlay)

推荐阅读