Files
ethereum-rpc-docker/volume-utils.sh
Claude Agent 345538954d restore/cleanup: implement static-file -> /slowdisk offload + free it on removal
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>
2026-06-15 03:05:04 +00:00

101 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# Shared helpers for compose volume operations.
# Ephemeral volumes (init-container config) are excluded from backup/restore/size.
is_ephemeral_volume_key() {
local key=$1
local compose_file=$2
# op-node rollup config volumes
[[ "$key" == *_node_config ]] && return 0
if [[ -n "$compose_file" && -f "$compose_file" ]]; then
local ephemeral
ephemeral=$(yaml2json < "$compose_file" 2>/dev/null | jq -r '.["x-ephemeral-volumes"] // [] | .[]' 2>/dev/null)
while IFS= read -r vol; do
[[ -z "$vol" ]] && continue
[[ "$key" == "$vol" ]] && return 0
done <<< "$ephemeral"
fi
return 1
}
get_volume_keys() {
local compose_file=$1
yaml2json < "$compose_file" 2>/dev/null | jq -r '.volumes | keys[]' 2>/dev/null
}
get_persistent_volume_keys() {
local compose_file=$1
local key
while IFS= read -r key; do
[[ -z "$key" ]] && continue
if ! is_ephemeral_volume_key "$key" "$compose_file"; then
echo "$key"
fi
done < <(get_volume_keys "$compose_file")
}
# Returns 0 when a backup HTTP/WebDAV URL refers to this machine.
is_local_backup_url() {
local url=$1
[[ -z "$url" ]] && return 1
local host="${url#*://}"
host="${host%%/*}"
host="${host%%:*}"
[[ -z "$host" ]] && return 1
case "$host" in
localhost|127.0.0.1|::1|0.0.0.0) return 0 ;;
esac
local env_file
env_file="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.env"
if [[ -f "$env_file" ]]; then
local domain ip
domain=$(grep -E '^DOMAIN=' "$env_file" | head -n 1 | cut -d= -f2- | tr -d '"' | tr -d "'")
ip=$(grep -E '^IP=' "$env_file" | head -n 1 | cut -d= -f2- | tr -d '"' | tr -d "'")
[[ -n "$domain" && "$host" == "$domain" ]] && return 0
[[ -n "$ip" && "$host" == "$ip" ]] && return 0
fi
local local_fqdn local_short
local_fqdn=$(hostname -f 2>/dev/null || true)
local_short=$(hostname 2>/dev/null || true)
[[ -n "$local_fqdn" && "$host" == "$local_fqdn" ]] && return 0
[[ -n "$local_short" && "$host" == "$local_short" ]] && return 0
return 1
}
# Delete the /slowdisk static-file offload targets for a single volume key, so removing a
# volume also frees the static data behind the symlinks (otherwise it leaks on /slowdisk).
# Safe: scoped to the key and to /slowdisk, and only removes dirs matching the
# rpc_<key>__data_ naming this repo creates (the same pattern delete-volumes.sh deletes).
delete_slowdisk_targets_for_key() {
local key=$1
[[ -z "$key" ]] && return 0
[[ -d /slowdisk ]] || return 0
local data_dir="/var/lib/docker/volumes/rpc_${key}/_data"
# 1) follow live symlinks in the volume and delete their /slowdisk targets
if [[ -d "$data_dir" ]]; then
while IFS= read -r -d '' l; do
local t; t=$(readlink -f "$l" 2>/dev/null)
if [[ -n "$t" && -d "$t" && "$t" == /slowdisk/rpc_${key}__data_* ]]; then
echo " rm slowdisk static target $t"; rm -rf "$t"
fi
done < <(find "$data_dir" -type l -print0 2>/dev/null)
fi
# 2) sweep any orphaned targets for this key (re-restore / dangling-symlink safety)
local t
shopt -s nullglob
for t in /slowdisk/rpc_${key}__data_*; do
[[ -d "$t" ]] && { echo " rm orphan slowdisk static target $t"; rm -rf "$t"; }
done
shopt -u nullglob
}