#!/bin/bash # List (default) or, with --remove-from-disk, delete the docker volumes that are NOT # referenced by the current COMPOSE_FILE. Removal also frees the static-file data that was # offloaded to /slowdisk behind the volume's symlinks (delete_slowdisk_targets_for_key), # so nothing leaks on /slowdisk. BASEPATH="$(dirname "$0")" source $BASEPATH/.env source $BASEPATH/volume-utils.sh IFS=':' read -ra parts <<< $COMPOSE_FILE used_volumes=() for part in "${parts[@]}"; do volumes=$(get_volume_keys "$BASEPATH/$part") # Prefix each compose volume key with rpc_ to match docker's volume names. prefix="rpc_" IFS=$'\n' read -r -d '' -a volumes_array <<< "$(printf "%s\n" "${volumes[@]}" | sed "/^$/! s/^/$prefix/")" used_volumes=("${used_volumes[@]}" "${volumes_array[@]}") done on_disk=($(docker volume ls --format '{{.Name}}' | grep '^rpc_')) # A volume counts as "used" only on an EXACT name match. The previous substring test # ([[ "${used_volumes[@]}" =~ "$element" ]]) could mis-classify a volume whose name is a # substring of another (e.g. ...-pruned vs ...-pruned-trace) and wrongly purge a live one. is_used() { local v=$1 u for u in "${used_volumes[@]}"; do [[ "$u" == "$v" ]] && return 0 done return 1 } unused_volumes=() for element in "${on_disk[@]}"; do is_used "$element" || unused_volumes+=("$element") done if [ "$1" = "--remove-from-disk" ]; then # Remove each unused volume AND the /slowdisk static data behind its symlinks. for volume in "${unused_volumes[@]}"; do echo "removing unused volume: $volume" delete_slowdisk_targets_for_key "${volume#rpc_}" docker volume rm "$volume" done else printf '%s\n' "${unused_volumes[@]}" fi