I want to check a directory with Ansible if it's not empty.
Since it is not defined what empty means and if there could be zero byte files, I understand your question that you are interested in the folder size.
According Use folder size in Conditional
The size attribute returned by the stat module for a folder does not tell you the size of the folder's contents! It only reports the size of the directory entry, which may depend on a number of factors such as the number of files contained in the directory.
If you're looking to calculate the amount of data contained in a folder, you may proceed further with the answer there or Ansible: Need generic solution to find size of folder/directory or file.
Since that require to use command
or shell
which is not generally recommended for all cases, it might be possible to transfer the task into a Custom Module. To do so, creating a Custom Module written in Bash or Shell seems to be the best approach.
The following concept / example module takes a string parameter (path
) and test if it is a directory or file. After it is providing the size of the directory with all files and including sub directories or the file size only as results set.
Concept / Example Module size.sh
#!/bin/sh
exec 3>&1 4>&2 > /dev/null 2>&1
# Create functions
function return_json() {
exec 1>&3 2>&4
jq --null-input --monochrome-output \
--arg changed "$changed" \
--arg rc "$rc" \
--arg stdout "$stdout" \
--arg stderr "$stderr" \
--arg directory "$directory" \
--arg file "$file" \
--arg msg "$msg" \
'$ARGS.named'
exec 3>&1 4>&2 > /dev/null 2>&1
}
# Module helper functions
function dirsize() {
du -sh "$path" | sort -h
}
function filesize() {
du -sh "$path"
}
# Module main logic
function module_logic() {
if [ -f "$path" ]; then
filesize $path
file="true"
elif [ -d "$path" ]; then
dirsize $path
directory="true"
else
stderr="Cannot access: No such file or directory or Permission denied."
rc=1
fi
}
# Set default values
changed="false"
rc=0
stdout=""
stderr=""
directory="false"
file="false"
msg=""
source "$1"
# Check prerequisites
if ! which jq &>/dev/null; then
exec 1>&3 2>&4
printf "{ \"changed\": \"$changed\",
\"rc\": \"1\" ,
\"stdout\": \"\",
\"stderr\": \"Command not found: This module require 'jq' installed on the target host. Exiting ...\",
\"directory\": \"false\" ,
\"file\": \"false\",
\"msg\": \"\"}"
exit 127
fi
if ! grep -q "Red Hat Enterprise Linux" /etc/redhat-release; then
stderr="Operation not supported: Red Hat Enterprise Linux not found. Exiting ..."
rc=95
return_json
exit $rc
fi
# Validate parameter key and value
if [ -z "$path" ]; then
stderr="Invalid argument: Parameter path is not provided. Exiting ..."
rc=22
return_json
exit $rc
fi
if [[ $path == *['!:*']* ]]; then
stderr="Invalid argument: Value path contains invalid characters. Exiting ..."
rc=22
return_json
exit $rc
fi
if [ ${#path} -ge 127 ]; then
stderr="Argument too long: Value path has too many characters. Exiting ..."
rc=7
return_json
exit $rc
fi
# Main
module_logic $path
changed="false"
msg=$(module_logic $path | sed 's/\t/ /g')
return_json
exit $rc
Test Playbook size.yml
---
- hosts: test
become: false
gather_facts: false
tasks:
- name: Get size behind path
size:
path: /root/anaconda-ks.cfg
register: result
ignore_errors: true
- name: Get size behind path
size:
path: ''
register: result
ignore_errors: true
- name: Get size behind path
size:
register: result
ignore_errors: true
- name: Get size behind path
size:
path: "/home/{{ ansible_user }}/*"
register: result
ignore_errors: true
- name: Get size behind path
size:
path: "/home/{{ ansible_user }}/1111111111/2222222222/3333333333/4444444444/5555555555/6666666666/7777777777/8888888888/9999999999/0000000000/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/"
register: result
ignore_errors: true
- name: Get size behind path
size:
path: /home/{{ ansible_user }}
register: result
- name: Show result
debug:
var: result
Result ansible-playbook --user ${ANSIBLE_USER} size.yml
TASK [Get size behind path] **********************************************
fatal: [test.example.com]: FAILED! => changed=false
msg: ''
rc: '1'
stderr: 'Cannot access: No such file or directory or Permission denied.'
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
...ignoring
TASK [Get size behind path] **********************************************
fatal: [test.example.com]: FAILED! => changed=false
msg: ''
rc: '1'
stderr: Parameter path is not provided. Exiting ...
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
...ignoring
TASK [Get size behind path] **********************************************
fatal: [test.example.com]: FAILED! => changed=false
directory: 'false'
file: 'false'
msg: ''
rc: '22'
stderr: 'Invalid argument: Value path contains invalid characters. Exiting ...'
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
...ignoring
TASK [Get size behind path] **********************************************
fatal: [test.example.com]: FAILED! => changed=false
msg: ''
rc: '7'
stderr: Argument 'path' too long. Exiting ...
stderr_lines: <omitted>
stdout: ''
stdout_lines: <omitted>
...ignoring
TASK [Get size behind path] **********************************************
changed: [test.example.com]
TASK [Show result] *******************************************************
ok: [test.example.com] =>
result:
changed: 'false'
failed: false
msg: 722M /home/user
rc: '0'
stderr: ''
stderr_lines: []
stdout: ''
stdout_lines: []
Thanks to
For script and module
For general Linux and Shell