| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- #!/usr/bin/env bash
- # pack.sh - RK3578 二进制部署打包脚本
- # 用法: bash deploy/pack.sh [输出目录]
- #
- # 前置条件:
- # 在项目根目录执行: pyinstaller HookVision-linux.spec --noconfirm
- #
- # 输出:
- # hookvision_rk3578/ - 可直接传输到 RK3578 的二进制部署目录(不含源码)
- set -euo pipefail
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
- PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
- PACKAGE_NAME="hookvision_rk3578"
- BUILD_DIR="/tmp/${PACKAGE_NAME}"
- echo "=== HookVision RK3578 二进制部署包构建 ==="
- echo "项目根目录: ${PROJECT_ROOT}"
- echo "构建目录: ${BUILD_DIR}"
- # 检查 PyInstaller 产出
- DIST_DIR="${PROJECT_ROOT}/dist/HookVision"
- if [ ! -f "${DIST_DIR}/HookVision" ]; then
- echo "错误: 未找到 PyInstaller 构建产物 ${DIST_DIR}/HookVision"
- echo "请先在项目根目录执行: pyinstaller HookVision-linux.spec --noconfirm"
- exit 1
- fi
- # 清理旧构建
- rm -rf "${BUILD_DIR}"
- mkdir -p "${BUILD_DIR}/hookvision"
- # ---------- 复制二进制 ----------
- echo "[1/5] 复制二进制可执行文件..."
- cp "${DIST_DIR}/HookVision" "${BUILD_DIR}/hookvision/"
- cp -r "${DIST_DIR}/_internal" "${BUILD_DIR}/hookvision/"
- # ---------- 复制配置文件 ----------
- echo "[2/5] 复制配置文件..."
- cp "${PROJECT_ROOT}/config.ini" "${BUILD_DIR}/hookvision/"
- cp "${PROJECT_ROOT}/config.prod.ini" "${BUILD_DIR}/hookvision/"
- cp "${PROJECT_ROOT}/config.dev.ini" "${BUILD_DIR}/hookvision/"
- # ---------- 复制离线依赖 ----------
- echo "[3/5] 复制离线 .deb 依赖..."
- if [ -d "${PROJECT_ROOT}/deploy/hookvision_rk3578/debs" ]; then
- cp -r "${PROJECT_ROOT}/deploy/hookvision_rk3578/debs" "${BUILD_DIR}/"
- fi
- # ---------- 生成 install.sh ----------
- echo "[4/5] 生成 install.sh..."
- cat > "${BUILD_DIR}/install.sh" << 'INSTALL_EOF'
- #!/usr/bin/env bash
- # install.sh - RK3578 二进制部署安装脚本
- # 用法: sudo bash install.sh
- #
- # 说明: 此包为 PyInstaller 编译的二进制版本,无需安装 Python 依赖
- # 系统依赖以离线 .deb 包提供,无需联网
- set -euo pipefail
- INSTALL_DIR="/opt/hookvision"
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
- echo "=== HookVision RK3578 二进制安装 ==="
- # 卸载旧版本
- echo "卸载旧版本..."
- if [ -d "${INSTALL_DIR}" ]; then
- systemctl stop hookvision 2>/dev/null || true
- systemctl disable hookvision 2>/dev/null || true
- rm -rf "${INSTALL_DIR}"
- echo "旧版本已卸载"
- else
- echo "未找到旧版本,跳过"
- fi
- # 安装离线系统依赖
- echo "[1/3] 安装离线系统依赖..."
- if [ -d "${SCRIPT_DIR}/debs" ] && ls "${SCRIPT_DIR}/debs/"*.deb >/dev/null 2>&1; then
- dpkg -i "${SCRIPT_DIR}/debs/"*.deb 2>/dev/null || true
- apt-get install -y -f 2>/dev/null || true
- echo "离线依赖安装完成"
- else
- echo "未找到离线依赖包,跳过"
- fi
- # 备份目标设备上的已有配置文件
- echo "[2/4] 检查已有配置文件..."
- BACKUP_DIR=""
- if [ -d "${INSTALL_DIR}" ]; then
- BACKUP_DIR="/tmp/hookvision_config_backup_$$"
- mkdir -p "${BACKUP_DIR}"
- for f in config.ini config.prod.ini config.dev.ini; do
- if [ -f "${INSTALL_DIR}/hookvision/$f" ]; then
- cp "${INSTALL_DIR}/hookvision/$f" "${BACKUP_DIR}/"
- echo " 备份: $f"
- fi
- done
- fi
- # 创建安装目录
- echo "[3/4] 创建安装目录 ${INSTALL_DIR}..."
- mkdir -p "${INSTALL_DIR}"
- # 复制文件
- echo "[4/4] 复制应用文件..."
- cp -r "${SCRIPT_DIR}/hookvision" "${INSTALL_DIR}/"
- cp -r "${SCRIPT_DIR}/start.sh" "${INSTALL_DIR}/"
- chmod +x "${INSTALL_DIR}/hookvision/HookVision"
- # 恢复目标设备上的配置文件
- if [ -n "${BACKUP_DIR}" ] && [ -d "${BACKUP_DIR}" ]; then
- echo "恢复已有配置文件..."
- for f in config.ini config.prod.ini config.dev.ini; do
- if [ -f "${BACKUP_DIR}/$f" ]; then
- cp "${BACKUP_DIR}/$f" "${INSTALL_DIR}/hookvision/"
- echo " 恢复: $f"
- fi
- done
- rm -rf "${BACKUP_DIR}"
- fi
- # 安装 systemd 服务
- echo "安装 systemd 服务..."
- cat > /etc/systemd/system/hookvision.service << 'SERVICE_EOF'
- [Unit]
- Description=HookVision - 钢包工位视频监测系统
- After=network-online.target graphical.target
- Wants=network-online.target
- Requires=display-manager.service
- [Service]
- Type=simple
- ExecStart=/opt/hookvision/start.sh
- WorkingDirectory=/opt/hookvision
- Restart=on-failure
- RestartSec=5
- Environment=DISPLAY=:0
- Environment=QT_QPA_PLATFORM=xcb
- [Install]
- WantedBy=graphical.target
- SERVICE_EOF
- systemctl daemon-reload
- systemctl enable hookvision
- echo "systemd 服务已安装并设置开机自启"
- # 设置屏幕永不熄屏
- echo "设置屏幕永不熄屏..."
- if [ -d /etc/xdg/autostart ]; then
- cat > /etc/xdg/autostart/screensaver-disable.desktop << 'DESKTOP_EOF'
- [Desktop Entry]
- Type=Application
- Name=Disable Screensaver
- Exec=bash -c 'xset s off && xset -dpms && xset s noblank'
- Hidden=false
- NoDisplay=true
- X-GNOME-Autostart-enabled=true
- DESKTOP_EOF
- fi
- if command -v xset &>/dev/null; then
- xset s off 2>/dev/null || true
- xset -dpms 2>/dev/null || true
- xset s noblank 2>/dev/null || true
- fi
- # 禁用 lightdm 屏幕保护(如使用 lightdm)
- if [ -f /etc/lightdm/lightdm.conf ]; then
- sed -i 's/^greeter-setup-script=.*/greeter-setup-script=xset s off \&\& xset -dpms \&\& xset s noblank/' /etc/lightdm/lightdm.conf 2>/dev/null || true
- fi
- echo "屏幕永不熄屏已设置"
- # 创建软链接
- ln -sf "${INSTALL_DIR}/install.sh" /usr/local/bin/hv-install 2>/dev/null || true
- echo ""
- echo "=== 安装完成 ==="
- echo "启动服务: systemctl start hookvision"
- echo "查看状态: systemctl status hookvision"
- INSTALL_EOF
- chmod +x "${BUILD_DIR}/install.sh"
- # ---------- 生成 start.sh ----------
- echo "[5/5] 生成 start.sh..."
- cat > "${BUILD_DIR}/start.sh" << 'START_EOF'
- #!/usr/bin/env bash
- # start.sh - HookVision 二进制启动脚本
- # 用法: bash start.sh [--prod|--dev]
- set -uo pipefail
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
- # 默认使用生产配置
- MODE_FLAG="--prod"
- case "${1:-}" in
- --dev)
- MODE_FLAG="--dev"
- ;;
- --prod)
- MODE_FLAG="--prod"
- ;;
- *)
- if [ -f "${SCRIPT_DIR}/config.prod.ini" ]; then
- MODE_FLAG="--prod"
- elif [ -f "${SCRIPT_DIR}/config.dev.ini" ]; then
- MODE_FLAG="--dev"
- fi
- ;;
- esac
- cd "${SCRIPT_DIR}"
- # 捕获信号,优雅退出
- cleanup() {
- echo "收到退出信号,正在停止 HookVision..."
- kill "$PID" 2>/dev/null
- wait "$PID" 2>/dev/null
- echo "已退出"
- exit 0
- }
- trap cleanup SIGINT SIGTERM SIGHUP
- echo "启动 HookVision (${MODE_FLAG})..."
- ./hookvision/HookVision ${MODE_FLAG} &
- PID=$!
- wait "$PID"
- START_EOF
- chmod +x "${BUILD_DIR}/start.sh"
- # ---------- 拷贝到输出目录 ----------
- OUTPUT_DIR="${1:-$(dirname "${PROJECT_ROOT}")}"
- OUTPUT_PATH="${OUTPUT_DIR}/${PACKAGE_NAME}"
- rm -rf "${OUTPUT_PATH}"
- cp -r "${BUILD_DIR}" "${OUTPUT_PATH}"
- # 清理构建目录
- rm -rf "${BUILD_DIR}"
- echo ""
- echo "=== 构建完成 ==="
- echo "部署目录: ${OUTPUT_PATH}"
- echo "大小: $(du -sh "${OUTPUT_PATH}" | cut -f1)"
- echo ""
- echo "部署到 RK3578:"
- echo " scp -r ${OUTPUT_PATH} root@<RK3578_IP>:/tmp/"
- echo " ssh root@<RK3578_IP>"
- echo " cd /tmp/hookvision_rk3578 && sudo bash install.sh"
- echo " bash /opt/hookvision/start.sh"
|