fix: rewrite tar extract onto target volumes root when it is a cross-device symlink
Hosts like rpc-us-32 put /var/lib/docker (or volumes/) on another mount; tar -C / then EXDEV on every var/lib/docker/volumes/... member. Canonicalize the deepest static prefix (readlink -f /var/lib/docker/volumes) and append a --transform after SLOWDISK_TRANSFORMS. Keying only on /var/lib/docker misses a real docker root with volumes/ as the symlink. No-op on normal hosts. Per-volume _data static-file offload stays on SLOWDISK_TRANSFORMS. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -350,6 +350,17 @@ transfer_backup() {
|
||||
echo "No metadata file found, using normal extraction"
|
||||
fi
|
||||
|
||||
|
||||
# AFTER SLOWDISK_TRANSFORMS: rewrite remaining var/lib/docker/ members onto
|
||||
# the target's real docker root when it is a cross-device symlink (see
|
||||
# docker_root_transform in volume-utils.sh).
|
||||
local _drt
|
||||
_drt=$(docker_root_transform)
|
||||
if [[ -n "$_drt" ]]; then
|
||||
echo "Target /var/lib/docker is a symlink; appending docker-root --transform (after slowdisk)"
|
||||
tar_extract_opts="${tar_extract_opts}${_drt}"
|
||||
fi
|
||||
|
||||
local file_size=$(stat -f%z "$backup_file" 2>/dev/null || stat -c%s "$backup_file" 2>/dev/null)
|
||||
|
||||
# Find an available port
|
||||
@@ -529,6 +540,17 @@ transfer_backup_ssh() {
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# AFTER SLOWDISK_TRANSFORMS: rewrite remaining var/lib/docker/ members onto
|
||||
# the target's real docker root when it is a cross-device symlink (see
|
||||
# docker_root_transform in volume-utils.sh).
|
||||
local _drt
|
||||
_drt=$(docker_root_transform)
|
||||
if [[ -n "$_drt" ]]; then
|
||||
echo "Target /var/lib/docker is a symlink; appending docker-root --transform (after slowdisk)"
|
||||
tar_extract_opts="${tar_extract_opts}${_drt}"
|
||||
fi
|
||||
|
||||
echo "Using direct SSH transfer for $key (file: $(basename "$backup_file"), size: $((file_size / 1048576))MB)"
|
||||
|
||||
pv -pterb -s "$file_size" -N "$key" < "$backup_file" | \
|
||||
|
||||
@@ -319,6 +319,17 @@ transfer_volume() {
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# AFTER SLOWDISK_TRANSFORMS: rewrite remaining var/lib/docker/ members onto
|
||||
# the target's real docker root when it is a cross-device symlink (see
|
||||
# docker_root_transform in volume-utils.sh).
|
||||
local _drt
|
||||
_drt=$(docker_root_transform)
|
||||
if [[ -n "$_drt" ]]; then
|
||||
echo "Target /var/lib/docker is a symlink; appending docker-root --transform (after slowdisk)"
|
||||
tar_extract_opts="${tar_extract_opts}${_drt}"
|
||||
fi
|
||||
|
||||
# Find an available port
|
||||
local port=$(find_available_port)
|
||||
if [[ $? -ne 0 ]]; then
|
||||
@@ -500,6 +511,17 @@ transfer_volume_ssh() {
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# AFTER SLOWDISK_TRANSFORMS: rewrite remaining var/lib/docker/ members onto
|
||||
# the target's real docker root when it is a cross-device symlink (see
|
||||
# docker_root_transform in volume-utils.sh).
|
||||
local _drt
|
||||
_drt=$(docker_root_transform)
|
||||
if [[ -n "$_drt" ]]; then
|
||||
echo "Target /var/lib/docker is a symlink; appending docker-root --transform (after slowdisk)"
|
||||
tar_extract_opts="${tar_extract_opts}${_drt}"
|
||||
fi
|
||||
|
||||
echo "Using direct SSH transfer for $key (size: $((folder_size / 1048576))MB)"
|
||||
|
||||
tar -cf - --dereference "$source_folder" 2>/dev/null | \
|
||||
|
||||
@@ -294,3 +294,32 @@ delete_slowdisk_targets_for_key() {
|
||||
done
|
||||
shopt -u nullglob
|
||||
}
|
||||
|
||||
# Echo a tar --transform fragment (leading space + quoted --transform=...) that
|
||||
# rewrites archive members from var/lib/docker/volumes/... onto the TARGET's
|
||||
# real volumes root when that path is a cross-device symlink (EXDEV under
|
||||
# tar -C /). Key on the DEEPEST static prefix — readlink -f
|
||||
# /var/lib/docker/volumes — so we cover symlinks at /var, /var/lib,
|
||||
# /var/lib/docker, OR /var/lib/docker/volumes itself (canonicalizing only
|
||||
# /var/lib/docker misses a real dir with volumes/ as the symlink).
|
||||
# Reproduced rpc-us-32 2026-07-15/18: /var on sda4, /var/lib/docker -> /docker
|
||||
# on md0 → volumes resolves to /docker/volumes. Empty when readlink -f
|
||||
# returns /var/lib/docker/volumes itself (no-op).
|
||||
# Requires SSH_CMD + DEST_HOST (set by clone-*/cache-deploy after multiplexing).
|
||||
# Must be appended AFTER any SLOWDISK_TRANSFORMS — tar applies transforms in
|
||||
# order; slowdisk-rewritten members start with slowdisk/ and must not be
|
||||
# re-touched, while remaining var/lib/docker/volumes/... members still need
|
||||
# the rewrite. Per-volume _data static-file symlinks onto /slowdisk remain the
|
||||
# SLOWDISK_TRANSFORMS mechanism — this helper only relocates the volumes root.
|
||||
# Quoting follows the SLOWDISK_TRANSFORMS '|'-delimiter + single-quote pattern
|
||||
# so the script-file listener heredoc expands once without mangling the regex.
|
||||
docker_root_transform() {
|
||||
local real
|
||||
real=$($SSH_CMD "$DEST_HOST" "readlink -f /var/lib/docker/volumes" 2>/dev/null || true)
|
||||
real="${real%/}"
|
||||
if [[ -z "$real" || "$real" == "/var/lib/docker/volumes" ]]; then
|
||||
return 0
|
||||
fi
|
||||
local rel="${real#/}"
|
||||
echo " --transform='s|^\\(\\./\\)\\?var/lib/docker/volumes/|${rel}/|'"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user