Reputation: 165
I have an Ansible script that checks Linux file systems for capacity and issues a message if it is over a certain threshold.
- 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 }}"
The problem is that even though I added quiet: yes
I still get this as output on drives that are OK:
{
"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"
}
}
And this on the failed:
{
"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"
}
}
I would like to suppress everything but the assert failed message.
Upvotes: 1
Views: 2292
Reputation: 311416
The short answer is to set an explicit label
in a loop_control
directive, which will suppress the default behavior of outputting the entire loop variable for each loop iteration.
But you're also doing something odd in the vars
section of your task.
If we fix both of those, we get:
- 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 }}"
Which will output something like this for healthy filesystems:
ok: [host0] => (item=/)
And something like this for filesystems that fail your assert:
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"}
Note that the contents of ansible_mounts
may contain filesystems that legitimately have no free space (e.g., read-only squashfs or isofs mounts), or that don't have size_total
and size_available
keys. You might want to add a filter onto your task, for example:
- 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 }}"
With that filter in place, the output on my system is:
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)
Upvotes: 2