wuran commited on
Commit
480c72b
·
verified ·
1 Parent(s): bc50b77

Update sync_data.sh

Browse files
Files changed (1) hide show
  1. sync_data.sh +450 -108
sync_data.sh CHANGED
@@ -1,149 +1,491 @@
1
  #!/bin/bash
2
 
3
  # 检查必要的环境变量
4
- if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
5
- echo "缺少必要的 WebDAV 环境变量:WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD"
6
  exit 1
7
  fi
8
 
9
- # 使用独立的工作目录
10
  WORK_DIR="/tmp/mcp_sync_work"
11
- mkdir -p "$WORK_DIR"
12
 
13
  # 从 WebDAV 恢复配置的函数
14
  restore_from_webdav() {
 
 
 
 
 
15
  echo "正在从 WebDAV 恢复配置文件..."
16
-
17
  # 创建临时恢复目录
18
- RESTORE_DIR="$WORK_DIR/webdav_restore"
19
- mkdir -p "$RESTORE_DIR"
20
-
21
  # 获取WebDAV上所有备份文件列表
22
  echo "获取 WebDAV 备份文件列表..."
 
23
  # 尝试使用PROPFIND方法获取目录列表(WebDAV标准方法)
24
  RAW_RESPONSE=$(curl -s -X PROPFIND \
25
  --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \
26
  -H "Depth: 1" \
27
- -H "Content-Type: text/xml" \
28
- -d '<?xml version="1.0" encoding="utf-8"?><propfind xmlns="DAV:"><prop><displayname/></prop></propfind>' \
29
- "$WEBDAV_URL/")
30
- # 如果PROPFIND失败,尝试简单的GET请求
31
- if [ -z "$RAW_RESPONSE" ] || echo "$RAW_RESPONSE" | grep -q "Method Not Allowed"; then
32
- RAW_RESPONSE=$(curl -s --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/")
33
- fi
34
- # 多种匹配方式提取文件名
35
- BACKUP_LIST=$(echo "$RAW_RESPONSE" | grep -oE 'mcp_backup_[0-9]+_[0-9]+\.tar\.gz' | sort -u | sort -r)
36
-
37
- if [ -z "$BACKUP_LIST" ]; then
38
- echo "未找到任何备份文件。"
39
- rm -rf "$RESTORE_DIR"
40
- return 1 # 返回1表示失败,这是关键
41
  fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- echo "找到以下备份文件:"
44
- echo "$BACKUP_LIST" | head -5 | while read file; do echo " - $file"; done
45
- if [ $(echo "$BACKUP_LIST" | wc -l) -gt 5 ]; then
46
- echo " ... 等共 $(echo "$BACKUP_LIST" | wc -l) 个文件"
47
- fi
48
 
49
- LATEST_BACKUP=$(echo "$BACKUP_LIST" | head -1)
50
- echo "尝试下载最新备份: $LATEST_BACKUP"
51
-
52
- if curl -f --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$LATEST_BACKUP" -o "$RESTORE_DIR/$LATEST_BACKUP" 2>/dev/null; then
53
- echo "下载备份成功: $LATEST_BACKUP"
54
- cd "$RESTORE_DIR"
55
- tar -xzf "$LATEST_BACKUP" && {
56
- echo "解压缩备份文件成功"
57
- [ -d "config" ] && [ "$(ls -A config 2>/dev/null)" ] && echo "恢复 config 目录..." && mkdir -p /mcp-proxy-server/config && cp -r config/* /mcp-proxy-server/config/
58
- [ -d "tools" ] && [ "$(ls -A tools 2>/dev/null)" ] && echo "恢复 tools 目录..." && mkdir -p /tools && cp -r tools/* /tools/
59
- echo "从 WebDAV 恢复配置文件完成"
60
- } || {
61
- echo "解压缩备份文件失败"
62
- }
63
- cd - > /dev/null
64
- else
65
- echo "下载最新备份失败,将跳过恢复。"
66
- fi
67
 
68
- rm -rf "$RESTORE_DIR"
69
- return 0 # 返回0表示成功
 
 
 
70
  }
71
 
72
- # 定义备份到 WebDAV 的函数
73
- backup_to_webdav() {
74
- echo "开始备份到 WebDAV..."
75
-
76
- BACKUP_DIR="$WORK_DIR/webdav_backup"
77
- rm -rf "$BACKUP_DIR"
78
- mkdir -p "$BACKUP_DIR"
79
-
80
- # 准备要备份的目录
81
- [ -d "/mcp-proxy-server/config" ] && cp -r /mcp-proxy-server/config "$BACKUP_DIR/"
82
- [ -d "/tools" ] && cp -r /tools "$BACKUP_DIR/"
83
-
84
- if [ -z "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
85
- echo "没有需要备份的文件,跳过此次备份。"
86
- rm -rf "$BACKUP_DIR"
87
- return
88
  fi
 
89
 
90
- TIMESTAMP=$(date +%Y%m%d_%H%M%S)
91
- BACKUP_FILE="mcp_backup_${TIMESTAMP}.tar.gz"
 
 
 
 
 
 
92
 
93
- cd "$BACKUP_DIR"
94
- tar -czf "$BACKUP_FILE" *
 
 
 
95
 
96
- echo "正在上传备份文件: $BACKUP_FILE"
97
- if curl -T "$BACKUP_FILE" --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$BACKUP_FILE"; then
98
- echo "备份成功上传到 WebDAV。"
 
 
 
 
99
  else
100
- echo "备份上传失败。"
101
  fi
102
 
103
- cd - > /dev/null
104
- rm -rf "$BACKUP_DIR"
105
-
106
- # 清理旧的备份 (可选, 保留最近的10个)
107
- MAX_BACKUPS=${MAX_BACKUPS:-10}
108
- echo "清理 WebDAV 上的旧备份,保留最新的 $MAX_BACKUPS 个..."
109
- RAW_RESPONSE=$(curl -s --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/")
110
- BACKUP_LIST=$(echo "$RAW_RESPONSE" | grep -oE 'mcp_backup_[0-9]+_[0-9]+\.tar\.gz' | sort -r)
111
- OLD_BACKUPS=$(echo "$BACKUP_LIST" | tail -n +$((MAX_BACKUPS + 1)))
 
 
 
 
 
 
 
112
 
113
- for old_backup in $OLD_BACKUPS; do
114
- echo "删除旧备份: $old_backup"
115
- curl -s -X DELETE --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$old_backup"
116
- done
117
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
 
120
- # --- 脚本主逻辑 ---
121
 
122
- # 处理 --restore-only 参数
 
123
  if [ "$1" = "--restore-only" ]; then
124
- restore_from_webdav
125
  exit 0
126
  fi
127
 
128
- # 启动时先尝试恢复
129
- echo "脚本启动,首先尝试从 WebDAV 恢复..."
130
- if ! restore_from_webdav; then
131
- # 如果恢复函数返回非0值 (即失败,通常是因为没找到备份)
132
- echo "恢复失败或未找到备份文件。这可能是首次启动。"
133
- # 等待一小段时间,给主程序生成初始配置的机会
134
- INITIAL_BACKUP_DELAY=${INITIAL_BACKUP_DELAY:-30}
135
- echo "将在 ${INITIAL_BACKUP_DELAY} 秒后执行首次备份,以捕获初始配置文件..."
136
- sleep $INITIAL_BACKUP_DELAY
137
- backup_to_webdav
138
- fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
- # 定义同步(备份)间隔
141
- SYNC_INTERVAL=${SYNC_INTERVAL:-3600} # 默认1小时
142
 
143
- # 进入正常的循环备份流程
144
- while true; do
145
- echo "----------------------------------------"
146
- echo "下一次 WebDAV 备份将在 $SYNC_INTERVAL 秒后进行..."
147
- sleep "$SYNC_INTERVAL"
148
- backup_to_webdav
149
- done
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #!/bin/bash
2
 
3
  # 检查必要的环境变量
4
+ if [ -z "$G_NAME" ] || [ -z "$G_TOKEN" ]; then
5
+ echo "缺少必要的环境变量 G_NAME G_TOKEN"
6
  exit 1
7
  fi
8
 
9
+ # 使用独立的工作目录,避免与配置目录冲突
10
  WORK_DIR="/tmp/mcp_sync_work"
11
+ GITHUB_DATA_DIR="$WORK_DIR/github_data"
12
 
13
  # 从 WebDAV 恢复配置的函数
14
  restore_from_webdav() {
15
+ if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
16
+ echo "WebDAV 环境变量缺失,无法从 WebDAV 恢复。"
17
+ return 1
18
+ fi
19
+
20
  echo "正在从 WebDAV 恢复配置文件..."
21
+
22
  # 创建临时恢复目录
 
 
 
23
  # 获取WebDAV上所有备份文件列表
24
  echo "获取 WebDAV 备份文件列表..."
25
+
26
  # 尝试使用PROPFIND方法获取目录列表(WebDAV标准方法)
27
  RAW_RESPONSE=$(curl -s -X PROPFIND \
28
  --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \
29
  -H "Depth: 1" \
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  fi
31
+
32
+ # 多种匹配方式
33
+ # 方式1: 从XML响应中提取文件名
34
+ BACKUP_LIST1=$(echo "$RAW_RESPONSE" | grep -oE '<D:displayname[^>]*>[^<]*mcp_backup_[0-9]+_[0-9]+\.tar\.gz[^<]*</D:displayname>' | sed 's/<[^>]*>//g')
35
+
36
+ # 方式2: 从href属性中提取
37
+ BACKUP_LIST2=$(echo "$RAW_RESPONSE" | grep -oE 'href="[^"]*mcp_backup_[0-9]+_[0-9]+\.tar\.gz[^"]*"' | sed 's/.*href="[^"]*\///g' | sed 's/".*//g')
38
+
39
+ # 方式3: 简单文本匹配
40
+ BACKUP_LIST3=$(echo "$RAW_RESPONSE" | grep -oE 'mcp_backup_[0-9]+_[0-9]+\.tar\.gz')
41
+
42
+ # 合并所有结果
43
+ return 0
44
+ }
45
 
46
+ # 解析仓库名和用户名
47
+ IFS='/' read -r GITHUB_USER GITHUB_REPO <<< "$G_NAME"
 
 
 
48
 
49
+ # 构建 GitHub 仓库的克隆 URL,包含令牌
50
+ REPO_URL="https://${G_TOKEN}@github.com/${G_NAME}.git"
51
+ mkdir -p "$GITHUB_DATA_DIR"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
+ # 克隆仓库
54
+ echo "正在克隆仓库到 $GITHUB_DATA_DIR ……"
55
+ git clone "$REPO_URL" "$GITHUB_DATA_DIR" || {
56
+ echo "克隆失败,请检查 G_NAME 和 G_TOKEN 是否正确。"
57
+ exit 1
58
  }
59
 
60
+ # 检查命令行参数,支持选择恢复源
61
+ RESTORE_SOURCE="auto" # 默认自动选择
62
+ if [ "$1" = "--restore-webdav" ]; then
63
+ RESTORE_SOURCE="webdav"
64
+ elif [ "$1" = "--restore-github" ]; then
65
+ RESTORE_SOURCE="github"
66
+ elif [ "$1" = "--restore-only" ]; then
67
+ RESTORE_SOURCE="$2"
68
+ if [ "$RESTORE_SOURCE" = "webdav" ]; then
69
+ restore_from_webdav
70
+ exit 0
71
+ elif [ "$RESTORE_SOURCE" = "github" ]; then
72
+ RESTORE_SOURCE="github"
73
+ else
74
+ echo "用法: $0 --restore-only [github|webdav]"
75
+ exit 1
76
  fi
77
+ fi
78
 
79
+ # 恢复逻辑
80
+ if [ "$RESTORE_SOURCE" = "webdav" ]; then
81
+ # 仅从 WebDAV 恢复
82
+ restore_from_webdav
83
+ elif [ "$RESTORE_SOURCE" = "github" ] || [ "$RESTORE_SOURCE" = "auto" ]; then
84
+ # 从 GitHub 恢复(根据环境变量决定是否包含tools)
85
+ GITHUB_RESTORED=0
86
+ GITHUB_TOOLS_RESTORED=0
87
 
88
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
89
+ echo "从 GitHub 恢复配置(config 和 tools 目录)..."
90
+ else
91
+ echo "从 GitHub 恢复配置(仅 config 目录)..."
92
+ fi
93
 
94
+ # 检查并恢复 config 目录
95
+ if [ -d "$GITHUB_DATA_DIR/config" ] && [ "$(ls -A $GITHUB_DATA_DIR/config 2>/dev/null)" ]; then
96
+ echo " GitHub 恢复 config 目录..."
97
+ mkdir -p /mcp-proxy-server/config
98
+ cp -r "$GITHUB_DATA_DIR/config"/* /mcp-proxy-server/config/
99
+ echo "GitHub: config 目录恢复成功"
100
+ GITHUB_RESTORED=1
101
  else
102
+ echo "GitHub 仓库中没有 config 目录或目录为空"
103
  fi
104
 
105
+ # 检查并恢复 tools 目录(仅当环境变量允许时)
106
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
107
+ if [ -d "$GITHUB_DATA_DIR/tools" ] && [ "$(ls -A $GITHUB_DATA_DIR/tools 2>/dev/null)" ]; then
108
+ echo "从 GitHub 恢复 tools 目录..."
109
+ mkdir -p /tools
110
+ cp -r "$GITHUB_DATA_DIR/tools"/* /tools/
111
+ echo "GitHub: tools 目录恢复成功"
112
+ GITHUB_TOOLS_RESTORED=1
113
+ else
114
+ echo "GitHub 仓库中没有 tools 目录或目录为空"
115
+ fi
116
+ else
117
+ echo "跳过 tools 目录恢复(由 GITHUB_BACKUP_TOOLS=false 控制)"
118
+ # 当 GITHUB_BACKUP_TOOLS=false 时,强制从 WebDAV 恢复 tools
119
+ GITHUB_TOOLS_RESTORED=0
120
+ fi
121
 
122
+ # auto 模式的补充恢复逻辑
123
+ if [ "$RESTORE_SOURCE" = "auto" ]; then
124
+ if [ "$GITHUB_RESTORED" = "0" ]; then
125
+ # GitHub完全没有恢复任何内容,尝试完整WebDAV恢复
126
+ echo "GitHub 中没有找到任何配置,尝试从 WebDAV 恢复..."
127
+ restore_from_webdav || echo "WebDAV 恢复失败,将在同步时重新备份"
128
+ elif [ "$GITHUB_TOOLS_RESTORED" = "0" ]; then
129
+ # GitHub恢复了config但没有tools,或者禁用了GitHub tools备份,从WebDAV恢复tools
130
+ if [ "$GITHUB_BACKUP_TOOLS" = "false" ]; then
131
+ echo "GitHub tools 备份已禁用,从 WebDAV 恢复 tools 目录..."
132
+ else
133
+ echo "GitHub 中没有 tools 目录,尝试从 WebDAV 补充恢复..."
134
+ fi
135
+ restore_from_webdav || echo "WebDAV 恢复失败"
136
+ fi
137
+ elif [ "$GITHUB_RESTORED" = "1" ]; then
138
+ echo "从 GitHub 恢复配置完成"
139
+ else
140
+ echo "GitHub 中没有可恢复的配置"
141
+ fi
142
+ fi
143
 
144
 
 
145
 
146
+
147
+ # 如果是仅恢复模式,则退出
148
  if [ "$1" = "--restore-only" ]; then
 
149
  exit 0
150
  fi
151
 
152
+ # 定义同步函数
153
+ sync_data() {
154
+
155
+
156
+
157
+
158
+
159
+ while true; do
160
+ # 1. 同步到 GitHub
161
+ echo "正在开始同步"
162
+ # 进入仓库目录
163
+ cd "$GITHUB_DATA_DIR"
164
+ # 配置 Git 用户信息
165
+ git config user.name "AutoSync Bot"
166
+ git config user.email "[email protected]"
167
+
168
+ # 确保在正确的分支
169
+ git checkout main || git checkout master
170
+
171
+ # 复制最新的配置文件
172
+ GITHUB_BACKUP_TOOLS=${GITHUB_BACKUP_TOOLS:-true}
173
+
174
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
175
+ echo "检查配置文件变化(GitHub 备份 config 和 tools 目录)..."
176
+ else
177
+ echo "检查配置文件变化(GitHub 仅备份 config 目录)..."
178
+ fi
179
+
180
+ # 先从GitHub拉取最新状态,实现双向同步
181
+ echo "从 GitHub 拉取最新状态..."
182
+ git fetch origin
183
+
184
+ # 检查是否有远程更新
185
+ LOCAL_COMMIT=$(git rev-parse HEAD)
186
+ REMOTE_COMMIT=$(git rev-parse origin/$(git branch --show-current))
187
+
188
+ if [ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]; then
189
+ echo "检测到 GitHub 有更新,正在同步..."
190
+
191
+
192
+
193
+
194
+ # 保存本地文件状态
195
+ TEMP_BACKUP_DIR="$WORK_DIR/local_backup"
196
+ rm -rf "$TEMP_BACKUP_DIR"
197
+ mkdir -p "$TEMP_BACKUP_DIR"
198
+
199
+ # 备份本地的config和tools到临时目录
200
+ if [ -d "/mcp-proxy-server/config" ]; then
201
+ cp -r "/mcp-proxy-server/config" "$TEMP_BACKUP_DIR/" 2>/dev/null || true
202
+ fi
203
+ if [ -d "/tools" ] && [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
204
+ cp -r "/tools" "$TEMP_BACKUP_DIR/" 2>/dev/null || true
205
+ fi
206
+
207
+
208
+
209
 
 
 
210
 
211
+
212
+
213
+
214
+ # 执行硬重置到远程状态
215
+ git reset --hard origin/$(git branch --show-current)
216
+
217
+ # 从GitHub更新本地文件
218
+ if [ -d "./config" ] && [ "$(ls -A ./config 2>/dev/null)" ]; then
219
+ echo "从 GitHub 更新 config 目录..."
220
+ mkdir -p /mcp-proxy-server/config
221
+ cp -r ./config/* /mcp-proxy-server/config/
222
+ else
223
+ # 如果GitHub中没有config目录,清空本地config
224
+ echo "GitHub 中没有 config 目录,清空本地 config..."
225
+ rm -rf /mcp-proxy-server/config/*
226
+ fi
227
+
228
+
229
+
230
+
231
+
232
+
233
+ # 根据GITHUB_BACKUP_TOOLS设置处理tools目录
234
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
235
+ if [ -d "./tools" ] && [ "$(ls -A ./tools 2>/dev/null)" ]; then
236
+ echo "从 GitHub 更新 tools 目录..."
237
+ mkdir -p /tools
238
+ rm -rf /tools/* # 清空现有tools
239
+ cp -r ./tools/* /tools/
240
+ else
241
+ # 如果GitHub中没有tools目录,清空本地tools
242
+ echo "GitHub 中没有 tools 目录,清空本地 tools..."
243
+ rm -rf /tools/*
244
+ fi
245
+ else
246
+ # 如果禁用了GitHub tools备份,从WebDAV恢复tools
247
+ echo "GitHub tools 备份已禁用,从 WebDAV 恢复 tools 目录..."
248
+ restore_from_webdav || echo "WebDAV 恢复失败"
249
+ fi
250
+
251
+ echo "GitHub 同步完成"
252
+
253
+
254
+
255
+
256
+ # 清理临时备份
257
+ rm -rf "$TEMP_BACKUP_DIR"
258
+ else
259
+ echo "GitHub 状态已是最新"
260
+ fi
261
+
262
+ # 同步 config 目录到 GitHub
263
+ if [ -d "/mcp-proxy-server/config" ]; then
264
+ # 检查是否有非工作目录的文件
265
+ CONFIG_FILES=$(ls -A /mcp-proxy-server/config 2>/dev/null | grep -v -E '(github_data|temp_backup|webdav_restore)' || true)
266
+
267
+ if [ -n "$CONFIG_FILES" ]; then
268
+ # 使用 cp 代替 rsync,逐步复制,排除工作目录
269
+
270
+ for item in /mcp-proxy-server/config/*; do
271
+ if [ -e "$item" ]; then
272
+ BASENAME=$(basename "$item")
273
+ ;;
274
+ *)
275
+ if [ -d "$item" ]; then
276
+ cp -r "$item" ./config/ 2>/dev/null
277
+ else
278
+ cp "$item" ./config/ 2>/dev/null
279
+ fi
280
+ ;;
281
+ esac
282
+ fi
283
+ done
284
+ fi
285
+ fi
286
+
287
+ # 同步 tools 目录到 GitHub(处理多个MCP仓库)
288
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ] && [ -d "/tools" ] && [ "$(ls -A /tools 2>/dev/null)" ]; then
289
+ # 清空目标目录
290
+ rm -rf ./tools/*
291
+
292
+ echo "处理 tools 目录中的 MCP 工具..."
293
+
294
+ PROCESSED_COUNT=0
295
+
296
+ # 逐个处理 tools 目录下的MCP工具
297
+ for item in /tools/*; do
298
+ if [ -e "$item" ]; then
299
+ BASENAME=$(basename "$item")
300
+
301
+ if [ -d "$item" ]; then
302
+ echo " 处理 MCP 工具: $BASENAME"
303
+
304
+ # 检查是否是Git仓库
305
+ if [ -d "$item/.git" ]; then
306
+ echo " → 检测到Git仓库,排除.git目录"
307
+ fi
308
+
309
+ # 创建目标目录
310
+ mkdir -p "./tools/$BASENAME"
311
+
312
+ # 复制目录内容
313
+ if [ "$(ls -A "$item" 2>/dev/null)" ]; then
314
+ # 复制所有普通文件和目录(排除.git)
315
+ for subitem in "$item"/*; do
316
+ if [ -e "$subitem" ] && [ "$(basename "$subitem")" != ".git" ]; then
317
+ cp -r "$subitem" "./tools/$BASENAME/" 2>/dev/null || true
318
+ fi
319
+ done
320
+
321
+ # 复制隐藏文件,但排除 .git 目录
322
+ for hidden in "$item"/.[!.]*; do
323
+ if [ -e "$hidden" ] && [ "$(basename "$hidden")" != ".git" ]; then
324
+ cp -r "$hidden" "./tools/$BASENAME/" 2>/dev/null || true
325
+ fi
326
+ done
327
+
328
+ # 检查复制结果
329
+ COPIED_FILES=$(ls -A "./tools/$BASENAME" 2>/dev/null | wc -l)
330
+ echo " → 已复制 $COPIED_FILES 个文件/目录"
331
+ else
332
+ # 空目录创建 .gitkeep
333
+ touch "./tools/$BASENAME/.gitkeep"
334
+ echo " → 空目录,已创建 .gitkeep"
335
+ fi
336
+
337
+ PROCESSED_COUNT=$((PROCESSED_COUNT + 1))
338
+ else
339
+ # 直接复制文件
340
+ echo " 复制文件: $BASENAME"
341
+ cp "$item" "./tools/" 2>/dev/null || true
342
+ PROCESSED_COUNT=$((PROCESSED_COUNT + 1))
343
+ fi
344
+ fi
345
+ done
346
+
347
+ # 显示处理结果摘要
348
+ if [ "$PROCESSED_COUNT" -gt 0 ]; then
349
+ echo "总计处理 $PROCESSED_COUNT 个 MCP 工具"
350
+ fi
351
+ elif [ "$GITHUB_BACKUP_TOOLS" = "false" ]; then
352
+ echo "跳过 tools 目录(由 GITHUB_BACKUP_TOOLS=false 控制)"
353
+ fi
354
+
355
+ # 检查是否有变化
356
+ CONFIG_CHANGED=0
357
+ TOOLS_CHANGED=0
358
+
359
+ # 检查 config 目录变化(用于 GitHub 备份)
360
+ if [[ -n $(git status -s) ]]; then
361
+ CONFIG_CHANGED=1
362
+ fi
363
+
364
+ # 检查 tools 目录变化(用于 WebDAV 备份)
365
+ TOOLS_LAST_CHECK_FILE="$WORK_DIR/tools_last_check"
366
+ if [ -d "/tools" ] && [ "$(ls -A /tools 2>/dev/null)" ]; then
367
+ # 获取 tools 目录的最新修改时间
368
+ CURRENT_TOOLS_TIME=$(find /tools -type f -exec stat -c %Y {} \; 2>/dev/null | sort -n | tail -1)
369
+
370
+ if [ -f "$TOOLS_LAST_CHECK_FILE" ]; then
371
+ LAST_TOOLS_TIME=$(cat "$TOOLS_LAST_CHECK_FILE" 2>/dev/null || echo "0")
372
+ if [ "$CURRENT_TOOLS_TIME" != "$LAST_TOOLS_TIME" ]; then
373
+ TOOLS_CHANGED=1
374
+ fi
375
+ else
376
+ TOOLS_CHANGED=1
377
+ fi
378
+
379
+ # 更新检查时间戳
380
+ echo "$CURRENT_TOOLS_TIME" > "$TOOLS_LAST_CHECK_FILE"
381
+ fi
382
+
383
+ # 根据变化情况执行备份
384
+ if [ "$CONFIG_CHANGED" = "1" ] || [ "$TOOLS_CHANGED" = "1" ]; then
385
+ echo "检测到文件变化,开始备份..."
386
+
387
+ # GitHub 备份(仅当 config 有变化时)
388
+ if [ "$CONFIG_CHANGED" = "1" ]; then
389
+ if [ "$GITHUB_BACKUP_TOOLS" = "true" ]; then
390
+ echo "→ GitHub 备份 (config + tools)"
391
+ git add config/ tools/
392
+ git commit -m "Auto sync config and tools $(date '+%Y-%m-%d %H:%M:%S')"
393
+ else
394
+ echo "→ GitHub 备份 (config only)"
395
+ git add config/
396
+ git commit -m "Auto sync config $(date '+%Y-%m-%d %H:%M:%S')"
397
+ fi
398
+ git push origin HEAD >/dev/null 2>&1 && echo " ✓ 推送成功" || echo " ✗ 推送失败"
399
+ fi
400
+
401
+ # WebDAV 备份(当 config 或 tools 有变化时)
402
+ if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
403
+ echo " WebDAV 环境变量缺失,跳过"
404
+ else
405
+ echo "→ WebDAV 备份 (config + tools)"
406
+ # 使用时间戳(年月日时分),每次同步都创建新备份
407
+ FILENAME="mcp_backup_$(date +'%Y%m%d_%H%M').tar.gz"
408
+
409
+ # 创建临时备份压缩包(使用独立目录)
410
+ TEMP_DIR="$WORK_DIR/temp_backup"
411
+ rm -rf "$TEMP_DIR"
412
+ mkdir -p "$TEMP_DIR"
413
+
414
+ # 复制要备份的目录到临时目录(WebDAV 备份包含 config 和 tools)
415
+ BACKUP_CREATED=0
416
+
417
+ if [ -d "/mcp-proxy-server/config" ]; then
418
+ CONFIG_FILES=$(ls -A /mcp-proxy-server/config 2>/dev/null | grep -v -E '(github_data|temp_backup|webdav_restore)' || true)
419
+
420
+ if [ -n "$CONFIG_FILES" ]; then
421
+ mkdir -p "$TEMP_DIR/config"
422
+ for item in /mcp-proxy-server/config/*; do
423
+ if [ -e "$item" ]; then
424
+ BASENAME=$(basename "$item")
425
+ case "$BASENAME" in
426
+ github_data|temp_backup|webdav_restore)
427
+ ;;
428
+ *)
429
+ if [ -d "$item" ]; then
430
+ cp -r "$item" "$TEMP_DIR/config/" 2>/dev/null && BACKUP_CREATED=1
431
+ else
432
+ cp "$item" "$TEMP_DIR/config/" 2>/dev/null && BACKUP_CREATED=1
433
+ fi
434
+ ;;
435
+ esac
436
+ fi
437
+ done
438
+ fi
439
+ fi
440
+
441
+ if [ -d "/tools" ] && [ "$(ls -A /tools 2>/dev/null)" ]; then
442
+ mkdir -p "$TEMP_DIR/tools"
443
+ for item in /tools/*; do
444
+ if [ -e "$item" ]; then
445
+ BASENAME=$(basename "$item")
446
+ if [ -d "$item" ]; then
447
+ mkdir -p "$TEMP_DIR/tools/$BASENAME"
448
+ if [ "$(ls -A "$item" 2>/dev/null)" ]; then
449
+ cp -r "$item"/* "$TEMP_DIR/tools/$BASENAME/" 2>/dev/null && BACKUP_CREATED=1
450
+ cp -r "$item"/.[!.]* "$TEMP_DIR/tools/$BASENAME/" 2>/dev/null || true
451
+ else
452
+ touch "$TEMP_DIR/tools/$BASENAME/.gitkeep"
453
+ BACKUP_CREATED=1
454
+ fi
455
+ else
456
+ cp "$item" "$TEMP_DIR/tools/" 2>/dev/null && BACKUP_CREATED=1
457
+ fi
458
+ fi
459
+ done
460
+ fi
461
+
462
+ # 创建压缩包
463
+ if [ "$BACKUP_CREATED" = "1" ] && [ "$(ls -A $TEMP_DIR)" ]; then
464
+ (cd "$TEMP_DIR" && tar -czf "../$FILENAME" .)
465
+
466
+ curl -T "$WORK_DIR/$FILENAME" --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$FILENAME" >/dev/null 2>&1 && echo " ✓ 上传成功" || echo " ✗ 上传失败"
467
+ rm -f "$WORK_DIR/$FILENAME"
468
+ else
469
+ echo " ✗ 无文件可备份"
470
+ fi
471
+
472
+ rm -rf "$TEMP_DIR"
473
+
474
+ fi
475
+
476
+ echo "备份完成"
477
+
478
+ else
479
+ echo "无文件变化,跳过备份"
480
+ fi
481
+
482
+ # 返回上级目录
483
+ cd - > /dev/null
484
+
485
+ # 3. 等待统一的时间间隔
486
+ SYNC_INTERVAL=${SYNC_INTERVAL:-7200} # 默认间隔时间为 7200 秒
487
+ echo "等待 ${SYNC_INTERVAL} 秒后进行下一次检查..."
488
+ sleep $SYNC_INTERVAL
489
+
490
+ done
491
+ }