#!/usr/bin/env bash # Installiert und startet die lokalen TTS/STT-Wrapper-Server (services/tts_server.py, # services/stt_server.py) als systemd-User-Dienste auf GPU 2. # # Frueher liefen die beiden als nohup-Hintergrundprozesse — die ueberleben keinen # Reboot, und ein Podcast scheitert dann in der Vertonungsphase mit # "Failed to generate speech: All connection attempts failed". Als systemd-Units # starten sie automatisch mit (dank enable-linger auch ohne Login). # # Idempotent: mehrfach ausfuehrbar, aktualisiert die Units und startet sie neu. set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" UNIT_SRC="$REPO/services/systemd" UNIT_DST="$HOME/.config/systemd/user" UNITS=(open-notebook-tts.service open-notebook-stt.service) mkdir -p "$UNIT_DST" for unit in "${UNITS[@]}"; do install -m 644 "$UNIT_SRC/$unit" "$UNIT_DST/$unit" done systemctl --user daemon-reload # Ohne Linger laufen User-Dienste nur waehrend einer aktiven Login-Session und # starten nicht beim Boot. if [ "$(loginctl show-user "$USER" --property=Linger --value 2>/dev/null)" != "yes" ]; then echo "Aktiviere linger (Dienste sollen auch ohne Login laufen)..." loginctl enable-linger "$USER" fi echo "Starte TTS/STT-Dienste..." systemctl --user enable --quiet "${UNITS[@]}" systemctl --user restart "${UNITS[@]}" # Modelle werden beim Start geladen (whisper large-v3 braucht ~1 Minute). wait_healthy() { local name="$1" port="$2" for _ in $(seq 1 45); do if curl -sf -m 2 "http://127.0.0.1:${port}/health" >/dev/null 2>&1; then echo " $name (Port $port) ist bereit." return 0 fi sleep 4 done echo "WARNUNG: $name antwortet nach 180s nicht auf /health." >&2 echo " Logs: journalctl --user -u open-notebook-${name} -n 50" >&2 return 1 } rc=0 wait_healthy tts 8901 || rc=1 wait_healthy stt 8902 || rc=1 if [ "$rc" -eq 0 ]; then echo "Fertig. Status: systemctl --user status ${UNITS[*]}" fi exit "$rc"