File size: 3,850 Bytes
c796b35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/bin/bash
set -ex

# ==========================================
# 1. 环境初始化与核心工具定义
# ==========================================
mkdir -p /root/.openclaw/
BACKUP_CMD="python3 /app/sync.py backup"

# 定义带锁的备份函数
safe_backup() {
    echo "[Backup] Attempting to acquire lock..."
    flock -n /tmp/backup.lock -c "$BACKUP_CMD" || echo "[Backup] Lock busy. Skipped."
}

# ==========================================
# 2. 状态恢复与智能配置映射 (纯决策层)
# ==========================================
CONFIG_FILE="/root/.openclaw/openclaw.json"
MARKER_FILE="/root/.openclaw/.version_marker"

# 获取新版本号并拉取云端旧数据
CURRENT_VERSION=$(openclaw --version 2>/dev/null || echo "unknown")
python3 /app/sync.py restore || echo "[Restore] No backup found or failed."
RESTORED_VERSION=$(cat "$MARKER_FILE" 2>/dev/null || echo "none")

# 决策逻辑
if [ ! -s "$CONFIG_FILE" ]; then
    echo "[Init] No config found. Applying fresh template..."
    envsubst < /app/openclaw.json > "$CONFIG_FILE"
    echo "$CURRENT_VERSION" > "$MARKER_FILE"
    
elif [ "$FORCE_OVERWRITE" = "true" ]; then
    echo "[Config] FORCE_OVERWRITE triggered! Resetting to template..."
    envsubst < /app/openclaw.json > "$CONFIG_FILE"
    echo "$CURRENT_VERSION" > "$MARKER_FILE"
    
elif [ "$CURRENT_VERSION" != "$RESTORED_VERSION" ] && [ "$CURRENT_VERSION" != "unknown" ]; then
    echo "[Upgrade] Upgrading from $RESTORED_VERSION to $CURRENT_VERSION."
    echo "$CURRENT_VERSION" > "$MARKER_FILE"
    
else
    echo "[Start] Version matches ($CURRENT_VERSION). Normal boot."
fi

# ==========================================
# 3. 预检、修复与统一固化 (执行层)
# ==========================================
# 清理浏览器残留缓存
rm -rf /root/.openclaw/browser/*/user-data/Singleton* /tmp/org.chromium.Chromium.* 2>/dev/null || true

# 统一交给 doctor 检查和修复
echo "[Doctor] Checking and fixing data structures..."
openclaw doctor --fix

# 只有在发生版本升级、强制重置或全新安装时,才在开机触发基础备份
if [ "$CURRENT_VERSION" != "$RESTORED_VERSION" ] || [ "$FORCE_OVERWRITE" = "true" ] || [ ! -s "$CONFIG_FILE" ]; then
    echo "[Init/Upgrade] Performing baseline backup..."
    safe_backup
fi

# ==========================================
# 4. 主进程启动与优雅关闭 (Graceful Shutdown)
# ==========================================
echo "[Main] Starting OpenClaw Gateway..."
# 真正启动网关的核心命令!
openclaw gateway run --port $PORT &
MAIN_PID=$!

# 关机保护逻辑
shutdown_handler() {
    echo "[Shutdown] Caught termination signal! Forwarding SIGTERM to OpenClaw (PID $MAIN_PID)..."
    kill -TERM $MAIN_PID 2>/dev/null || true
    
    echo "[Shutdown] Waiting for OpenClaw to safely flush databases..."
    wait $MAIN_PID || true
    
    echo "[Shutdown] OpenClaw exited safely. Performing final monolithic backup..."
    safe_backup
    
    echo "[Shutdown] Data secured. Goodbye."
    exit 0
}

# 捕获系统关机信号
trap shutdown_handler SIGTERM SIGINT

# ==========================================
# 5. 后台安全巡航备份
# ==========================================
(
    while kill -0 $MAIN_PID 2>/dev/null; do
        sleep 1800
        # 每半小时执行一次带锁的安全备份
        if kill -0 $MAIN_PID 2>/dev/null; then
            safe_backup
        fi
    done
) &
LOOP_PID=$!

# ==========================================
# 6. 主进程阻塞
# ==========================================
# 脚本停在这里,维持容器长亮
wait $MAIN_PID

# 如果 OpenClaw 异常崩溃(非系统关机),杀掉巡航脚本,做最后一次抢救备份
echo "[Main] Gateway process exited unexpectedly. Attempting final rescue sync..."
kill $LOOP_PID 2>/dev/null || true
safe_backup