File size: 5,900 Bytes
5ab404f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/bin/bash

# 检查环境变量
if [[ -z "$WEBDAV_URL" ]] || [[ -z "$WEBDAV_USERNAME" ]] || [[ -z "$WEBDAV_PASSWORD" ]]; then
    echo "缺少 WEBDAV_URL、WEBDAV_USERNAME 或 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

# 确保数据目录存在
mkdir -p /data

# 下载最新备份并恢复
restore_backup() {
    echo "开始从 WebDAV 下载最新备份..."
    # 显式使用虚拟环境中的 python3,确保找到安装的库
    /app/venv/bin/python3 -c "
import sys
import os
import tarfile
import requests
from webdav3.client import Client
import shutil
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('cloudpaste_backup_')]
if not backups:
    print('没有找到备份文件')
    sys.exit()
latest_backup = sorted(backups)[-1]
print(f'最新备份文件:{latest_backup}')
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}')
        if os.path.exists(f'/tmp/{latest_backup}'):
            # 解压备份文件到临时目录
            temp_dir = '/tmp/restore'
            os.makedirs(temp_dir, exist_ok=True)
            tar = tarfile.open(f'/tmp/{latest_backup}', 'r:gz')
            tar.extractall(temp_dir)
            tar.close()
            # 查找并移动 cloudpaste.db 文件
            for root, dirs, files in os.walk(temp_dir):
                for file in files:
                    if file.endswith('.db'):  # 查找任何.db文件
                        db_path = os.path.join(root, file)
                        os.makedirs('/data', exist_ok=True)
                        target_path = os.path.join('/data', 'cloudpaste.db')
                        os.replace(db_path, target_path)
                        print(f'成功从 {latest_backup} 恢复备份到 {target_path}')
                        break
                else:
                    continue
                break
            else:
                print('备份文件中未找到数据库文件')
            # 删除临时目录
            try:
                shutil.rmtree(temp_dir)
            except Exception as e:
                print(f'删除临时目录时出错:{e}')
            os.remove(f'/tmp/{latest_backup}')
        else:
            print('下载的备份文件不存在')
    else:
        print(f'下载备份失败:{r.status_code}')
"
}

# 首次启动时下载最新备份
echo "正在从 WebDAV 下载最新备份..."
restore_backup

#pip install webdav3-client requests >/dev/null 2>&1

# 同步函数
sync_data() {
    while true; do
        echo "在 $(date) 开始同步进程"

        # 检查数据库文件是否存在
        DB_FILE="/data/cloudpaste.db"
        if [ -f "$DB_FILE" ]; then
            timestamp=$(date +%Y%m%d_%H%M%S)
            backup_file="cloudpaste_backup_${timestamp}.tar.gz"
            
            # 确保备份目录存在
            mkdir -p /tmp/backup

            # 创建备份目录结构
            cp "$DB_FILE" "/tmp/backup/cloudpaste.db"
            
            # 打包数据库文件
            tar -czf "/tmp/${backup_file}" -C /tmp/backup .
            
            # 上传新备份到WebDAV
            curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/${backup_file}"
            if [ $? -eq 0 ]; then
                echo "成功将 ${backup_file} 上传至 WebDAV"
                
                # 同时上传一个固定名称的最新备份
                curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/cloudpaste_latest.tar.gz"
                if [ $? -eq 0 ]; then
                    echo "成功将最新备份上传至 WebDAV"
                else
                    echo "上传最新备份至 WebDAV 失败"
                fi
            else
                echo "上传 ${backup_file} 至 WebDAV 失败"
            fi

            # 清理临时文件
            rm -rf /tmp/backup
            rm -f "/tmp/${backup_file}"

            # 清理旧备份文件,保留最近10个
            # 显式使用虚拟环境中的 python3,确保找到安装的库
            # python3 -c "
            /app/venv/bin/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('cloudpaste_backup_')]
backups.sort()
if len(backups) > 5:  # 保留最近5个备份
    to_delete = len(backups) - 10
    for file in backups[:to_delete]:
        try:
            client.clean(file)
            print(f'成功删除旧备份: {file}')
        except Exception as e:
            print(f'删除 {file} 时出错: {e}')
else:
    print(f'仅找到 {len(backups)} 个备份,无需清理')
" 2>&1
        else
            echo "数据库文件 $DB_FILE 尚不存在,等待下次同步..."
        fi

        # 设置同步间隔,默认20分钟
        SYNC_INTERVAL=${SYNC_INTERVAL:-1200}
        echo "下次同步将在 ${SYNC_INTERVAL} 秒后进行..."
        sleep $SYNC_INTERVAL
    done
}

# 后台启动同步进程
sync_data &