#!/bin/bash # package-deb.sh — Empaqueta gr-locutor (Locutor IA - GRP) como .deb instalable # Uso: ./package-deb.sh # # El .deb NO requiere cargo/rust en destino: incluye el binario ya compilado # (target/release/gr-locutor-config). Sirve para Debian 12 y 13 amd64 por # igual (glibc retrocompatible — ver notas en el README/CLAUDE.md). # # El .deb NO instala el motor de voz (PyTorch/XTTS-v2, varios GB, requiere # detectar GPU en destino) — eso lo hace `gr-locutor-instalar-motor` como # paso separado, después de instalar el .deb. El .deb solo deja el binario, # los scripts/contexto/voz genérica, y el lanzador de escritorio. set -e VERSION="${1:?Uso: $0 ej: $0 0.1.0}" ARCH="$(dpkg --print-architecture)" PKG_NAME="gr-locutor" PKG_DIR="${PKG_NAME}_${VERSION}_${ARCH}" ROOT="$(cd "$(dirname "$0")" && pwd)" BIN="$ROOT/target/release/gr-locutor-config" if [ ! -f "$BIN" ]; then echo "[!] Binario faltante: target/release/gr-locutor-config" echo " Ejecuta primero: cargo build --release" exit 1 fi echo "========================================" echo " Empaquetando $PKG_NAME $VERSION ($ARCH)" echo "========================================" # ── Limpiar directorio anterior ─────────────────────────────────────────────── rm -rf "$PKG_DIR" # ── Estructura de directorios ───────────────────────────────────────────────── mkdir -p "$PKG_DIR/DEBIAN" mkdir -p "$PKG_DIR/usr/local/bin" mkdir -p "$PKG_DIR/usr/local/share/gr-locutor/locutor-ia" mkdir -p "$PKG_DIR/usr/share/applications" # ── Binario principal (ya compilado — no hace falta cargo en destino) ──────── echo "[*] Copiando binario gr-locutor-config..." cp "$BIN" "$PKG_DIR/usr/local/bin/gr-locutor-config" chmod 755 "$PKG_DIR/usr/local/bin/gr-locutor-config" # ── Instalador del motor de voz (paso manual post-instalación) ─────────────── echo "[*] Copiando instalador del motor de voz..." cp "$ROOT/instalar-locutor-amd64.sh" "$PKG_DIR/usr/local/bin/gr-locutor-instalar-motor" chmod 755 "$PKG_DIR/usr/local/bin/gr-locutor-instalar-motor" # ── Assets estáticos (scripts, contexto para opencode, voz genérica) ──────── echo "[*] Copiando scripts/contexto/voz genérica..." ASSETS_SRC="$ROOT/assets/locutor-ia" cp -r "$ASSETS_SRC/"* "$PKG_DIR/usr/local/share/gr-locutor/locutor-ia/" find "$PKG_DIR/usr/local/share/gr-locutor/locutor-ia" -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true find "$PKG_DIR/usr/local/share/gr-locutor/locutor-ia" \( -name "*.sh" -o -name "*.py" \) -exec chmod 755 {} + # ── Lanzador de escritorio ──────────────────────────────────────────────────── cat > "$PKG_DIR/usr/share/applications/gr-locutor-config.desktop" << DESKTOP [Desktop Entry] Type=Application Name=Locutor IA - GRP Comment=Configuración del Locutor Automático IA de G Radio Player Exec=/usr/local/bin/gr-locutor-config Terminal=false Categories=AudioVideo; DESKTOP # ── DEBIAN/control ──────────────────────────────────────────────────────────── echo "[*] Generando DEBIAN/control..." INSTALLED_SIZE=$(du -sk "$PKG_DIR/usr" | cut -f1) cat > "$PKG_DIR/DEBIAN/control" << CONTROL Package: gr-locutor Version: ${VERSION} Architecture: ${ARCH} Maintainer: G Radio Installed-Size: ${INSTALLED_SIZE} Depends: libgtk-4-1 (>= 4.6), libc6 (>= 2.17), python3, python3-venv, ffmpeg, gradio-player (>= 0.4.11) Recommends: pulseaudio-utils | pipewire-pulse Section: sound Priority: optional Description: Locutor IA - GRP — locuciones de radio con voz IA local Interfaz de configuración del Locutor Automático IA de G Radio Player: genera locuciones (presentación de temas, datos curiosos, identificación de la radio) con síntesis de voz local (XTTS-v2), sin depender de APIs de voz en la nube. . Este paquete instala la interfaz gráfica y los scripts/contexto; el motor de voz (PyTorch + XTTS-v2, con o sin GPU) se instala aparte corriendo 'gr-locutor-instalar-motor' una vez, ya que requiere detectar el hardware del equipo de destino y descargar varios GB. CONTROL # ── DEBIAN/postinst ─────────────────────────────────────────────────────────── cat > "$PKG_DIR/DEBIAN/postinst" << 'POSTINST' #!/bin/bash set -e if command -v update-desktop-database &>/dev/null; then update-desktop-database /usr/share/applications 2>/dev/null || true fi echo "" echo "Locutor IA - GRP instalado correctamente." echo "Buscar 'Locutor IA - GRP' en el menú, o ejecutar: gr-locutor-config" echo "" echo "Antes de generar locuciones hace falta instalar el motor de voz" echo "(una sola vez, detecta GPU/CPU automáticamente):" echo " gr-locutor-instalar-motor" POSTINST chmod 755 "$PKG_DIR/DEBIAN/postinst" # ── DEBIAN/prerm ────────────────────────────────────────────────────────────── # No matamos procesos acá. Lección de radio-player (ver REPARAR-DPKG.md): # un prerm con pkill puede matarse a sí mismo y a dpkg si el patrón de # nombre matchea la línea de comando de dpkg/el propio script. Linux # mantiene el binario anterior abierto mientras el proceso corra, así que # reemplazar el archivo en disco durante un upgrade es seguro sin matar nada. cat > "$PKG_DIR/DEBIAN/prerm" << 'PRERM' #!/bin/bash exit 0 PRERM chmod 755 "$PKG_DIR/DEBIAN/prerm" # ── DEBIAN/postrm ───────────────────────────────────────────────────────────── # Solo borrar en remove/purge — nunca en upgrade/failed-upgrade (dpkg ya # instaló los archivos nuevos antes de correr el postrm del paquete viejo). cat > "$PKG_DIR/DEBIAN/postrm" << 'POSTRM' #!/bin/bash case "$1" in remove|purge) rm -f /usr/local/bin/gr-locutor-config rm -f /usr/local/bin/gr-locutor-instalar-motor rm -rf /usr/local/share/gr-locutor rm -f /usr/share/applications/gr-locutor-config.desktop command -v update-desktop-database &>/dev/null && \ update-desktop-database /usr/share/applications 2>/dev/null || true ;; esac POSTRM chmod 755 "$PKG_DIR/DEBIAN/postrm" # ── Construir el .deb ───────────────────────────────────────────────────────── echo "[*] Construyendo paquete .deb..." dpkg-deb --build --root-owner-group "$PKG_DIR" DEB_FILE="${PKG_DIR}.deb" SIZE=$(du -sh "$DEB_FILE" | cut -f1) echo "" echo "========================================" echo " Paquete listo: $DEB_FILE ($SIZE)" echo "========================================" echo "" echo " Instalar: sudo dpkg -i $DEB_FILE" echo " Después: gr-locutor-instalar-motor (instala el motor de voz)" echo " Desinstalar: sudo apt remove gr-locutor"