Ctrl K
ComunidadGuías…

update.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash
# ==============================================================================
# 织网 (WebWeaver) - 源码部署服务器一键 / 自动更新脚本
# 支持手动更新与 Crontab 定时无人值守自动更新
# ==============================================================================

set -e

GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# 1. 检查 root 权限
if [ "$(id -u)" -ne 0 ]; then
    echo -e "${RED}[错误] 请使用 root 用户或 sudo 执行此脚本:${NC}"
    echo -e "例如: sudo bash $0"
    exit 1
fi

# 2. 定位部署目录
INSTALL_DIR="/opt/webweaver"
CURRENT_DIR=$(cd "$(dirname "$0")" && pwd)

if [ -d "$CURRENT_DIR/backend" ] && [ -d "$CURRENT_DIR/.git" ]; then
    TARGET_DIR="$CURRENT_DIR"
elif [ -d "$INSTALL_DIR/.git" ]; then
    TARGET_DIR="$INSTALL_DIR"
else
    echo -e "${RED}[错误] 未找到 WebWeaver 源码部署目录 ($INSTALL_DIR 或当前目录)。${NC}"
    exit 1
fi

# 3. 处理 Crontab 定时自动更新安装 / 卸载参数
if [ "$1" = "--cron" ]; then
    CRON_CMD="0 3 * * * /bin/bash $TARGET_DIR/update.sh > /var/log/webweaver-autoupdate.log 2>&1"
    (crontab -l 2>/dev/null | grep -v "$TARGET_DIR/update.sh" ; echo "$CRON_CMD") | crontab -
    echo -e "${GREEN}✓ 已成功设置 Crontab 定时任务!每天凌晨 03:00 将自动拉取 Git 最新代码并热更新。${NC}"
    echo -e "日志文件: /var/log/webweaver-autoupdate.log"
    exit 0
elif [ "$1" = "--remove-cron" ]; then
    crontab -l 2>/dev/null | grep -v "$TARGET_DIR/update.sh" | crontab -
    echo -e "${GREEN}✓ 已移除 Crontab 定时自动更新任务。${NC}"
    exit 0
fi

echo -e "${BLUE}======================================================${NC}"
echo -e "${GREEN}         织网 (WebWeaver) 服务更新程序                ${NC}"
echo -e "${BLUE}======================================================${NC}"
echo -e "目标目录: ${YELLOW}$TARGET_DIR${NC}"

cd "$TARGET_DIR"

# 4. 自动备份当前数据库与配置(安全双保险)
echo -e "\n${YELLOW}[1/5] 执行数据安全快照备份...${NC}"
BACKUP_DIR="$TARGET_DIR/data/backups"
mkdir -p "$BACKUP_DIR"

# 优先从 .env 读取实际数据库路径,缺省使用 $TARGET_DIR/data/weaver.db
DB_FILE="$TARGET_DIR/data/weaver.db"
if [ -f "$TARGET_DIR/backend/.env" ]; then
    CUSTOM_DB=$(grep -E "^WEAVER_DB_URL=" "$TARGET_DIR/backend/.env" | cut -d'=' -f2 | sed 's|sqlite:///||')
    if [ -n "$CUSTOM_DB" ] && [ -f "$CUSTOM_DB" ]; then
        DB_FILE="$CUSTOM_DB"
    fi
fi

if [ -f "$DB_FILE" ]; then
    BACKUP_NAME="weaver.db.pre_update_$(date +%Y%m%d_%H%M%S)"
    cp "$DB_FILE" "$BACKUP_DIR/$BACKUP_NAME"
    echo -e "${GREEN}✓ 已自动备份数据库至: $BACKUP_DIR/$BACKUP_NAME${NC}"
    # 仅保留最近 15 份预更新备份,防止占满磁盘
    ls -t "$BACKUP_DIR"/weaver.db.pre_update_* 2>/dev/null | tail -n +16 | xargs rm -f 2>/dev/null || true
else
    echo -e "${YELLOW}未发现已有数据库文件 ($DB_FILE),跳过备份。${NC}"
fi

# 5. 拉取 Git 最新代码
echo -e "\n${YELLOW}[2/5] 从 GitHub 远程仓库拉取最新代码...${NC}"
git fetch --all
BEFORE_COMMIT=$(git rev-parse HEAD)
git reset --hard origin/main
AFTER_COMMIT=$(git rev-parse HEAD)

if [ "$BEFORE_COMMIT" = "$AFTER_COMMIT" ]; then
    echo -e "${GREEN}当前已是最新代码 ($AFTER_COMMIT)。${NC}"
else
    echo -e "${GREEN}代码更新成功: ${BEFORE_COMMIT:0:7} -> ${AFTER_COMMIT:0:7}${NC}"
fi

# 6. 更新后端 Python 依赖
echo -e "\n${YELLOW}[3/5] 检查并更新后端 Python 依赖...${NC}"
if [ -d "$TARGET_DIR/backend/.venv" ]; then
    "$TARGET_DIR/backend/.venv/bin/pip" install --upgrade pip -q
    "$TARGET_DIR/backend/.venv/bin/pip" install -r "$TARGET_DIR/backend/requirements.txt" -q
    # 确保 ping 权限 (setcap)
    PYTHON_BIN=$(readlink -f "$TARGET_DIR/backend/.venv/bin/python3" || true)
    if [ -n "$PYTHON_BIN" ]; then
        setcap cap_net_raw+ep "$PYTHON_BIN" 2>/dev/null || true
    fi
else
    echo -e "${YELLOW}未检测到 backend/.venv,跳过 pip 依赖检查。${NC}"
fi

# 7. 编译 / 更新前端静态资源
echo -e "\n${YELLOW}[4/5] 检查前端资源...${NC}"
if command -v npm >/dev/null 2>&1 && [ -d "$TARGET_DIR/frontend" ]; then
    echo -e "${BLUE}检测到 Node/npm 环境,正在构建前端 dist...${NC}"
    cd "$TARGET_DIR/frontend"
    npm install --no-audit --prefer-offline -q
    npm run build -q
    cd "$TARGET_DIR"
else
    echo -e "${YELLOW}未安装 Node/npm,跳过前端现场编译,保留现有静态页面。${NC}"
fi

# 8. 重启 systemd 服务
echo -e "\n${YELLOW}[5/5] 平滑重启 WebWeaver 服务...${NC}"
if systemctl list-unit-files | grep -q "webweaver.service"; then
    systemctl daemon-reload
    systemctl restart webweaver
    sleep 2
    if systemctl is-active --quiet webweaver; then
        echo -e "${GREEN}✓ WebWeaver 服务重启成功,当前正在平稳运行!${NC}"
    else
        echo -e "${RED}⚠️ 服务重启后状态异常,请查看日志:journalctl -u webweaver -n 30 --no-pager${NC}"
    fi
else
    echo -e "${YELLOW}未检测到 systemd 服务 webweaver,请手动重启你的主进程。${NC}"
fi

echo -e "\n${BLUE}======================================================${NC}"
echo -e "${GREEN}🎉 更新流程全部完成!${NC}"
echo -e "${BLUE}======================================================${NC}"