File size: 4,549 Bytes
17e971c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env bash
set -euo pipefail

# Preserve HF Space variables (from os.environ) before sourcing env files
# Priority: HF Space vars > env files
_HF_SPACE_VARS=(
  "OPENCLAW_BACKUP_DATASET_REPO"
  "OPENCLAW_RESTORE_DATASET_REPO"
  "OPENCLAW_BACKUP_ENABLED"
  "OPENCLAW_BACKUP_NPM_ENABLED"
  "OPENCLAW_RESTORE_NPM_ENABLED"
  "OPENCLAW_VERSION"
  "HF_TOKEN"
  "HF_STORAGE_REPO"
)
declare -A _PRESERVED_HF_VARS
for _var in "${_HF_SPACE_VARS[@]}"; do
  if [[ -n "${!_var:-}" ]]; then
    _PRESERVED_HF_VARS["$_var"]="${!_var}"
  fi
done

# 恢复日志配置
RESTORE_LOG_DIR="${OPENCLAW_RESTORE_LOG_DIR:-/var/log/openclaw}"
RESTORE_LOG_FILE="${RESTORE_LOG_DIR}/restore.log"

# 确保日志目录存在
mkdir -p "$RESTORE_LOG_DIR"

# 日志函数
restore_log() {
  local level="$1"
  shift
  local message="$*"
  local timestamp
  timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
  echo "[$timestamp] [$level] $message" | timeout 1 tee -a "$RESTORE_LOG_FILE" 2>/dev/null || echo "[$timestamp] [$level] $message"
}

restore_log_info() {
  restore_log "INFO" "$@"
}

restore_log_warn() {
  restore_log "WARN" "$@"
}

restore_log_error() {
  restore_log "ERROR" "$@" >&2
}

restore_log_info "=== Starting Backup Restore ==="
restore_log_info "Restore started at: $(date -u +"%Y-%m-%d %H:%M:%S UTC")"

BACKUP_ENV_FILE_PATH="${OPENCLAW_BACKUP_ENV_FILE_PATH:-/root/.env.d/openclaw-backup.env}"
if [[ -f "$BACKUP_ENV_FILE_PATH" ]]; then
  # shellcheck disable=SC1091
  source "$BACKUP_ENV_FILE_PATH"
  restore_log_info "Loaded backup environment from: $BACKUP_ENV_FILE_PATH"
else
  restore_log_warn "Backup environment file not found: $BACKUP_ENV_FILE_PATH"
fi

# Restore HF Space variables (they take priority over env files)
for _var in "${!_PRESERVED_HF_VARS[@]}"; do
  export "$_var"="${_PRESERVED_HF_VARS[$_var]}"
done
unset _HF_SPACE_VARS _PRESERVED_HF_VARS _var

# 记录恢复配置信息
restore_log_info "Restore Configuration:"
# 多数据集支持:优先使用 OPENCLAW_RESTORE_DATASET_REPO,否则使用 OPENCLAW_BACKUP_DATASET_REPO
RESTORE_DATASET_REPO="${OPENCLAW_RESTORE_DATASET_REPO:-${OPENCLAW_BACKUP_DATASET_REPO:-}}"
if [[ -z "${RESTORE_DATASET_REPO:-}" ]]; then
  restore_log_warn "Restore skipped: no dataset configured"
  restore_log_warn "  OPENCLAW_RESTORE_DATASET_REPO: ${OPENCLAW_RESTORE_DATASET_REPO:-<not set>}"
  restore_log_warn "  OPENCLAW_BACKUP_DATASET_REPO: ${OPENCLAW_BACKUP_DATASET_REPO:-<not set>}"
  exit 2
fi
restore_log_info "  Restore Source Dataset: ${RESTORE_DATASET_REPO}"
restore_log_info "  Backup Dataset: ${OPENCLAW_BACKUP_DATASET_REPO:-<not set>}"
restore_log_info "  State Dir: ${OPENCLAW_STATE_DIR:-/root/.openclaw}"
restore_log_info "  Backup Source Dir: ${OPENCLAW_BACKUP_SOURCE_DIR:-<not set>}"
restore_log_info "  Path Prefix: ${OPENCLAW_BACKUP_PATH_PREFIX:-backups}"


# 检查数据集配置
if [[ -z "${OPENCLAW_BACKUP_DATASET_REPO:-}" ]]; then
  restore_log_warn "Restore skipped: OPENCLAW_BACKUP_DATASET_REPO is not set"
  restore_log_warn "Backup target dataset is required for restore"
  exit 2
fi

# 注意:容器重启/重建时总是执行恢复,这是设计决定的
restore_log_info ""
restore_log_info "Starting restore process from dataset: ${RESTORE_DATASET_REPO}"
restore_log_info "----------------------------------------"

# Run restore with logging that won't block on disk full / write errors
# Use a subshell to capture exit code independently of tee's exit status
restore_exit_code=0
restore_output=$(python3 /opt/openclaw-hf/openclaw_hf/backup.py restore 2>&1) || restore_exit_code=$?

# Write to log file without affecting restore result
# If log file is not writable, we still want restore to succeed/fail based on actual result
if ! echo "$restore_output" | tee -a "$RESTORE_LOG_FILE" >/dev/null 2>&1; then
  # Fallback: write to stderr if log file is not writable
  echo "$restore_output" >&2
  restore_log_warn "Could not write to restore log file, output redirected to stderr"
fi

if [[ $restore_exit_code -eq 0 ]]; then
  restore_log_info "----------------------------------------"
  restore_log_info "=== Backup Restore Completed Successfully ==="
  restore_log_info "Restore source: ${RESTORE_DATASET_REPO}"
  restore_log_info "Restore finished at: $(date -u +"%Y-%m-%d %H:%M:%S UTC")"
  exit 0
else
  restore_log_error "----------------------------------------"
  restore_log_error "=== Backup Restore Failed ==="
  restore_log_error "Restore source: ${RESTORE_DATASET_REPO}"
  restore_log_error "Restore failed at: $(date -u +"%Y-%m-%d %H:%M:%S UTC")"
  exit 1
fi