File size: 5,393 Bytes
3ead6d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6a05c0b
3ead6d8
6a05c0b
3ead6d8
 
 
6a05c0b
3ead6d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6a05c0b
3ead6d8
 
 
 
6a05c0b
 
3ead6d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9aa3ddc
3ead6d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/bin/sh

# 检查环境变量是否存在:WebDAV的URL、用户名和密码
if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
    echo "缺少WEBDAV_URL、WEBDAV_USERNAME或WEBDAV_PASSWORD,启动时不启用备份功能"
    exec node server/server.js  # 直接启动主程序,不进行备份恢复
    exit 0
fi

# 设置备份路径变量,如果没设置则为空字符串
WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH:-""}

# 组合完整的WebDAV URL(基础URL + 备份路径)
FULL_WEBDAV_URL="${WEBDAV_URL}"
if [ -n "$WEBDAV_BACKUP_PATH" ]; then
    FULL_WEBDAV_URL="${WEBDAV_URL}/${WEBDAV_BACKUP_PATH}"
fi

# 定义一个函数:从WebDAV下载最新备份并恢复数据
restore_backup() {
    echo "开始从 WebDAV 下载最新备份..."

    # 使用python脚本实现WebDAV备份文件的列出、下载、解压和恢复
    python3 -c "
import sys
import os
import tarfile
import requests
import shutil
from webdav3.client import Client

# 配置WebDAV客户端参数
options = {
    'webdav_hostname': '$FULL_WEBDAV_URL',
    'webdav_login': '$WEBDAV_USERNAME',
    'webdav_password': '$WEBDAV_PASSWORD'
}
client = Client(options)

# 列出所有备份文件(.tar.gz格式,且文件名以uptime_kuma_backup_开头)
backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('uptime_kuma_backup_')]

# 如果没有找到备份文件,则退出
if not backups:
    print('没有找到备份文件')
    sys.exit()

# 选择最新的备份文件(按文件名排序,默认文件名含时间戳)
latest_backup = sorted(backups)[-1]
print(f'最新备份文件:{latest_backup}')

# 通过requests库带认证下载备份文件到本地临时目录
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}'):
            # 如果data目录已存在,先删除以避免冲突
            if os.path.exists('/home/app/site-alert/data'):
                print('删除现有的data目录')
                shutil.rmtree('/home/app/site-alert/data')
            
            # 解压tar.gz备份文件到指定目录
            with tarfile.open(f'/tmp/{latest_backup}', 'r:gz') as tar:
                tar.extractall('/home/app/site-alert/')
            
            print(f'成功从 {latest_backup} 恢复备份')
        else:
            print('下载的备份文件不存在')
    else:
        print(f'下载备份失败,HTTP状态码:{r.status_code}')
"
}

# 脚本启动时先尝试下载并恢复最新备份
echo "Downloading latest backup from WebDAV..."
restore_backup

# 定义同步函数,循环定时备份并上传数据到WebDAV
sync_data() {
    while true; do
        echo "开始同步数据,时间:$(date)"

        # 判断本地data目录是否存在,存在则打包上传
        if [ -d "/home/app/site-alert/data" ]; then
            # 生成带时间戳的备份文件名
            timestamp=$(date +%Y%m%d_%H%M%S)
            backup_file="uptime_kuma_backup_${timestamp}.tar.gz"

            # 进入site-alert目录,打包data目录到临时目录
            cd /home/app/site-alert
            tar -czf "/tmp/${backup_file}" data

            # 使用curl上传备份文件到WebDAV
            curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/${backup_file}"
            if [ $? -eq 0 ]; then
                echo "成功上传备份文件 ${backup_file} 到 WebDAV"
            else
                echo "上传备份文件 ${backup_file} 失败"
            fi

            # 清理旧备份,保持最多5个备份文件,删除较旧的文件
            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('uptime_kuma_backup_')]
backups.sort()

# 如果备份数量超过5,则删除最旧的多余文件
if len(backups) > 5:
    to_delete = len(backups) - 5
    for file in backups[:to_delete]:
        client.clean(file)
        print(f'成功删除旧备份文件:{file}')
else:
    print(f'当前备份文件数量 {len(backups)},无需清理')
" 2>&1

            # 删除本地临时备份文件,释放空间
            rm -f "/tmp/${backup_file}"
        else
            echo "/home/app/site-alert/data 目录不存在,等待下一次同步"
        fi

        # 休眠一段时间,默认600秒(10分钟),可通过环境变量调整
        SYNC_INTERVAL=${SYNC_INTERVAL:-600}
        echo "下次同步将在 ${SYNC_INTERVAL} 秒后开始..."
        sleep $SYNC_INTERVAL
    done
}

# 后台启动同步进程,持续上传备份
sync_data &

# 等待30秒后启动主应用,保证备份线程已启动
sleep 30
exec node server/server.js