使用搬瓦工api自动周期性创建快照并telegrambot通知完整版

该教程详细指导如何配置搬瓦工VPS自动创建快照并通过Telegram机器人通知。核心配置包括修改脚本中的VEID、API密钥、机器人令牌和聊天ID四个参数,并需预装jq工具处理JSON数据。脚本实现了每日自动生成带日期标记的快照,同时具备清理旧快照和锁定重要快照的功能,通过日志记录和Telegram实时推送确保操作可追溯。
  • 输入命令:su -(注意:su 后面有个空格和减号,这很重要,代表同时切换环境变量)
  • 输入 Root 密码(输入时看不见)。
  • 此时你的提示符会变成#,代表你又是 Root 了。
  • 先检查是否安装了jq

    输入jq --version

    如果输出

    -bash: jq: command not found

    说明没有安装

    安装jq

    1. Debian / Ubuntu

    sudo apt update sudo apt install jq -y

    2. CentOS / RHEL

    如果是 CentOS 7,可能需要先安装 epel-release

    sudo yum install epel-release -y

    sudo yum install jq -y

    如果是 RHEL 8/9 或 AlmaLinux

    sudo dnf install jq -y

    验证是否安装成功

    安装完成后,你可以输入

    jq --version

    脚本

    需要修改的地方

    VEID=“你的VEID”

    API_KEY=“你的API_KEY”

    TG_BOT_TOKEN=“你的BOT_TOKEN”

    TG_CHAT_ID=“你的CHAT_ID”

    TAG_PREFIX=“bwgApiAutoSnapShot” #快照描述的前缀 作为判断快照是否创建、删除、锁定的重要依据

    MAX_LOG_LINES=500 # 设置日志最大保留行数,超过则清空

    LOG_FILE=“/var/log/bwg_snapshot.log” # 日志文件路径


    检查 /root/autosnapshot.sh 是否存在

    输入ls /root/autosnapshot.sh

    上面 蓝色框框就是文件不存在 就可以不修改文件名

    下面的红色框框 就是文件存在 需要修改文件名字 /root/这里是文件名字.sh 比如修改成/root/autosnapshot11.sh

    把下面内容修改后 就可以复制粘贴到ssh里面 然后按回车 就可以创建脚本文件了


    使用搬瓦工api自动周期性创建快照并telegrambot通知完整版

    cat << 'EOF' > /root/autosnapshot.sh
    #!/bin/bash
    
    # ================= 配置区域 =================
    VEID="你的VEID"
    API_KEY="你的API_KEY"
    TG_BOT_TOKEN="你的BOT_TOKEN"
    TG_CHAT_ID="你的CHAT_ID"
    
    MAX_LOG_LINES=500 # 调整日志最大保留行数,超过则清空
    
    
    LOG_FILE="/var/log/bwg_snapshot.log"
    TAG_PREFIX="bwgApiAutoSnapShot"
    # ===========================================
    
    API_URL="https://api.64clouds.com/v1"
    DATE_TODAY=$(date +"%Y_%m_%d")
    CURRENT_SNAPSHOT_NAME="${TAG_PREFIX}_${DATE_TODAY}"
    
    log() {
     # 检查日志文件是否存在
     if [ -f "$LOG_FILE" ]; then
     # 获取当前行数
     local current_lines=$(grep -c "" "$LOG_FILE")
     if [ "$current_lines" -gt "$MAX_LOG_LINES" ]; then
     # 超过行数,保留最后 10 行并标记清空,或者直接清空
     echo "[$(date '+%Y-%m-%d %H:%M:%S')] 日志达到上限,执行自动清理。" > "$LOG_FILE"
     fi
     fi
     # 正常写入日志
     echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
    }
    
    send_tg() {
     local msg="$1"
     # 发送 TG 消息并根据 curl 状态码记录日志
     curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" 
     -d "chat_id=${TG_CHAT_ID}" 
     -d "text=${msg}" 
     -d "disable_notification=true" > /dev/null
    
     if [ $? -eq 0 ]; then
     log "Telegram 通知发送成功: $msg"
     else
     log "Telegram 通知发送失败,请检查网络或 Token。"
     fi
    }
    
    call_api() {
     local endpoint="$1"
     local extra_params="$2"
     # --max-time 30: 设置最大超时时间为30秒
     # --retry 3: 如果失败自动重试3次
     curl -s --max-time 30 --retry 3 -X POST "${API_URL}/${endpoint}" 
     -d "veid=${VEID}" 
     -d "api_key=${API_KEY}" 
     ${extra_params}
    }
    
    # 【新增函数】提取快照数据的公共逻辑
    get_snapshot_map() {
     echo "$SNAPSHOT_LIST" | jq -r --arg tag "$TAG_PREFIX" '
     .snapshots[] |
     select(try (.description | @base64d) catch "" | contains($tag)) |
     "(.sticky)|((.description | @base64d))|(.fileName)"
     '
    }
    
    # 预检
    if ! command -v jq &> /dev/null; then
     log "错误: 未安装 jq,请安装jq"
     exit 1
    fi
    
    log "--- 脚本启动 ---"
    SNAPSHOT_LIST=$(call_api "snapshot/list" "")
    
    # ================= 模式 1: 开机补刀/清理逻辑 (默认) =================
    if [[ "$1" != "-c" ]]; then
     log "进入开机自检模式..."
    
     # 调用函数获取数据
     MAP_DATA=$(get_snapshot_map)
    
     # 使用 grep -c 直接统计行数,不再使用 wc -l
     count_a=$(echo "$MAP_DATA" | grep -c "^true")
     count_b=$(echo "$MAP_DATA" | grep -c "^false")
    
     log "开机自检状态: 符合前缀的置顶数 $count_a, 符合前缀的未置顶数 $count_b"
    
     if [ "$count_a" -eq 0 ] && [ "$count_b" -eq 0 ]; then
     log "状态 [0,0]:未发现任何相关快照,无需操作。"
     exit 0
    
     elif [ "$count_b" -eq 1 ]; then
     NEW_FILENAME=$(echo "$MAP_DATA" | grep "^false" | cut -d "|" -f 3)
     NEW_DESC=$(echo "$MAP_DATA" | grep "^false" | cut -d "|" -f 2)
    
     if [ "$count_a" -eq 1 ]; then
     OLD_FILENAME=$(echo "$MAP_DATA" | grep "^true" | cut -d "|" -f 3)
     OLD_DESC=$(echo "$MAP_DATA" | grep "^true" | cut -d "|" -f 2)
    
     log "发现新快照,正在删除旧的已置顶快照: $OLD_DESC"
    
     DEL_RES=$(call_api "snapshot/delete" "--data-urlencode snapshot=${OLD_FILENAME}")
    
     # 【替换 1】使用 jq 判断删除结果
     API_ERR_DEL=$(echo "$DEL_RES" | jq -r '.error' 2>/dev/null)
     if [ "$API_ERR_DEL" = "0" ]; then
     log "旧快照删除成功。"
     DEL_MSG="已成功删除旧快照: ${OLD_DESC}。"
     else
     log "旧快照删除失败: $DEL_RES"
     DEL_MSG="删除旧快照发生错误。"
     fi
     fi
     # 锁定新快照(b)
     log "正在锁定新快照: $NEW_DESC ..."
     LOCK_RES=$(call_api "snapshot/toggleSticky" "--data-urlencode snapshot=${NEW_FILENAME} -d sticky=1")
    
     # 使用 jq 解析 error 字段的值是否等于 0
     API_ERROR=$(echo "$LOCK_RES" | jq -r '.error' 2>/dev/null)
    
     if [ "$API_ERROR" = "0" ]; then
     log "新快照锁定成功。"
     send_tg "✅ 快照更替完成!${DEL_MSG}新快照 ${NEW_DESC} 已成功锁定。"
     exit 0
     else
     log "新快照锁定失败,API返回: $LOCK_RES"
     send_tg "❌ ${DEL_MSG}但新快照 ${NEW_DESC} 锁定失败,解析出的错误码为: ${API_ERROR}"
     exit 1
     fi
    
     else
     log "自检状态 [$count_a,$count_b]:不满足自动更替条件。"
     send_tg "ℹ️ 搬瓦工自检报告:当前状态为 [$count_a,$count_b],未达到快照更迭条件,脚本未执行操作。请手动查看.."
     exit 1
     fi
    fi
    
    # ================= 模式 2: 创建逻辑 (-c 参数) =================
    log "进入快照创建模式 (-c)..."
    
    # 调用函数获取数据
    MAP_DATA=$(get_snapshot_map)
    
    count_a=$(echo "$MAP_DATA" | grep -c "^true")
    count_b=$(echo "$MAP_DATA" | grep -c "^false")
    
    log "状态检查: 符合前缀的已置顶快照数 $count_a, 符合前缀的未置顶的快照数 $count_b"
    
    DO_CREATE=false
    
    if [ "$count_a" -eq 0 ] && [ "$count_b" -eq 0 ]; then
     log "状态 [0,0]:准备发起首次创建。"
     DO_CREATE=true
    elif [ "$count_a" -eq 1 ] && [ "$count_b" -eq 0 ]; then
     log "状态 [1,0]:准备创建新的备份。"
     DO_CREATE=true
    elif [ "$count_a" -eq 0 ] && [ "$count_b" -eq 1 ]; then
     log "状态 [0,1]:存在未锁定的快照,无法判断未锁定的快照目的,停止自动化创建快照,请锁定或删除旧快照或更改description"
     send_tg "⚠️ 存在未锁定的快照,无法判断未锁定的快照目的,停止自动化创建快照,请锁定或删除旧快照或更改description"
    elif [ "$count_a" -eq 2 ]; then
     log "状态 [$count_a,$count_b]:置顶名额满。"
     send_tg "🚫 快照置顶名额已满 (2/2),请手动删除旧备份。"
    else
     log "状态 [$count_a,$count_b]:未知状态,停止操作。"
     send_tg "❌ 未创建快照:不清楚的快照数量 (a=$count_a, b=$count_b)。"
    fi
    
    if [ "$DO_CREATE" = true ]; then
     # 再次检查日期防止重复
     if echo "$MAP_DATA" | grep -q "$DATE_TODAY"; then
     log "今日快照已存在,跳过。今日: $DATE_TODAY"
     else
     log "发起创建快照请求: $CURRENT_SNAPSHOT_NAME"
     CREATE_RESULT=$(call_api "snapshot/create" "--data-urlencode description=${CURRENT_SNAPSHOT_NAME}")
    
     # 【替换 2】使用 jq 判断创建请求结果
     API_ERR_CREATE=$(echo "$CREATE_RESULT" | jq -r '.error' 2>/dev/null)
     if [ "$API_ERR_CREATE" = "0" ]; then
     log "创建快照请求成功发送。"
     else
     log "创建快照请求失败: $CREATE_RESULT"
     send_tg "⚠️ 搬瓦工 API 创建快照请求返回异常。"
     fi
     fi
    fi
    EOF
    
    

    授予运行权限

    输入

    chmod +x /root/autosnapshot.sh

    查看是否成功 输入ls -l /root/autosnapshot.sh

    像蓝色的有x就是成功了 像上面后红色的- 没有x 就是失败了…

    配置开机置顶快照 和定期创建快照

    0 3 * * 1

    这是一个cron的表达式 用来设定 运行时间的

    0 代表 第 0 分钟的时候

    3 代表 第3小时的时候 就是凌晨3点

    第一个 * 代表 哪一天 *代表所有天

    第二个 * 代表 哪一月 *代表所有月

    1 代表 星期一

    合起来就是

    每周一的凌晨3:00运行 创建快照的指令

    可以按照自己的时间自行修改

    0 3 * * 1 root /usr/local/bin/bwg_snap.sh -c >> /var/log/bwg_snapshot.log 2>&1

    开机启动检查是否有未锁定的快照(认为是上一次的快照)

    如果文件名 改了的话 这里也要修改 其他的地方不需要

    @reboot root /usr/local/bin/bwg_snap.sh >> /var/log/bwg_snapshot.log 2>&1

    检查定时文件是否存在

    输入ls /etc/cron.d/bwg_snap

    上面红色框框 就是 文件不存在 不需要修改名字

    下面蓝色框框 就是 文件存在 需要文件名字…/etc/cron.d/你需要修改的名字 比如/etc/cron.d/bwg_snap1

    修改后 复制粘贴到ssh里面 回车就行了

    cat <<EOF > /etc/cron.d/bwg_snap
    # 每周一凌晨 3 点创建快照
    0 3 * * 1 root /usr/local/bin/bwg_snap.sh -c >> /var/log/bwg_snapshot.log 2>&1
    # 开机自启
    @reboot root /usr/local/bin/bwg_snap.sh >> /var/log/bwg_snapshot.log 2>&1
    EOF
    
    

    修改文件权限

    chmod 644 /etc/cron.d/bwg_snap

    如果你想测试 可以输入

    /root/autosnapshot.sh -c

    根据时间 一天只能创建一个快照…脚本设定 非api设置的…

    创建快照 系统会重启 请注意为保存的数据会丢失…

    开机后应该会自动置顶这个快照 或 手动输入/root/autosnapshot.sh

    检查是否存在 有前缀名但未置顶的快照 或 有前缀 或 有一个 有前缀的并且置顶的快照 和 一个 有前缀未置顶的快照

    都会执行 删除置顶的快照(如果有)然后置顶那个 未置顶的快照

    查看日志 cat /var/log/bwg_snapshot.log

    原创文章,作者:banwagong,如若转载,请注明出处:https://bwgcn2gia.com/archives/358.html

    (0)
    上一篇 02/09/2026 12:31

    相关推荐

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注