cfiles commited on
Commit
dc9545c
·
verified ·
1 Parent(s): b37e280

Create sync-script.sh

Browse files
Files changed (1) hide show
  1. sync-script.sh +199 -0
sync-script.sh ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ WEBDAV_URL="${WEBDAV_URL}"
5
+ WEBDAV_USERNAME="${WEBDAV_USERNAME}"
6
+ WEBDAV_PASSWORD="${WEBDAV_PASSWORD}"
7
+ DB_PATH="${DB_PATH:-/app/db}" # 设置默认数据库路径
8
+ BACKUP_PATH="${BACKUP_PATH:-/app/backup}" # 设置默认备份路径
9
+ BACKUP_FILENAME="${BACKUP_FILENAME:-tgdrive_db_backup.tar.gz}" # 设置默认备份文件名
10
+ REMOTE_BACKUP_DIR="${REMOTE_BACKUP_DIR:-tgdrive_backup}" # 设置默认远程备份目录
11
+ CONFIG_FILE="/app/config/sync_config"
12
+ PYTHON_CMD="/app/venv/bin/python3"
13
+
14
+ mkdir -p ${BACKUP_PATH}
15
+ mkdir -p /app/logs
16
+
17
+ log() {
18
+ echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> /app/logs/sync.log 2>/dev/null || true
19
+ echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
20
+ }
21
+
22
+ mkdir -p /app/logs 2>/dev/null || true
23
+ touch /app/logs/sync.log 2>/dev/null || true
24
+
25
+ if [ ! -f "$CONFIG_FILE" ]; then
26
+ log "创建初始配置文件"
27
+ mkdir -p /app/config 2>/dev/null || true
28
+ echo "LAST_SYNC=0" > "$CONFIG_FILE" 2>/dev/null || true
29
+ fi
30
+
31
+ if [ -f "$CONFIG_FILE" ]; then
32
+ source "$CONFIG_FILE" 2>/dev/null || true
33
+ fi
34
+
35
+ if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
36
+ log "错误: WebDAV配置不完整,请设置WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD环境变量"
37
+ exit 1
38
+ fi
39
+
40
+ backup_db() {
41
+ log "开始备份数据库..."
42
+ if [ -d "$DB_PATH" ]; then
43
+ if [[ "$DB_PATH" == "/app/db" ]]; then
44
+ tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /app db
45
+ else
46
+ tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C "$(dirname "$DB_PATH")" "$(basename "$DB_PATH")"
47
+ fi
48
+ log "数据库已备份到 ${BACKUP_PATH}/${BACKUP_FILENAME}"
49
+ return 0
50
+ else
51
+ log "警告: 数据库目录不存在"
52
+ return 1
53
+ fi
54
+ }
55
+
56
+ upload_to_webdav() {
57
+ log "开始上传备份到WebDAV (目标目录: ${REMOTE_BACKUP_DIR})..."
58
+
59
+ FULL_WEBDAV_URL="${WEBDAV_URL}/${REMOTE_BACKUP_DIR}"
60
+ local_path="${BACKUP_PATH}/${BACKUP_FILENAME}"
61
+ remote_file="${BACKUP_FILENAME}"
62
+
63
+ if [ -f "$local_path" ]; then
64
+ curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "$local_path" "$FULL_WEBDAV_URL/$remote_file"
65
+ if [ $? -eq 0 ]; then
66
+ log "备份已成功上传到WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME})"
67
+ echo "LAST_SYNC=$(date +%s)" > "$CONFIG_FILE"
68
+ return 0
69
+ else
70
+ log "上传到WebDAV失败"
71
+ return 1
72
+ fi
73
+ else
74
+ log "错误: 本地备份文件不存在"
75
+ return 1
76
+ fi
77
+ }
78
+
79
+ download_from_webdav() {
80
+ log "开始从WebDAV下载备份 (源目录: ${REMOTE_BACKUP_DIR})..."
81
+
82
+ $PYTHON_CMD -c "
83
+ import webdav3.client as wc
84
+ import os
85
+
86
+ options = {
87
+ 'webdav_hostname': '$WEBDAV_URL',
88
+ 'webdav_login': '$WEBDAV_USERNAME',
89
+ 'webdav_password': '$WEBDAV_PASSWORD',
90
+ 'webdav_timeout': 30
91
+ }
92
+
93
+ client = wc.Client(options)
94
+
95
+ # 检查远程文件是否存在
96
+ remote_path = '$REMOTE_BACKUP_DIR/${BACKUP_FILENAME}'
97
+ local_path = '${BACKUP_PATH}/${BACKUP_FILENAME}'
98
+
99
+ if client.check(remote_path):
100
+ try:
101
+ client.download_sync(remote_path=remote_path, local_path=local_path)
102
+ print('下载成功')
103
+ except Exception as e:
104
+ print(f'下载失败: {e}')
105
+ else:
106
+ print('远程备份文件不存在')
107
+ "
108
+
109
+ if [ $? -eq 0 ]; then
110
+ log "备份已成功从WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME}) 下载"
111
+ return 0
112
+ else
113
+ log "从WebDAV下载备份失败"
114
+ return 1
115
+ fi
116
+ }
117
+
118
+ restore_db() {
119
+ log "开始恢复数据库到 ${DB_PATH}..."
120
+
121
+ if [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then
122
+ if [ -d "$DB_PATH" ] && [ "$(ls -A $DB_PATH 2>/dev/null)" ]; then
123
+ local timestamp=$(date +%Y%m%d%H%M%S)
124
+ if [[ "$DB_PATH" == "/app/db" ]]; then
125
+ tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C /app db 2>/dev/null || log "无法创建当前数据库备份,继续恢复..."
126
+ else
127
+ tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C "$(dirname "$DB_PATH")" "$(basename "$DB_PATH")" 2>/dev/null || log "无法创建当前数据库备份,继续恢复..."
128
+ fi
129
+ log "尝试备份当前数据库到 ${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz"
130
+ fi
131
+
132
+ # 创建临时恢复目录
133
+ mkdir -p /tmp/tgdrive_restore 2>/dev/null || true
134
+
135
+ # 解压备份文件到临时目录
136
+ tar -xzf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /tmp/tgdrive_restore 2>/dev/null || {
137
+ log "解压备份文件失败,可能是格式不正确"
138
+ rm -rf /tmp/tgdrive_restore 2>/dev/null || true
139
+ return 1
140
+ }
141
+
142
+ # 确保数据库目录存在
143
+ mkdir -p "$DB_PATH" 2>/dev/null || true
144
+
145
+ # 清空数据库目录内容(逐个文件删除而不是删除整个目录)
146
+ find "$DB_PATH" -mindepth 1 -delete 2>/dev/null || log "无法清空数据库目录,将尝试直接覆盖..."
147
+
148
+ # 复制恢复的文件到数据库目录
149
+ if [ -d "/tmp/tgdrive_restore/db" ]; then
150
+ cp -rf /tmp/tgdrive_restore/db/* "$DB_PATH"/ 2>/dev/null || {
151
+ log "复制恢复文件失败,尝试使用rsync..."
152
+ which rsync >/dev/null 2>&1 && rsync -a /tmp/tgdrive_restore/db/ "$DB_PATH"/ 2>/dev/null
153
+ }
154
+ else
155
+ log "备份中找不到db目录,尝试直接复制临时目录内容..."
156
+ cp -rf /tmp/tgdrive_restore/* "$DB_PATH"/ 2>/dev/null || {
157
+ log "复制恢复文件失败,尝试使用rsync..."
158
+ which rsync >/dev/null 2>&1 && rsync -a /tmp/tgdrive_restore/ "$DB_PATH"/ 2>/dev/null
159
+ }
160
+ fi
161
+
162
+ rm -rf /tmp/tgdrive_restore 2>/dev/null || true
163
+
164
+ log "数据库已尝试恢复到 ${DB_PATH}"
165
+ return 0
166
+ else
167
+ log "错误: 备份文件不存在,无法恢复数据库"
168
+ return 1
169
+ fi
170
+ }
171
+
172
+ case "$1" in
173
+ backup)
174
+ backup_db && upload_to_webdav
175
+ ;;
176
+ restore)
177
+ download_from_webdav && restore_db
178
+ ;;
179
+ sync)
180
+ current_time=$(date +%s)
181
+ download_from_webdav
182
+
183
+ if { [ ! -d "$DB_PATH" ] || [ ! "$(ls -A $DB_PATH 2>/dev/null)" ]; } && [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then
184
+ log "检测到本地数据库不存在或为空,开始恢复..."
185
+ restore_db
186
+ fi
187
+
188
+ backup_db && upload_to_webdav
189
+ ;;
190
+ *)
191
+ echo "用法: $0 {backup|restore|sync}"
192
+ echo " backup - 备份数据库并上传到WebDAV"
193
+ echo " restore - 从WebDAV下载备份并恢复数据库"
194
+ echo " sync - 同步数据库(双向)"
195
+ exit 1
196
+ ;;
197
+ esac
198
+
199
+ exit 0