Spaces:
Paused
Paused
File size: 5,764 Bytes
c1ccdca |
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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
#!/bin/bash
set -e
WEBDAV_URL="${WEBDAV_URL}"
WEBDAV_USERNAME="${WEBDAV_USERNAME}"
WEBDAV_PASSWORD="${WEBDAV_PASSWORD}"
DB_PATH="${DB_PATH:-/app/db}"
BACKUP_PATH="${BACKUP_PATH:-/app/backup}"
BACKUP_FILENAME="${BACKUP_FILENAME:-tgdrive_db_backup.tar.gz}"
REMOTE_BACKUP_DIR="${REMOTE_BACKUP_DIR:-tgdrive_backup}"
CONFIG_FILE="/app/config/sync_config"
PYTHON_CMD="/app/venv/bin/python3"
mkdir -p ${BACKUP_PATH}
mkdir -p /app/logs
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> /app/logs/sync.log 2>/dev/null || true
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
mkdir -p /app/logs 2>/dev/null || true
touch /app/logs/sync.log 2>/dev/null || true
if [ ! -f "$CONFIG_FILE" ]; then
log "创建初始配置文件"
mkdir -p /app/config 2>/dev/null || true
echo "LAST_SYNC=0" > "$CONFIG_FILE" 2>/dev/null || true
fi
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE" 2>/dev/null || true
fi
if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
log "错误: WebDAV配置不完整,请设置WEBDAV_URL, WEBDAV_USERNAME, WEBDAV_PASSWORD环境变量"
exit 1
fi
backup_db() {
log "开始备份数据库..."
if [ -d "$DB_PATH" ]; then
if [[ "$DB_PATH" == "/app/db" ]]; then
tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /app db
else
tar -czf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C $(dirname "$DB_PATH") $(basename "$DB_PATH")
fi
log "数据库已备份到 ${BACKUP_PATH}/${BACKUP_FILENAME}"
return 0
else
log "警告: 数据库目录不存在"
return 1
fi
}
upload_to_webdav() {
log "开始上传备份到WebDAV (目标目录: ${REMOTE_BACKUP_DIR})..."
$PYTHON_CMD -c "
import webdav3.client as wc
import os
options = {
'webdav_hostname': '$WEBDAV_URL',
'webdav_login': '$WEBDAV_USERNAME',
'webdav_password': '$WEBDAV_PASSWORD',
'webdav_timeout': 30
}
client = wc.Client(options)
# 检查远程目录是否存在
if not client.check('$REMOTE_BACKUP_DIR'):
client.mkdir('$REMOTE_BACKUP_DIR')
# 上传文件
local_path = '${BACKUP_PATH}/${BACKUP_FILENAME}'
remote_path = '$REMOTE_BACKUP_DIR/${BACKUP_FILENAME}'
if os.path.exists(local_path):
try:
client.upload_sync(remote_path=remote_path, local_path=local_path)
print('上传成功')
except Exception as e:
print(f'上传失败: {e}')
else:
print('本地备份文件不存在')
"
if [ $? -eq 0 ]; then
log "备份已成功上传到WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME})"
echo "LAST_SYNC=$(date +%s)" > "$CONFIG_FILE"
return 0
else
log "上传到WebDAV失败"
return 1
fi
}
download_from_webdav() {
log "开始从WebDAV下载备份 (源目录: ${REMOTE_BACKUP_DIR})..."
$PYTHON_CMD -c "
import webdav3.client as wc
import os
options = {
'webdav_hostname': '$WEBDAV_URL',
'webdav_login': '$WEBDAV_USERNAME',
'webdav_password': '$WEBDAV_PASSWORD',
'webdav_timeout': 30
}
client = wc.Client(options)
# 检查远程文件是否存在
remote_path = '$REMOTE_BACKUP_DIR/${BACKUP_FILENAME}'
local_path = '${BACKUP_PATH}/${BACKUP_FILENAME}'
if client.check(remote_path):
try:
client.download_sync(remote_path=remote_path, local_path=local_path)
print('下载成功')
except Exception as e:
print(f'下载失败: {e}')
else:
print('远程备份文件不存在')
"
if [ $? -eq 0 ]; then
log "备份已成功从WebDAV (${REMOTE_BACKUP_DIR}/${BACKUP_FILENAME}) 下载"
return 0
else
log "从WebDAV下载备份失败"
return 1
fi
}
restore_db() {
log "开始恢复数据库到 ${DB_PATH}..."
if [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then
if [ -d "$DB_PATH" ] && [ "$(ls -A $DB_PATH 2>/dev/null)" ]; then
local timestamp=$(date +%Y%m%d%H%M%S)
if [[ "$DB_PATH" == "/app/db" ]]; then
tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C /app db
else
tar -czf "${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz" -C $(dirname "$DB_PATH") $(basename "$DB_PATH")
fi
log "当前数据库已备份到 ${BACKUP_PATH}/db_before_restore_${timestamp}.tar.gz"
fi
rm -rf "$DB_PATH"
mkdir -p "$DB_PATH"
if [[ "$DB_PATH" == "/app/db" ]]; then
tar -xzf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /app
else
mkdir -p /tmp/tgdrive_restore
tar -xzf "${BACKUP_PATH}/${BACKUP_FILENAME}" -C /tmp/tgdrive_restore
cp -r /tmp/tgdrive_restore/db/* "$DB_PATH"/
rm -rf /tmp/tgdrive_restore
fi
log "数据库已成功恢复到 ${DB_PATH}"
return 0
else
log "错误: 备份文件不存在,无法恢复数据库"
return 1
fi
}
case "$1" in
backup)
backup_db && upload_to_webdav
;;
restore)
download_from_webdav && restore_db
;;
sync)
current_time=$(date +%s)
download_from_webdav
if { [ ! -d "$DB_PATH" ] || [ ! "$(ls -A $DB_PATH 2>/dev/null)" ]; } && [ -f "${BACKUP_PATH}/${BACKUP_FILENAME}" ]; then
log "检测到本地数据库不存在或为空,开始恢复..."
restore_db
fi
backup_db && upload_to_webdav
;;
*)
echo "用法: $0 {backup|restore|sync}"
echo " backup - 备份数据库并上传到WebDAV"
echo " restore - 从WebDAV下载备份并恢复数据库"
echo " sync - 同步数据库(双向)"
exit 1
;;
esac
exit 0 |