Files
PiDoBot/setup.sh
2026-04-12 22:41:24 +00:00

275 lines
10 KiB
Bash
Executable File

#!/bin/bash
# ==========================================
# Farbdefinitionen
# ==========================================
C_DEF=$'\e[0m' # Default / Reset
C_BOLD=$'\e[1m' # Fett
C_CYAN=$'\e[1;36m' # Cyan
C_BLUE=$'\e[1;34m' # Blau
C_GREEN=$'\e[1;32m' # Grün
C_YELLOW=$'\e[1;33m' # Gelb
C_RED=$'\e[1;31m' # Rot
REPO_URL="https://git.pi-farm.de/pi-farm/PiDoBot.git"
SERVICE_FILE="/etc/systemd/system/jarvis.service"
echo -e "${C_CYAN}${C_BOLD}==========================================${C_DEF}"
echo -e "${C_CYAN}${C_BOLD}>>> J.A.R.V.I.S.-AI - Setup <<<${C_DEF}"
echo -e "${C_CYAN}${C_BOLD}==========================================${C_DEF}"
# 0. Installationsverzeichnis abfragen
read -p "${C_CYAN}Installationsverzeichnis (Standard: ${C_YELLOW}/home/pi/jarvis-ai${C_CYAN}): ${C_DEF}" input_dir </dev/tty
INSTALL_DIR=${input_dir:-/home/pi/jarvis-ai}
# Pfad normalisieren
INSTALL_DIR=$(realpath -m "$INSTALL_DIR")
<<<<<<< HEAD
# 3. Repository klonen
if [ ! -d "$INSTALL_DIR" ]; then
echo "--- Klone Repository von $REPO_URL..."
git clone --branch main --single-branch "$REPO_URL" "$INSTALL_DIR"
else
echo "--- Verzeichnis $INSTALL_DIR existiert bereits. Überspringe Klonen..."
fi
# In das Verzeichnis wechseln
=======
echo -e "\n${C_GREEN}Zielverzeichnis: ${C_BOLD}$INSTALL_DIR${C_DEF}"
mkdir -p "$INSTALL_DIR"
>>>>>>> dev
cd "$INSTALL_DIR" || exit
# 1. System-Abhängigkeiten
echo -e "\n${C_BLUE}${C_BOLD}--- 1. Prüfe und installiere System-Pakete...${C_DEF}"
sudo apt-get update
sudo apt-get install -y git wget sshpass python3-pip python3-venv iproute2
# 2. Repository klonen
echo -e "\n${C_BLUE}${C_BOLD}--- 2. Hole Quellcode...${C_DEF}"
if [ ! -d ".git" ]; then
git clone --branch dev --single-branch "$REPO_URL" .
else
echo -e "${C_YELLOW}Repo bereits vorhanden, aktualisiere...${C_DEF}"
git pull
fi
# 3. Virtual Environment
echo -e "\n${C_BLUE}${C_BOLD}--- 3. Richte Python-Umgebung ein...${C_DEF}"
if [ ! -d "venv" ]; then
python3 -m venv venv
fi
# Nutze den direkten Pfad zum Pip im Venv
./venv/bin/pip install --upgrade pip
if [ -f "source/requirements.txt" ]; then
./venv/bin/pip install -r source/requirements.txt
else
echo -e "${C_RED}❌ FEHLER: requirements.txt nicht gefunden!${C_DEF}"
exit 1
fi
# 4. SSH-Key & Konfiguration (Silent Mode)
echo -e "\n${C_BLUE}${C_BOLD}--- 4. Prüfe SSH-Schlüssel und Konfiguration...${C_DEF}"
if [ ! -f "$HOME/.ssh/id_rsa" ]; then
ssh-keygen -t rsa -N "" -f "$HOME/.ssh/id_rsa"
echo -e "${C_GREEN}✅ SSH-Key generiert.${C_DEF}"
else
echo -e "${C_GREEN}✅ SSH-Key existiert bereits.${C_DEF}"
fi
# SSH 'Silent Mode' einrichten, um Spam im Log zu verhindern
mkdir -p "$HOME/.ssh"
if [ ! -f "$HOME/.ssh/config" ] || ! grep -q "StrictHostKeyChecking no" "$HOME/.ssh/config"; then
echo -e "${C_YELLOW}Richte SSH Silent-Mode für lokale Netze ein...${C_DEF}"
cat <<EOF >> "$HOME/.ssh/config"
Host 192.168.* 10.* 172.*
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
EOF
chmod 600 "$HOME/.ssh/config"
fi
# 5. Static Dateien
echo -e "\n${C_BLUE}${C_BOLD}--- 5. Lade Frontend-Bibliotheken...${C_DEF}"
mkdir -p source/static
cd source/static
wget -nc -q https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack.min.css
wget -nc -q https://cdn.jsdelivr.net/npm/gridstack@7.2.3/dist/gridstack-all.js
wget -nc -q https://cdn.jsdelivr.net/npm/xterm@5.1.0/css/xterm.css
wget -nc -q https://cdn.jsdelivr.net/npm/xterm@5.1.0/lib/xterm.js
wget -nc -q https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.7.0/lib/xterm-addon-fit.js
wget -nc -q https://cdn.jsdelivr.net/npm/marked/marked.min.js
cd "$INSTALL_DIR"
# 6. .env Setup
echo -e "\n${C_BLUE}${C_BOLD}--- 6. Konfiguration (.env)...${C_DEF}"
mkdir -p config
ENV_FILE="config/.env"
# Standardwerte definieren
web_user="Tony"
ai_prov="google"
google_key=""
openai_key=""
nvidia_key=""
ollama_url="http://127.0.0.1:11434/v1"
google_mod="gemini-2.5-flash"
openai_mod="gpt-4o"
tg_token=""
tg_id=""
# Falls die Datei existiert, alte Werte laden
if [ -f "$ENV_FILE" ]; then
echo -e "${C_YELLOW}Bestehende .env gefunden. Lade aktuelle Werte...${C_DEF}"
set -a
source "$ENV_FILE"
set +a
web_user="${WEB_USER_NAME:-$web_user}"
ai_prov="${AI_PROVIDER:-$ai_prov}"
google_key="${GOOGLE_API_KEY:-$google_key}"
openai_key="${OPENAI_API_KEY:-$openai_key}"
nvidia_key="${NVIDIA_API_KEY:-$nvidia_key}"
ollama_url="${OLLAMA_BASE_URL:-$ollama_url}"
google_mod="${GOOGLE_MODEL:-$google_mod}"
openai_mod="${OPENAI_MODEL:-$openai_mod}"
tg_token="${TELEGRAM_BOT_TOKEN:-$tg_token}"
tg_id="${ALLOWED_TELEGRAM_USER_ID:-$tg_id}"
fi
echo -e "\nBitte gib die neuen Werte ein. (Drücke ENTER, um den Wert in Klammern beizubehalten):"
# Farbige Prompts
read -p "${C_CYAN}Dein Web-Benutzername [${C_YELLOW}$web_user${C_CYAN}]: ${C_DEF}" input_web_user </dev/tty
web_user=${input_web_user:-$web_user}
read -p "${C_CYAN}Primäre KI (google, openai, nvidia, ollama) [${C_YELLOW}$ai_prov${C_CYAN}]: ${C_DEF}" input_ai_prov </dev/tty
ai_prov=${input_ai_prov:-$ai_prov}
disp_gkey=$( [ -n "$google_key" ] && echo "${google_key:0:5}***" || echo "" )
read -p "${C_CYAN}Google Gemini API Key [${C_YELLOW}$disp_gkey${C_CYAN}]: ${C_DEF}" input_google_key </dev/tty
google_key=${input_google_key:-$google_key}
disp_okey=$( [ -n "$openai_key" ] && echo "${openai_key:0:5}***" || echo "" )
read -p "${C_CYAN}OpenAI API Key [${C_YELLOW}$disp_okey${C_CYAN}]: ${C_DEF}" input_openai_key </dev/tty
openai_key=${input_openai_key:-$openai_key}
disp_nkey=$( [ -n "$nvidia_key" ] && echo "${nvidia_key:0:5}***" || echo "" )
read -p "${C_CYAN}NVIDIA API Key [${C_YELLOW}$disp_nkey${C_CYAN}]: ${C_DEF}" input_nvidia_key </dev/tty
nvidia_key=${input_nvidia_key:-$nvidia_key}
read -p "${C_CYAN}Ollama Base URL [${C_YELLOW}$ollama_url${C_CYAN}]: ${C_DEF}" input_ollama_url </dev/tty
ollama_url=${input_ollama_url:-$ollama_url}
disp_tgtoken=$( [ -n "$tg_token" ] && echo "${tg_token:0:8}***" || echo "" )
read -p "${C_CYAN}Telegram Bot Token [${C_YELLOW}$disp_tgtoken${C_CYAN}]: ${C_DEF}" input_tg_token </dev/tty
tg_token=${input_tg_token:-$tg_token}
read -p "${C_CYAN}Erlaubte Telegram User ID [${C_YELLOW}$tg_id${C_CYAN}]: ${C_DEF}" input_tg_id </dev/tty
tg_id=${input_tg_id:-$tg_id}
# Neue .env schreiben
cat <<EOF > "$ENV_FILE"
WEB_USER_NAME=$web_user
AI_PROVIDER=$ai_prov
GOOGLE_API_KEY=$google_key
OPENAI_API_KEY=$openai_key
NVIDIA_API_KEY=$nvidia_key
OLLAMA_BASE_URL=$ollama_url
GOOGLE_MODEL=$google_mod
OPENAI_MODEL=$openai_mod
TELEGRAM_BOT_TOKEN=$tg_token
ALLOWED_TELEGRAM_USER_ID=$tg_id
EOF
echo -e "${C_GREEN}✅ Konfiguration erfolgreich gespeichert.${C_DEF}"
# ==========================================
# Weiche: Update vs. Neuinstallation
# ==========================================
if [ -f "$SERVICE_FILE" ]; then
echo -e "\n${C_BLUE}${C_BOLD}--- 7. Update-Modus: Bestehender Dienst gefunden...${C_DEF}"
echo -e "${C_YELLOW}Überspringe Port- und Firewall-Check, starte Dienst neu...${C_DEF}"
sudo systemctl daemon-reload
sudo systemctl restart jarvis.service
echo -e "\n${C_GREEN}${C_BOLD}==========================================${C_DEF}"
echo -e "${C_GREEN}✅ Update komplett! J.A.R.V.I.S. wurde erfolgreich aktualisiert und neu gestartet.${C_DEF}"
echo -e "Verzeichnis: ${C_BOLD}$INSTALL_DIR${C_DEF}"
echo -e "Web-Interface: ${C_CYAN}http://<deine-ip>:8000${C_DEF}"
echo -e "Log-Ausgabe: ${C_YELLOW}sudo journalctl -u jarvis -f${C_DEF}"
echo -e "${C_GREEN}${C_BOLD}==========================================${C_DEF}"
else
# 7. Port Check
echo -e "\n${C_BLUE}${C_BOLD}--- 7. Prüfe Port 8000...${C_DEF}"
if ss -tuln | grep -q ":8000 "; then
echo -e "${C_RED}⚠️ WARNUNG: Port 8000 wird bereits von einem anderen Prozess verwendet!${C_DEF}"
echo "J.A.R.V.I.S. wird möglicherweise nicht starten können. Bitte prüfe dies nach dem Setup."
read -p "Drücke ENTER, um trotzdem fortzufahren..." </dev/tty
else
echo -e "${C_GREEN}✅ Port 8000 ist frei.${C_DEF}"
fi
# 8. Firewall Check
echo -e "\n${C_BLUE}${C_BOLD}--- 8. Prüfe Firewall-Einstellungen...${C_DEF}"
if command -v ufw >/dev/null 2>&1; then
if sudo ufw status | grep -qw "active"; then
echo -e "${C_YELLOW}UFW Firewall ist aktiv. Öffne Port 8000...${C_DEF}"
sudo ufw allow 8000/tcp
echo -e "${C_GREEN}✅ Port 8000 (TCP) in UFW freigegeben.${C_DEF}"
else
echo -e "${C_GREEN}✅ UFW ist installiert, aber inaktiv. Keine Blockade zu erwarten.${C_DEF}"
fi
else
echo -e "${C_GREEN}✅ Keine UFW Firewall gefunden. Überspringe Firewall-Setup.${C_DEF}"
fi
# 9. Systemd Service einrichten
echo -e "\n${C_BLUE}${C_BOLD}--- 9. Systemdienst (Autostart) einrichten...${C_DEF}"
read -p "${C_CYAN}Möchtest du J.A.R.V.I.S. als Hintergrunddienst installieren? (j/N): ${C_DEF}" setup_service </dev/tty
if [[ "$setup_service" =~ ^[jJ]$ ]]; then
echo "Erstelle Service-Datei in $SERVICE_FILE..."
sudo bash -c "cat <<EOF > $SERVICE_FILE
[Unit]
Description=J.A.R.V.I.S. AI Web und Telegram Bot
After=network.target
[Service]
User=$USER
WorkingDirectory=$INSTALL_DIR
Environment=\"PYTHONPATH=$INSTALL_DIR/source\"
ExecStart=$INSTALL_DIR/venv/bin/python -m uvicorn source.main:app --host 0.0.0.0 --port 8000 --proxy-headers
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF"
echo "Aktiviere und starte den Dienst..."
sudo systemctl daemon-reload
sudo systemctl enable jarvis.service
sudo systemctl restart jarvis.service
echo -e "\n${C_GREEN}${C_BOLD}==========================================${C_DEF}"
echo -e "${C_GREEN}✅ Setup komplett! J.A.R.V.I.S. läuft als Dienst.${C_DEF}"
echo -e "Verzeichnis: ${C_BOLD}$INSTALL_DIR${C_DEF}"
echo -e "Web-Interface: ${C_CYAN}http://<deine-ip>:8000${C_DEF}"
echo -e "Log-Ausgabe: ${C_YELLOW}sudo journalctl -u jarvis -f${C_DEF}"
echo -e "${C_GREEN}${C_BOLD}==========================================${C_DEF}"
else
echo -e "\n${C_GREEN}${C_BOLD}==========================================${C_DEF}"
echo -e "${C_GREEN}✅ Setup komplett! Du kannst J.A.R.V.I.S. nun manuell starten:${C_DEF}"
echo "cd $INSTALL_DIR"
echo "source venv/bin/activate"
echo "export PYTHONPATH=\$PYTHONPATH:\$(pwd)/source"
echo "python3 -m uvicorn source.main:app --host 0.0.0.0 --port 8000"
echo -e "${C_GREEN}${C_BOLD}==========================================${C_DEF}"
fi