#!/bin/bash # 管理端离线部署包构建脚本 # 交叉编译 safesightd,打包配置、种子数据、工具和部署脚本 set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" EDGE_DIR="$(cd "$PROJECT_DIR/../safesight-edge" 2>/dev/null && pwd || echo '')" PACKAGE_NAME="safesight-control-$(date +%Y%m%d-%H%M%S)" BUILD_DIR="/tmp/$PACKAGE_NAME" echo "========== 构建管理端离线部署包 ==========" echo "项目目录: $PROJECT_DIR" [ -n "$EDGE_DIR" ] && echo "Edge 目录: $EDGE_DIR" echo "" # ── 编译 ── echo "[1/7] 交叉编译..." cd "$PROJECT_DIR" mkdir -p "$BUILD_DIR" CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o "$BUILD_DIR/safesightd-linux-arm64" ./cmd/safesightd/ 2>/dev/null && echo " ✓ ARM64" || echo " ✗ ARM64 failed" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o "$BUILD_DIR/safesightd-linux-amd64" ./cmd/safesightd/ 2>/dev/null && echo " ✓ AMD64" || echo " ✗ AMD64 failed" # ── 部署文件 ── echo "[2/7] 部署文件..." mkdir -p "$BUILD_DIR/scripts" cp scripts/deploy/safesightd.service "$BUILD_DIR/" cp scripts/deploy/install.sh "$BUILD_DIR/" cp scripts/deploy/safesightd "$BUILD_DIR/" 2>/dev/null || true cp scripts/deploy/import-assets.py "$BUILD_DIR/scripts/" 2>/dev/null || true cp scripts/deploy/register-face-gallery.py "$BUILD_DIR/scripts/" 2>/dev/null || true cp safesightd.json.example "$BUILD_DIR/safesightd.json.example" 2>/dev/null || true echo " ✓ 部署脚本已复制" # ── 种子配置数据 ── echo "[3/7] 种子配置数据..." SEED_SRC="" if [ -n "$EDGE_DIR" ] && [ -d "$EDGE_DIR/configs" ]; then SEED_SRC="$EDGE_DIR/configs" elif [ -d "$PROJECT_DIR/seed-configs" ]; then SEED_SRC="$PROJECT_DIR/seed-configs" fi if [ -n "$SEED_SRC" ]; then mkdir -p "$BUILD_DIR/configs" cp -r "$SEED_SRC/templates" "$BUILD_DIR/configs/" 2>/dev/null || true cp -r "$SEED_SRC/profiles" "$BUILD_DIR/configs/" 2>/dev/null || true cp -r "$SEED_SRC/overlays" "$BUILD_DIR/configs/" 2>/dev/null || true echo " ✓ 种子数据 ($SEED_SRC)" else echo " ⚠ 找不到 configs 目录,跳过" fi # ── 人脸库构建工具 ── echo "[4/7] 人脸库构建工具..." if [ -d "$PROJECT_DIR/tools" ]; then mkdir -p "$BUILD_DIR/tools" cp -r "$PROJECT_DIR/tools/gallery_builder" "$BUILD_DIR/tools/" 2>/dev/null || true cp "$PROJECT_DIR/tools/build_gallery.py" "$BUILD_DIR/tools/" 2>/dev/null || true mkdir -p "$BUILD_DIR/tools/models" cp "$PROJECT_DIR/tools/models"/*.onnx "$BUILD_DIR/tools/models/" 2>/dev/null || true cp "$PROJECT_DIR/tools/models"/*.json "$BUILD_DIR/tools/models/" 2>/dev/null || true echo " ✓ 构建工具已复制" else echo " ⚠ 找不到 tools 目录,跳过" fi # ── 标准模型 ── echo "[5/7] 标准模型..." if [ -d "$PROJECT_DIR/models/standard_models" ]; then mkdir -p "$BUILD_DIR/models/standard_models" cp "$PROJECT_DIR/models/standard_models"/*.rknn "$BUILD_DIR/models/standard_models/" 2>/dev/null || true echo " ✓ 标准模型已复制" else echo " ⚠ 找不到 models/standard_models,跳过" fi # ── 离线 Python 依赖 ── echo "[6/7] 离线 Python 依赖..." mkdir -p "$BUILD_DIR/deps" if [ -d "$PROJECT_DIR/deps" ] && ls "$PROJECT_DIR/deps"/*.whl >/dev/null 2>&1; then cp "$PROJECT_DIR/deps"/*.whl "$BUILD_DIR/deps/" 2>/dev/null echo " ✓ $(ls "$BUILD_DIR/deps/" | wc -l) 个 wheel" else echo " ⚠ deps/ 目录为空,请先在 ARM64 设备上运行: pip3 download onnxruntime numpy -d /tmp/deps" echo " 然后复制到项目的 deps/ 目录" fi # ── README ── echo "[7/7] 生成 README..." cat > "$BUILD_DIR/README.txt" << 'EOF' SafeSight Control 离线部署包 ============================= 一键安装: sudo bash install.sh 打开 http://:18080 --- 首次启动自动导入模板/场景/覆盖层,无需手动操作。 人脸库构建(离线环境): sudo pip3 install deps/*.whl # 安装 Python 依赖 curl -X POST http://localhost:18080/face-gallery/build # 触发构建 EOF # ── 打包 ── cd /tmp tar -czf "$PROJECT_DIR/$PACKAGE_NAME.tar.gz" "$PACKAGE_NAME" rm -rf "$BUILD_DIR" echo "" echo "========== 打包完成 ==========" echo "$PROJECT_DIR/$PACKAGE_NAME.tar.gz" ls -lh "$PROJECT_DIR/$PACKAGE_NAME.tar.gz"