feat(backup): 实现 keep_count 清理策略和自动更新功能
- 添加 keep_count 配置读取,支持按数量保留备份 - 实现基于文件数量的清理逻辑,保留最新的 N 个备份文件 - 添加 docker-backup update 自动更新命令,从远程仓库拉取最新版本 - 添加 docker-backup help 帮助信息,显示完整使用说明 - 优化清理策略:优先使用 keep_days,其次使用 keep_count - 添加版本备份和错误恢复机制,确保更新安全
This commit is contained in:
187
bin/backup.sh
187
bin/backup.sh
@@ -146,6 +146,7 @@ load_config() {
|
||||
# 读取清理策略
|
||||
RETENTION_ENABLED=$(yq eval '.backup.retention.enabled' "${CONFIG_FILE}")
|
||||
KEEP_DAYS=$(yq eval '.backup.retention.keep_days' "${CONFIG_FILE}")
|
||||
KEEP_COUNT=$(yq eval '.backup.retention.keep_count' "${CONFIG_FILE}")
|
||||
|
||||
# 读取文件夹备份配置
|
||||
FOLDERS_ENABLED=$(yq eval '.folders.enabled' "${CONFIG_FILE}")
|
||||
@@ -394,24 +395,180 @@ cleanup_old_backups() {
|
||||
|
||||
log_info "开始清理旧备份..."
|
||||
|
||||
# 优先使用 keep_days 策略
|
||||
if [[ "${KEEP_DAYS}" != "null" ]] && [[ "${KEEP_DAYS}" =~ ^[0-9]+$ ]]; then
|
||||
log_info "删除 ${KEEP_DAYS} 天前的备份文件..."
|
||||
log_info "使用保留天数策略: 删除 ${KEEP_DAYS} 天前的备份文件..."
|
||||
|
||||
# 查找并删除旧文件
|
||||
find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -mtime +${KEEP_DAYS} -print | while read old_file; do
|
||||
log_info "删除旧备份: ${old_file}"
|
||||
rm -f "${old_file}"
|
||||
done
|
||||
# 如果没有设置 keep_days,使用 keep_count 策略
|
||||
elif [[ "${KEEP_COUNT}" != "null" ]] && [[ "${KEEP_COUNT}" =~ ^[0-9]+$ ]]; then
|
||||
log_info "使用保留数量策略: 保留最近 ${KEEP_COUNT} 个备份文件..."
|
||||
|
||||
# 获取所有备份文件,按修改时间倒序排列(最新的在前)
|
||||
local backup_files=($(find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -printf '%T@ %p\n' | sort -rn | awk '{print $2}'))
|
||||
local total_files=${#backup_files[@]}
|
||||
|
||||
log_info "当前备份文件总数: ${total_files}"
|
||||
|
||||
# 如果文件数量超过保留数量,删除多余的
|
||||
if [[ ${total_files} -gt ${KEEP_COUNT} ]]; then
|
||||
local files_to_delete=$((total_files - KEEP_COUNT))
|
||||
log_info "需要删除 ${files_to_delete} 个旧备份文件"
|
||||
|
||||
# 删除超出保留数量的文件(从数组末尾开始,即最旧的文件)
|
||||
for ((i=${KEEP_COUNT}; i<${total_files}; i++)); do
|
||||
local old_file="${backup_files[$i]}"
|
||||
log_info "删除旧备份: ${old_file}"
|
||||
rm -f "${old_file}"
|
||||
done
|
||||
else
|
||||
log_info "备份文件数量未超过保留限制,无需清理"
|
||||
fi
|
||||
else
|
||||
log_info "未配置有效的清理策略,跳过清理"
|
||||
fi
|
||||
|
||||
log_info "清理完成"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# 更新脚本
|
||||
###############################################################################
|
||||
|
||||
update_script() {
|
||||
log_info "=========================================="
|
||||
log_info "Docker Backup 自动更新"
|
||||
log_info "=========================================="
|
||||
|
||||
# 检查 root 权限
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "更新功能需要 root 权限"
|
||||
log_info "请使用: sudo docker-backup update"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 远程仓库地址
|
||||
local repo_url="https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main"
|
||||
|
||||
# 安装路径
|
||||
local bin_dir="/usr/local/bin"
|
||||
local backup_script="${bin_dir}/docker-backup"
|
||||
local cleanup_script="${bin_dir}/docker-backup-cleanup"
|
||||
|
||||
log_info "从远程仓库更新脚本..."
|
||||
log_info "仓库地址: ${repo_url}"
|
||||
|
||||
# 备份当前版本
|
||||
if [[ -f "${backup_script}" ]]; then
|
||||
local backup_backup="${backup_script}.backup"
|
||||
log_info "备份当前 backup.sh 到: ${backup_backup}"
|
||||
cp "${backup_script}" "${backup_backup}"
|
||||
fi
|
||||
|
||||
if [[ -f "${cleanup_script}" ]]; then
|
||||
local cleanup_backup="${cleanup_script}.backup"
|
||||
log_info "备份当前 cleanup.sh 到: ${cleanup_backup}"
|
||||
cp "${cleanup_script}" "${cleanup_backup}"
|
||||
fi
|
||||
|
||||
# 下载新版本 backup.sh
|
||||
log_info "下载最新 backup.sh..."
|
||||
if command -v wget &> /dev/null; then
|
||||
if ! wget -q "${repo_url}/bin/backup.sh" -O "${backup_script}.new"; then
|
||||
log_error "下载 backup.sh 失败"
|
||||
log_info "恢复备份..."
|
||||
[[ -f "${backup_script}.backup" ]] && mv "${backup_script}.backup" "${backup_script}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! curl -sL "${repo_url}/bin/backup.sh" -o "${backup_script}.new"; then
|
||||
log_error "下载 backup.sh 失败"
|
||||
log_info "恢复备份..."
|
||||
[[ -f "${backup_script}.backup" ]] && mv "${backup_script}.backup" "${backup_script}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 下载新版本 cleanup.sh
|
||||
log_info "下载最新 cleanup.sh..."
|
||||
if command -v wget &> /dev/null; then
|
||||
if ! wget -q "${repo_url}/bin/cleanup.sh" -O "${cleanup_script}.new"; then
|
||||
log_error "下载 cleanup.sh 失败"
|
||||
log_info "恢复备份..."
|
||||
[[ -f "${backup_script}.backup" ]] && mv "${backup_script}.backup" "${backup_script}"
|
||||
[[ -f "${cleanup_script}.backup" ]] && mv "${cleanup_script}.backup" "${cleanup_script}"
|
||||
rm -f "${backup_script}.new"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! curl -sL "${repo_url}/bin/cleanup.sh" -o "${cleanup_script}.new"; then
|
||||
log_error "下载 cleanup.sh 失败"
|
||||
log_info "恢复备份..."
|
||||
[[ -f "${backup_script}.backup" ]] && mv "${backup_script}.backup" "${backup_script}"
|
||||
[[ -f "${cleanup_script}.backup" ]] && mv "${cleanup_script}.backup" "${cleanup_script}"
|
||||
rm -f "${backup_script}.new"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 替换为新版本
|
||||
log_info "安装新版本..."
|
||||
mv "${backup_script}.new" "${backup_script}"
|
||||
mv "${cleanup_script}.new" "${cleanup_script}"
|
||||
chmod +x "${backup_script}"
|
||||
chmod +x "${cleanup_script}"
|
||||
|
||||
# 清理备份文件
|
||||
rm -f "${backup_script}.backup"
|
||||
rm -f "${cleanup_script}.backup"
|
||||
|
||||
log_info "=========================================="
|
||||
log_info "更新完成!"
|
||||
log_info "=========================================="
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# 显示帮助信息
|
||||
###############################################################################
|
||||
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Docker Backup - Docker 数据备份工具
|
||||
|
||||
使用方法:
|
||||
docker-backup [命令]
|
||||
|
||||
命令:
|
||||
(无参数) 执行备份任务
|
||||
update 从远程仓库更新脚本到最新版本
|
||||
help 显示此帮助信息
|
||||
|
||||
示例:
|
||||
docker-backup # 执行备份
|
||||
docker-backup update # 更新脚本
|
||||
sudo docker-backup update # 以 root 权限更新脚本
|
||||
|
||||
配置文件:
|
||||
/etc/docker-backup/config.yml
|
||||
|
||||
日志文件:
|
||||
配置文件中 logging.log_file 指定的路径
|
||||
默认: /var/log/docker-backup.log
|
||||
|
||||
项目地址:
|
||||
https://gitea.bcde.io/wangdefa/docker-backup
|
||||
EOF
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# 主函数
|
||||
###############################################################################
|
||||
|
||||
main() {
|
||||
run_backup() {
|
||||
log_info "=========================================="
|
||||
log_info "Docker Backup 开始执行"
|
||||
log_info "=========================================="
|
||||
@@ -444,5 +601,31 @@ main() {
|
||||
log_info "=========================================="
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# 参数解析
|
||||
###############################################################################
|
||||
|
||||
main() {
|
||||
local command="${1:-}"
|
||||
|
||||
case "${command}" in
|
||||
update)
|
||||
update_script
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
"")
|
||||
run_backup
|
||||
;;
|
||||
*)
|
||||
log_error "未知命令: ${command}"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user