#!/bin/bash # BorgBackup 智能安装配置脚本 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 log() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" } error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" exit 1 } # 检查系统 check_system() { log "检查系统环境..." # 检查操作系统 if [ ! -f /etc/os-release ]; then error "无法检测操作系统" fi source /etc/os-release log "检测到系统: $NAME $VERSION" # 检查架构 ARCH=$(uname -m) log "系统架构: $ARCH" # 检查磁盘空间 DISK_SPACE=$(df /tmp | awk 'NR==2 {print $4}') if [ "$DISK_SPACE" -lt 1048576 ]; then # 小于 1GB warn "磁盘空间可能不足 (当前: ${DISK_SPACE}KB)" read -p "是否继续? (y/N): " -n 1 -r if [[ ! $REPLY =~ ^[Yy]$ ]]; then error "安装中止" fi fi # 检查内存 MEMORY=$(free -m | awk 'NR==2{print $2}') if [ "$MEMORY" -lt 512 ]; then warn "内存较小 (当前: ${MEMORY}MB),可能会影响备份性能" fi } # 安装依赖 install_dependencies() { log "安装系统依赖..." # 根据系统类型安装依赖 if command -v apt >/dev/null 2>&1; then # Debian/Ubuntu sudo apt update || warn "apt update 失败,尝试继续..." sudo apt install -y \ python3 \ python3-pip \ curl \ wget \ fuse \ pv \ cron \ || error "依赖安装失败" elif command -v yum >/dev/null 2>&1; then # CentOS/RHEL sudo yum install -y \ python3 \ python3-pip \ curl \ wget \ fuse \ pv \ cronie \ || error "依赖安装失败" elif command -v dnf >/dev/null 2>&1; then # Fedora sudo dnf install -y \ python3 \ python3-pip \ curl \ wget \ fuse \ pv \ cronie \ || error "依赖安装失败" else error "不支持的包管理器" fi } # 安装 BorgBackup install_borg() { log "安装 BorgBackup..." # 检查是否已安装 if command -v borg >/dev/null 2>&1; then CURRENT_VERSION=$(borg --version) log "BorgBackup 已安装: $CURRENT_VERSION" read -p "是否重新安装? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then return 0 fi fi # 多种安装方式 log "尝试通过系统包管理器安装..." if command -v apt >/dev/null 2>&1; then sudo apt install -y borgbackup && return 0 elif command -v yum >/dev/null 2>&1; then sudo yum install -y borgbackup && return 0 elif command -v dnf >/dev/null 2>&1; then sudo dnf install -y borgbackup && return 0 fi # 包管理器安装失败,使用 pip warn "包管理器安装失败,尝试使用 pip 安装..." sudo pip3 install borgbackup || { # 如果 pip 安装失败,尝试使用 conda if command -v conda >/dev/null 2>&1; then warn "尝试使用 conda 安装..." conda install -c conda-forge borgbackup || error "BorgBackup 安装失败" else error "所有安装方式都失败,请手动安装" fi } log "BorgBackup 安装成功: $(borg --version)" } # 安装 rclone install_rclone() { log "安装 rclone..." if command -v rclone >/dev/null 2>&1; then log "rclone 已安装: $(rclone version | head -n1)" return 0 fi # 使用官方安装脚本 curl https://rclone.org/install.sh | sudo bash || { # 如果脚本安装失败,尝试包管理器 warn "脚本安装失败,尝试包管理器..." if command -v apt >/dev/null 2>&1; then sudo apt install -y rclone elif command -v yum >/dev/null 2>&1; then sudo yum install -y rclone else error "rclone 安装失败" fi } log "rclone 安装成功" } # 交互式配置 rclone configure_rclone() { log "配置云存储..." echo echo "=== 云存储服务商选择 ===" echo "1) Cloudflare R2 (推荐)" echo "2) AWS S3" echo "3) Backblaze B2" echo "4) Google Cloud Storage" echo "5) 阿里云 OSS" echo "6) 腾讯云 COS" echo "7) 其他 S3 兼容服务" echo "8) 跳过(仅本地备份)" read -p "请选择服务商 [1-8]: " provider_choice case $provider_choice in 1) remote_name="r2" provider="Cloudflare R2" endpoint_prompt="R2 端点 (通常为: https://.r2.cloudflarestorage.com)" region="auto" ;; 2) remote_name="s3" provider="Amazon S3" endpoint_prompt="S3 端点 (留空使用默认): " region_prompt="区域 (例如: us-east-1): " ;; 3) remote_name="b2" provider="Backblaze B2" endpoint_prompt="B2 端点 (留空使用默认): " region="" ;; 4) remote_name="gcs" provider="Google Cloud Storage" endpoint_prompt="GCS 端点 (留空使用默认): " region="" ;; 5) remote_name="oss" provider="Aliyun OSS" endpoint_prompt="OSS 端点 (例如: https://oss-cn-hangzhou.aliyuncs.com): " region="" ;; 6) remote_name="cos" provider="Tencent COS" endpoint_prompt="COS 端点 (例如: https://cos.ap-beijing.myqcloud.com): " region="" ;; 7) remote_name="s3-custom" provider="自定义 S3 兼容" endpoint_prompt="S3 兼容端点: " region_prompt="区域: " ;; 8) log "跳过远程存储配置" return 0 ;; *) error "无效选择" ;; esac # 获取配置信息 echo echo "=== 配置 $provider ===" read -p "请输入远程存储名称 [默认: $remote_name]: " input_remote remote_name=${input_remote:-$remote_name} read -p "$endpoint_prompt" endpoint if [ -n "$endpoint" ]; then endpoint_option="$endpoint" fi if [ -n "$region_prompt" ]; then read -p "$region_prompt" region fi echo echo "=== API 密钥信息 ===" echo "在哪里找到密钥:" case $provider_choice in 1) echo "- Cloudflare Dashboard → R2 → API Tokens" ;; 2) echo "- AWS Console → IAM → Users → Security credentials" ;; 3) echo "- Backblaze → My Account → App Keys" ;; 4) echo "- Google Cloud Console → Storage → Settings → Interoperability" ;; 5) echo "- 阿里云控制台 → 访问控制 → 用户管理" ;; 6) echo "- 腾讯云控制台 → 访问管理 → API密钥管理" ;; 7) echo "- 查看您的 S3 兼容服务商文档" ;; esac echo read -p "Access Key ID: " access_key read -s -p "Secret Access Key: " secret_key echo # 配置 rclone log "配置 rclone 远程存储: $remote_name" rclone config create \ "$remote_name" \ s3 \ provider "Other" \ env_auth false \ access_key_id "$access_key" \ secret_access_key "$secret_key" \ ${endpoint:+"endpoint" "$endpoint"} \ ${region:+"region" "$region"} \ acl private \ || error "rclone 配置失败" # 测试连接 log "测试连接..." if rclone lsd "$remote_name:" >/dev/null 2>&1; then log "连接测试成功!" else warn "连接测试失败,但配置已保存。请检查网络和密钥。" fi REMOTE_CONFIGURED=1 CONFIGURED_REMOTE="$remote_name" } # 创建备份脚本 create_backup_scripts() { log "创建备份脚本..." local scripts_dir="$HOME/backup-scripts" mkdir -p "$scripts_dir" # 主备份脚本 cat > "$scripts_dir/backup-system.sh" << 'EOF' #!/bin/bash # BorgBackup 系统备份脚本 set -e # 配置 BACKUP_NAME="$(hostname)-system" LOCAL_REPO="$HOME/borg-repo" LOG_FILE="$HOME/backup-scripts/backup.log" CONFIG_FILE="$HOME/backup-scripts/backup.conf" # 加载配置 if [ -f "$CONFIG_FILE" ]; then source "$CONFIG_FILE" fi # 颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"; } warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"; } # 初始化仓库 init_repo() { if [ ! -d "$LOCAL_REPO" ]; then log "初始化 Borg 仓库..." borg init --encryption=repokey-blake2 "$LOCAL_REPO" 2>/dev/null || true fi } # 执行备份 create_backup() { local archive_name="$BACKUP_NAME-$(date +%Y%m%d-%H%M%S)" log "创建备份: $archive_name" sudo borg create \ --compression lz4 \ --stats \ --progress \ --exclude-caches \ --exclude '/var/cache/*' \ --exclude '/var/tmp/*' \ --exclude '/tmp/*' \ --exclude '/proc/*' \ --exclude '/sys/*' \ --exclude '/dev/*' \ --exclude '/mnt/*' \ --exclude '/media/*' \ --exclude '/run/*' \ --exclude '/boot/*' \ --exclude '/lost+found' \ --exclude '*.pyc' \ --exclude '*.swap' \ --exclude '*.tmp' \ "$LOCAL_REPO::$archive_name" \ / 2>&1 | tee -a "$LOG_FILE" } # 清理旧备份 prune_backups() { log "清理旧备份..." borg prune --list --stats \ --keep-daily=7 \ --keep-weekly=4 \ --keep-monthly=3 \ "$LOCAL_REPO" 2>&1 | tee -a "$LOG_FILE" } # 同步到远程 sync_to_remote() { if [ -n "$REMOTE_CONFIG" ]; then log "同步到远程存储: $REMOTE_CONFIG" rclone sync "$LOCAL_REPO" "$REMOTE_CONFIG" --progress 2>&1 | tee -a "$LOG_FILE" fi } # 主函数 main() { log "=== 开始备份任务 ===" init_repo create_backup prune_backups sync_to_remote log "=== 备份任务完成 ===" } main "$@" EOF # 如果配置了远程存储,更新配置文件 if [ "$REMOTE_CONFIGURED" = "1" ]; then echo "REMOTE_CONFIG=\"$CONFIGURED_REMOTE:backups/$(hostname)\"" > "$scripts_dir/backup.conf" fi chmod +x "$scripts_dir/backup-system.sh" log "备份脚本创建完成: $scripts_dir/backup-system.sh" } # 显示总结信息 show_summary() { echo echo "=== 安装完成 ===" echo -e "${GREEN}✓ BorgBackup 已安装${NC}" echo -e "${GREEN}✓ rclone 已安装${NC}" if [ "$REMOTE_CONFIGURED" = "1" ]; then echo -e "${GREEN}✓ 远程存储已配置: $CONFIGURED_REMOTE${NC}" else echo -e "${YELLOW}⚠ 未配置远程存储(仅本地备份)${NC}" fi echo echo "=== 下一步操作 ===" echo "1. 首次备份: ~/backup-scripts/backup-system.sh" echo "2. 设置定时任务: crontab -e" echo "3. 查看备份: borg list ~/borg-repo" if [ "$REMOTE_CONFIGURED" = "1" ]; then echo "4. 查看远程备份: rclone lsd $CONFIGURED_REMOTE:" fi echo echo "=== 重要提醒 ===" echo "• 备份 Borg 密钥: ~/borg-repo/keyfile" echo "• 定期测试恢复功能" echo "• 监控备份日志: ~/backup-scripts/backup.log" } # 主函数 main() { clear echo -e "${BLUE}" echo "╔══════════════════════════════════════╗" echo "║ BorgBackup 智能安装脚本 ║" echo "║ 适用于多平台系统备份 ║" echo "╚══════════════════════════════════════╝" echo -e "${NC}" # 检查 root 权限 if [ "$EUID" -eq 0 ]; then warn "不建议使用 root 用户运行此脚本" read -p "是否继续? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then error "请使用普通用户运行" fi fi # 执行安装步骤 check_system install_dependencies install_borg install_rclone configure_rclone create_backup_scripts show_summary } # 运行主函数 main "$@"