Files
awoooi/scripts/backup/common.sh
OG T f51bf5a6a8 feat(backup): 全服務備份覆蓋 + 告警機制 — 9/9 服務完整
新增備份(已部署到 110,首次執行全部通過):
- backup-langfuse.sh: Langfuse AI 追蹤/評測 DB (7238 traces)
- backup-monitoring.sh: Prometheus + Grafana + Alertmanager volumes + configs
- backup-signoz.sh: SignOz ClickHouse + SQLite (分散式追蹤/日誌)
- backup-open-webui.sh: Open-WebUI LLM 對話紀錄 (SSH 188 volume)
- backup-clawbot.sh: ClawBot Redis 狀態/快取 (SSH 188 volume)
- backup-all.sh v3.0: 整合至 9/9 服務

告警機制:
- common.sh: notify_clawbot 改用 /webhook/custom 正確格式
- failed → severity:critical → Telegram 🔴 立即告警
- 告警測試通過:{"status":"ok","alert_id":"878c4c59..."}

GFS 保留:30日/12週/24月 (AWOOOI 額外 28h 高頻)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 11:12:42 +08:00

148 lines
4.9 KiB
Bash

#\!/bin/bash
# =============================================================================
# WOOO AIOps - 備份共用函式庫
# 版本: 1.0.0
# 建立日期: 2026-03-12
# =============================================================================
# -----------------------------------------------------------------------------
# 配置區 (待 CEO 提供 B2 帳號後更新)
# -----------------------------------------------------------------------------
export BACKUP_BASE="/backup"
export BACKUP_LOG_DIR="${BACKUP_BASE}/logs"
export RESTIC_PASSWORD_FILE="${BACKUP_BASE}/scripts/.restic-password"
# Backblaze B2 配置 (待填入)
export B2_ACCOUNT_ID="" # 待 CEO 提供
export B2_APPLICATION_KEY="" # 待 CEO 提供
export B2_BUCKET="wooo-aiops-backup"
# ClawBot 通知 Webhook
export CLAWBOT_WEBHOOK="http://192.168.0.188:8088/api/v1/webhook/custom"
# 保留策略 (GFS 祖父子)
export KEEP_DAILY=30 # 2026-04-05 Claude Code: 延長保留 (原7→30)
export KEEP_WEEKLY=12 # 2026-04-05 Claude Code: 延長保留 (原4→12)
export KEEP_MONTHLY=24 # 2026-04-05 Claude Code: 延長保留 (原6→24)
# -----------------------------------------------------------------------------
# 日誌函式
# -----------------------------------------------------------------------------
log() {
local level="$1"
local message="$2"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[${timestamp}] [${level}] ${message}" | tee -a "${BACKUP_LOG_DIR}/backup.log"
}
log_info() { log "INFO" "$1"; }
log_warn() { log "WARN" "$1"; }
log_error() { log "ERROR" "$1"; }
log_success() { log "SUCCESS" "$1"; }
# -----------------------------------------------------------------------------
# 通知函式
# -----------------------------------------------------------------------------
notify_clawbot() {
local status="$1"
local service="$2"
local message="$3"
local duration="${4:-0}"
# 2026-04-05 Claude Code: 正確的 /webhook/custom payload + severity 依狀態
local severity="info"
[ "$status" = "warning" ] && severity="warning"
[ "$status" = "failed" ] && severity="critical"
if command -v curl &> /dev/null; then
curl -s -X POST "${CLAWBOT_WEBHOOK}" \
-H 'Content-Type: application/json' \
-d "{\"name\":\"Backup.${service}\",\"severity\":\"${severity}\",\"service\":\"${service}\",\"description\":\"[${status}] ${message} (${duration}s)\"}" \
--connect-timeout 5 2>/dev/null || true
fi
}
# -----------------------------------------------------------------------------
# Restic 標籤函式
# -----------------------------------------------------------------------------
get_app_version() {
local service="$1"
case "$service" in
gitea)
docker exec gitea gitea --version 2>/dev/null | grep -oP "\\d+\\.\\d+\\.\\d+" | head -1 || echo "unknown"
;;
harbor)
cat /opt/harbor/harbor.yml 2>/dev/null | grep -oP "version: \\K.*" || echo "unknown"
;;
momo)
echo "1.0.0" # MOMO 版本固定或從配置讀取
;;
*)
echo "unknown"
;;
esac
}
get_git_hash() {
local service="$1"
case "$service" in
gitea)
cd /var/lib/gitea 2>/dev/null && git rev-parse --short HEAD 2>/dev/null || echo "none"
;;
*)
echo "none"
;;
esac
}
build_tags() {
local service="$1"
local version=$(get_app_version "$service")
local git_hash=$(get_git_hash "$service")
local timestamp=$(date "+%Y%m%d_%H%M%S")
echo "--tag service:${service} --tag version:${version} --tag git:${git_hash} --tag timestamp:${timestamp}"
}
# -----------------------------------------------------------------------------
# 備份驗證函式
# -----------------------------------------------------------------------------
verify_backup() {
local repo="$1"
local snapshot_id="$2"
log_info "驗證備份快照: ${snapshot_id}"
restic -r "${repo}" check --read-data-subset=1% 2>&1
return $?
}
# -----------------------------------------------------------------------------
# 清理函式 (GFS 策略)
# -----------------------------------------------------------------------------
cleanup_old_backups() {
local repo="$1"
log_info "執行 GFS 清理策略"
restic -r "${repo}" forget \
--keep-daily ${KEEP_DAILY} \
--keep-weekly ${KEEP_WEEKLY} \
--keep-monthly ${KEEP_MONTHLY} \
--prune 2>&1
}
# -----------------------------------------------------------------------------
# 檢查配置
# -----------------------------------------------------------------------------
check_b2_config() {
if [ -z "${B2_ACCOUNT_ID}" ] || [ -z "${B2_APPLICATION_KEY}" ]; then
log_warn "B2 配置未設定,僅執行本地備份"
return 1
fi
return 0
}
# 初始化日誌目錄
mkdir -p "${BACKUP_LOG_DIR}"
log_info "共用函式庫載入完成 (v1.0.0)"