File size: 4,146 Bytes
cf265e6
683a5ee
 
cf265e6
 
683a5ee
 
 
8953b9e
 
 
 
 
 
 
 
 
cf265e6
683a5ee
 
 
 
8953b9e
 
cf265e6
8953b9e
cf265e6
8953b9e
cf265e6
 
 
8953b9e
 
cf265e6
 
 
 
 
 
8953b9e
cf265e6
 
 
8953b9e
 
cf265e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8953b9e
 
cf265e6
8953b9e
 
cf265e6
 
 
683a5ee
 
 
 
cf265e6
8953b9e
683a5ee
 
 
 
 
8953b9e
cf265e6
e359b99
cf265e6
8953b9e
cf265e6
 
 
8953b9e
cf265e6
e359b99
 
cf265e6
e359b99
cf265e6
e359b99
 
 
 
8953b9e
 
 
cf265e6
 
 
8953b9e
 
cf265e6
8953b9e
 
 
 
 
 
 
 
 
 
e359b99
cf265e6
8953b9e
683a5ee
 
 
 
 
8953b9e
 
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
#!/bin/sh

# 检查环境变量
if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
    echo "Starting without sync functionality - missing WEBDAV_URL, WEBDAV_USERNAME, or WEBDAV_PASSWORD"
    exit 0
fi

# 设置备份路径
WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH:-""}
FULL_WEBDAV_URL="${WEBDAV_URL}"
if [ -n "$WEBDAV_BACKUP_PATH" ]; then
    FULL_WEBDAV_URL="${WEBDAV_URL}/${WEBDAV_BACKUP_PATH}"
fi

# 下载最新备份并恢复
restore_backup() {
    echo "开始从 网页DAV 下载最新备份..."
    python3 -c "
import sys
import os
import tarfile
import requests
import shutil
import subprocess
from webdav3.client import Client
# 设置 WebDAV 客户端
options = {
    'webdav_hostname': '${FULL_WEBDAV_URL}',
    'webdav_login': '${WEBDAV_USERNAME}',
    'webdav_password': '${WEBDAV_PASSWORD}'
}
client = Client(options)
# 列出备份文件
try:
    backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('qexo_backup_')]
except Exception as e:
    print(f'连接 WebDAV 服务器出错: {e}')
    sys.exit(1)
if not backups:
    print('没有找到备份文件,跳过恢复步骤。')
    sys.exit(0)
# 获取最新备份文件
latest_backup = sorted(backups)[-1]
print(f'最新备份文件:{latest_backup}')
# 下载最新备份
try:
    with requests.get(f'${FULL_WEBDAV_URL}/{latest_backup}', auth=('${WEBDAV_USERNAME}', '${WEBDAV_PASSWORD}'), stream=True) as r:
        if r.status_code == 200:
            with open(f'/tmp/{latest_backup}', 'wb') as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
            print(f'成功下载备份文件到 /tmp/{latest_backup}')
            # 检查数据库文件是否被占用
            try:
                pids = subprocess.check_output(['lsof', '-t', '/app/db/db.sqlite3']).decode().strip()
                if pids:
                    print('数据库文件被占用,无法恢复备份。')
                    sys.exit(1)
            except subprocess.CalledProcessError:
                # 没有进程占用数据库文件
                pass
            # 解压备份文件
            with tarfile.open(f'/tmp/{latest_backup}', 'r:gz') as tar:
                tar.extractall('/app/')
            print(f'成功从 {latest_backup} 恢复备份')
        else:
            print(f'下载备份失败:{r.status_code}')
except Exception as e:
    print(f'恢复备份过程中出错: {e}')
"
}

# 首次启动时下载最新备份
echo "Downloading latest backup from 网页DAV..."
restore_backup

# 同步函数
sync_data() {
    while true; do
        echo "Starting sync process at $(date)"

        # 直接备份数据库文件
        timestamp=$(date +%Y%m%d_%H%M%S)
        backup_file="qexo_backup_${timestamp}.tar.gz"

        # 备份数据库和配置文件
        cd /app
        tar -czf "/tmp/${backup_file}" db/db.sqlite3 configs.py

        # 上传新备份到 网页DAV
        curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/${backup_file}"
        if [ $? -eq 0 ]; then
            echo "Successfully uploaded ${backup_file} to 网页DAV"
        else
            echo "Failed to upload ${backup_file} to 网页DAV"
        fi

        # 清理旧备份文件
        python3 -c "
import sys
from webdav3.client import Client
options = {
    'webdav_hostname': '${FULL_WEBDAV_URL}',
    'webdav_login': '${WEBDAV_USERNAME}',
    'webdav_password': '${WEBDAV_PASSWORD}'
}
client = Client(options)
backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('qexo_backup_')]
backups.sort()
if len(backups) > 5:
    to_delete = len(backups) - 5
    for file in backups[:to_delete]:
        client.clean(file)
        print(f'Successfully deleted {file}.')
else:
    print('Only {} backups found, no need to clean.'.format(len(backups)))
" 2>&1

        rm -f "/tmp/${backup_file}"

        SYNC_INTERVAL=${SYNC_INTERVAL:-600}
        echo "Next sync in ${SYNC_INTERVAL} seconds..."
        sleep $SYNC_INTERVAL
    done
}

# 启动同步进程
sync_data &