feat(backup): add standalone backup script, deprecate Go API route
This commit is contained in:
parent
b237cc9aeb
commit
c3db6ffe30
|
|
@ -1,130 +1,56 @@
|
|||
#!/bin/bash
|
||||
# ====== 织忆备份脚本 ======
|
||||
# 备份到 server Gitea(http://192.168.123.11:3000)
|
||||
# 用法:./backup.sh [commit_message]
|
||||
# 自动:每天 03:00(见 cron 配置)
|
||||
# 织忆每日备份脚本(由 cronjob 每天 04:00 调用)
|
||||
# 直接执行备份,不走 Go HTTP API
|
||||
|
||||
set -e
|
||||
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
LOG_FILE="${HOME}/.hermes/logs/backup.log"
|
||||
API_KEY="zhiyi-dev-key-2026"
|
||||
BACKUP_ROOT="/home/muc/backups/memoryweave"
|
||||
DATA_DIR="/var/lib/memoryweave"
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
|
||||
|
||||
# 项目根目录(backup.sh 同级)
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
echo "[$TIMESTAMP] 织忆备份开始..."
|
||||
|
||||
# 备份临时目录
|
||||
BACKUP_DIR="/tmp/zhiyi_backup_${DATE}"
|
||||
CONFIG_DIR="/tmp/zhiyi_config_${DATE}"
|
||||
# 1. 创建备份目录
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 日志
|
||||
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
|
||||
# 2. SQLite graph.db 备份
|
||||
echo "[$TIMESTAMP] 备份 graph.db..."
|
||||
if ! sqlite3 "$DATA_DIR/graph.db" ".backup $BACKUP_DIR/graph.db"; then
|
||||
echo "[$TIMESTAMP] ERROR: graph.db 备份失败"
|
||||
exit 1
|
||||
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
|
||||
# 3. SQLite memoryweave.db 备份
|
||||
echo "[$TIMESTAMP] 备份 memoryweave.db..."
|
||||
if ! sqlite3 "$DATA_DIR/memoryweave.db" ".backup $BACKUP_DIR/memoryweave.db"; then
|
||||
echo "[$TIMESTAMP] ERROR: memoryweave.db 备份失败"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${PROJECT_ROOT}"
|
||||
# 4. Redis 异步保存
|
||||
echo "[$TIMESTAMP] 触发 Redis BGSAVE..."
|
||||
redis-cli BGSAVE 2>/dev/null || true
|
||||
|
||||
# 确保 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 仓库不存在或无法访问,跳过数据推送"
|
||||
}
|
||||
# 5. LanceDB 目录 tar 打包(最多等 300s)
|
||||
echo "[$TIMESTAMP] 打包 LanceDB 数据(可能需要 1-2 分钟)..."
|
||||
if ! timeout 300 tar czf "$BACKUP_DIR/lance-data.tar.gz" \
|
||||
-C "$DATA_DIR" episodes.lance memories.lance tombstones.lance; then
|
||||
echo "[$TIMESTAMP] ERROR: LanceDB 打包超时或失败"
|
||||
exit 1
|
||||
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"
|
||||
# 6. 验证
|
||||
echo "[$TIMESTAMP] 验证备份..."
|
||||
for f in graph.db memoryweave.db lance-data.tar.gz; do
|
||||
if [ ! -s "$BACKUP_DIR/$f" ]; then
|
||||
echo "[$TIMESTAMP] ERROR: $f 为空或不存在"
|
||||
exit 1
|
||||
fi
|
||||
cd "${PROJECT_ROOT}"
|
||||
fi
|
||||
done
|
||||
|
||||
# 推送配置
|
||||
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 ""
|
||||
# 7. 打印结果
|
||||
SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
|
||||
echo "[$TIMESTAMP] 备份成功 | 路径: $BACKUP_DIR | 大小: $SIZE"
|
||||
echo "[$TIMESTAMP] 织忆备份结果: OK | 路径: $BACKUP_DIR | 时间戳: $TIMESTAMP" > "$HOME/projects/memoryweave/backups/backup-$TIMESTAMP.log"
|
||||
Loading…
Reference in New Issue