0

Im using stat module to get the size of folders and files like below:

cat test.yml

- name: "Play 1"
  hosts: localhost
  tasks:

    - name: Check file size
      stat:
        path: "{{ inputf }}"
      register: file_size

    - name: Report file size
      debug:
        msg: "{{ ( file_size.stat.size / 1024 / 1024 ) | int }}MiB"

    - debug:
        msg: "ITEM IS {{ inputf }} and DETT: {{ file_size }}"

Below is how i run my playbook:

ansible-playbook test.yml -e inputf=/web/playbooks/automation/getfiles/filedump/file1.out

This works fine and i get the size of the file.

Output:

TASK [Report file size] *******************************************************************************
Monday 12 September 2022  02:03:43 -0500 (0:00:02.785)       0:00:04.555 ******
ok: [localhost] => {
    "msg": "817MiB"
}

TASK [debug] ******************************************************************************************
Monday 12 September 2022  02:03:43 -0500 (0:00:00.069)       0:00:04.624 ******
ok: [localhost] => {
    "msg": "ITEM IS /web/playbooks/automation/getfiles/filedump/file1.out and DETT: {'changed': False, 'stat': {'exists': True, 'path': '/web/playbooks/automation/getfiles/filedump/file1.out', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 600000008, 'gid': 64395, 'size': 856686592, 'inode': 53385579, 'dev': 64770, 'nlink': 1, 'atime': 1662960143.5284567, 'mtime': 1662807256.140487, 'ctime': 1662807256.140487, 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False, 'blocks': 1673216, 'block_size': 4096, 'device_type': 0, 'readable': True, 'writeable': True, 'executable': False, 'pw_name': 'wladmin', 'gr_name': 'aces', 'checksum': 'd380e27655ab9a2d4a4e157f68ec330e002f1c06', 'mimetype': 'application/octet-stream', 'charset': 'binary', 'version': '18446744072265319601', 'attributes': [], 'attr_flags': ''}, 'failed': False}"
}

However, when i provide a folder/directory instead of the file it always returns 0MB

ansible-playbook test.yml -e inputf=/web/playbooks/automation/getfiles/filedump/

Output:

TASK [Report file size] *******************************************************************************
Monday 12 September 2022  02:04:04 -0500 (0:00:00.572)       0:00:02.300 ******
ok: [localhost] => {
    "msg": "0MiB"
}

TASK [debug] ******************************************************************************************
Monday 12 September 2022  02:04:04 -0500 (0:00:00.078)       0:00:02.378 ******
ok: [localhost] => {
    "msg": "ITEM IS /web/playbooks/automation/getfiles/filedump and DETT: {'changed': False, 'stat': {'exists': True, 'path': '/web/playbooks/automation/getfiles/filedump', 'mode': '0755', 'isdir': True, 'ischr': False, 'isblk': False, 'isreg': False, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 600000008, 'gid': 64395, 'size': 57, 'inode': 53385577, 'dev': 64770, 'nlink': 2, 'atime': 1662961550.851861, 'mtime': 1662807259.3727617, 'ctime': 1662807259.3727617, 'wusr': True, 'rusr': True, 'xusr': True, 'wgrp': False, 'rgrp': True, 'xgrp': True, 'woth': False, 'roth': True, 'xoth': True, 'isuid': False, 'isgid': False, 'blocks': 0, 'block_size': 4096, 'device_type': 0, 'readable': True, 'writeable': True, 'executable': True, 'pw_name': 'wladmin', 'gr_name': 'aces', 'mimetype': 'inode/directory', 'charset': 'binary', 'version': '367679943', 'attributes': [], 'attr_flags': ''}, 'failed': False}"
}

I m looking for a generic solution to get size in MBs whether i provide file or folder.

I was also expecting ansible to have a module to provide this fuctionality for both file and folders.

Can you please suggest?

Ashar
  • 2,942
  • 10
  • 58
  • 122

2 Answers2

1
- name: get size of current folder, subfolders and files in this folder
  shell: shell: "df -h . ; du -sh -- * | sort -h ; du -sh . | sort -h"
  register: size
  changed_when: false
  args:
    chdir: /var

- debug:
    msg: "{{ size.stdout }}"

To have pretty output, configure in your ansible.cfg:

stdout_callback = yaml
Kevin C
  • 4,851
  • 8
  • 30
  • 64
  • i tried you solution but there are 2 problems 1. It is not generic to work for both file or folder. 2. I dont get the total folder size which is `2451MB` here is the output: `$ cd /web/playbooks/automation/getfiles/filedump/; du -sh -- * | sort -h -> Output: 817M file1.out 817M file2.out 817M file3.out ` – Ashar Sep 12 '22 at 07:58
  • edited my answer, this should work. If not, try to play around with 'df'. – Kevin C Sep 12 '22 at 08:08
1

I believe if we break it down into shell script and ansible playbook it would be easier. Here's a sample implementation.

test.yaml

## Playbok to run a shell script on localhost

- hosts: localhost
  environment:
    input: ""
  tasks:
    - name: Run a shell script
      shell: bash test.sh {{ input }}
      register: result
    - name: Print the output
      debug: var=result.stdout_lines

test.sh

#!/bin/bash

# Function to check if input is file or directory
function check_file_or_dir() {
    if [ -f "$1" ]; then
        # echo "File"
        filesize $1
    elif [ -d "$1" ]; then
        # echo "Directory"
        dirsize $1
    else
        echo "Invalid input"
    fi
}

# Function to find the size of all files and folders in a directory recursively
function dirsize() {
    du -sh "$1"/* | sort -h
}

# Function to find the size of a file
function filesize() {
    du -sh "$1"
}

check_file_or_dir $1

Run

─ ansible-playbook test.yaml -e "input=test.sh" 

PLAY [localhost] *******************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************
ok: [localhost]

TASK [Run a shell script] **********************************************************************************************************************************
changed: [localhost]

TASK [Print the output] ************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "4.0K\ttest.sh"
    ]
}

PLAY RECAP *************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


─ ansible-playbook test.yaml -e "input=/tmp/tmpdir"

PLAY [localhost] *******************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************
ok: [localhost]

TASK [Run a shell script] **********************************************************************************************************************************
changed: [localhost]

TASK [Print the output] ************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "4.0K\t/tmp/tmpdir/test.sh",
        "4.0K\t/tmp/tmpdir/test.yaml"
    ]
}

PLAY RECAP *************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

You can obviously change the du command to get the info in required format.

codeaprendiz
  • 2,703
  • 1
  • 25
  • 49