Command-line output of physical disk usage for VMs


I put this in “General” rather than “Storage” because it’s not tied to a specific storage system, or indeed any storage system.

We are running ON and I am sure you all already know how quickly disk space gets eaten up across storage clusters, there is a computing adage that “data expands to fill the disk space provided”.

Is there a way of generating a report of the amount of disk space used by each VM? I’m not interested in a per-disk report, if a VM has three separate disks then I want the total added up.

The idea here is to find the VMs that use the most disk space, and the users who own those VMs.

I can find some disk usage data in the {MONITORING { DISK_SIZE section of the ‘onevm show …’ output but that does not reflect the number of actual disks the VM is using.

The [TEMPLATE] section seemed more likely but the format is not particularly consistent, if there is more than one disk it returns a list of dictionaries but if it’s only one disk then it returns a dictionary {} .

I’m sure I could write a python script that worked out if it was just one or more disks and work out the total in that manner, but wanted to see if there was something simpler to use before applying my time to it.

The system itself understands how much disk space is in use, in the Sunstone web interface, on the dashboard it shows the amount of disk used by all the images, I just want to split that out per VM.

I guess no one else had any ideas on this so I offer you this. It is, frankly, a mess involving shell, jq, sed and awk, but it works. It could certainly be neatened up and put in to Python, which I know handles JSON data well, but jq works very efficiently in this instance.

#!/usr/bin/env bash

# Retain variable values after pipes close
shopt -s lastpipe

# Get the list of VM IDs and their owmers
onevm list --no-header -l USER,ID | while read vmowner vmid; do
        # For each VM get all the info in JSON format, strip the DISK
        # SIZE out, add the disks up and print out the VM ID and total
        # disk space used.

        # If you want per-VM data then delete the awk / sort bits on the last
        # three lines.
        onevm show --all --json $vmid | \
                jq '.VM.TEMPLATE | (.DISK)' | \
                fgrep '"SIZE":' | \
                sed -e 's/^.*SIZE": "\([^"]*\)".*$/\1/' | \
                while read dsiz
                dtot=$(expr $dtot + $dsiz)
        printf '%s\t%u\t%u\n' $vmowner $vmid $dtot
done | sort | awk 'BEGIN {o=""; t=0;}
{if ($1 != o) {if (o != "") { printf("%s\t%u\n", o, t);} o=$1; t=0} t=t+$3}
END { printf("%s\t%u\n", o, t)}' | sort -k2nr