77 行
2.3 KiB
Bash
可执行文件
77 行
2.3 KiB
Bash
可执行文件
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
BACKUP_FILE="${1:-${BACKUP_FILE:-}}"
|
|
if [[ -z "${BACKUP_FILE:-}" ]]; then
|
|
echo "Usage: $0 <backup-file.tar.gz>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$BACKUP_FILE" ]]; then
|
|
echo "[ERR] backup file not found: $BACKUP_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
STORAGE_DIR_HOST="${2:-${STORAGE_DIR_HOST:-}}"
|
|
if [[ -z "$STORAGE_DIR_HOST" ]]; then
|
|
echo "[ERR] explicit restore target is required as the second argument or STORAGE_DIR_HOST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${RESTORE_SCOPE:-}" != "shadow" ]]; then
|
|
echo "[ERR] RESTORE_SCOPE=shadow is required; production restore is not available from this command path" >&2
|
|
exit 1
|
|
fi
|
|
|
|
TARGET_PATH="$(realpath -m "$STORAGE_DIR_HOST")"
|
|
LIVE_STORAGE_PATH="$(realpath -m "$ROOT_DIR/deploy/trialrun/data/storage")"
|
|
if [[ "$TARGET_PATH" == "/" || "$TARGET_PATH" == "$ROOT_DIR" || "$TARGET_PATH" == "$LIVE_STORAGE_PATH" ]]; then
|
|
echo "[ERR] unsafe storage restore target" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -d "$TARGET_PATH" && -n "$(find "$TARGET_PATH" -mindepth 1 -print -quit)" ]]; then
|
|
echo "[ERR] storage restore target must be empty: $TARGET_PATH" >&2
|
|
exit 1
|
|
fi
|
|
|
|
validate_archive_entries() {
|
|
local entry normalized part listing_line
|
|
tar -tzf "$BACKUP_FILE" >/dev/null
|
|
while IFS= read -r entry; do
|
|
if [[ -z "$entry" || "$entry" == /* ]]; then
|
|
echo "[ERR] unsafe archive path" >&2
|
|
return 1
|
|
fi
|
|
normalized="${entry#./}"
|
|
[[ -z "$normalized" || "$normalized" == "." ]] && continue
|
|
IFS='/' read -r -a path_parts <<<"$normalized"
|
|
for part in "${path_parts[@]}"; do
|
|
if [[ "$part" == ".." ]]; then
|
|
echo "[ERR] unsafe archive path segment" >&2
|
|
return 1
|
|
fi
|
|
done
|
|
done < <(tar -tzf "$BACKUP_FILE")
|
|
|
|
tar -tvzf "$BACKUP_FILE" >/dev/null
|
|
while IFS= read -r listing_line; do
|
|
if [[ "${listing_line:0:1}" == "l" || "${listing_line:0:1}" == "h" ]]; then
|
|
echo "[ERR] storage archive links are not allowed" >&2
|
|
return 1
|
|
fi
|
|
done < <(tar -tvzf "$BACKUP_FILE")
|
|
}
|
|
|
|
validate_archive_entries
|
|
mkdir -p "$TARGET_PATH"
|
|
|
|
echo "[INFO] Storage restore start: $BACKUP_FILE"
|
|
echo "[INFO] Storage target confirmed: shadow"
|
|
|
|
tar -xzf "$BACKUP_FILE" --no-same-owner --no-same-permissions -C "$TARGET_PATH"
|
|
|
|
echo "[OK] Storage restore done: $BACKUP_FILE"
|