Skip to content

Instantly share code, notes, and snippets.

@lucaspar
Last active December 10, 2024 15:09
Show Gist options
  • Save lucaspar/57d91d95cff220a808c7f2da4e233641 to your computer and use it in GitHub Desktop.
Save lucaspar/57d91d95cff220a808c7f2da4e233641 to your computer and use it in GitHub Desktop.
Lists dangling docker volumes and their sizes
#!/usr/bin/env bash
# Usage: dckr-volumes [OPTIONS]
# Lists dangling Docker volumes and their sizes.
# Options:
# -h, --help Shows this help message and exit
# -a, --all Lists all Docker volumes and their sizes, not only dangling ones
# --no-header Hides the header
#
set -euo pipefail
# loop through each volume and calculate its size
function list_vols_and_sizes() {
# params
no_header=false
for arg in "$@"; do
case $arg in
--no-header)
no_header=true
;;
esac
done
# variables
header_l1="VOLUME NAME,SIZE,CREATION DATE"
header_l2="-----------,----,-------------"
VOLUMES=${1}
declare -a lines
# gather info
sudo -v -p "[sudo] I need root access to list volume sizes: "
for volume_name in $VOLUMES; do
SIZE=$(sudo du -sh "${DOCKER_VOLUME_DIR}/${volume_name}/_data" 2>/dev/null | awk '{print $1}')
CREATION_DATE=$(docker volume inspect "${volume_name}" --format '{{.CreatedAt}}' | cut -d'T' -f1)
LINE="${volume_name},${SIZE},${CREATION_DATE}"
lines+=("${LINE}")
done
# sudo -k # commented out to avoid asking for password again on subsequent runs
# sorting and formatting
mapfile -t lines_sorted < <(printf "%s\n" "${lines[@]}" | sort -t, -k2 -h)
if [[ "$no_header" == false ]]; then
lines_sorted=("${header_l1}" "${header_l2}" "${lines_sorted[@]}")
fi
mapfile -t lines_fmt < <(printf "%s\n" "${lines_sorted[@]}" | column -t -s, -o " | ")
# print formatted output
for line in "${lines_fmt[@]}"; do
echo "${line}"
done
}
function show_help_and_exit() {
echo -e "\n\tUsage: \033[34m$(basename "$0") [OPTIONS]\033[0m\n"
echo -e "Lists dangling Docker volumes and their sizes."
echo -e "\n\tOptions:"
echo -e "\t -h, --help Shows this help message and exit"
echo -e "\t -a, --all Lists all Docker volumes and their sizes, not only dangling ones"
echo -e "\t --no-header Hides the header"
echo -e "\n"
exit 0
}
# List dangling Docker volumes and their sizes.
function main() {
# directory where Docker volumes are stored.
DOCKER_VOLUME_DIR="$(docker info --format '{{.DockerRootDir}}')/volumes"
list_mode="dangling"
no_header=false
while getopts "ah-:" opt; do
case $opt in
a)
list_mode="all"
;;
h)
show_help_and_exit
;;
-)
case "${OPTARG}" in
all)
list_mode="all"
;;
no-header)
no_header=true
;;
help)
show_help_and_exit
;;
*)
echo "Invalid long option: --${OPTARG}" >&2
exit 1
;;
esac
;;
\?)
echo "Invalid short option: -${OPTARG}" >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [[ "$list_mode" == "dangling" ]]; then
echo "Listing dangling volumes..." >&2
VOLUMES=$(docker volume ls -qf dangling=true)
echo "Found $(echo "${VOLUMES}" | wc -w) dangling volumes"
else
echo "Listing all volumes..." >&2
VOLUMES=$(docker volume ls -q)
echo "Found $(echo "${VOLUMES}" | wc -w) volumes (all volumes)" >&2
fi
if [[ "$no_header" == false ]]; then
list_vols_and_sizes "${VOLUMES}"
else
list_vols_and_sizes "${VOLUMES}" --no-header
fi
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment