Files
docker-backup/install.sh
Wang Defa 46a0ade8ba feat: 实现日志级别功能并修复日志输出问题
- 实现 logging.level 配置项支持(DEBUG/INFO/WARN/ERROR)
- 修复日志文件中 ANSI 颜色代码显示问题
- 修复 install.sh 中 show_info() 函数颜色显示
- 日志输出现在会根据配置的级别进行过滤
2025-12-25 16:34:30 +08:00

551 lines
16 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
###############################################################################
# Docker Backup 远程安装脚本
# 功能:安装依赖、下载文件、配置 systemd 服务
# 使用bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)
###############################################################################
set -e
set -o pipefail
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Gitea 仓库地址
REPO_URL="https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main"
# 安装路径
BIN_DIR="/usr/local/bin"
CONFIG_DIR="/etc/docker-backup"
SYSTEMD_DIR="/etc/systemd/system"
# 默认服务名称
DEFAULT_SERVICE_NAME="docker-backup"
SERVICE_NAME="${SERVICE_NAME:-$DEFAULT_SERVICE_NAME}"
# 默认定时计划
DEFAULT_SCHEDULE="*-*-* 02:00:00" # 每天凌晨 2 点
SCHEDULE="${SCHEDULE:-$DEFAULT_SCHEDULE}"
###############################################################################
# 日志函数
###############################################################################
log_info() {
echo -e "${GREEN}[INFO]${NC} $@"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $@"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $@"
}
log_step() {
echo -e "\n${BLUE}==>${NC} $@"
}
###############################################################################
# 检查是否以 root 权限运行
###############################################################################
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本需要 root 权限运行"
log_info "请使用: sudo bash <(curl -sL ...)"
exit 1
fi
}
###############################################################################
# 检测操作系统
###############################################################################
detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
OS_VERSION=$VERSION_ID
else
log_error "无法检测操作系统类型"
exit 1
fi
log_info "检测到操作系统: $OS $OS_VERSION"
}
###############################################################################
# 安装 yq
###############################################################################
install_yq() {
log_step "检查 yq 是否已安装..."
if command -v yq &> /dev/null; then
log_info "yq 已安装: $(yq --version)"
return 0
fi
log_info "yq 未安装,正在安装..."
# 检测系统架构
local arch=$(uname -m)
case $arch in
x86_64)
arch="amd64"
;;
aarch64|arm64)
arch="arm64"
;;
armv7l)
arch="arm"
;;
*)
log_error "不支持的系统架构: $arch"
exit 1
;;
esac
# 下载并安装 yq
local yq_version="v4.40.5"
local yq_url="https://github.com/mikefarah/yq/releases/download/${yq_version}/yq_linux_${arch}"
log_info "下载 yq ${yq_version} for ${arch}..."
if command -v wget &> /dev/null; then
wget -q "${yq_url}" -O /usr/local/bin/yq
elif command -v curl &> /dev/null; then
curl -sL "${yq_url}" -o /usr/local/bin/yq
else
log_error "需要 wget 或 curl 来下载 yq"
exit 1
fi
chmod +x /usr/local/bin/yq
if command -v yq &> /dev/null; then
log_info "yq 安装成功: $(yq --version)"
else
log_error "yq 安装失败"
exit 1
fi
}
###############################################################################
# 安装其他依赖
###############################################################################
install_dependencies() {
log_step "检查并安装依赖工具..."
local deps=("tar" "gzip" "docker" "find")
local missing_deps=()
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
missing_deps+=("$dep")
fi
done
if [[ ${#missing_deps[@]} -eq 0 ]]; then
log_info "所有依赖工具已安装"
return 0
fi
log_warn "缺少以下工具: ${missing_deps[*]}"
case $OS in
ubuntu|debian)
log_info "使用 apt 安装依赖..."
apt-get update -qq
apt-get install -y -qq "${missing_deps[@]}" docker.io
;;
centos|rhel|fedora)
log_info "使用 yum/dnf 安装依赖..."
if command -v dnf &> /dev/null; then
dnf install -y -q "${missing_deps[@]}" docker
else
yum install -y -q "${missing_deps[@]}" docker
fi
;;
*)
log_error "不支持的操作系统,请手动安装: ${missing_deps[*]}"
exit 1
;;
esac
log_info "依赖安装完成"
}
###############################################################################
# 下载并部署文件
###############################################################################
deploy_files() {
log_step "从远程仓库下载文件..."
# 创建必要的目录
mkdir -p "${BIN_DIR}"
mkdir -p "${CONFIG_DIR}"
mkdir -p "${SYSTEMD_DIR}"
# 下载备份脚本
log_info "下载 backup.sh..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/bin/backup.sh" -O "${BIN_DIR}/docker-backup"
else
curl -sL "${REPO_URL}/bin/backup.sh" -o "${BIN_DIR}/docker-backup"
fi
chmod +x "${BIN_DIR}/docker-backup"
# 下载清理脚本
log_info "下载 cleanup.sh..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/bin/cleanup.sh" -O "${BIN_DIR}/docker-backup-cleanup"
else
curl -sL "${REPO_URL}/bin/cleanup.sh" -o "${BIN_DIR}/docker-backup-cleanup"
fi
chmod +x "${BIN_DIR}/docker-backup-cleanup"
# 下载配置文件示例
if [[ ! -f "${CONFIG_DIR}/config.yml" ]]; then
log_info "下载配置文件示例..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/config/backup.yml.example" -O "${CONFIG_DIR}/config.yml"
else
curl -sL "${REPO_URL}/config/backup.yml.example" -o "${CONFIG_DIR}/config.yml"
fi
log_warn "请编辑配置文件: ${CONFIG_DIR}/config.yml"
else
log_info "配置文件已存在,跳过"
fi
log_info "文件部署完成"
}
###############################################################################
# 配置 systemd 服务
###############################################################################
setup_systemd() {
log_step "配置 systemd 服务..."
# 生成 service 文件
log_info "生成 ${SERVICE_NAME}.service..."
cat > "${SYSTEMD_DIR}/${SERVICE_NAME}.service" << EOF
[Unit]
Description=Docker Backup Service
Documentation=https://gitea.bcde.io/wangdefa/docker-backup
After=network.target docker.service
Requires=docker.service
[Service]
Type=oneshot
User=root
Group=root
# 执行备份脚本
ExecStart=${BIN_DIR}/docker-backup
# 标准输出和错误输出
StandardOutput=journal
StandardError=journal
# 超时设置30分钟
TimeoutStartSec=1800
# 资源限制
Nice=19
IOSchedulingClass=idle
[Install]
WantedBy=multi-user.target
EOF
# 生成 timer 文件
log_info "生成 ${SERVICE_NAME}.timer..."
cat > "${SYSTEMD_DIR}/${SERVICE_NAME}.timer" << EOF
[Unit]
Description=Docker Backup Timer
Documentation=https://gitea.bcde.io/wangdefa/docker-backup
Requires=${SERVICE_NAME}.service
[Timer]
# 定时执行时间
OnCalendar=${SCHEDULE}
# 如果错过了执行时间,启动时立即执行一次
Persistent=true
# 随机延迟0-10分钟避免多个任务同时执行
RandomizedDelaySec=10min
[Install]
WantedBy=timers.target
EOF
# 重新加载 systemd
log_info "重新加载 systemd..."
systemctl daemon-reload
log_info "systemd 服务配置完成"
}
###############################################################################
# 启用并启动服务
###############################################################################
enable_service() {
log_step "启用 systemd 服务..."
# 启用 timer
log_info "启用 ${SERVICE_NAME}.timer..."
systemctl enable "${SERVICE_NAME}.timer"
# 启动 timer
log_info "启动 ${SERVICE_NAME}.timer..."
systemctl start "${SERVICE_NAME}.timer"
# 检查状态
log_info "服务状态:"
systemctl status "${SERVICE_NAME}.timer" --no-pager || true
log_info "定时任务已启用"
}
###############################################################################
# 测试备份
###############################################################################
test_backup() {
log_step "测试备份功能..."
read -p "是否立即执行一次备份测试? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "执行备份测试..."
"${BIN_DIR}/docker-backup" || log_error "备份测试失败,请检查配置和日志"
else
log_info "跳过备份测试"
fi
}
###############################################################################
# 显示安装信息
###############################################################################
show_info() {
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Docker Backup 安装完成! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${BLUE}安装信息:${NC}"
echo " - 备份脚本: ${BIN_DIR}/docker-backup"
echo " - 清理脚本: ${BIN_DIR}/docker-backup-cleanup"
echo " - 配置文件: ${CONFIG_DIR}/config.yml"
echo " - 服务名称: ${SERVICE_NAME}"
echo ""
echo -e "${BLUE}常用命令:${NC}"
echo " # 查看定时任务状态"
echo " systemctl status ${SERVICE_NAME}.timer"
echo ""
echo " # 查看定时计划"
echo " systemctl list-timers ${SERVICE_NAME}.timer"
echo ""
echo " # 手动执行备份"
echo " docker-backup"
echo ""
echo " # 列出所有备份"
echo " docker-backup-cleanup --list"
echo ""
echo " # 清理旧备份"
echo " docker-backup-cleanup --auto"
echo ""
echo " # 停止定时任务"
echo " systemctl stop ${SERVICE_NAME}.timer"
echo ""
echo " # 禁用定时任务"
echo " systemctl disable ${SERVICE_NAME}.timer"
echo ""
echo -e "${YELLOW}重要提示:${NC}"
echo " 1. 请编辑配置文件以适应您的环境:"
echo " vi ${CONFIG_DIR}/config.yml"
echo ""
echo " 2. 修改配置后无需重启服务,下次执行时自动生效"
echo ""
echo " 3. 查看下次执行时间:"
echo " systemctl list-timers | grep ${SERVICE_NAME}"
echo ""
echo " 4. 查看备份日志:"
echo " journalctl -u ${SERVICE_NAME}.service -f"
echo ""
}
###############################################################################
# 卸载函数
###############################################################################
uninstall() {
log_step "卸载 Docker Backup..."
# 停止并禁用服务
if systemctl is-active --quiet "${SERVICE_NAME}.timer"; then
log_info "停止 ${SERVICE_NAME}.timer..."
systemctl stop "${SERVICE_NAME}.timer"
fi
if systemctl is-enabled --quiet "${SERVICE_NAME}.timer"; then
log_info "禁用 ${SERVICE_NAME}.timer..."
systemctl disable "${SERVICE_NAME}.timer"
fi
# 删除 systemd 文件
log_info "删除 systemd 文件..."
rm -f "${SYSTEMD_DIR}/${SERVICE_NAME}.service"
rm -f "${SYSTEMD_DIR}/${SERVICE_NAME}.timer"
# 重新加载 systemd
systemctl daemon-reload
# 删除脚本文件
log_info "删除脚本文件..."
rm -f "${BIN_DIR}/docker-backup"
rm -f "${BIN_DIR}/docker-backup-cleanup"
# 删除配置文件
read -p "是否删除配置目录 ${CONFIG_DIR}? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "删除配置目录..."
rm -rf "${CONFIG_DIR}"
else
log_info "保留配置目录"
fi
log_info "卸载完成"
exit 0
}
###############################################################################
# 显示使用帮助
###############################################################################
show_usage() {
cat << EOF
Docker Backup 远程安装脚本
用法: bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) [选项]
选项:
-h, --help 显示此帮助信息
-n, --name NAME 指定服务名称 (默认: ${DEFAULT_SERVICE_NAME})
-s, --schedule SCHEDULE 指定定时计划 (默认: ${DEFAULT_SCHEDULE})
-u, --uninstall 卸载 Docker Backup
定时计划示例:
"daily" 每天执行
"*-*-* 02:00:00" 每天凌晨 2 点
"Mon *-*-* 02:00:00" 每周一凌晨 2 点
"*-*-01 02:00:00" 每月 1 号凌晨 2 点
"hourly" 每小时执行
示例:
# 默认安装
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)
# 自定义服务名称
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --name mybackup
# 自定义定时计划(每天早上 6 点)
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --schedule "*-*-* 06:00:00"
# 卸载
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --uninstall
EOF
}
###############################################################################
# 主函数
###############################################################################
main() {
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-n|--name)
SERVICE_NAME="$2"
shift 2
;;
-s|--schedule)
SCHEDULE="$2"
shift 2
;;
-u|--uninstall)
check_root
uninstall
;;
*)
log_error "未知选项: $1"
show_usage
exit 1
;;
esac
done
# 显示欢迎信息
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ 欢迎使用 Docker Backup 安装程序 ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "安装配置:"
echo " - 服务名称: ${SERVICE_NAME}"
echo " - 定时计划: ${SCHEDULE}"
echo " - 配置目录: ${CONFIG_DIR}"
echo " - 脚本目录: ${BIN_DIR}"
echo ""
# 检查 root 权限
check_root
# 检测操作系统
detect_os
# 安装 yq
install_yq
# 安装其他依赖
install_dependencies
# 部署文件
deploy_files
# 配置 systemd
setup_systemd
# 启用服务
enable_service
# 测试备份
test_backup
# 显示安装信息
show_info
}
# 执行主函数
main "$@"