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>
101 lines
3.2 KiB
Bash
Executable File
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
|
|
}
|