restore-volumes.sh: pre-create static-file symlinks from the backup's .txt manifest so the immutable ancient/freezer dirs land on /slowdisk (SSD) and extract THROUGH the symlinks via tar --keep-directory-symlink (was --dereference, which clobbered them); hot state stays on the primary disk. Cleans stale /slowdisk targets first (no leak on re-restore). Safe fallbacks: no /slowdisk / no manifest / no static paths -> normal extract. Reth excluded (reth dropped whole-dir static-file symlinks). volume-utils.sh: add delete_slowdisk_targets_for_key() — follows a volume's symlinks and sweeps the rpc_<key>__data_ pattern under /slowdisk (matches delete-volumes.sh). cleanup-volumes.sh: free the /slowdisk static data before docker volume rm (was leaking), and fix the fragile substring used/unused match to an exact name match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
Bash
Executable File
52 lines
1.7 KiB
Bash
Executable File
#!/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
|