#!/bin/bash # ====== 织忆备份脚本 ====== # 备份到 server Gitea(http://192.168.123.11:3000) # 用法:./backup.sh [commit_message] # 自动:每天 03:00(见 cron 配置) set -e DATE=$(date +%Y%m%d_%H%M%S) LOG_FILE="${HOME}/.hermes/logs/backup.log" # 项目根目录(backup.sh 同级) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # 备份临时目录 BACKUP_DIR="/tmp/zhiyi_backup_${DATE}" CONFIG_DIR="/tmp/zhiyi_config_${DATE}" # 日志 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } log "===== 备份开始: ${DATE} =====" # 1. 备份数据文件 log "[1/6] 备份数据文件..." mkdir -p "${BACKUP_DIR}" sudo rsync -a /var/lib/memoryweave/ "${BACKUP_DIR}/memoryweave/" --quiet DATA_SIZE=$(du -sh "${BACKUP_DIR}" | cut -f1) log " 数据备份完成: ${DATA_SIZE}" # 2. 打包 log "[2/6] 打包数据..." cd /tmp tar -czf "zhiyi_backup_${DATE}.tar.gz" "zhiyi_backup_${DATE}/" rm -rf "zhiyi_backup_${DATE}" ARCHIVE_SIZE=$(du -sh "/tmp/zhiyi_backup_${DATE}.tar.gz" | cut -f1) log " 打包完成: ${ARCHIVE_SIZE}" # 3. 备份 Hermes 配置 log "[3/6] 备份 Hermes 配置..." mkdir -p "${CONFIG_DIR}" # 核心人格文件 rsync -a "${HOME}/.hermes/SOUL.md" "${CONFIG_DIR}/" 2>/dev/null || true rsync -a "${HOME}/.hermes/AGENTS.md" "${CONFIG_DIR}/" 2>/dev/null || true rsync -a "${HOME}/.hermes/MEMORY.md" "${CONFIG_DIR}/" 2>/dev/null || true rsync -a "${HOME}/.hermes/USER.md" "${CONFIG_DIR}/" 2>/dev/null || true # 配置文件 rsync -a "${HOME}/.hermes/config.yaml" "${CONFIG_DIR}/" 2>/dev/null || true rsync -a "${HOME}/.hermes/.env" "${CONFIG_DIR}/" 2>/dev/null || true rsync -a "${HOME}/.hermes/auth.json" "${CONFIG_DIR}/" 2>/dev/null || true # skills / cron / kanban [ -d "${HOME}/.hermes/skills" ] && rsync -a "${HOME}/.hermes/skills/" "${CONFIG_DIR}/skills/" --quiet [ -d "${HOME}/.hermes/cron" ] && rsync -a "${HOME}/.hermes/cron/" "${CONFIG_DIR}/cron/" --quiet [ -f "${HOME}/.hermes/kanban.db" ] && rsync -a "${HOME}/.hermes/kanban.db" "${CONFIG_DIR}/" 2>/dev/null || true # memories / sessions(可选,较大) if [ -d "${HOME}/.hermes/memories" ] && [ "$(du -sm "${HOME}/.hermes/memories" 2>/dev/null | cut -f1)" -lt 500 ]; then rsync -a "${HOME}/.hermes/memories/" "${CONFIG_DIR}/memories/" --quiet fi if [ -d "${HOME}/.hermes/sessions" ] && [ "$(du -sm "${HOME}/.hermes/sessions" 2>/dev/null | cut -f1)" -lt 200 ]; then rsync -a "${HOME}/.hermes/sessions/" "${CONFIG_DIR}/sessions/" --quiet fi CONFIG_SIZE=$(du -sh "${CONFIG_DIR}" | cut -f1) log " 配置备份完成: ${CONFIG_SIZE}" # 4. 推送到 Gitea log "[4/6] 推送到 Gitea..." # 确保 git 仓库存在 if [ ! -d "${PROJECT_ROOT}/.git" ]; then log " WARM: ${PROJECT_ROOT} 不是 git 仓库,初始化..." cd "${PROJECT_ROOT}" git init git remote add origin "http://192.168.123.11:3000/xiaoxue_admin/zhiyi-config.git" 2>/dev/null || true fi cd "${PROJECT_ROOT}" # 确保 data 目录存在 mkdir -p data # 移动备份到 data 目录 mv "/tmp/zhiyi_backup_${DATE}.tar.gz" data/ # 把数据仓库也 clone/update if [ ! -d "${PROJECT_ROOT}/zhiyi-backup" ]; then git clone "http://192.168.123.11:3000/xiaoxue_admin/zhiyi-backup.git" "${PROJECT_ROOT}/zhiyi-backup" 2>/dev/null || { # 如果仓库不存在,跳过数据备份 log " WARN: zhiyi-backup 仓库不存在或无法访问,跳过数据推送" } fi if [ -d "${PROJECT_ROOT}/zhiyi-backup" ]; then cd "${PROJECT_ROOT}/zhiyi-backup" # 移动 archive if [ -f "${PROJECT_ROOT}/data/zhiyi_backup_${DATE}.tar.gz" ]; then cp "${PROJECT_ROOT}/data/zhiyi_backup_${DATE}.tar.gz" . git add "zhiyi_backup_${DATE}.tar.gz" git commit -m "Backup data ${DATE}" 2>/dev/null || true git push origin main 2>/dev/null || log " WARN: 数据推送失败(可能需要 token)" rm -f "zhiyi_backup_${DATE}.tar.gz" fi cd "${PROJECT_ROOT}" fi # 推送配置 git add data/zhiyi_backup_${DATE}.tar.gz git add config/ 2>/dev/null || true git add -A COMMIT_MSG="${1:-Backup ${DATE}}" git commit -m "${COMMIT_MSG}" 2>/dev/null || log " WARN: 没有新内容需要提交" git push origin main 2>/dev/null || log " WARN: 配置推送失败(可能需要 token)" # 5. 清理 log "[5/6] 清理临时文件..." rm -rf "${BACKUP_DIR}" "${CONFIG_DIR}" log " 清理完成" # 6. 完成 log "[6/6] 备份完成" log "===== 备份结束: ${DATE} =====" echo ""