diff --git a/backend/COMMON_ERRORS.md b/backend/COMMON_ERRORS.md index d15974332..6ec3a7845 100644 --- a/backend/COMMON_ERRORS.md +++ b/backend/COMMON_ERRORS.md @@ -177,6 +177,59 @@ sudo systemctl restart NetworkManager ## 🖥️ Desktop- und Kiosk-Fehler +### Graphical Session Target Not Found + +**Problem:** +``` +graphical session target not found +Unit graphical-session.target could not be found +Failed to start myp-kiosk.service +``` + +**Ursache**: Das `graphical-session.target` existiert nicht auf allen Raspberry Pi-Konfigurationen + +**🚀 SCHNELLE LÖSUNG:** +```bash +# Super-Skript ausführen (behebt ALLES automatisch): +cd /opt/myp +sudo ./setup_https_only.sh + +# Das Super-Skript erkennt und behebt automatisch: +# ✅ Graphical session target Problem +# ✅ Service-Konfiguration reparieren +# ✅ Korrekte Targets verwenden +# ✅ Headless/Desktop-System automatisch erkennen +``` + +**🔧 Manuelle Lösung:** +```bash +# 1. Service-Datei anpassen +sudo systemctl edit myp-kiosk.service --full + +# 2. Ersetze in der [Unit]-Sektion: +# VON: After=graphical-session.target +# ZU: After=graphical.target + +# 3. SystemD neu laden +sudo systemctl daemon-reload +sudo systemctl restart myp-kiosk +``` + +**📋 Für verschiedene Szenarien:** +```bash +# Headless-System (ohne Display): +sudo systemctl disable myp-kiosk + +# Desktop-Environment installieren: +sudo apt install --no-install-recommends xserver-xorg xinit + +# Graphical Target als Standard setzen: +sudo systemctl set-default graphical.target + +# Verfügbare Targets prüfen: +systemctl list-unit-files --type=target | grep graphical +``` + ### Chromium startet nicht im Kiosk-Modus **Problem:** @@ -308,16 +361,23 @@ This site can't provide a secure connection SSL certificate key usage incompatible ``` -**🚀 NEUE PRODUKTIONS-LÖSUNG (HTTPS-Only):** +**🚀 SUPER-SKRIPT LÖSUNG (Intelligente Komplettlösung):** ```bash -# Ein Skript für alles - HTTPS-Only Setup: +# Das EINZIGE Super-Skript für ALLE Probleme: cd /opt/myp sudo ./setup_https_only.sh -# Das Skript macht automatisch: -# ✅ Browser-kompatible SSL-Zertifikate +# Das intelligente Super-Skript macht automatisch: +# ✅ ERR_SSL_KEY_USAGE_INCOMPATIBLE beheben +# ✅ Browser-kompatible SSL-Zertifikate erstellen # ✅ Port 5000 blockieren, nur Port 443 öffnen -# ✅ Kiosk-Modus automatisch konfigurieren +# ✅ SSL-Zertifikat-Gesundheit prüfen und erneuern +# ✅ Alle SSL-Probleme automatisch reparieren +# ✅ Connection refused beheben +# ✅ Graphical session target beheben +# ✅ Service-Dependencies reparieren +# ✅ Port-Konflikte lösen +# ✅ Kiosk intelligent konfigurieren # ✅ Firewall für maximale Sicherheit ``` @@ -522,25 +582,22 @@ Kiosk startet aber kann sich nicht mit MYP-Server verbinden **🚀 Schnelle Lösung:** ```bash -# Quick Fix ausführen +# Super-Skript ausführen (INTELLIGENTE Komplettlösung): cd /opt/myp -sudo chmod +x quick_fix_connection.sh -sudo ./quick_fix_connection.sh +sudo ./setup_https_only.sh -# Services manuell neu starten -sudo systemctl restart myp-https -sudo systemctl restart myp-app -sudo systemctl status myp-https +# Das Super-Skript erkennt und repariert automatisch: +# ✅ Connection refused Probleme +# ✅ Service-Status prüfen und reparieren +# ✅ Python-Module reparieren +# ✅ Port-Konflikte lösen +# ✅ SSL-Zertifikate validieren ``` -**🔍 Detaillierte Diagnose:** +**🔍 Manuelle Diagnose (falls nötig):** ```bash -# Vollständige Diagnose ausführen -cd /opt/myp -sudo chmod +x debug_connection_refused.sh -sudo ./debug_connection_refused.sh - # Service-Logs prüfen +journalctl -u myp-production -f journalctl -u myp-https -f journalctl -u myp-app -f diff --git a/backend/EINFACHE_ANLEITUNG.md b/backend/EINFACHE_ANLEITUNG.md index e20e57843..15ba1dc12 100644 --- a/backend/EINFACHE_ANLEITUNG.md +++ b/backend/EINFACHE_ANLEITUNG.md @@ -1,8 +1,8 @@ -# 🚀 MYP EINFACHE ANLEITUNG +# 🚀 MYP SUPER-ANLEITUNG -## Ein Skript für alles! +## Das EINZIGE Skript für ALLES! -Du musst nur **ein einziges Skript** ausführen und alles wird automatisch konfiguriert: +Du musst nur **ein einziges intelligentes Super-Skript** ausführen und ALLE Probleme werden automatisch erkannt und behoben: ### Auf dem Raspberry Pi: @@ -10,20 +10,25 @@ Du musst nur **ein einziges Skript** ausführen und alles wird automatisch konfi # 1. Ins MYP-Verzeichnis wechseln cd /opt/myp -# 2. HTTPS-Only Setup ausführen (macht ALLES automatisch) +# 2. Super-Skript ausführen (INTELLIGENTE Komplettlösung) sudo ./setup_https_only.sh ``` -**Das war's!** 🎉 +**Das war's!** Das Skript ist intelligent! 🎉 -## Was das Skript automatisch macht: +## Was das Super-Skript automatisch macht: +🔥 **INTELLIGENTE PROBLEMERKENNUNG** - erkennt und behebt alle Probleme automatisch ✅ **ERR_SSL_KEY_USAGE_INCOMPATIBLE** behebt -✅ **Port 5000 komplett blockiert** (nur noch HTTPS Port 443) -✅ **Browser-kompatible SSL-Zertifikate** erstellt -✅ **Kiosk-Modus automatisch** konfiguriert -✅ **Firewall nur Port 443** öffnet -✅ **Alle Services** installiert und startet +✅ **"graphical session target not found"** behebt +✅ **"connection refused"** automatisch repariert +✅ **Port 5000 komplett blockiert** (nur HTTPS Port 443) +✅ **Kiosk intelligent konfiguriert** (Desktop/Headless automatisch erkannt) +✅ **SSL-Zertifikate automatisch** generiert und geprüft +✅ **Firewall intelligent** konfiguriert +✅ **Alle Services automatisch** repariert +✅ **Port-Konflikte** automatisch gelöst +✅ **Service-Dependencies** automatisch korrigiert ## Nach dem Setup: @@ -34,6 +39,9 @@ sudo ./setup_https_only.sh ## Bei Problemen: ```bash +# EINFACH: Super-Skript nochmal ausführen (behebt ALLES automatisch) +sudo ./setup_https_only.sh + # Status prüfen: sudo systemctl status myp-production myp-kiosk @@ -44,6 +52,15 @@ sudo journalctl -u myp-production -f curl -k -v https://localhost ``` +**💡 Das Super-Skript erkennt und behebt automatisch:** +- ✅ "graphical session target not found" +- ✅ "connection refused" +- ✅ SSL-Probleme +- ✅ Service-Probleme +- ✅ Port-Konflikte +- ✅ Firewall-Probleme +- ✅ Kiosk-Konfiguration + --- **🎯 Ein Befehl - alles erledigt!** \ No newline at end of file diff --git a/backend/PRODUCTION_HTTPS_SETUP.md b/backend/PRODUCTION_HTTPS_SETUP.md index f7574ff1a..9c1f76e77 100644 --- a/backend/PRODUCTION_HTTPS_SETUP.md +++ b/backend/PRODUCTION_HTTPS_SETUP.md @@ -9,11 +9,21 @@ ## 🚀 Schnelle Lösung (Raspberry Pi) -### Automatisches Setup (Empfohlen) +### Super-Skript (Das EINZIGE was du brauchst!) ```bash -# Ein Skript für alles: +# Intelligentes Super-Skript für ALLE Probleme: cd /opt/myp sudo ./setup_https_only.sh + +# Das Super-Skript erkennt und behebt automatisch: +# ✅ ERR_SSL_KEY_USAGE_INCOMPATIBLE +# ✅ graphical session target not found +# ✅ connection refused +# ✅ Port-Konflikte (5000 blockieren, 443 öffnen) +# ✅ SSL-Zertifikat-Probleme +# ✅ Service-Dependencies +# ✅ Kiosk-Konfiguration (Desktop/Headless automatisch) +# ✅ Firewall-Optimierung ``` ### 3. Services prüfen diff --git a/backend/debug/fix-kiosk-definitiv.sh b/backend/debug/fix-kiosk-definitiv.sh deleted file mode 100644 index 26d092e69..000000000 --- a/backend/debug/fix-kiosk-definitiv.sh +++ /dev/null @@ -1,370 +0,0 @@ -#!/bin/bash - -# =================================================================== -# DEFINITIVER KIOSK-FIX FÜR RASPBERRY PI -# Löst ALLE X11/Framebuffer-Probleme garantiert -# =================================================================== - -set -euo pipefail - -# Farben -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -log() { echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}"; } -warning() { echo -e "${YELLOW}[WARNUNG] $1${NC}"; } -error() { echo -e "${RED}[FEHLER] $1${NC}"; exit 1; } -info() { echo -e "${BLUE}[INFO] $1${NC}"; } - -# Root-Check -if [ "$EUID" -ne 0 ]; then - error "Als Root ausführen: sudo $0" -fi - -log "=== DEFINITIVER KIOSK-FIX ===" - -# 1. STOPPE ALLES -log "Stoppe alle Display-Manager und X-Server..." -systemctl stop lightdm 2>/dev/null || true -systemctl stop gdm3 2>/dev/null || true -systemctl stop sddm 2>/dev/null || true -systemctl stop xdm 2>/dev/null || true -systemctl stop nodm 2>/dev/null || true -systemctl disable lightdm 2>/dev/null || true -systemctl disable gdm3 2>/dev/null || true -systemctl disable sddm 2>/dev/null || true -systemctl disable xdm 2>/dev/null || true -systemctl disable nodm 2>/dev/null || true - -pkill -f "X" 2>/dev/null || true -pkill -f "Xorg" 2>/dev/null || true -pkill -f "xinit" 2>/dev/null || true -pkill -f "chromium" 2>/dev/null || true -sleep 3 - -# 2. KERNEL MODE SETTING (KMS) AKTIVIEREN -log "Aktiviere KMS/DRM Treiber..." -if [ -f /boot/config.txt ]; then - cp /boot/config.txt /boot/config.txt.backup-$(date +%s) - - # Entferne alte Einstellungen - sed -i '/^dtoverlay=vc4-kms-v3d/d' /boot/config.txt - sed -i '/^dtoverlay=vc4-fkms-v3d/d' /boot/config.txt - sed -i '/^gpu_mem=/d' /boot/config.txt - - # Füge KMS-Treiber hinzu - cat >> /boot/config.txt << 'EOF' - -# Kiosk-Modus GPU-Konfiguration -dtoverlay=vc4-kms-v3d -max_framebuffers=2 -gpu_mem=256 -hdmi_force_hotplug=1 -hdmi_group=2 -hdmi_mode=82 -hdmi_drive=2 -disable_overscan=1 -EOF - - info "Boot-Konfiguration aktualisiert" -fi - -# 3. INSTALLIERE ALLE NÖTIGEN PAKETE -log "Installiere notwendige Pakete..." -apt-get update -apt-get install -y --no-install-recommends \ - xserver-xorg \ - xserver-xorg-video-all \ - xserver-xorg-input-all \ - xinit \ - x11-xserver-utils \ - openbox \ - chromium-browser \ - unclutter \ - xdotool \ - wmctrl \ - xvfb \ - 2>/dev/null || true - -# 4. ERSTELLE MINIMALE X11-KONFIGURATION -log "Erstelle X11-Konfiguration..." -mkdir -p /etc/X11/xorg.conf.d - -# Hauptkonfiguration -cat > /etc/X11/xorg.conf << 'EOF' -Section "ServerFlags" - Option "BlankTime" "0" - Option "StandbyTime" "0" - Option "SuspendTime" "0" - Option "OffTime" "0" - Option "DPMS" "false" - Option "AllowEmptyInput" "true" - Option "AutoAddDevices" "true" -EndSection - -Section "Monitor" - Identifier "Monitor0" - Option "DPMS" "false" -EndSection - -Section "Device" - Identifier "Card0" - Driver "modesetting" - Option "AccelMethod" "glamor" - Option "DRI" "3" -EndSection - -Section "Screen" - Identifier "Screen0" - Device "Card0" - Monitor "Monitor0" - DefaultDepth 24 - SubSection "Display" - Depth 24 - EndSubSection -EndSection -EOF - -# 5. ERSTELLE KIOSK-USER WENN NICHT VORHANDEN -if ! id "kiosk" &>/dev/null; then - log "Erstelle kiosk-User..." - useradd -m -s /bin/bash kiosk - usermod -aG audio,video,input,dialout,plugdev,users kiosk -fi - -# 6. ERSTELLE AUTOLOGIN -log "Konfiguriere Autologin..." -mkdir -p /etc/systemd/system/getty@tty1.service.d -cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << 'EOF' -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin kiosk --noclear %I \$TERM -Type=idle -EOF - -# 7. ERSTELLE DREI VERSCHIEDENE START-METHODEN - -# Methode 1: Direkt-Start ohne Display Manager -log "Erstelle Methode 1: Direkt-Start..." -cat > /home/kiosk/kiosk-direct.sh << 'EOF' -#!/bin/bash -export DISPLAY=:0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# Warte auf Netzwerk -sleep 10 - -# Erstelle .Xauthority -touch $XAUTHORITY -chmod 600 $XAUTHORITY - -# Starte X-Server direkt -/usr/bin/xinit /home/kiosk/kiosk-browser.sh -- /usr/bin/X :0 -nolisten tcp -nocursor -EOF - -# Browser-Start-Skript -cat > /home/kiosk/kiosk-browser.sh << 'EOF' -#!/bin/bash - -# Warte auf X-Server -sleep 3 - -# X11-Einstellungen -xset s off -xset s noblank -xset -dpms - -# Window Manager -openbox-session & -sleep 2 - -# Warte auf Backend -echo "Warte auf Backend..." -while ! curl -s http://localhost:5000 >/dev/null 2>&1; do - sleep 2 -done - -# Starte Browser -chromium-browser \ - --kiosk \ - --no-sandbox \ - --disable-setuid-sandbox \ - --disable-dev-shm-usage \ - --disable-accelerated-2d-canvas \ - --no-first-run \ - --no-zygote \ - --single-process \ - --disable-gpu \ - --window-size=1920,1080 \ - --start-fullscreen \ - --incognito \ - http://localhost:5000 -EOF - -# Methode 2: Mit startx -log "Erstelle Methode 2: startx..." -cat > /home/kiosk/.xinitrc << 'EOF' -#!/bin/bash -xset s off -xset s noblank -xset -dpms - -openbox-session & -sleep 2 - -# Warte auf Backend -while ! curl -s http://localhost:5000 >/dev/null 2>&1; do - sleep 2 -done - -exec chromium-browser --kiosk --no-sandbox --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage http://localhost:5000 -EOF - -# Methode 3: Systemd Service -log "Erstelle Methode 3: Systemd Service..." -cat > /etc/systemd/system/kiosk.service << 'EOF' -[Unit] -Description=Kiosk Mode -After=multi-user.target network.target - -[Service] -Type=simple -Restart=always -RestartSec=10 -User=kiosk -Group=kiosk -PAMName=login -TTYPath=/dev/tty2 -StandardInput=tty -StandardOutput=journal -StandardError=journal -Environment="DISPLAY=:0" -Environment="XAUTHORITY=/home/kiosk/.Xauthority" -ExecStartPre=/bin/sleep 10 -ExecStart=/usr/bin/xinit /home/kiosk/kiosk-browser.sh -- /usr/bin/X :0 -nolisten tcp - -[Install] -WantedBy=multi-user.target -EOF - -# 8. ERSTELLE FALLBACK: TERMINAL-BROWSER -log "Erstelle Terminal-Browser-Fallback..." -cat > /home/kiosk/terminal-browser.sh << 'EOF' -#!/bin/bash -# Terminal-basierter Browser als Fallback -clear -echo "=== KIOSK-MODUS (Terminal) ===" -echo "Warte auf Backend..." - -while ! curl -s http://localhost:5000 >/dev/null 2>&1; do - sleep 2 - echo -n "." -done - -echo "" -echo "Backend verfügbar!" -echo "" -echo "Optionen:" -echo "1) Links2 Browser starten (Terminal)" -echo "2) W3M Browser starten (Terminal)" -echo "3) Versuche X11 erneut" -echo "" - -# Installiere Terminal-Browser falls nötig -which links2 >/dev/null 2>&1 || apt-get install -y links2 -which w3m >/dev/null 2>&1 || apt-get install -y w3m - -links2 http://localhost:5000 -EOF - -# 9. BERECHTIGUNGEN SETZEN -log "Setze Berechtigungen..." -chmod +x /home/kiosk/*.sh -chmod +x /home/kiosk/.xinitrc -chown -R kiosk:kiosk /home/kiosk/ -touch /home/kiosk/.Xauthority -chown kiosk:kiosk /home/kiosk/.Xauthority -chmod 600 /home/kiosk/.Xauthority - -# 10. ERSTELLE MASTER-START-SKRIPT -log "Erstelle Master-Start-Skript..." -cat > /home/kiosk/.bashrc << 'EOF' -# Kiosk Auto-Start -if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then - echo "=== KIOSK-MODUS WIRD GESTARTET ===" - echo "" - echo "Versuche Methode 1: Direkt-Start..." - - # Methode 1 - if /home/kiosk/kiosk-direct.sh 2>/tmp/kiosk-error1.log; then - exit 0 - fi - - echo "Methode 1 fehlgeschlagen. Versuche Methode 2: startx..." - sleep 2 - - # Methode 2 - if startx -- -nocursor 2>/tmp/kiosk-error2.log; then - exit 0 - fi - - echo "Methode 2 fehlgeschlagen. Versuche Methode 3: Xvfb..." - sleep 2 - - # Methode 3: Virtual Framebuffer - Xvfb :0 -screen 0 1920x1080x24 & - export DISPLAY=:0 - sleep 2 - /home/kiosk/kiosk-browser.sh 2>/tmp/kiosk-error3.log - - # Wenn alles fehlschlägt - echo "" - echo "ALLE X11-METHODEN FEHLGESCHLAGEN!" - echo "" - echo "Fehler-Logs:" - echo "- /tmp/kiosk-error1.log" - echo "- /tmp/kiosk-error2.log" - echo "- /tmp/kiosk-error3.log" - echo "" - echo "Starte Terminal-Browser als Fallback..." - sleep 3 - /home/kiosk/terminal-browser.sh -fi -EOF - -chown kiosk:kiosk /home/kiosk/.bashrc - -# 11. SYSTEMD-DIENSTE -log "Konfiguriere Systemd..." -systemctl daemon-reload -systemctl enable getty@tty1.service -systemctl enable kiosk.service 2>/dev/null || true - -# 12. FINALE ÜBERPRÜFUNG -log "✅ INSTALLATION ABGESCHLOSSEN!" -info "" -info "📋 Was wurde installiert:" -info " - KMS/DRM-Treiber aktiviert" -info " - X11 komplett neu konfiguriert" -info " - 3 verschiedene Start-Methoden" -info " - Terminal-Browser als Fallback" -info " - Autologin konfiguriert" -info "" -warning "⚠️ NEUSTART ERFORDERLICH!" -info "" -info "Nach dem Neustart:" -info "1. System startet automatisch in Kiosk-Modus" -info "2. Falls X11 fehlschlägt, startet Terminal-Browser" -info "" -info "Manueller Test ohne Neustart:" -info " su - kiosk" -info " ./kiosk-direct.sh" -info "" -read -p "Jetzt neustarten? (j/n) " -n 1 -r -echo -if [[ $REPLY =~ ^[Jj]$ ]]; then - reboot -fi \ No newline at end of file diff --git a/backend/debug/fix-x11-framebuffer.sh b/backend/debug/fix-x11-framebuffer.sh deleted file mode 100644 index c3fc3c4bf..000000000 --- a/backend/debug/fix-x11-framebuffer.sh +++ /dev/null @@ -1,237 +0,0 @@ -#!/bin/bash - -# =================================================================== -# MYP X11 Framebuffer-Fix für Raspberry Pi -# Behebt den "Cannot run in framebuffer mode" Fehler -# =================================================================== - -set -euo pipefail - -# Farben für Ausgabe -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -log() { - echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}" -} - -warning() { - echo -e "${YELLOW}[WARNUNG] $1${NC}" -} - -error() { - echo -e "${RED}[FEHLER] $1${NC}" - exit 1 -} - -info() { - echo -e "${BLUE}[INFO] $1${NC}" -} - -# Prüfe root-Berechtigung -if [ "$EUID" -ne 0 ]; then - error "Dieses Skript muss als Root ausgeführt werden: sudo $0" -fi - -log "=== X11 FRAMEBUFFER-FIX FÜR RASPBERRY PI ===" - -# Stoppe laufende X-Server -log "Stoppe laufende X-Server..." -pkill -f "X :0" 2>/dev/null || true -pkill -f "Xorg" 2>/dev/null || true -pkill -f "xinit" 2>/dev/null || true -pkill -f "chromium" 2>/dev/null || true -sleep 2 - -# Erstelle X11-Konfigurationsverzeichnis -log "Erstelle X11-Konfiguration..." -mkdir -p /etc/X11/xorg.conf.d - -# Erstelle Framebuffer-Fix-Konfiguration -cat > /etc/X11/xorg.conf.d/99-fbdev.conf << 'EOF' -# X11 Konfiguration für Raspberry Pi - behebt Framebuffer-Fehler -Section "Device" - Identifier "Raspberry Pi FBDEV" - Driver "fbdev" - Option "fbdev" "/dev/fb0" - Option "SwapbuffersWait" "true" -EndSection - -Section "Screen" - Identifier "Primary Screen" - Device "Raspberry Pi FBDEV" - DefaultDepth 24 - SubSection "Display" - Depth 24 - Modes "1920x1080" "1680x1050" "1600x900" "1280x1024" "1280x800" "1024x768" - EndSubSection -EndSection - -Section "ServerLayout" - Identifier "Default Layout" - Screen "Primary Screen" -EndSection - -Section "ServerFlags" - Option "BlankTime" "0" - Option "StandbyTime" "0" - Option "SuspendTime" "0" - Option "OffTime" "0" - Option "DPMS" "false" -EndSection -EOF - -# Alternative Modesetting-Konfiguration -cat > /etc/X11/xorg.conf.d/20-modesetting.conf << 'EOF' -# Alternative Modesetting-Konfiguration -Section "Device" - Identifier "Raspberry Pi Modesetting" - Driver "modesetting" - Option "AccelMethod" "none" -EndSection -EOF - -# Installiere fehlende Video-Treiber -log "Installiere Video-Treiber..." -apt-get update -apt-get install -y xserver-xorg-video-fbturbo 2>/dev/null || { - # Fallback zu Standard-Treibern - apt-get install -y xserver-xorg-video-all 2>/dev/null || true -} - -# Erstelle X11-Start-Wrapper -log "Erstelle X11-Start-Wrapper..." -cat > /usr/local/bin/start-x11-kiosk << 'EOF' -#!/bin/bash - -# X11 Kiosk-Start-Wrapper für Raspberry Pi -export DISPLAY=:0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# Erstelle .Xauthority -if [ ! -f "$XAUTHORITY" ]; then - touch "$XAUTHORITY" - chown kiosk:kiosk "$XAUTHORITY" - chmod 600 "$XAUTHORITY" -fi - -# Stoppe alte X-Server -pkill -f "X :0" 2>/dev/null || true -pkill -f "Xorg" 2>/dev/null || true -sleep 2 - -echo "Starte X-Server..." - -# Versuche verschiedene Start-Methoden -if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -novtswitch -nolisten tcp -dpi 96 2>/tmp/x11-error.log; then - echo "Methode 1 fehlgeschlagen, versuche Alternative..." - - if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -config /etc/X11/xorg.conf.d/99-fbdev.conf -ignoreABI 2>>/tmp/x11-error.log; then - echo "Methode 2 fehlgeschlagen, versuche Fallback..." - xinit /home/kiosk/.xinitrc -- :0 2>>/tmp/x11-error.log - fi -fi - -if [ -f /tmp/x11-error.log ]; then - echo "X11 Fehler-Log:" - tail -20 /tmp/x11-error.log -fi -EOF - -chmod +x /usr/local/bin/start-x11-kiosk - -# Erstelle einfaches .xinitrc für kiosk -log "Erstelle korrigiertes .xinitrc..." -cat > /home/kiosk/.xinitrc << 'EOF' -#!/bin/bash - -# Fehlerlog -exec 2>/tmp/xinitrc-error.log - -# X11 Einstellungen -xset s off -xset s noblank -xset -dpms - -# Window Manager -openbox-session & -sleep 2 - -# Browser starten -BROWSER="" -if command -v chromium >/dev/null 2>&1; then - BROWSER="chromium" -elif command -v chromium-browser >/dev/null 2>&1; then - BROWSER="chromium-browser" -else - BROWSER="firefox-esr" -fi - -# Starte Browser mit GPU-Deaktivierung -exec $BROWSER \ - --kiosk \ - --no-sandbox \ - --disable-gpu \ - --disable-software-rasterizer \ - --disable-dev-shm-usage \ - --no-first-run \ - --start-fullscreen \ - http://localhost:5000 -EOF - -chmod +x /home/kiosk/.xinitrc -chown kiosk:kiosk /home/kiosk/.xinitrc - -# Konfiguriere Raspberry Pi Boot-Einstellungen -if [ -f /boot/config.txt ]; then - log "Konfiguriere Raspberry Pi GPU-Einstellungen..." - - # Backup - cp /boot/config.txt /boot/config.txt.backup - - # GPU-Einstellungen - if ! grep -q "^gpu_mem=" /boot/config.txt; then - echo "gpu_mem=128" >> /boot/config.txt - fi - - if ! grep -q "^hdmi_force_hotplug=" /boot/config.txt; then - cat >> /boot/config.txt << 'EOF' - -# X11 Kiosk-Modus Optimierungen -hdmi_force_hotplug=1 -hdmi_drive=2 -config_hdmi_boost=4 -disable_overscan=1 -framebuffer_width=1920 -framebuffer_height=1080 -framebuffer_depth=32 -framebuffer_ignore_alpha=1 -EOF - fi -fi - -log "✅ X11 Framebuffer-Fix installiert!" -info "" -info "📋 Was wurde konfiguriert:" -info " - X11 fbdev-Konfiguration erstellt" -info " - Video-Treiber installiert" -info " - X11-Start-Wrapper erstellt: /usr/local/bin/start-x11-kiosk" -info " - GPU-Einstellungen optimiert" -info "" -info "🔧 Nächste Schritte:" -info " 1. System neustarten: sudo reboot" -info " 2. Als kiosk-User einloggen" -info " 3. X11 wird automatisch mit den Fixes starten" -info "" -info "💡 Manueller Test:" -info " su - kiosk" -info " /usr/local/bin/start-x11-kiosk" -info "" - -# Prüfe ob Neustart erforderlich -if [ -f /boot/config.txt.backup ]; then - warning "⚠️ Boot-Konfiguration geändert - Neustart erforderlich!" -fi \ No newline at end of file diff --git a/backend/fix_ssl_raspberry.sh b/backend/fix_ssl_raspberry.sh deleted file mode 100644 index bdef0d7e6..000000000 --- a/backend/fix_ssl_raspberry.sh +++ /dev/null @@ -1,305 +0,0 @@ -#!/bin/bash -# MYP SSL Browser-Kompatibilitäts-Fix für Raspberry Pi -# Löst ERR_SSL_KEY_USAGE_INCOMPATIBLE Fehler auf Linux-Zielsystem - -set -e # Beende bei Fehler - -# Farbcodes für Output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -echo -e "${CYAN}=========================================================${NC}" -echo -e "${CYAN}MYP SSL BROWSER-KOMPATIBILITÄTS-FIX für Raspberry Pi${NC}" -echo -e "${CYAN}Löst ERR_SSL_KEY_USAGE_INCOMPATIBLE Fehler${NC}" -echo -e "${CYAN}=========================================================${NC}" -echo "" - -# Aktuelles Verzeichnis und Pfade -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -APP_DIR="/opt/myp" -SSL_DIR="$APP_DIR/ssl" -CERT_PATH="$SSL_DIR/cert.pem" -KEY_PATH="$SSL_DIR/key.pem" - -echo -e "${BLUE}📁 Arbeitsverzeichnis: $SCRIPT_DIR${NC}" -echo -e "${BLUE}📁 App-Verzeichnis: $APP_DIR${NC}" -echo -e "${BLUE}🔐 SSL-Verzeichnis: $SSL_DIR${NC}" -echo "" - -# Prüfe ob als root/sudo ausgeführt wird -if [[ $EUID -ne 0 ]]; then - echo -e "${RED}❌ Dieses Skript muss als root ausgeführt werden!${NC}" - echo -e "${YELLOW}💡 Verwende: sudo $0${NC}" - exit 1 -fi - -# Prüfe ob OpenSSL verfügbar ist -if ! command -v openssl &> /dev/null; then - echo -e "${RED}❌ OpenSSL ist nicht installiert!${NC}" - echo -e "${YELLOW}📦 Installiere OpenSSL...${NC}" - apt update && apt install -y openssl - - if ! command -v openssl &> /dev/null; then - echo -e "${RED}❌ OpenSSL Installation fehlgeschlagen!${NC}" - exit 1 - fi - echo -e "${GREEN}✅ OpenSSL erfolgreich installiert${NC}" -fi - -# SSL-Verzeichnis erstellen -echo -e "${YELLOW}📁 Erstelle SSL-Verzeichnis...${NC}" -mkdir -p "$SSL_DIR" -mkdir -p "$SSL_DIR/backup" - -# Backup existierender Zertifikate -if [ -f "$CERT_PATH" ]; then - TIMESTAMP=$(date +"%Y%m%d_%H%M%S") - echo -e "${YELLOW}💾 Erstelle Backup der alten Zertifikate...${NC}" - cp "$CERT_PATH" "$SSL_DIR/backup/cert_backup_$TIMESTAMP.pem" 2>/dev/null || true - cp "$KEY_PATH" "$SSL_DIR/backup/key_backup_$TIMESTAMP.pem" 2>/dev/null || true - echo -e "${GREEN}✅ Backup erstellt: $SSL_DIR/backup/cert_backup_$TIMESTAMP.pem${NC}" -fi - -# Erstelle Raspberry Pi spezifische OpenSSL-Konfiguration -echo -e "${YELLOW}📝 Erstelle browser-kompatible OpenSSL-Konfiguration...${NC}" - -cat > "$SSL_DIR/openssl_raspberry_fix.conf" << 'EOF' -[req] -distinguished_name = req_distinguished_name -req_extensions = v3_req -prompt = no - -[req_distinguished_name] -C = DE -ST = Baden-Wuerttemberg -L = Stuttgart -O = Mercedes-Benz AG -OU = MYP Druckerverwaltung -CN = m040tbaraspi001 - -[v3_req] -# Basic Constraints - KRITISCH für Browser-Kompatibilität -basicConstraints = critical, CA:FALSE - -# Key Usage - KRITISCH für ERR_SSL_KEY_USAGE_INCOMPATIBLE Fix -keyUsage = critical, digitalSignature, keyEncipherment, keyAgreement - -# Extended Key Usage - TLS Server Authentication -extendedKeyUsage = critical, serverAuth, clientAuth - -# Subject Alternative Names - Alle Raspberry Pi Domains/IPs -subjectAltName = critical, @alt_names - -# Netscape Extensions für Legacy-Browser -nsCertType = server -nsComment = "MYP Raspberry Pi SSL Fix - ERR_SSL_KEY_USAGE_INCOMPATIBLE Lösung" - -[alt_names] -# Lokale Entwicklung -DNS.1 = localhost -DNS.2 = *.localhost -IP.1 = 127.0.0.1 -IP.2 = ::1 - -# Raspberry Pi Hostname -DNS.3 = m040tbaraspi001 -DNS.4 = m040tbaraspi001.local -DNS.5 = raspberrypi -DNS.6 = raspberrypi.local - -# Intranet-Domain -DNS.7 = m040tbaraspi001.de040.corpintra.net -DNS.8 = *.de040.corpintra.net - -# Raspberry Pi typische IPs -IP.3 = 0.0.0.0 -IP.4 = 192.168.1.0/24 -IP.5 = 10.0.0.0/8 -EOF - -echo -e "${GREEN}✅ OpenSSL-Konfiguration erstellt${NC}" - -# Generiere Private Key -echo -e "${YELLOW}🔑 Generiere Private Key (RSA 2048)...${NC}" -openssl genrsa -out "$KEY_PATH" 2048 - -if [ $? -eq 0 ]; then - echo -e "${GREEN}✅ Private Key generiert${NC}" -else - echo -e "${RED}❌ Private Key Generierung fehlgeschlagen!${NC}" - exit 1 -fi - -# Generiere browser-kompatibles Zertifikat -echo -e "${YELLOW}📜 Generiere browser-kompatibles Zertifikat...${NC}" -openssl req -new -x509 \ - -key "$KEY_PATH" \ - -out "$CERT_PATH" \ - -days 365 \ - -config "$SSL_DIR/openssl_raspberry_fix.conf" \ - -extensions v3_req \ - -sha256 - -if [ $? -eq 0 ]; then - echo -e "${GREEN}✅ Browser-kompatibles Zertifikat generiert${NC}" -else - echo -e "${RED}❌ Zertifikat-Generierung fehlgeschlagen!${NC}" - exit 1 -fi - -# Berechtigungen setzen -echo -e "${YELLOW}🔒 Setze korrekte Berechtigungen...${NC}" -chown root:root "$CERT_PATH" "$KEY_PATH" -chmod 644 "$CERT_PATH" # Alle können lesen -chmod 600 "$KEY_PATH" # Nur root kann lesen -echo -e "${GREEN}✅ Berechtigungen gesetzt${NC}" - -# Aufräumen -rm -f "$SSL_DIR/openssl_raspberry_fix.conf" - -# Validierung der Browser-Kompatibilität -echo "" -echo -e "${CYAN}=========================================================${NC}" -echo -e "${CYAN}🔍 BROWSER-KOMPATIBILITÄTS-VALIDIERUNG${NC}" -echo -e "${CYAN}=========================================================${NC}" - -echo -e "${YELLOW}Prüfe Zertifikat-Extensions...${NC}" - -# Extrahiere Zertifikat-Informationen -CERT_INFO=$(openssl x509 -in "$CERT_PATH" -noout -text 2>/dev/null) - -# Browser-Kompatibilitäts-Checks -declare -A checks=( - ["Digital Signature"]="Digital Signature" - ["Key Encipherment"]="Key Encipherment" - ["Key Agreement"]="Key Agreement" - ["TLS Web Server Authentication"]="TLS Web Server Authentication" - ["Subject Alternative Name"]="Subject Alternative Name" - ["CA:FALSE"]="CA:FALSE" - ["SHA-256 Signature"]="sha256WithRSAEncryption" -) - -all_passed=true - -for check_name in "${!checks[@]}"; do - pattern="${checks[$check_name]}" - if echo "$CERT_INFO" | grep -q "$pattern"; then - echo -e " ${GREEN}✅ $check_name${NC}" - else - echo -e " ${RED}❌ $check_name${NC}" - all_passed=false - fi -done - -# Zusätzliche Raspberry Pi spezifische Checks -echo "" -echo -e "${YELLOW}Prüfe Raspberry Pi spezifische Konfiguration...${NC}" - -# Hostname Check -if echo "$CERT_INFO" | grep -q "m040tbaraspi001"; then - echo -e " ${GREEN}✅ Raspberry Pi Hostname (m040tbaraspi001)${NC}" -else - echo -e " ${RED}❌ Raspberry Pi Hostname fehlt${NC}" -fi - -# Localhost Check -if echo "$CERT_INFO" | grep -q "localhost"; then - echo -e " ${GREEN}✅ Localhost Support${NC}" -else - echo -e " ${RED}❌ Localhost Support fehlt${NC}" -fi - -# Intranet Domain Check -if echo "$CERT_INFO" | grep -q "de040.corpintra.net"; then - echo -e " ${GREEN}✅ Intranet Domain Support${NC}" -else - echo -e " ${YELLOW}⚠️ Intranet Domain möglicherweise nicht verfügbar${NC}" -fi - -# Zertifikat-Details anzeigen -echo "" -echo -e "${BLUE}📋 Zertifikat-Details:${NC}" -openssl x509 -in "$CERT_PATH" -noout -subject -dates - -# Systemd Service Integration -echo "" -echo -e "${YELLOW}🔄 Integriere mit MYP Services...${NC}" - -# Prüfe ob MYP App Service existiert -if systemctl list-units --type=service | grep -q "myp-app"; then - echo -e "${BLUE}🔄 Starte MYP App Service neu...${NC}" - systemctl restart myp-app.service - echo -e "${GREEN}✅ MYP App Service neu gestartet${NC}" -fi - -# Prüfe ob MYP Kiosk Service existiert -if systemctl list-units --type=service | grep -q "myp-kiosk"; then - echo -e "${BLUE}🔄 Starte MYP Kiosk Service neu...${NC}" - systemctl restart myp-kiosk.service - echo -e "${GREEN}✅ MYP Kiosk Service neu gestartet${NC}" -fi - -# Abschlussbericht -echo "" -if [ "$all_passed" = true ]; then - echo -e "${GREEN}=========================================================${NC}" - echo -e "${GREEN}🎉 SSL-FIX ERFOLGREICH ABGESCHLOSSEN!${NC}" - echo -e "${GREEN}=========================================================${NC}" -else - echo -e "${YELLOW}=========================================================${NC}" - echo -e "${YELLOW}⚠️ SSL-FIX ABGESCHLOSSEN (mit Warnungen)${NC}" - echo -e "${YELLOW}=========================================================${NC}" -fi - -echo "" -echo -e "${CYAN}📊 ERGEBNIS:${NC}" -echo -e " 📄 Zertifikat: $CERT_PATH" -echo -e " 🔑 Private Key: $KEY_PATH" -echo -e " 📅 Gültig bis: $(date -d '+365 days' '+%Y-%m-%d')" -echo "" - -echo -e "${CYAN}🌐 NÄCHSTE SCHRITTE:${NC}" -echo -e "${BLUE}1. Browser-Cache auf CLIENT-SYSTEM leeren:${NC}" -echo -e " • Chrome/Edge: Strg+Shift+Del → 'Gesamte Zeit' → alle Optionen" -echo -e " • Firefox: Strg+Shift+Del → 'Alles' auswählen" -echo "" -echo -e "${BLUE}2. Zugriff testen:${NC}" -echo -e " • Lokal: https://localhost:5000" -echo -e " • Intranet: https://m040tbaraspi001.de040.corpintra.net" -echo "" -echo -e "${BLUE}3. Bei SSL-Warnung im Browser:${NC}" -echo -e " • 'Erweitert' → 'Weiter zu [hostname] (unsicher)'" -echo "" -echo -e "${GREEN}💡 Der Fehler ERR_SSL_KEY_USAGE_INCOMPATIBLE sollte behoben sein!${NC}" -echo "" - -# System-Info für Debugging -echo -e "${BLUE}🔍 System-Informationen:${NC}" -echo -e " 📟 Hostname: $(hostname)" -echo -e " 🌐 IP-Adressen: $(hostname -I | tr ' ' '\n' | head -3 | tr '\n' ' ')" -echo -e " 🐧 OS: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)" -echo -e " 🔐 OpenSSL: $(openssl version)" -echo "" - -# Firewall-Check -if command -v ufw &> /dev/null; then - echo -e "${YELLOW}🔥 Prüfe Firewall (UFW)...${NC}" - ufw_status=$(ufw status | grep "Status:") - if echo "$ufw_status" | grep -q "active"; then - echo -e " 🔥 UFW aktiv - prüfe HTTPS Port 443..." - if ufw status | grep -q "443"; then - echo -e " ${GREEN}✅ Port 443 (HTTPS) ist geöffnet${NC}" - else - echo -e " ${YELLOW}⚠️ Port 443 (HTTPS) möglicherweise blockiert${NC}" - echo -e " 💡 Öffne mit: sudo ufw allow 443" - fi - else - echo -e " ${GREEN}✅ UFW inaktiv - keine Firewall-Blockierung${NC}" - fi -fi - -echo -e "${GREEN}🏁 SSL-Fix für Raspberry Pi abgeschlossen!${NC}" \ No newline at end of file diff --git a/backend/scripts/get_kiosk_url.sh b/backend/scripts/get_kiosk_url.sh deleted file mode 100644 index a3705ece1..000000000 --- a/backend/scripts/get_kiosk_url.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# MYP Kiosk URL Ermittlung - HTTPS-Only -# Ermittelt die beste HTTPS-URL für den Kiosk-Modus - -# Prioritäten für URL-Ermittlung: -# 1. Intranet-Domain (falls erreichbar) -# 2. Lokaler Hostname (falls erreichbar) -# 3. Localhost (Fallback) - -# Teste Intranet-Domain -INTRANET_URL="https://m040tbaraspi001.de040.corpintra.net" -if curl -k -s --connect-timeout 2 --max-time 3 "$INTRANET_URL" >/dev/null 2>&1; then - echo "$INTRANET_URL" - exit 0 -fi - -# Teste lokalen Hostname -HOSTNAME=$(hostname) -LOCAL_URL="https://$HOSTNAME" -if curl -k -s --connect-timeout 2 --max-time 3 "$LOCAL_URL" >/dev/null 2>&1; then - echo "$LOCAL_URL" - exit 0 -fi - -# Teste localhost mit Port 443 -if curl -k -s --connect-timeout 2 --max-time 3 "https://localhost:443" >/dev/null 2>&1; then - echo "https://localhost:443" - exit 0 -fi - -# Fallback: localhost ohne Port -echo "https://localhost" \ No newline at end of file diff --git a/backend/scripts/update_fehlerresilienz.sh b/backend/scripts/update_fehlerresilienz.sh deleted file mode 100644 index 150129efe..000000000 --- a/backend/scripts/update_fehlerresilienz.sh +++ /dev/null @@ -1,1030 +0,0 @@ -#!/bin/bash - -# ============================================================================= -# MYP Fehlerresilienz und Wartungsfreier Betrieb - Update Script -# ============================================================================= -# Installiert und konfiguriert alle Komponenten für absolute Fehlerresilienz -# und wartungsfreien Produktionsbetrieb mit Kiosk-Modus. -# BEREINIGT ALLE DESKTOP-ENVIRONMENTS für maximale Stabilität! -# -# Autor: MYP System -# Version: 2.1.0 -# Datum: $(date '+%Y-%m-%d') -# ============================================================================= - -set -euo pipefail - -# Farben für Output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -PURPLE='\033[0;35m' -CYAN='\033[0;36m' -WHITE='\033[1;37m' -NC='\033[0m' # No Color - -# Logging-Funktionen -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -log_debug() { - echo -e "${BLUE}[DEBUG]${NC} $1" -} - -log_header() { - echo -e "\n${PURPLE}=== $1 ===${NC}" -} - -log_step() { - echo -e "${CYAN}➤${NC} $1" -} - -# Fehlerbehandlung -error_exit() { - log_error "$1" - exit 1 -} - -# Prüfe Root-Rechte -check_root() { - if [[ $EUID -ne 0 ]]; then - error_exit "Dieses Script muss als root ausgeführt werden!" - fi -} - -# Prüfe Betriebssystem -check_os() { - if [[ ! -f /etc/os-release ]]; then - error_exit "Kann Betriebssystem nicht identifizieren!" - fi - - . /etc/os-release - - case "$ID" in - ubuntu|debian) - PACKAGE_MANAGER="apt" - ;; - centos|rhel|fedora) - PACKAGE_MANAGER="yum" - ;; - arch) - PACKAGE_MANAGER="pacman" - ;; - *) - error_exit "Nicht unterstütztes Betriebssystem: $ID" - ;; - esac - - log_info "Erkanntes OS: $PRETTY_NAME ($ID)" - log_info "Package Manager: $PACKAGE_MANAGER" -} - -# ============================================================================= -# DESKTOP-ENVIRONMENT BEREINIGUNG -# ============================================================================= - -cleanup_desktop_environments() { - log_header "Desktop-Environment Bereinigung" - - log_step "Stoppe alle laufenden Desktop-Services..." - - # Stoppe Display-Manager und Desktop-Services - systemctl stop gdm3 2>/dev/null || true - systemctl stop gdm 2>/dev/null || true - systemctl stop lightdm 2>/dev/null || true - systemctl stop sddm 2>/dev/null || true - systemctl stop xdm 2>/dev/null || true - systemctl stop kdm 2>/dev/null || true - systemctl stop lxdm 2>/dev/null || true - - # Deaktiviere Display-Manager - systemctl disable gdm3 2>/dev/null || true - systemctl disable gdm 2>/dev/null || true - systemctl disable lightdm 2>/dev/null || true - systemctl disable sddm 2>/dev/null || true - systemctl disable xdm 2>/dev/null || true - systemctl disable kdm 2>/dev/null || true - systemctl disable lxdm 2>/dev/null || true - - log_step "Entferne Desktop-Environments und unnötige Pakete..." - - if [[ "$PACKAGE_MANAGER" == "apt" ]]; then - # GNOME entfernen - apt-get remove --purge -y \ - ubuntu-desktop \ - gnome-desktop* \ - gnome-shell \ - gnome-session \ - gnome-control-center \ - gnome-settings-daemon \ - nautilus \ - gdm3 \ - gdm \ - 2>/dev/null || true - - # KDE entfernen - apt-get remove --purge -y \ - kubuntu-desktop \ - kde-plasma-desktop \ - plasma-desktop \ - kdebase-workspace \ - kde-window-manager \ - kwin \ - dolphin \ - sddm \ - kdm \ - 2>/dev/null || true - - # XFCE entfernen - apt-get remove --purge -y \ - xubuntu-desktop \ - xfce4 \ - xfce4-session \ - xfce4-panel \ - xfwm4 \ - thunar \ - lightdm \ - 2>/dev/null || true - - # LXDE/LXQt entfernen - apt-get remove --purge -y \ - lubuntu-desktop \ - lxde \ - lxde-core \ - lxqt \ - lxsession \ - pcmanfm \ - lxdm \ - 2>/dev/null || true - - # MATE entfernen - apt-get remove --purge -y \ - ubuntu-mate-desktop \ - mate-desktop-environment \ - mate-session-manager \ - mate-panel \ - caja \ - 2>/dev/null || true - - # Cinnamon entfernen - apt-get remove --purge -y \ - cinnamon \ - cinnamon-desktop-environment \ - cinnamon-session \ - nemo \ - 2>/dev/null || true - - # Budgie entfernen - apt-get remove --purge -y \ - ubuntu-budgie-desktop \ - budgie-desktop \ - budgie-desktop-environment \ - 2>/dev/null || true - - # Unity entfernen (falls noch vorhanden) - apt-get remove --purge -y \ - ubuntu-unity-desktop \ - unity \ - unity-control-center \ - unity-settings-daemon \ - 2>/dev/null || true - - # Weitere Desktop-Programme entfernen - apt-get remove --purge -y \ - firefox \ - libreoffice* \ - thunderbird \ - evolution \ - rhythmbox \ - totem \ - cheese \ - shotwell \ - simple-scan \ - remmina \ - transmission-gtk \ - brasero \ - deja-dup \ - usb-creator-gtk \ - software-center \ - ubuntu-software \ - gnome-software \ - snap-store \ - update-manager \ - 2>/dev/null || true - - # Autoremove ausführen - apt-get autoremove --purge -y - apt-get autoclean - - elif [[ "$PACKAGE_MANAGER" == "yum" ]]; then - # GNOME entfernen - yum groupremove -y "GNOME Desktop" 2>/dev/null || true - yum remove -y gnome-shell gdm 2>/dev/null || true - - # KDE entfernen - yum groupremove -y "KDE Plasma Workspaces" 2>/dev/null || true - yum remove -y plasma-desktop sddm 2>/dev/null || true - - # XFCE entfernen - yum groupremove -y "Xfce Desktop" 2>/dev/null || true - yum remove -y xfce4-session lightdm 2>/dev/null || true - - # LXDE entfernen - yum groupremove -y "LXDE Desktop" 2>/dev/null || true - yum remove -y lxde-common lxdm 2>/dev/null || true - - # MATE entfernen - yum groupremove -y "MATE Desktop" 2>/dev/null || true - - # Cinnamon entfernen - yum remove -y cinnamon 2>/dev/null || true - - elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then - # GNOME entfernen - pacman -Rns --noconfirm gnome gnome-extra gdm 2>/dev/null || true - - # KDE entfernen - pacman -Rns --noconfirm plasma kde-applications sddm 2>/dev/null || true - - # XFCE entfernen - pacman -Rns --noconfirm xfce4 xfce4-goodies lightdm 2>/dev/null || true - - # LXDE entfernen - pacman -Rns --noconfirm lxde lxdm 2>/dev/null || true - - # MATE entfernen - pacman -Rns --noconfirm mate mate-extra 2>/dev/null || true - - # Cinnamon entfernen - pacman -Rns --noconfirm cinnamon 2>/dev/null || true - fi - - log_step "Bereinige Autostart-Verzeichnisse..." - - # Bereinige System-Autostart - rm -rf /etc/xdg/autostart/* 2>/dev/null || true - rm -rf /usr/share/autostart/* 2>/dev/null || true - - # Bereinige Benutzer-Autostart (falls vorhanden) - for user_home in /home/*; do - if [[ -d "$user_home" ]]; then - rm -rf "$user_home/.config/autostart"/* 2>/dev/null || true - rm -rf "$user_home/.kde/Autostart"/* 2>/dev/null || true - rm -rf "$user_home/.kde4/Autostart"/* 2>/dev/null || true - fi - done - - log_step "Setze Text-Boot als Standard..." - - # Setze Standard-Target auf Multi-User (Text-Modus) - systemctl set-default multi-user.target - - log_step "Bereinige Desktop-Konfigurationsdateien..." - - # Entferne Desktop-Konfigurationen - rm -rf /etc/gdm3 2>/dev/null || true - rm -rf /etc/gdm 2>/dev/null || true - rm -rf /etc/lightdm 2>/dev/null || true - rm -rf /etc/sddm.conf 2>/dev/null || true - rm -rf /etc/kde 2>/dev/null || true - rm -rf /etc/xdg/plasma* 2>/dev/null || true - rm -rf /etc/xdg/kde* 2>/dev/null || true - - # Bereinige X11-Sessions (außer dem was wir für Kiosk brauchen) - find /usr/share/xsessions/ -name "*.desktop" -not -name "kiosk*" -delete 2>/dev/null || true - find /usr/share/wayland-sessions/ -name "*.desktop" -delete 2>/dev/null || true - - log_info "✅ Desktop-Environment Bereinigung abgeschlossen" -} - -# ============================================================================= -# MINIMALE X11-INSTALLATION FÜR KIOSK -# ============================================================================= - -install_minimal_x11() { - log_header "Minimale X11-Installation für Kiosk" - - log_step "Installiere minimale X11-Komponenten..." - - if [[ "$PACKAGE_MANAGER" == "apt" ]]; then - apt-get update - apt-get install -y \ - xorg \ - xserver-xorg-core \ - xserver-xorg-input-all \ - xserver-xorg-video-all \ - xinit \ - xauth \ - xterm \ - openbox \ - unclutter \ - 2>/dev/null || true - - elif [[ "$PACKAGE_MANAGER" == "yum" ]]; then - yum install -y \ - xorg-x11-server-Xorg \ - xorg-x11-drv-* \ - xinit \ - xauth \ - xterm \ - openbox \ - unclutter \ - 2>/dev/null || true - - elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then - pacman -S --noconfirm \ - xorg-server \ - xorg-xinit \ - xorg-xauth \ - xterm \ - openbox \ - unclutter \ - 2>/dev/null || true - fi - - log_info "✅ Minimale X11-Installation abgeschlossen" -} - -# ============================================================================= -# KIOSK-BENUTZER KONFIGURATION -# ============================================================================= - -configure_kiosk_user() { - log_header "Kiosk-Benutzer Konfiguration" - - # Erstelle kiosk-Benutzer falls nicht vorhanden - if ! id "kiosk" &>/dev/null; then - log_step "Erstelle kiosk-Benutzer..." - useradd -m -s /bin/bash -G audio,video,input kiosk - # Setze einfaches Passwort (wird für Autologin nicht benötigt) - echo "kiosk:kiosk123" | chpasswd - log_info "✅ Kiosk-Benutzer erstellt" - else - log_info "ℹ️ Kiosk-Benutzer bereits vorhanden" - fi - - # Konfiguriere Kiosk-Benutzer-Umgebung - log_step "Konfiguriere Kiosk-Benutzer-Umgebung..." - - # Erstelle .xinitrc für Kiosk-Session - cat > /home/kiosk/.xinitrc << 'EOF' -#!/bin/bash - -# Deaktiviere Bildschirmschoner und Energiesparfunktionen -xset s off -xset s noblank -xset -dpms - -# Verstecke Mauszeiger bei Inaktivität -unclutter -idle 1 & - -# Starte Openbox Window Manager (minimal) -openbox & - -# Warte bis Backend verfügbar ist (mit Timeout) -BACKEND_URL="https://localhost" -TIMEOUT=300 -ELAPSED=0 - -while ! curl -k -s "$BACKEND_URL" >/dev/null 2>&1; do - if [ $ELAPSED -ge $TIMEOUT ]; then - echo "❌ Backend nach ${TIMEOUT}s nicht erreichbar - starte trotzdem Browser" - break - fi - echo "⏳ Warte auf Backend... (${ELAPSED}s/${TIMEOUT}s)" - sleep 5 - ELAPSED=$((ELAPSED + 5)) -done - -# Browser-Präferenzen für Stabilität -export MOZ_DISABLE_RDD_SANDBOX=1 -export MOZ_DISABLE_CONTENT_SANDBOX=1 - -# Starte Browser im Kiosk-Modus (Failover: Chromium -> Firefox -> Chrome) -if command -v chromium-browser >/dev/null; then - BROWSER="chromium-browser" - BROWSER_ARGS="--kiosk --no-sandbox --disable-dev-shm-usage --disable-gpu --disable-software-rasterizer --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-renderer-backgrounding --disable-features=TranslateUI --disable-ipc-flooding-protection --noerrdialogs --disable-infobars --disable-session-crashed-bubble --disable-component-update --check-for-update-interval=31536000" -elif command -v firefox >/dev/null; then - BROWSER="firefox" - BROWSER_ARGS="--kiosk" -elif command -v google-chrome >/dev/null; then - BROWSER="google-chrome" - BROWSER_ARGS="--kiosk --no-sandbox --disable-dev-shm-usage --disable-gpu" -else - echo "❌ Kein unterstützter Browser gefunden!" - exit 1 -fi - -echo "🚀 Starte $BROWSER im Kiosk-Modus..." -exec $BROWSER $BROWSER_ARGS "$BACKEND_URL" -EOF - - chmod +x /home/kiosk/.xinitrc - chown kiosk:kiosk /home/kiosk/.xinitrc - - # Konfiguriere Bash-Profile für automatisches X-Start - cat > /home/kiosk/.bash_profile << 'EOF' -# Automatisches X-Start für Kiosk-Modus -if [[ -z $DISPLAY && $(tty) == /dev/tty1 ]]; then - exec startx -fi -EOF - - chown kiosk:kiosk /home/kiosk/.bash_profile - - log_info "✅ Kiosk-Benutzer konfiguriert" -} - -# ============================================================================= -# AUTOLOGIN KONFIGURATION -# ============================================================================= - -configure_autologin() { - log_header "Autologin Konfiguration" - - log_step "Konfiguriere Getty für Autologin..." - - # Erstelle Getty Override für tty1 - mkdir -p /etc/systemd/system/getty@tty1.service.d/ - - cat > /etc/systemd/system/getty@tty1.service.d/override.conf << 'EOF' -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin kiosk --noclear %I $TERM -Type=idle -EOF - - # Stelle sicher, dass getty@tty1 aktiviert ist - systemctl enable getty@tty1.service - - log_info "✅ Autologin konfiguriert" -} - -# ============================================================================= -# SYSTEM-ABHÄNGIGKEITEN -# ============================================================================= - -install_system_dependencies() { - log_header "System-Abhängigkeiten Installation" - - log_step "Aktualisiere Paket-Listen..." - - if [[ "$PACKAGE_MANAGER" == "apt" ]]; then - apt-get update - - log_step "Installiere System-Abhängigkeiten..." - apt-get install -y \ - python3 \ - python3-pip \ - python3-venv \ - curl \ - wget \ - sudo \ - systemd \ - rsyslog \ - cron \ - logrotate \ - unzip \ - git \ - psutil \ - htop \ - netcat \ - jq - - log_step "Installiere Browser..." - # Installiere bevorzugten Browser (Chromium) - apt-get install -y chromium-browser 2>/dev/null || { - log_warn "Chromium nicht verfügbar, versuche Firefox..." - apt-get install -y firefox 2>/dev/null || { - log_warn "Firefox nicht verfügbar, versuche Chrome..." - # Chrome Repository hinzufügen falls verfügbar - wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - 2>/dev/null || true - echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list 2>/dev/null || true - apt-get update 2>/dev/null || true - apt-get install -y google-chrome-stable 2>/dev/null || log_error "Kein Browser installiert!" - } - } - - elif [[ "$PACKAGE_MANAGER" == "yum" ]]; then - yum update -y - yum install -y \ - python3 \ - python3-pip \ - curl \ - wget \ - sudo \ - systemd \ - rsyslog \ - cronie \ - logrotate \ - unzip \ - git \ - python3-psutil \ - htop \ - nc \ - jq \ - chromium \ - firefox - - elif [[ "$PACKAGE_MANAGER" == "pacman" ]]; then - pacman -Sy - pacman -S --noconfirm \ - python \ - python-pip \ - curl \ - wget \ - sudo \ - systemd \ - rsyslog \ - cronie \ - logrotate \ - unzip \ - git \ - python-psutil \ - htop \ - netcat \ - jq \ - chromium \ - firefox - fi - - log_info "✅ System-Abhängigkeiten installiert" -} - -install_python_dependencies() { - log_header "Python-Abhängigkeiten Installation" - - log_step "Installiere Python-Pakete für Error-Recovery..." - - # Upgrade pip - python3 -m pip install --upgrade pip - - # Installiere erforderliche Python-Pakete - python3 -m pip install \ - psutil \ - watchdog \ - requests \ - flask \ - sqlalchemy \ - APScheduler - - log_info "✅ Python-Abhängigkeiten installiert" -} - -configure_logging() { - log_header "Logging-Konfiguration" - - log_step "Erstelle Log-Verzeichnisse..." - - # Erstelle Log-Verzeichnisse mit korrekten Berechtigungen - mkdir -p /var/log/myp/{system_control,error_recovery,kiosk} - chmod 755 /var/log/myp - chmod 755 /var/log/myp/* - - log_step "Konfiguriere Logrotate..." - - # Konfiguriere Log-Rotation - cat > /etc/logrotate.d/myp << 'EOF' -/var/log/myp/*.log { - daily - rotate 30 - compress - delaycompress - missingok - notifempty - create 644 root root - postrotate - systemctl reload rsyslog 2>/dev/null || true - endscript -} - -/var/log/myp/*/*.log { - daily - rotate 30 - compress - delaycompress - missingok - notifempty - create 644 root root - postrotate - systemctl reload rsyslog 2>/dev/null || true - endscript -} -EOF - - log_step "Konfiguriere Rsyslog für MYP..." - - # Konfiguriere Rsyslog für MYP-spezifische Logs - cat > /etc/rsyslog.d/50-myp.conf << 'EOF' -# MYP System Logging - -# System Control Logs -:programname,isequal,"myp-system" /var/log/myp/system_control/system.log -:programname,isequal,"myp-kiosk" /var/log/myp/kiosk/kiosk.log - -# Error Recovery Logs -if $programname contains "error-recovery" then /var/log/myp/error_recovery/recovery.log - -# Stop weitere Verarbeitung für MYP-Messages -if $programname contains "myp-" then stop -EOF - - # Rsyslog neu starten - systemctl restart rsyslog - - log_info "✅ Logging konfiguriert" -} - -configure_sudo_permissions() { - log_header "Sudo-Berechtigungen Konfiguration" - - log_step "Konfiguriere Sudo-Rechte für System-Operationen..." - - # Erstelle sudoers-Datei für MYP-System-Operationen - cat > /etc/sudoers.d/myp-system << 'EOF' -# MYP System Control Permissions -# Erlaubt webapp-Benutzer System-Operationen für wartungsfreien Betrieb - -# System-Neustart und Shutdown -%sudo ALL=(ALL) NOPASSWD: /sbin/reboot, /sbin/shutdown, /bin/systemctl reboot, /bin/systemctl poweroff - -# Service-Management -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl start myp-*, /bin/systemctl stop myp-*, /bin/systemctl restart myp-*, /bin/systemctl reload myp-* -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl enable myp-*, /bin/systemctl disable myp-* -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl status myp-*, /bin/systemctl is-active myp-* - -# Kiosk-spezifische Services -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl restart getty@tty1.service -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl set-default multi-user.target, /bin/systemctl set-default graphical.target - -# Log-Management -%sudo ALL=(ALL) NOPASSWD: /bin/journalctl * - -# Netzwerk-Services (für Recovery) -%sudo ALL=(ALL) NOPASSWD: /bin/systemctl restart NetworkManager, /bin/systemctl restart networking - -# Cache und Temp-Bereinigung -%sudo ALL=(ALL) NOPASSWD: /bin/sync, /usr/bin/echo * > /proc/sys/vm/drop_caches - -# Kiosk-Benutzer Management -%sudo ALL=(ALL) NOPASSWD: /bin/su - kiosk, /bin/loginctl kill-user kiosk -EOF - - # Validiere sudoers-Datei - if ! visudo -c -f /etc/sudoers.d/myp-system; then - log_error "Sudoers-Konfiguration ungültig!" - rm -f /etc/sudoers.d/myp-system - return 1 - fi - - log_info "✅ Sudo-Berechtigungen konfiguriert" -} - -install_error_recovery_files() { - log_header "Error-Recovery-Dateien Installation" - - log_step "Kopiere Error-Recovery-Module..." - - # Prüfe ob Backend-Verzeichnis existiert - if [[ ! -d "/opt/myp-backend" ]] && [[ ! -d "/var/www/myp" ]] && [[ ! -d "$(pwd)" ]]; then - error_exit "MYP-Backend-Verzeichnis nicht gefunden!" - fi - - # Bestimme Backend-Pfad - BACKEND_PATH="" - if [[ -d "/opt/myp-backend" ]]; then - BACKEND_PATH="/opt/myp-backend" - elif [[ -d "/var/www/myp" ]]; then - BACKEND_PATH="/var/www/myp" - else - BACKEND_PATH="$(pwd)" - fi - - log_info "Backend-Pfad: $BACKEND_PATH" - - # Prüfe ob Error-Recovery-Dateien existieren - if [[ ! -f "$BACKEND_PATH/utils/error_recovery.py" ]]; then - log_warn "Error-Recovery-Module nicht gefunden in $BACKEND_PATH" - log_warn "Bitte stellen Sie sicher, dass das Update korrekt angewendet wurde" - return 1 - fi - - # Prüfe ob System-Control-Module existiert - if [[ ! -f "$BACKEND_PATH/utils/system_control.py" ]]; then - log_warn "System-Control-Module nicht gefunden in $BACKEND_PATH" - log_warn "Bitte stellen Sie sicher, dass das Update korrekt angewendet wurde" - return 1 - fi - - log_info "✅ Error-Recovery-Module gefunden und validiert" -} - -install_kiosk_service() { - log_header "Kiosk-Service Installation" - - log_step "Installiere optimierten Kiosk-Service..." - - # Der Kiosk-Service wurde bereits durch das Update installiert - # Wir müssen nur sicherstellen, dass er korrekt konfiguriert ist - - if [[ ! -f "/etc/systemd/system/myp-kiosk.service" ]]; then - log_warn "Kiosk-Service-Datei nicht gefunden!" - log_warn "Bitte führen Sie zuerst das Backend-Update durch" - return 1 - fi - - # Service aktivieren aber noch nicht starten - systemctl daemon-reload - systemctl enable myp-kiosk.service - - log_info "✅ Kiosk-Service installiert und aktiviert" -} - -configure_system_optimizations() { - log_header "System-Optimierungen" - - log_step "Konfiguriere Kernel-Parameter für Stabilität..." - - # Kernel-Parameter für bessere Stabilität - cat > /etc/sysctl.d/99-myp-stability.conf << 'EOF' -# MYP System Stability Configuration - -# Speicher-Management -vm.swappiness = 10 -vm.dirty_ratio = 15 -vm.dirty_background_ratio = 5 - -# Netzwerk-Stabilität -net.core.rmem_max = 16777216 -net.core.wmem_max = 16777216 -net.ipv4.tcp_rmem = 4096 87380 16777216 -net.ipv4.tcp_wmem = 4096 65536 16777216 - -# File-System-Stabilität -fs.file-max = 65536 -fs.inotify.max_user_watches = 524288 -EOF - - # Lade neue sysctl-Einstellungen - sysctl -p /etc/sysctl.d/99-myp-stability.conf - - log_step "Konfiguriere System-Limits..." - - # System-Limits für bessere Performance - cat > /etc/security/limits.d/99-myp.conf << 'EOF' -# MYP System Limits - -* soft nofile 65536 -* hard nofile 65536 -* soft nproc 32768 -* hard nproc 32768 - -kiosk soft nofile 8192 -kiosk hard nofile 8192 -kiosk soft nproc 4096 -kiosk hard nproc 4096 -EOF - - log_step "Deaktiviere unnötige Services..." - - # Deaktiviere Services die für Kiosk-Betrieb nicht benötigt werden - SERVICES_TO_DISABLE=( - "cups" - "cups-browsed" - "bluetooth" - "ModemManager" - "avahi-daemon" - "whoopsie" - "apport" - "speech-dispatcher" - "brltty" - "snapd" - "ubuntu-advantage" - ) - - for service in "${SERVICES_TO_DISABLE[@]}"; do - if systemctl is-enabled "$service" &>/dev/null; then - log_debug "Deaktiviere Service: $service" - systemctl disable "$service" 2>/dev/null || true - systemctl stop "$service" 2>/dev/null || true - fi - done - - log_step "Konfiguriere automatische Updates-Deaktivierung..." - - # Deaktiviere automatische Updates für Stabilität - if [[ -f "/etc/apt/apt.conf.d/20auto-upgrades" ]]; then - cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF' -APT::Periodic::Update-Package-Lists "0"; -APT::Periodic::Unattended-Upgrade "0"; -APT::Periodic::Download-Upgradeable-Packages "0"; -APT::Periodic::AutocleanInterval "0"; -EOF - fi - - # Deaktiviere unattended-upgrades - systemctl disable unattended-upgrades 2>/dev/null || true - systemctl stop unattended-upgrades 2>/dev/null || true - - log_info "✅ System-Optimierungen angewendet" -} - -validate_installation() { - log_header "Installation validieren" - - local errors=0 - - log_step "Prüfe Kiosk-Benutzer..." - if ! id "kiosk" &>/dev/null; then - log_error "❌ Kiosk-Benutzer nicht gefunden" - ((errors++)) - else - log_info "✅ Kiosk-Benutzer OK" - fi - - log_step "Prüfe Kiosk-Service..." - if ! systemctl is-enabled myp-kiosk.service &>/dev/null; then - log_error "❌ Kiosk-Service nicht aktiviert" - ((errors++)) - else - log_info "✅ Kiosk-Service OK" - fi - - log_step "Prüfe Browser-Installation..." - if ! command -v chromium-browser &>/dev/null && ! command -v firefox &>/dev/null && ! command -v google-chrome &>/dev/null; then - log_error "❌ Kein unterstützter Browser gefunden" - ((errors++)) - else - log_info "✅ Browser verfügbar" - fi - - log_step "Prüfe X11-Installation..." - if ! command -v X &>/dev/null && ! command -v Xorg &>/dev/null; then - log_error "❌ X11-Server nicht gefunden" - ((errors++)) - else - log_info "✅ X11-Server verfügbar" - fi - - log_step "Prüfe Autologin-Konfiguration..." - if [[ ! -f "/etc/systemd/system/getty@tty1.service.d/override.conf" ]]; then - log_error "❌ Autologin nicht konfiguriert" - ((errors++)) - else - log_info "✅ Autologin konfiguriert" - fi - - log_step "Prüfe Python-Module..." - if ! python3 -c "import psutil" &>/dev/null; then - log_error "❌ Python psutil-Modul fehlt" - ((errors++)) - else - log_info "✅ Python-Module verfügbar" - fi - - if [[ $errors -eq 0 ]]; then - log_info "✅ Alle Validierungen erfolgreich" - return 0 - else - log_error "❌ $errors Validierungsfehler gefunden" - return 1 - fi -} - -show_completion_summary() { - log_header "Installation Abgeschlossen" - - echo -e "${GREEN}" - echo "==================================================" - echo " 🎉 MYP FEHLERRESILIENZ INSTALLATION ERFOLG " - echo "==================================================" - echo -e "${NC}" - - echo "✅ Desktop-Environments bereinigt" - echo "✅ Minimale X11-Umgebung installiert" - echo "✅ Kiosk-Benutzer konfiguriert" - echo "✅ Autologin aktiviert" - echo "✅ Error-Recovery-System installiert" - echo "✅ System-Control-Manager konfiguriert" - echo "✅ Robuster Kiosk-Service installiert" - echo "✅ System-Optimierungen angewendet" - echo - echo -e "${YELLOW}📋 NÄCHSTE SCHRITTE:${NC}" - echo "1. System neu starten für vollständige Aktivierung:" - echo " ${CYAN}sudo reboot${NC}" - echo - echo "2. Nach dem Neustart startet automatisch der Kiosk-Modus" - echo - echo "3. Überwachen Sie das System über die Admin-Oberfläche:" - echo " ${CYAN}https:///admin${NC}" - echo - echo -e "${YELLOW}🔧 WARTUNG:${NC}" - echo "• Error-Recovery läuft automatisch im Hintergrund" - echo "• System-Control über Admin-Panel verfügbar" - echo "• Logs werden automatisch rotiert" - echo "• Kein manueller Wartungsaufwand erforderlich" - echo - echo -e "${YELLOW}🆘 NOTFALL-ZUGRIFF:${NC}" - echo "• SSH-Zugriff bleibt für Wartung verfügbar" - echo "• Kiosk-Deaktivierung über Admin-Panel" - echo "• System-Recovery über Tastatur: Strg+Alt+F2" - echo - echo -e "${RED}⚠️ WICHTIG:${NC}" - echo "Das System läuft jetzt im wartungsfreien Produktionsmodus!" - echo "Alle Änderungen sollten über die Admin-Oberfläche erfolgen." - echo -} - -# ============================================================================= -# MAIN EXECUTION -# ============================================================================= - -main() { - clear - - echo -e "${PURPLE}" - echo "==============================================================" - echo " MYP FEHLERRESILIENZ & WARTUNGSFREIER BETRIEB - UPDATE " - echo "==============================================================" - echo -e "${NC}" - echo - echo "Dieses Script installiert:" - echo "• Absolute Fehlerresilienz mit automatischer Wiederherstellung" - echo "• Wartungsfreien Produktionsbetrieb" - echo "• Optimierten Kiosk-Modus mit robuster Browser-Steuerung" - echo "• Vollautomatische System-Überwachung und -Reparatur" - echo "• Desktop-Environment-Bereinigung für maximale Stabilität" - echo - echo -e "${RED}⚠️ WARNUNG: Alle Desktop-Environments werden entfernt!${NC}" - echo -e "${RED} Das System wird zu einem reinen Kiosk-System!${NC}" - echo - read -p "Möchten Sie fortfahren? [y/N]: " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "Installation abgebrochen." - exit 0 - fi - - log_info "Starte MYP Fehlerresilienz-Installation..." - - # Grundlegende Systemprüfungen - check_root - check_os - - # Desktop-Environment vollständig bereinigen - cleanup_desktop_environments - - # Minimale X11-Umgebung für Kiosk installieren - install_minimal_x11 - - # System-Abhängigkeiten installieren - install_system_dependencies - install_python_dependencies - - # Kiosk-Benutzer und Autologin konfigurieren - configure_kiosk_user - configure_autologin - - # Logging und Berechtigungen konfigurieren - configure_logging - configure_sudo_permissions - - # Error-Recovery und Kiosk-Service installieren - install_error_recovery_files - install_kiosk_service - - # System-Optimierungen anwenden - configure_system_optimizations - - # Installation validieren - if validate_installation; then - show_completion_summary - - echo - read -p "System jetzt neu starten? [y/N]: " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - log_info "🔄 System wird neu gestartet..." - sleep 3 - reboot - else - log_info "🔄 Bitte starten Sie das System manuell neu: sudo reboot" - fi - else - log_error "❌ Installation nicht erfolgreich - bitte Fehler beheben" - exit 1 - fi -} - -# Script ausführen -main "$@" \ No newline at end of file diff --git a/backend/setup.sh b/backend/setup.sh deleted file mode 100755 index 4d8a1d5d6..000000000 --- a/backend/setup.sh +++ /dev/null @@ -1,6576 +0,0 @@ -#!/bin/bash - -# =================================================================== -# MYP Druckerverwaltung - VOLLAUTOMATISCHES SETUP-SKRIPT (OPTIMIERT) -# Intelligente Installation ohne Benutzerinteraktion -# Erkennt automatisch den Systemzustand und installiert entsprechend -# Optimiert für Debian/Linux (Raspberry Pi OS) - KEIN Windows-Support -# HTTPS auf Port 443 mit automatischer SSL-Zertifikat-Generierung -# Kiosk-Modus mit Chromium-Autostart ohne Desktop-Environment -# Version: 5.0.0 - Vollautomatische Installation -# =================================================================== - -set -euo pipefail - -# =========================== GLOBALE KONFIGURATION =========================== -readonly APP_NAME="MYP Druckerverwaltung" -readonly APP_VERSION="5.0.0" -readonly APP_DIR="/opt/myp" -readonly HTTP_SERVICE_NAME="myp-https" -readonly KIOSK_SERVICE_NAME="myp-kiosk" -readonly WATCHDOG_SERVICE_NAME="kiosk-watchdog" -readonly WATCHDOG_PYTHON_SERVICE_NAME="kiosk-watchdog-python" -readonly FIREWALL_SERVICE_NAME="myp-firewall" -readonly KIOSK_USER="kiosk" - -# =========================== INTELLIGENTE PFAD-ERKENNUNG =========================== -# Erkenne ob Skript im Git-Clone (backend/) oder Produktions-Verzeichnis läuft -detect_script_location() { - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local script_basename="$(basename "$script_dir")" - - if [[ "$script_basename" == "backend" ]]; then - # Skript läuft im Git-Clone backend/ Verzeichnis - readonly GIT_CLONE_MODE=true - readonly CURRENT_DIR="$script_dir" - readonly SOURCE_BACKEND_DIR="$script_dir" - readonly PROJECT_ROOT_DIR="$(dirname "$script_dir")" - - # Verwende echo statt log (da log-Funktionen noch nicht definiert sind) - echo "🔍 GIT-CLONE-MODUS ERKANNT" - echo " 📁 Skript-Verzeichnis: $CURRENT_DIR" - echo " 📁 Backend-Quelle: $SOURCE_BACKEND_DIR" - echo " 📁 Projekt-Root: $PROJECT_ROOT_DIR" - echo " 🎯 Ziel: $APP_DIR" - else - # Skript läuft bereits im Produktions-Verzeichnis - readonly GIT_CLONE_MODE=false - readonly CURRENT_DIR="$script_dir" - readonly SOURCE_BACKEND_DIR="$script_dir" - readonly PROJECT_ROOT_DIR="$script_dir" - - # Verwende echo statt log (da log-Funktionen noch nicht definiert sind) - echo "🏠 PRODUKTIONS-MODUS ERKANNT" - echo " 📁 Produktions-Verzeichnis: $CURRENT_DIR" - fi -} - -# Führe Pfad-Erkennung aus (early, bevor logging initialisiert wird) -detect_script_location - -# Automatische Installationsmodus-Erkennung -AUTO_INSTALL_MODE="" -FORCE_PRODUCTION=false -FORCE_DEVELOPMENT=false - -# =========================== DYNAMISCHE CREDENTIALS KONFIGURATION =========================== -# Zentrale Credentials-Verwaltung mit dynamischen Override-Möglichkeiten - -# Standard-Credentials (werden ggf. überschrieben) -MYP_SECRET_KEY="7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F" -MYP_MAIN_PASSWORD="744563017196A" -MYP_SSH_PASSWORD="raspberry" -MYP_ADMIN_EMAIL="admin@mercedes-benz.com" -MYP_TAPO_EMAIL="till.tomczak@mercedes-benz.com" -MYP_TAPO_PASSWORD="744563017196A" -MYP_ROUTER_USER="admin" -MYP_ROUTER_PASSWORD="vT6Vsd^p" -MYP_GITHUB_CLIENT_ID="7c5d8bef1a5519ec1fdc" -MYP_GITHUB_CLIENT_SECRET="5f1e586204358fbd53cf5fb7d418b3f06ccab8fd" - -# Funktion: Dynamische Credentials laden/ändern -load_dynamic_credentials() { - log "🔑 LADE DYNAMISCHE CREDENTIALS..." - - # Credentials aus Umgebungsvariablen überschreiben (falls gesetzt) - MYP_SECRET_KEY="${MYP_SECRET_KEY_OVERRIDE:-$MYP_SECRET_KEY}" - MYP_MAIN_PASSWORD="${MYP_MAIN_PASSWORD_OVERRIDE:-$MYP_MAIN_PASSWORD}" - MYP_SSH_PASSWORD="${MYP_SSH_PASSWORD_OVERRIDE:-$MYP_SSH_PASSWORD}" - MYP_ADMIN_EMAIL="${MYP_ADMIN_EMAIL_OVERRIDE:-$MYP_ADMIN_EMAIL}" - MYP_TAPO_EMAIL="${MYP_TAPO_EMAIL_OVERRIDE:-$MYP_TAPO_EMAIL}" - MYP_TAPO_PASSWORD="${MYP_TAPO_PASSWORD_OVERRIDE:-$MYP_TAPO_PASSWORD}" - MYP_ROUTER_USER="${MYP_ROUTER_USER_OVERRIDE:-$MYP_ROUTER_USER}" - MYP_ROUTER_PASSWORD="${MYP_ROUTER_PASSWORD_OVERRIDE:-$MYP_ROUTER_PASSWORD}" - MYP_GITHUB_CLIENT_ID="${MYP_GITHUB_CLIENT_ID_OVERRIDE:-$MYP_GITHUB_CLIENT_ID}" - MYP_GITHUB_CLIENT_SECRET="${MYP_GITHUB_CLIENT_SECRET_OVERRIDE:-$MYP_GITHUB_CLIENT_SECRET}" - - # Credentials aus externer Datei laden (Git-Clone-bewusst) - local credentials_file="$SOURCE_BACKEND_DIR/CREDENTIALS_OVERRIDE.env" - if [ -f "$credentials_file" ]; then - progress "Lade Credentials aus: $credentials_file" - source "$credentials_file" - info "✅ Externe Credentials-Datei geladen" - fi - - # Interaktive Credentials-Änderung (falls gewünscht) - if [ "${INTERACTIVE_CREDENTIALS:-0}" = "1" ]; then - interactive_credentials_setup - fi - - success "✅ Dynamische Credentials geladen" -} - -# Funktion: Interaktive Credentials-Einrichtung -interactive_credentials_setup() { - log "🔧 INTERAKTIVE CREDENTIALS-EINRICHTUNG" - - echo "" - echo "🔑 CREDENTIALS ANPASSEN (Enter = Standard beibehalten)" - echo "=====================================================" - - # Secret Key - echo -n "MYP Secret Key [${MYP_SECRET_KEY:0:8}...]: " - read input_secret_key - if [ -n "$input_secret_key" ]; then - MYP_SECRET_KEY="$input_secret_key" - fi - - # Main Password - echo -n "MYP Main Password [***]: " - read -s input_main_password - echo "" - if [ -n "$input_main_password" ]; then - MYP_MAIN_PASSWORD="$input_main_password" - fi - - # SSH Password - echo -n "SSH Password [***]: " - read -s input_ssh_password - echo "" - if [ -n "$input_ssh_password" ]; then - MYP_SSH_PASSWORD="$input_ssh_password" - fi - - # Admin Email - echo -n "Admin Email [$MYP_ADMIN_EMAIL]: " - read input_admin_email - if [ -n "$input_admin_email" ]; then - MYP_ADMIN_EMAIL="$input_admin_email" - fi - - # TAPO Email - echo -n "TAPO Email [$MYP_TAPO_EMAIL]: " - read input_tapo_email - if [ -n "$input_tapo_email" ]; then - MYP_TAPO_EMAIL="$input_tapo_email" - fi - - # TAPO Password - echo -n "TAPO Password [***]: " - read -s input_tapo_password - echo "" - if [ -n "$input_tapo_password" ]; then - MYP_TAPO_PASSWORD="$input_tapo_password" - fi - - # Router Credentials - echo -n "Router User [$MYP_ROUTER_USER]: " - read input_router_user - if [ -n "$input_router_user" ]; then - MYP_ROUTER_USER="$input_router_user" - fi - - echo -n "Router Password [***]: " - read -s input_router_password - echo "" - if [ -n "$input_router_password" ]; then - MYP_ROUTER_PASSWORD="$input_router_password" - fi - - # GitHub Credentials - echo -n "GitHub Client ID [${MYP_GITHUB_CLIENT_ID:0:8}...]: " - read input_github_id - if [ -n "$input_github_id" ]; then - MYP_GITHUB_CLIENT_ID="$input_github_id" - fi - - echo -n "GitHub Client Secret [***]: " - read -s input_github_secret - echo "" - if [ -n "$input_github_secret" ]; then - MYP_GITHUB_CLIENT_SECRET="$input_github_secret" - fi - - echo "" - info "✅ Interaktive Credentials-Einrichtung abgeschlossen" - - # Optional: Credentials in Override-Datei speichern - echo -n "Sollen die neuen Credentials gespeichert werden? (j/N): " - read save_credentials - if [[ "$save_credentials" =~ ^[jJ]$ ]]; then - save_credentials_override - fi -} - -# Funktion: Credentials in Override-Datei speichern -save_credentials_override() { - local override_file="$SOURCE_BACKEND_DIR/CREDENTIALS_OVERRIDE.env" - - progress "Speichere Credentials-Override in: $override_file" - cat > "$override_file" << EOF -# MYP Credentials Override -# Diese Datei überschreibt die Standard-Credentials -# Generiert: $(date '+%Y-%m-%d %H:%M:%S') - -export MYP_SECRET_KEY_OVERRIDE="$MYP_SECRET_KEY" -export MYP_MAIN_PASSWORD_OVERRIDE="$MYP_MAIN_PASSWORD" -export MYP_SSH_PASSWORD_OVERRIDE="$MYP_SSH_PASSWORD" -export MYP_ADMIN_EMAIL_OVERRIDE="$MYP_ADMIN_EMAIL" -export MYP_TAPO_EMAIL_OVERRIDE="$MYP_TAPO_EMAIL" -export MYP_TAPO_PASSWORD_OVERRIDE="$MYP_TAPO_PASSWORD" -export MYP_ROUTER_USER_OVERRIDE="$MYP_ROUTER_USER" -export MYP_ROUTER_PASSWORD_OVERRIDE="$MYP_ROUTER_PASSWORD" -export MYP_GITHUB_CLIENT_ID_OVERRIDE="$MYP_GITHUB_CLIENT_ID" -export MYP_GITHUB_CLIENT_SECRET_OVERRIDE="$MYP_GITHUB_CLIENT_SECRET" - -# Verwendung: -# source CREDENTIALS_OVERRIDE.env && sudo ./setup.sh -# oder -# MYP_SECRET_KEY_OVERRIDE="neuer_key" sudo ./setup.sh -EOF - - chmod 600 "$override_file" - success "✅ Credentials-Override gespeichert: $override_file" - info " Verwendung: source $override_file && sudo ./setup.sh" -} - -# Log-Dateien - verwende relatives logs-Verzeichnis -mkdir -p "$CURRENT_DIR/logs" 2>/dev/null || true -INSTALL_LOG="$CURRENT_DIR/logs/install.log" -ERROR_LOG="$CURRENT_DIR/logs/errors.log" -WARNING_LOG="$CURRENT_DIR/logs/warnings.log" -DEBUG_LOG="$CURRENT_DIR/logs/debug.log" -readonly HTTP_PORT="5000" -readonly HTTP_URL="http://localhost:${HTTP_PORT}" -readonly SYSTEMD_DIR="$CURRENT_DIR/systemd" -readonly SYSTEM_SYSTEMD_DIR="/etc/systemd/system" - -# Retry-Konfiguration -readonly MAX_RETRIES=3 -readonly RETRY_DELAY=5 - -# Farben für Ausgabe -readonly RED='\033[0;31m' -readonly GREEN='\033[0;32m' -readonly YELLOW='\033[1;33m' -readonly BLUE='\033[0;34m' -readonly PURPLE='\033[0;35m' -readonly CYAN='\033[0;36m' -readonly NC='\033[0m' - -# =========================== AUTOMATISCHE MODUS-ERKENNUNG =========================== -detect_installation_mode() { - log "=== AUTOMATISCHE INSTALLATIONSMODUS-ERKENNUNG ===" - - # Prüfe Kommandozeilen-Parameter - for arg in "$@"; do - case $arg in - --production|--prod|-p) - FORCE_PRODUCTION=true - log "🎯 Produktionsmodus durch Parameter erzwungen" - ;; - --development|--dev|-d) - FORCE_DEVELOPMENT=true - log "🔧 Entwicklungsmodus durch Parameter erzwungen" - ;; - --help|-h) - show_help - exit 0 - ;; - esac - done - - # Wenn explizit gesetzt, verwende das - if [ "$FORCE_PRODUCTION" = true ]; then - AUTO_INSTALL_MODE="production" - log "✅ Installationsmodus: PRODUKTION (erzwungen)" - return - elif [ "$FORCE_DEVELOPMENT" = true ]; then - AUTO_INSTALL_MODE="development" - log "✅ Installationsmodus: ENTWICKLUNG (erzwungen)" - return - fi - - # Automatische Erkennung basierend auf Systemzustand - local indicators_production=0 - local indicators_development=0 - - # Prüfe Hardware-Indikatoren - if grep -q "Raspberry Pi" /proc/cpuinfo 2>/dev/null; then - indicators_production=$((indicators_production + 2)) - log "🔍 Raspberry Pi Hardware erkannt (+2 Punkte für Produktion)" - fi - - # Prüfe RAM (weniger RAM = eher Produktion/Kiosk) - local ram_mb=$(free -m 2>/dev/null | awk '/^Mem:/{print $2}' 2>/dev/null || echo "0") - if [ "$ram_mb" -lt 2048 ] 2>/dev/null; then - indicators_production=$((indicators_production + 1)) - log "🔍 Wenig RAM ($ram_mb MB) erkannt (+1 Punkt für Produktion)" - else - indicators_development=$((indicators_development + 1)) - log "🔍 Viel RAM ($ram_mb MB) erkannt (+1 Punkt für Entwicklung)" - fi - - # Prüfe ob Desktop-Environment vorhanden ist - if command -v gnome-session >/dev/null 2>&1 || command -v kde-session >/dev/null 2>&1 || command -v xfce4-session >/dev/null 2>&1; then - indicators_development=$((indicators_development + 2)) - log "🔍 Desktop-Environment erkannt (+2 Punkte für Entwicklung)" - else - indicators_production=$((indicators_production + 1)) - log "🔍 Kein Desktop-Environment erkannt (+1 Punkt für Produktion)" - fi - - # Prüfe ob bereits Kiosk-User existiert - if id "$KIOSK_USER" >/dev/null 2>&1; then - indicators_production=$((indicators_production + 2)) - log "🔍 Kiosk-User bereits vorhanden (+2 Punkte für Produktion)" - fi - - # Prüfe ob bereits Services installiert sind - if systemctl list-unit-files | grep -q "$HTTP_SERVICE_NAME"; then - indicators_production=$((indicators_production + 1)) - log "🔍 MYP-Services bereits installiert (+1 Punkt für Produktion)" - fi - - # Prüfe SSH-Konfiguration (Remote-Zugang deutet auf Produktion hin) - if systemctl is-active ssh >/dev/null 2>&1; then - indicators_production=$((indicators_production + 1)) - log "🔍 SSH-Service aktiv (+1 Punkt für Produktion)" - fi - - # Prüfe ob Entwicklungstools vorhanden sind - if command -v git >/dev/null 2>&1 && command -v code >/dev/null 2>&1; then - indicators_development=$((indicators_development + 2)) - log "🔍 Entwicklungstools erkannt (+2 Punkte für Entwicklung)" - fi - - # Prüfe Hostname - local hostname=$(hostname 2>/dev/null || echo "") - if [[ "$hostname" == *"kiosk"* ]] || [[ "$hostname" == *"display"* ]] || [[ "$hostname" == *"terminal"* ]]; then - indicators_production=$((indicators_production + 2)) - log "🔍 Kiosk-Hostname erkannt: $hostname (+2 Punkte für Produktion)" - elif [[ "$hostname" == *"dev"* ]] || [[ "$hostname" == *"development"* ]]; then - indicators_development=$((indicators_development + 2)) - log "🔍 Entwicklungs-Hostname erkannt: $hostname (+2 Punkte für Entwicklung)" - fi - - # Entscheidung treffen - log "📊 Bewertung: Produktion=$indicators_production, Entwicklung=$indicators_development" - - if [ $indicators_production -gt $indicators_development ]; then - AUTO_INSTALL_MODE="production" - log "✅ Automatisch erkannt: PRODUKTIONS-INSTALLATION" - log " → Vollständige Kiosk-Installation mit Remote-Zugang" - elif [ $indicators_development -gt $indicators_production ]; then - AUTO_INSTALL_MODE="development" - log "✅ Automatisch erkannt: ENTWICKLUNGS-INSTALLATION" - log " → Abhängigkeiten und System für manuelles Testen" - else - # Bei Gleichstand: Default zu Entwicklung (sicherer) - AUTO_INSTALL_MODE="development" - log "⚖️ Unentschieden - Standard: ENTWICKLUNGS-INSTALLATION" - log " → Verwenden Sie --production für Kiosk-Installation" - fi -} - -show_help() { - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} $APP_NAME - Automatisches Setup-Skript v$APP_VERSION${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}VERWENDUNG:${NC}" - echo -e " sudo $0 [OPTIONEN]" - echo "" - echo -e "${YELLOW}OPTIONEN:${NC}" - echo -e " ${GREEN}--production, --prod, -p${NC} Erzwinge Produktions-Installation" - echo -e " → Vollständige Kiosk-Installation" - echo -e " → Remote-Zugang (RDP/SSH)" - echo -e " → Automatischer Kiosk-Start" - echo "" - echo -e " ${GREEN}--development, --dev, -d${NC} Erzwinge Entwicklungs-Installation" - echo -e " → Nur Abhängigkeiten und Basis-System" - echo -e " → Für manuelle Tests und Entwicklung" - echo "" - echo -e " ${GREEN}--help, -h${NC} Zeige diese Hilfe" - echo "" - echo -e "${YELLOW}AUTOMATISCHE ERKENNUNG:${NC}" - echo -e " Ohne Parameter erkennt das Skript automatisch den besten Modus:" - echo -e " • Raspberry Pi Hardware → Produktion" - echo -e " • Wenig RAM (< 2GB) → Produktion" - echo -e " • Kein Desktop-Environment → Produktion" - echo -e " • Entwicklungstools vorhanden → Entwicklung" - echo -e " • Viel RAM (≥ 2GB) → Entwicklung" - echo "" - echo -e "${YELLOW}BEISPIELE:${NC}" - echo -e " ${CYAN}sudo $0${NC} # Automatische Erkennung" - echo -e " ${CYAN}sudo $0 --production${NC} # Erzwinge Kiosk-Installation" - echo -e " ${CYAN}sudo $0 --development${NC} # Erzwinge Entwicklungs-Setup" - echo "" - echo -e "${CYAN}=================================================================${NC}" -} - -# =========================== UMFASSENDE CREDENTIALS VALIDIERUNG =========================== -validate_credentials_comprehensive() { - log "=== VALIDIERE CREDENTIALS KONFIGURATION ===" - - local validation_errors=0 - - # Prüfe ob alle wichtigen Credentials gesetzt sind - if [ -z "$MYP_SECRET_KEY" ] || [ ${#MYP_SECRET_KEY} -lt 32 ]; then - error "MYP_SECRET_KEY ist nicht gesetzt oder zu kurz" - ((validation_errors++)) - fi - - if [ -z "$MYP_MAIN_PASSWORD" ] || [ ${#MYP_MAIN_PASSWORD} -lt 8 ]; then - error "MYP_MAIN_PASSWORD ist nicht gesetzt oder zu kurz" - ((validation_errors++)) - fi - - if [ -z "$MYP_SSH_PASSWORD" ] || [ ${#MYP_SSH_PASSWORD} -lt 4 ]; then - error "MYP_SSH_PASSWORD ist nicht gesetzt oder zu kurz" - ((validation_errors++)) - fi - - if [ -z "$MYP_ADMIN_EMAIL" ] || [[ ! "$MYP_ADMIN_EMAIL" =~ @.*\. ]]; then - error "MYP_ADMIN_EMAIL ist nicht gesetzt oder ungültig" - ((validation_errors++)) - fi - - if [ -z "$MYP_TAPO_EMAIL" ] || [[ ! "$MYP_TAPO_EMAIL" =~ @.*\. ]]; then - error "MYP_TAPO_EMAIL ist nicht gesetzt oder ungültig" - ((validation_errors++)) - fi - - if [ -z "$MYP_GITHUB_CLIENT_ID" ] || [ ${#MYP_GITHUB_CLIENT_ID} -lt 16 ]; then - error "MYP_GITHUB_CLIENT_ID ist nicht gesetzt oder zu kurz" - ((validation_errors++)) - fi - - if [ -z "$MYP_GITHUB_CLIENT_SECRET" ] || [ ${#MYP_GITHUB_CLIENT_SECRET} -lt 32 ]; then - error "MYP_GITHUB_CLIENT_SECRET ist nicht gesetzt oder zu kurz" - ((validation_errors++)) - fi - - if [ $validation_errors -eq 0 ]; then - success "✅ Alle Credentials korrekt konfiguriert" - log " 🔑 SECRET_KEY: ${MYP_SECRET_KEY:0:8}... (${#MYP_SECRET_KEY} Zeichen)" - log " 🔒 MAIN_PASSWORD: ${MYP_MAIN_PASSWORD:0:4}... (${#MYP_MAIN_PASSWORD} Zeichen)" - log " 📧 ADMIN_EMAIL: $MYP_ADMIN_EMAIL" - log " 📧 TAPO_EMAIL: $MYP_TAPO_EMAIL" - log " 🐙 GITHUB_CLIENT_ID: ${MYP_GITHUB_CLIENT_ID:0:8}..." - else - error "❌ $validation_errors Credentials-Fehler gefunden - Installation abgebrochen" - fi -} - -# =========================== LOG-DATEIEN INITIALISIERUNG =========================== -# Log-Dateien - verwende relatives logs-Verzeichnis (Git-Clone-bewusst) -if [ -z "$INSTALL_LOG" ]; then - mkdir -p "$SOURCE_BACKEND_DIR/logs" 2>/dev/null || true - INSTALL_LOG="$SOURCE_BACKEND_DIR/logs/install.log" - ERROR_LOG="$SOURCE_BACKEND_DIR/logs/errors.log" - WARNING_LOG="$SOURCE_BACKEND_DIR/logs/warnings.log" - DEBUG_LOG="$SOURCE_BACKEND_DIR/logs/debug.log" -fi - -# =========================== VERBESSERTE LOGGING-FUNKTIONEN =========================== -# Globale Variablen für Fehler-Tracking -ERROR_COUNT=0 -WARNING_COUNT=0 - -# Log-Dateien initialisieren -init_logging() { - # Sichere Log-Verzeichnis-Erstellung (Git-Clone-bewusst) - if ! mkdir -p "$SOURCE_BACKEND_DIR/logs" 2>/dev/null; then - echo "FEHLER: Kann logs-Verzeichnis nicht erstellen - verwende /tmp" >&2 - INSTALL_LOG="/tmp/myp-install.log" - ERROR_LOG="/tmp/myp-install-errors.log" - WARNING_LOG="/tmp/myp-install-warnings.log" - DEBUG_LOG="/tmp/myp-install-debug.log" - fi - - # Überschreibe bestehende Log-Dateien - { - echo "=================================================================" - echo "MYP Installation Log - $(date '+%Y-%m-%d %H:%M:%S')" - echo "Script Version: $APP_VERSION" - echo "System: $(timeout 5 uname -a 2>/dev/null || echo 'System-Info nicht verfügbar')" - echo "Git-Clone-Modus: $GIT_CLONE_MODE" - echo "Backend-Quelle: $SOURCE_BACKEND_DIR" - echo "Arbeitsverzeichnis: $CURRENT_DIR" - echo "Ziel-Verzeichnis: $APP_DIR" - echo "Log-Verzeichnis: $(dirname "$INSTALL_LOG")" - echo "=================================================================" - echo "" - } > "$INSTALL_LOG" 2>/dev/null || { - echo "KRITISCH: Kann Haupt-Log nicht schreiben!" >&2 - exit 1 - } - - { - echo "=================================================================" - echo "MYP Installation FEHLER Log - $(date '+%Y-%m-%d %H:%M:%S')" - echo "=================================================================" - echo "" - } > "$ERROR_LOG" - - { - echo "=================================================================" - echo "MYP Installation WARNUNGEN Log - $(date '+%Y-%m-%d %H:%M:%S')" - echo "=================================================================" - echo "" - } > "$WARNING_LOG" - - { - echo "=================================================================" - echo "MYP Installation DEBUG Log - $(date '+%Y-%m-%d %H:%M:%S')" - echo "=================================================================" - echo "" - } > "$DEBUG_LOG" -} - -log() { - local message="[$(date '+%Y-%m-%d %H:%M:%S')] $1" - echo -e "${GREEN}${message}${NC}" | tee -a "$INSTALL_LOG" -} - -error() { - local timestamp="$(date '+%Y-%m-%d %H:%M:%S')" - local caller="${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}" - local message="[FEHLER] $1" - - # Erhöhe Fehler-Zähler - ((ERROR_COUNT++)) - - # Ausgabe auf Konsole - echo -e "${RED}${message}${NC}" | tee -a "$INSTALL_LOG" - - # Detaillierte Fehler-Information in Fehler-Log - { - echo "[$timestamp] FEHLER #$ERROR_COUNT" - echo "Quelle: $caller" - echo "Nachricht: $1" - echo "Arbeitsverzeichnis: $(pwd)" - echo "Benutzer: $(whoami)" - echo "---" - echo "" - } >> "$ERROR_LOG" - - # Debug-Informationen sammeln - { - echo "[$timestamp] FEHLER AUFGETRETEN - Debug-Info:" - echo "Caller: $caller" - echo "PWD: $(pwd)" - echo "User: $(whoami)" - echo "Disk Space: $(df -h / | tail -1)" - echo "Memory: $(free -m | grep '^Mem:' | awk '{print $3"/"$2" MB"}')" - echo "Load Average: $(uptime | awk -F'load average:' '{print $2}')" - echo "Recent commands from history:" - history | tail -5 2>/dev/null || echo "History nicht verfügbar" - echo "===============================================" - echo "" - } >> "$DEBUG_LOG" - - exit 1 -} - -warning() { - local timestamp="$(date '+%Y-%m-%d %H:%M:%S')" - local caller="${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}" - local message="[WARNUNG] $1" - - # Erhöhe Warnungs-Zähler - ((WARNING_COUNT++)) - - # Ausgabe auf Konsole - echo -e "${YELLOW}${message}${NC}" | tee -a "$INSTALL_LOG" - - # Detaillierte Warnungs-Information in Warnungs-Log - { - echo "[$timestamp] WARNUNG #$WARNING_COUNT" - echo "Quelle: $caller" - echo "Nachricht: $1" - echo "---" - echo "" - } >> "$WARNING_LOG" -} - -info() { - echo -e "${BLUE}[INFO] $1${NC}" | tee -a "$INSTALL_LOG" -} - -progress() { - echo -e "${PURPLE}[FORTSCHRITT] $1${NC}" | tee -a "$INSTALL_LOG" -} - -success() { - echo -e "${CYAN}[ERFOLG] $1${NC}" | tee -a "$INSTALL_LOG" -} - -debug() { - local timestamp="$(date '+%Y-%m-%d %H:%M:%S')" - local caller="${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]}" - - # Debug sowohl in normales Log als auch Debug-Log - echo -e "${BLUE}[DEBUG] $1${NC}" >> "$INSTALL_LOG" - - { - echo "[$timestamp] DEBUG von $caller" - echo "$1" - echo "---" - echo "" - } >> "$DEBUG_LOG" -} - -# Fehler-Zusammenfassung anzeigen -show_error_summary() { - echo "" - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} INSTALLATION ABGESCHLOSSEN - FEHLER-ZUSAMMENFASSUNG${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - - echo -e "${BLUE}📊 Statistiken:${NC}" - echo -e " ${RED}❌ Fehler: $ERROR_COUNT${NC}" - echo -e " ${YELLOW}⚠️ Warnungen: $WARNING_COUNT${NC}" - echo "" - - echo -e "${BLUE}📁 Log-Dateien:${NC}" - echo -e " 📄 Vollständiges Log: $INSTALL_LOG" - echo -e " 🚨 Fehler-Log: $ERROR_LOG" - echo -e " ⚠️ Warnungs-Log: $WARNING_LOG" - echo -e " 🔍 Debug-Log: $DEBUG_LOG" - echo "" - - if [ $ERROR_COUNT -gt 0 ]; then - echo -e "${RED}⚠️ Es sind $ERROR_COUNT Fehler aufgetreten!${NC}" - echo -e "${RED} Bitte prüfen Sie: $ERROR_LOG${NC}" - echo "" - - # Zeige die letzten 3 Fehler an - if [ -f "$ERROR_LOG" ] && [ -s "$ERROR_LOG" ]; then - echo -e "${RED}🔍 Letzte Fehler:${NC}" - tail -n 20 "$ERROR_LOG" | head -n 15 - echo "" - fi - fi - - if [ $WARNING_COUNT -gt 0 ]; then - echo -e "${YELLOW}⚠️ Es sind $WARNING_COUNT Warnungen aufgetreten${NC}" - echo -e "${YELLOW} Bitte prüfen Sie: $WARNING_LOG${NC}" - echo "" - fi - - if [ $ERROR_COUNT -eq 0 ] && [ $WARNING_COUNT -eq 0 ]; then - echo -e "${GREEN}✅ Installation ohne Fehler oder Warnungen abgeschlossen!${NC}" - elif [ $ERROR_COUNT -eq 0 ]; then - echo -e "${GREEN}✅ Installation erfolgreich mit $WARNING_COUNT Warnungen${NC}" - fi - - echo -e "${CYAN}=================================================================${NC}" - - # Erstelle automatische Log-Zusammenfassung - create_log_summary -} - -# Automatische Log-Zusammenfassung erstellen -create_log_summary() { - local summary_file="$CURRENT_DIR/logs/install-summary.txt" - - { - echo "=================================================================" - echo "MYP INSTALLATION ZUSAMMENFASSUNG" - echo "Erstellt: $(date '+%Y-%m-%d %H:%M:%S')" - echo "=================================================================" - echo "" - echo "STATISTIKEN:" - echo "- Fehler: $ERROR_COUNT" - echo "- Warnungen: $WARNING_COUNT" - echo "- Script Version: $APP_VERSION" - echo "- System: $(uname -a 2>/dev/null || echo 'Unbekannt')" - echo "- Hostname: $(hostname 2>/dev/null || echo 'Unbekannt')" - echo "- User: $(whoami 2>/dev/null || echo 'Unbekannt')" - echo "" - echo "SYSTEM-INFORMATIONEN:" - echo "- Festplattenspeicher: $(df -h / | tail -1 2>/dev/null || echo 'Nicht verfügbar')" - echo "- Arbeitsspeicher: $(free -m | grep '^Mem:' | awk '{print $3"/"$2" MB"}' 2>/dev/null || echo 'Nicht verfügbar')" - echo "- Python Version: $(python3 --version 2>&1 || echo 'Nicht installiert')" - echo "- Node.js Version: $(node --version 2>&1 || echo 'Nicht installiert')" - echo "" - echo "LOG-DATEIEN:" - echo "- Vollständiges Log: $INSTALL_LOG" - echo "- Fehler-Log: $ERROR_LOG" - echo "- Warnungs-Log: $WARNING_LOG" - echo "- Debug-Log: $DEBUG_LOG" - echo "" - - if [ $ERROR_COUNT -gt 0 ] && [ -f "$ERROR_LOG" ] && [ -s "$ERROR_LOG" ]; then - echo "FEHLER-ÜBERSICHT:" - echo "=================" - tail -n 50 "$ERROR_LOG" - echo "" - fi - - if [ $WARNING_COUNT -gt 0 ] && [ -f "$WARNING_LOG" ] && [ -s "$WARNING_LOG" ]; then - echo "WARNUNGS-ÜBERSICHT:" - echo "===================" - tail -n 30 "$WARNING_LOG" - echo "" - fi - - echo "INSTALLATION ABGESCHLOSSEN: $(date '+%Y-%m-%d %H:%M:%S')" - echo "=================================================================" - - } > "$summary_file" - - # Berechtigung für Zusammenfassungs-Datei setzen - chmod 644 "$summary_file" 2>/dev/null || true - - debug "Log-Zusammenfassung erstellt: $summary_file" -} - -# =========================== RETRY-MECHANISMEN =========================== -retry_command() { - local cmd="$1" - local description="$2" - local attempts=0 - - while [ $attempts -lt $MAX_RETRIES ]; do - if eval "$cmd"; then - return 0 - fi - - attempts=$((attempts + 1)) - if [ $attempts -lt $MAX_RETRIES ]; then - warning "$description fehlgeschlagen (Versuch $attempts/$MAX_RETRIES) - wiederhole in ${RETRY_DELAY}s..." - - # Debug-Information für jeden fehlgeschlagenen Versuch - debug "Retry-Versuch für '$description': $attempts/$MAX_RETRIES" - debug "Fehlgeschlagener Befehl: $cmd" - debug "Aktuelles Arbeitsverzeichnis: $(pwd)" - debug "Verfügbarer Speicher: $(free -m | grep '^Mem:' | awk '{print $3"/"$2" MB"}' 2>/dev/null || echo 'Unbekannt')" - debug "Exit-Code des letzten Befehls: $?" - - sleep $RETRY_DELAY - fi - done - - # Detaillierte Fehler-Information vor dem Beenden - debug "CRITICAL: Retry-Mechanismus erschöpft für '$description'" - debug "Letzter Befehl: $cmd" - debug "Versuche: $MAX_RETRIES" - debug "System-Status zum Zeitpunkt des kritischen Fehlers:" - debug " - Disk Usage: $(df -h / | tail -1 2>/dev/null || echo 'Nicht verfügbar')" - debug " - Memory Usage: $(free -m 2>/dev/null || echo 'Nicht verfügbar')" - debug " - Load Average: $(uptime 2>/dev/null | awk -F'load average:' '{print $2}' || echo 'Nicht verfügbar')" - debug " - Network Status: $(ip addr show 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' || echo 'Nicht verfügbar')" - debug " - APT Status: $(ps aux | grep -i apt | grep -v grep || echo 'Keine APT-Prozesse')" - debug " - Python Status: $(python3 --version 2>&1 || echo 'Python nicht verfügbar')" - - error "$description nach $MAX_RETRIES Versuchen fehlgeschlagen!" -} - -# APT-Pakete mit Retry installieren -apt_install_retry() { - local packages="$*" - local cmd="DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $packages" - - progress "Installiere Pakete: $packages" - retry_command "$cmd" "APT Installation für: $packages" -} - -# =========================== ERWEITERTE SYSTEM-VALIDIERUNG =========================== -check_root() { - if [ "$EUID" -ne 0 ]; then - error "Dieses Skript muss als Root ausgeführt werden: sudo $0" - fi - export PATH="/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/bin:$PATH" - log "✅ Root-Berechtigung bestätigt" -} - -check_system_resources() { - log "=== SYSTEM-RESSOURCEN PRÜFUNG ===" - - # RAM prüfen (robuster) - progress "Prüfe RAM..." - local ram_mb="" - - # Verschiedene Methoden zur RAM-Ermittlung - if command -v free >/dev/null 2>&1; then - ram_mb=$(free -m 2>/dev/null | awk '/^Mem:/{print $2}' 2>/dev/null || echo "") - fi - - # Fallback über /proc/meminfo - if [ -z "$ram_mb" ] && [ -f "/proc/meminfo" ]; then - ram_mb=$(grep '^MemTotal:' /proc/meminfo 2>/dev/null | awk '{print int($2/1024)}' 2>/dev/null || echo "") - fi - - if [ -n "$ram_mb" ] && [ "$ram_mb" -gt 0 ] 2>/dev/null; then - progress "Verfügbarer RAM: ${ram_mb}MB" - - if [ "$ram_mb" -lt 512 ] 2>/dev/null; then - warning "⚠️ Wenig RAM verfügbar (${ram_mb}MB) - Installation könnte langsam sein" - else - success "✅ Ausreichend RAM verfügbar (${ram_mb}MB)" - fi - else - warning "⚠️ RAM-Größe konnte nicht ermittelt werden" - debug "RAM-Ermittlung fehlgeschlagen: free-Output: $(free -m 2>&1 || echo 'Befehl nicht verfügbar')" - fi - - # Festplattenplatz prüfen (robuster ohne bc) - progress "Prüfe Festplattenplatz..." - local disk_free_gb="" - local disk_free_mb="" - - if command -v df >/dev/null 2>&1; then - # Hole Festplattenplatz in MB - disk_free_mb=$(df / 2>/dev/null | awk 'NR==2{print int($4/1024)}' 2>/dev/null || echo "") - - if [ -n "$disk_free_mb" ] && [ "$disk_free_mb" -gt 0 ] 2>/dev/null; then - # Berechne GB ohne bc (einfache Division) - disk_free_gb=$(awk -v mb="$disk_free_mb" 'BEGIN{printf "%.1f", mb/1024}' 2>/dev/null || echo "$((disk_free_mb/1024))") - - progress "Verfügbarer Festplattenplatz: ${disk_free_gb}GB (${disk_free_mb}MB)" - - # Prüfe ob mindestens 2GB verfügbar (2048 MB) - if [ "$disk_free_mb" -lt 2048 ] 2>/dev/null; then - warning "⚠️ Wenig Festplattenplatz verfügbar (${disk_free_gb}GB)" - else - success "✅ Ausreichend Festplattenplatz verfügbar (${disk_free_gb}GB)" - fi - else - warning "⚠️ Festplattenplatz konnte nicht ermittelt werden" - debug "Disk-Ermittlung fehlgeschlagen: df-Output: $(df / 2>&1 || echo 'Befehl nicht verfügbar')" - fi - else - warning "⚠️ df-Befehl nicht verfügbar - kann Festplattenplatz nicht prüfen" - fi - - # CPU prüfen (robuster) - progress "Prüfe CPU..." - local cpu_count="" - local cpu_model="" - - # CPU-Anzahl ermitteln - if command -v nproc >/dev/null 2>&1; then - cpu_count=$(nproc 2>/dev/null || echo "") - fi - - if [ -z "$cpu_count" ] && [ -f "/proc/cpuinfo" ]; then - cpu_count=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null || echo "") - fi - - # CPU-Modell ermitteln - if [ -f "/proc/cpuinfo" ]; then - cpu_model=$(grep "model name" /proc/cpuinfo 2>/dev/null | head -1 | cut -d: -f2 2>/dev/null | sed 's/^[[:space:]]*//' 2>/dev/null || echo "Unbekannt") - fi - - if [ -n "$cpu_count" ] && [ "$cpu_count" -gt 0 ] 2>/dev/null; then - progress "CPU: $cpu_count Kern(e) - $cpu_model" - success "✅ CPU-Information erfolgreich ermittelt" - else - progress "CPU: Unbekannte Anzahl Kerne - $cpu_model" - warning "⚠️ CPU-Kern-Anzahl konnte nicht ermittelt werden" - debug "CPU-Ermittlung fehlgeschlagen: nproc-Output: $(nproc 2>&1 || echo 'Befehl nicht verfügbar')" - fi - - log "✅ System-Ressourcen-Prüfung abgeschlossen" -} - -check_debian_system() { - progress "Prüfe Debian/Raspbian-System..." - - # Robuste Debian-Erkennung - local is_debian=false - local debian_version="Unbekannt" - - # Verschiedene Methoden zur Debian-Erkennung - if [ -f /etc/debian_version ]; then - debian_version=$(cat /etc/debian_version 2>/dev/null | head -1 | tr -d '\n\r' || echo "Unbekannt") - is_debian=true - debug "Debian erkannt über /etc/debian_version: $debian_version" - fi - - # Fallback über os-release - if [ "$is_debian" = false ] && [ -f /etc/os-release ]; then - local os_id=$(grep '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "") - if [[ "$os_id" =~ ^(debian|raspbian|ubuntu)$ ]]; then - is_debian=true - local os_version=$(grep '^VERSION=' /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "Unbekannt") - debian_version="$os_id $os_version" - debug "Debian-basiertes System erkannt über os-release: $debian_version" - fi - fi - - # Fallback über lsb_release - if [ "$is_debian" = false ] && command -v lsb_release >/dev/null 2>&1; then - local lsb_id=$(lsb_release -si 2>/dev/null | tr '[:upper:]' '[:lower:]' || echo "") - if [[ "$lsb_id" =~ ^(debian|raspbian|ubuntu)$ ]]; then - is_debian=true - debian_version="$lsb_id $(lsb_release -sr 2>/dev/null || echo 'Unbekannt')" - debug "Debian-basiertes System erkannt über lsb_release: $debian_version" - fi - fi - - if [ "$is_debian" = false ]; then - warning "⚠️ System ist möglicherweise nicht Debian/Raspbian-basiert!" - warning "⚠️ Installation wird fortgesetzt, könnte aber fehlschlagen" - debug "System-Erkennung fehlgeschlagen. Verfügbare Info:" - debug " - /etc/debian_version: $([ -f /etc/debian_version ] && echo 'vorhanden' || echo 'nicht vorhanden')" - debug " - /etc/os-release: $([ -f /etc/os-release ] && grep '^ID=' /etc/os-release 2>/dev/null || echo 'nicht verfügbar')" - debug " - lsb_release: $(command -v lsb_release >/dev/null 2>&1 && lsb_release -si 2>/dev/null || echo 'nicht verfügbar')" - else - log "✅ Debian/Raspbian-basiertes System erkannt (Version: $debian_version)" - fi - - # Prüfe auf Raspberry Pi (robuster) - progress "Prüfe Raspberry Pi Hardware..." - local is_raspberry_pi=false - local pi_model="Unbekannt" - - # Methode 1: Device Tree Model - if [ -f /proc/device-tree/model ]; then - pi_model=$(cat /proc/device-tree/model 2>/dev/null | tr -d '\0\n\r' | head -c 100 || echo "") - if [[ "$pi_model" =~ [Rr]aspberry.*[Pp]i ]]; then - is_raspberry_pi=true - debug "Raspberry Pi erkannt über device-tree: $pi_model" - fi - fi - - # Methode 2: CPU Info - if [ "$is_raspberry_pi" = false ] && [ -f /proc/cpuinfo ]; then - local cpu_hardware=$(grep '^Hardware' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^[[:space:]]*//' | head -1 || echo "") - local cpu_model=$(grep '^Model' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^[[:space:]]*//' | head -1 || echo "") - - if [[ "$cpu_hardware" =~ [Bb][Cc][Mm] ]] || [[ "$cpu_model" =~ [Rr]aspberry.*[Pp]i ]]; then - is_raspberry_pi=true - pi_model="$cpu_model ($cpu_hardware)" - debug "Raspberry Pi erkannt über cpuinfo: $pi_model" - fi - fi - - if [ "$is_raspberry_pi" = true ]; then - info "🍓 Raspberry Pi erkannt: $pi_model" - progress "Aktiviere Raspberry Pi spezifische Optimierungen..." - export RASPBERRY_PI_DETECTED=1 - debug "Raspberry Pi Optimierungen aktiviert" - else - info "💻 Standard-PC/Server System (kein Raspberry Pi)" - debug "Kein Raspberry Pi erkannt. Hardware-Info:" - debug " - Device Tree: $([ -f /proc/device-tree/model ] && cat /proc/device-tree/model 2>/dev/null | tr -d '\0' || echo 'nicht verfügbar')" - debug " - CPU Hardware: $(grep '^Hardware' /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^[[:space:]]*//' || echo 'nicht verfügbar')" - fi - - # System-Architektur prüfen (robuster) - progress "Prüfe System-Architektur..." - local arch="" - - if command -v uname >/dev/null 2>&1; then - arch=$(uname -m 2>/dev/null || echo "Unbekannt") - info "📐 System-Architektur: $arch" - - # Architektur-spezifische Hinweise - case "$arch" in - "aarch64"|"arm64") - info " → 64-Bit ARM Architektur erkannt" - ;; - "armv7l"|"armv6l") - info " → 32-Bit ARM Architektur erkannt" - ;; - "x86_64"|"amd64") - info " → 64-Bit x86 Architektur erkannt" - ;; - "i386"|"i686") - info " → 32-Bit x86 Architektur erkannt" - ;; - *) - warning "⚠️ Unbekannte Architektur: $arch" - ;; - esac - else - warning "⚠️ uname-Befehl nicht verfügbar - kann Architektur nicht ermitteln" - fi - - # Kernel-Version prüfen (robuster) - progress "Prüfe Kernel-Version..." - local kernel="" - - if command -v uname >/dev/null 2>&1; then - kernel=$(uname -r 2>/dev/null || echo "Unbekannt") - info "🐧 Kernel-Version: $kernel" - debug "Vollständige Kernel-Info: $(uname -a 2>/dev/null || echo 'Nicht verfügbar')" - else - warning "⚠️ Kernel-Version konnte nicht ermittelt werden" - fi - - log "✅ System-Analyse abgeschlossen" -} - -check_internet_connection() { - progress "Prüfe Internetverbindung (erweiterte Methoden)..." - - local connection_ok=false - local test_method="" - local debug_info="" - - # Methode 1: DNS-Auflösung (robuster) - progress "Teste DNS-Auflösung..." - local dns_hosts=("8.8.8.8" "1.1.1.1" "google.com" "cloudflare.com") - - for host in "${dns_hosts[@]}"; do - debug_info="${debug_info}Teste DNS für $host: " - - # Teste nslookup - if command -v nslookup >/dev/null 2>&1; then - if timeout 10 nslookup "$host" >/dev/null 2>&1; then - connection_ok=true - test_method="DNS-Auflösung (nslookup: $host)" - debug_info="${debug_info}Erfolg mit nslookup. " - break - fi - debug_info="${debug_info}nslookup fehlgeschlagen. " - fi - - # Teste getent hosts - if [ "$connection_ok" = false ] && command -v getent >/dev/null 2>&1; then - if timeout 8 getent hosts "$host" >/dev/null 2>&1; then - connection_ok=true - test_method="DNS-Auflösung (getent: $host)" - debug_info="${debug_info}Erfolg mit getent. " - break - fi - debug_info="${debug_info}getent fehlgeschlagen. " - fi - - # Teste ping als Fallback - if [ "$connection_ok" = false ] && command -v ping >/dev/null 2>&1; then - if timeout 5 ping -c 1 "$host" >/dev/null 2>&1; then - connection_ok=true - test_method="Netzwerk-Verbindung (ping: $host)" - debug_info="${debug_info}Erfolg mit ping. " - break - fi - debug_info="${debug_info}ping fehlgeschlagen. " - fi - done - - debug "DNS-Test Details: $debug_info" - - # Methode 2: HTTP/HTTPS-Tests (robuster) - if [ "$connection_ok" = false ]; then - progress "Teste HTTP/HTTPS-Verbindungen..." - local http_urls=("http://connectivitycheck.gstatic.com/generate_204" "http://detectportal.firefox.com/success.txt" "https://www.google.com") - - for url in "${http_urls[@]}"; do - debug_info="Teste HTTP für $url: " - - # Teste curl - if command -v curl >/dev/null 2>&1; then - if timeout 15 curl -s --connect-timeout 8 --max-time 12 --fail "$url" >/dev/null 2>&1; then - connection_ok=true - test_method="HTTP/HTTPS (curl: $url)" - debug_info="${debug_info}Erfolg mit curl. " - break - fi - debug_info="${debug_info}curl fehlgeschlagen. " - fi - - # Teste wget - if [ "$connection_ok" = false ] && command -v wget >/dev/null 2>&1; then - if timeout 15 wget -q --timeout=8 --tries=1 --spider "$url" 2>/dev/null; then - connection_ok=true - test_method="HTTP/HTTPS (wget: $url)" - debug_info="${debug_info}Erfolg mit wget. " - break - fi - debug_info="${debug_info}wget fehlgeschlagen. " - fi - - debug "HTTP-Test Details: $debug_info" - done - fi - - # Methode 3: Lokale Netzwerk-Interface Prüfung - if [ "$connection_ok" = false ]; then - progress "Prüfe lokale Netzwerk-Interfaces..." - - local has_network_interface=false - - # Prüfe ob aktive Netzwerk-Interfaces vorhanden sind - if command -v ip >/dev/null 2>&1; then - local active_interfaces=$(ip route show default 2>/dev/null | awk '{print $5}' | head -1) - if [ -n "$active_interfaces" ]; then - has_network_interface=true - local interface_ip=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7}' | head -1 || echo "Unbekannt") - info " 📡 Aktives Interface: $active_interfaces (IP: $interface_ip)" - debug "Netzwerk-Interface gefunden: $active_interfaces mit IP $interface_ip" - fi - fi - - # Fallback über ifconfig - if [ "$has_network_interface" = false ] && command -v ifconfig >/dev/null 2>&1; then - local active_interfaces=$(ifconfig 2>/dev/null | grep -E '^[a-zA-Z]' | grep -v '^lo' | head -1 | cut -d: -f1) - if [ -n "$active_interfaces" ]; then - has_network_interface=true - info " 📡 Interface erkannt: $active_interfaces" - debug "Netzwerk-Interface über ifconfig gefunden: $active_interfaces" - fi - fi - - if [ "$has_network_interface" = true ]; then - warning "⚠️ Netzwerk-Interface aktiv, aber Internet nicht erreichbar" - warning " → Möglicherweise Firewall, Proxy oder DNS-Problem" - else - warning "⚠️ Keine aktiven Netzwerk-Interfaces gefunden" - warning " → Bitte prüfen Sie die Netzwerk-Konfiguration" - fi - fi - - # Methode 4: APT-Repository-Test (nur als letzter Test) - if [ "$connection_ok" = false ]; then - progress "Teste APT-Repository-Zugang (kann länger dauern)..." - - # Sehr kurzer APT-Test ohne Update - if timeout 30 apt-get -qq --print-uris update 2>/dev/null | grep -q 'http'; then - connection_ok=true - test_method="APT-Repository-Konfiguration" - debug "APT-Repositories scheinen konfiguriert zu sein" - else - debug "APT-Repository-Test fehlgeschlagen" - fi - fi - - # Ergebnis-Bewertung - if [ "$connection_ok" = true ]; then - success "✅ Internetverbindung verfügbar" - info " 🔍 Erkannt via: $test_method" - - # Zusätzliche Informationen (robust) - if command -v curl >/dev/null 2>&1; then - progress "Ermittle externe IP-Adresse..." - local external_ip="" - local ip_services=("ifconfig.me" "ipinfo.io/ip" "icanhazip.com") - - for service in "${ip_services[@]}"; do - external_ip=$(timeout 8 curl -s --connect-timeout 5 "$service" 2>/dev/null | head -1 | tr -d '\n\r' || echo "") - if [ -n "$external_ip" ] && [[ "$external_ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - info " 🌐 Externe IP: $external_ip" - debug "Externe IP ermittelt über $service: $external_ip" - break - fi - done - - if [ -z "$external_ip" ]; then - debug "Externe IP konnte nicht ermittelt werden" - fi - fi - else - warning "⚠️ Keine Internetverbindung erkannt" - info " → Installation wird fortgesetzt, aber Downloads könnten fehlschlagen" - warning " → Bitte prüfen Sie die Netzwerkverbindung!" - - # Debug-Informationen bei fehlgeschlagener Verbindung - debug "Internet-Verbindungstest fehlgeschlagen. System-Info:" - debug " - DNS-Server: $(cat /etc/resolv.conf 2>/dev/null | grep nameserver | head -3 || echo 'Nicht verfügbar')" - debug " - Default Route: $(ip route show default 2>/dev/null || echo 'Nicht verfügbar')" - debug " - Network Interfaces: $(ip addr show 2>/dev/null | grep -E '^[0-9]+:' | cut -d: -f2 | tr -d ' ' | grep -v lo | head -3 || echo 'Nicht verfügbar')" - fi -} - -# =========================== ROBUSTE SYSTEM-VORBEREITUNG =========================== -update_system() { - log "=== ANTI-HÄNGE SYSTEM-UPDATE MIT TIMEOUTS ===" - - progress "Konfiguriere APT für bessere Zuverlässigkeit (timeout-gesichert)..." - - # APT-Konfiguration optimieren (aggressivere Timeouts) - timeout 10 bash -c 'cat > /etc/apt/apt.conf.d/99myp-optimized << "EOF" -APT::Acquire::Retries "2"; -APT::Acquire::http::Timeout "15"; -APT::Acquire::https::Timeout "15"; -APT::Acquire::ftp::Timeout "15"; -APT::Install-Recommends "false"; -APT::Install-Suggests "false"; -Dpkg::Options { - "--force-confdef"; - "--force-confold"; -} -APT::Get::Assume-Yes "true"; -APT::Get::Fix-Broken "true"; -EOF' || warning "APT-Konfiguration timeout - verwende Defaults" - - # Repository-Listen korrigieren (timeout-gesichert) - progress "Validiere APT-Repositories (timeout-gesichert)..." - timeout 20 bash -c ' - if [ -f /etc/apt/sources.list ]; then - cp /etc/apt/sources.list /etc/apt/sources.list.backup 2>/dev/null || true - if grep -q "deb-src" /etc/apt/sources.list 2>/dev/null; then - sed -i "s/^deb-src/#deb-src/g" /etc/apt/sources.list 2>/dev/null || true - echo "Source-Repositories deaktiviert" - fi - fi - ' || warning "Repository-Validierung timeout - fahre fort" - - # APT-Lock-Dateien bereinigen (falls hängend) - progress "Bereinige APT-Lock-Dateien..." - timeout 10 bash -c ' - rm -f /var/lib/dpkg/lock-frontend 2>/dev/null || true - rm -f /var/lib/dpkg/lock 2>/dev/null || true - rm -f /var/cache/apt/archives/lock 2>/dev/null || true - rm -f /var/lib/apt/lists/lock 2>/dev/null || true - ' || true - - progress "Aktualisiere Paketlisten (max 60s timeout)..." - if timeout 60 apt-get update 2>/dev/null; then - success "✅ APT Update erfolgreich" - else - warning "⚠️ APT Update timeout - fahre ohne Update fort" - fi - - progress "Führe System-Upgrade durch (max 120s timeout)..." - if timeout 120 bash -c 'DEBIAN_FRONTEND=noninteractive apt-get upgrade -y 2>/dev/null'; then - success "✅ System Upgrade erfolgreich" - else - warning "⚠️ System Upgrade timeout - fahre ohne Upgrade fort" - fi - - progress "Installiere essenzielle System-Tools..." - - # Grundlegende Tools in optimierter Reihenfolge - local essential_packages=( - "ca-certificates" - "gnupg" - "curl" - "wget" - "git" - "nano" - "htop" - "rsync" - "unzip" - "sudo" - "systemd" - "lsb-release" - "apt-transport-https" - "software-properties-common" - "bc" - "dbus" - "systemd-timesyncd" - ) - - for package in "${essential_packages[@]}"; do - apt_install_retry "$package" - done - - # Zeitserver synchronisieren - progress "Synchronisiere Systemzeit..." - systemctl enable systemd-timesyncd 2>/dev/null || true - systemctl start systemd-timesyncd 2>/dev/null || true - - log "✅ Robustes System-Update abgeschlossen" -} - -# =========================== VERBESSERTE PYTHON-INSTALLATION =========================== -install_python_dependencies() { - log "=== ROBUSTE PYTHON-INSTALLATION ===" - - progress "Installiere Python 3 und Build-Abhängigkeiten..." - - local python_packages=( - "python3" - "python3-pip" - "python3-dev" - "python3-setuptools" - "python3-venv" - "python3-wheel" - "build-essential" - "libssl-dev" - "libffi-dev" - "libbz2-dev" - "libreadline-dev" - "libsqlite3-dev" - "libncurses5-dev" - "libncursesw5-dev" - "zlib1g-dev" - "sqlite3" - ) - - for package in "${python_packages[@]}"; do - apt_install_retry "$package" - done - - # Python-Version validieren - progress "Validiere Python-Installation..." - local python_version=$(python3 --version 2>&1 | cut -d' ' -f2) - log "✅ Python Version: $python_version" - - # pip konfigurieren und aktualisieren - progress "Konfiguriere pip für bessere Zuverlässigkeit..." - - # Root pip-Konfiguration - mkdir -p /root/.pip - cat > /root/.pip/pip.conf << 'EOF' -[global] -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -cert = /etc/ssl/certs/ca-certificates.crt -timeout = 120 -retries = 5 -no-cache-dir = false -disable-pip-version-check = true -no-warn-script-location = true -break-system-packages = true - -[install] -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -user = false -break-system-packages = true -EOF - - # Systemweite pip-Konfiguration für alle Benutzer - progress "Erstelle systemweite pip-Konfiguration..." - mkdir -p /etc/pip - cat > /etc/pip/pip.conf << 'EOF' -[global] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -timeout = 120 -retries = 5 -disable-pip-version-check = true - -[install] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -user = false -EOF - - # pip-Konfiguration für existierende Benutzer erstellen - progress "Konfiguriere pip für alle Benutzer..." - for user_home in "/home/"*; do - if [ -d "$user_home" ] && [ "$user_home" != "/home/lost+found" ]; then - local username=$(basename "$user_home") - if id "$username" &>/dev/null; then - mkdir -p "$user_home/.pip" 2>/dev/null || true - cat > "$user_home/.pip/pip.conf" << 'EOF' -[global] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -timeout = 60 -retries = 3 - -[install] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -EOF - chown "$username:$username" "$user_home/.pip/pip.conf" 2>/dev/null || true - log "✅ pip konfiguriert für Benutzer: $username" - fi - fi - done - - # pip selbst aktualisieren - progress "Aktualisiere pip mit Retry..." - retry_command "python3 -m pip install --break-system-packages --upgrade pip setuptools wheel" "pip Upgrade" - - # pip-Version validieren - local pip_version=$(python3 -m pip --version | cut -d' ' -f2) - log "✅ pip Version: $pip_version" - - log "✅ Robuste Python-Umgebung installiert" -} - -create_clean_requirements() { - log "=== ERSTELLE BEREINIGTE REQUIREMENTS.TXT ===" - - local original_req="$SOURCE_BACKEND_DIR/requirements.txt" - local clean_req="$SOURCE_BACKEND_DIR/requirements_clean.txt" - - # Problematische Pakete, die übersprungen werden sollen - local problematic_packages=( - "Send2Trash" - "pywin32" - "wmi" - "RPi.GPIO" - "python-magic-bin" - ) - - progress "Erstelle bereinigte requirements.txt..." - - # Erstelle neue requirements.txt ohne problematische Pakete - > "$clean_req" # Datei leeren - - while IFS= read -r line || [ -n "$line" ]; do - local skip_line=false - local package_name=$(echo "$line" | sed 's/[<>=!].*//' | xargs) - - # Überspringe leere Zeilen und Kommentare - if [[ -z "${line// }" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then - echo "$line" >> "$clean_req" - continue - fi - - # Prüfe ob Paket problematisch ist - for problematic in "${problematic_packages[@]}"; do - if [[ "$package_name" == "$problematic" ]]; then - echo "# ÜBERSPRUNGEN (problematisch): $line" >> "$clean_req" - log "⚠️ Überspringe problematisches Paket: $package_name" - skip_line=true - break - fi - done - - # Spezielle Behandlung für plattformspezifische Pakete - if [[ "$line" =~ "sys_platform" ]]; then - # Prüfe Plattform-Kompatibilität - if [[ "$line" =~ "win32" ]] && [[ "$(uname -s)" != "CYGWIN"* ]] && [[ "$(uname -s)" != "MINGW"* ]]; then - echo "# ÜBERSPRUNGEN (Windows): $line" >> "$clean_req" - log "ℹ️ Überspringe Windows-spezifisches Paket: $package_name" - skip_line=true - elif [[ "$line" =~ "linux" ]] && [[ "$(uname -s)" != "Linux" ]]; then - echo "# ÜBERSPRUNGEN (Linux): $line" >> "$clean_req" - log "ℹ️ Überspringe Linux-spezifisches Paket: $package_name" - skip_line=true - fi - fi - - # Füge Zeile hinzu wenn nicht übersprungen - if [ "$skip_line" = false ]; then - echo "$line" >> "$clean_req" - fi - - done < "$original_req" - - log "✅ Bereinigte requirements.txt erstellt: $clean_req" - - # Zeige Statistiken - local original_count=$(grep -v -E '^[[:space:]]*#|^[[:space:]]*$' "$original_req" | wc -l) - local clean_count=$(grep -v -E '^[[:space:]]*#|^[[:space:]]*$' "$clean_req" | wc -l) - log "📊 Pakete: $original_count → $clean_count ($(($original_count - $clean_count)) übersprungen)" -} - -install_essential_packages_fallback() { - log "=== INSTALLIERE ESSENTIELLE PAKETE (FALLBACK) ===" - - # Minimale Liste essentieller Pakete für MYP - local essential_packages=( - "Flask>=2.0.0" - "Werkzeug>=2.0.0" - "Jinja2>=3.0.0" - "requests>=2.25.0" - "SQLAlchemy>=1.4.0" - "Flask-Login>=0.6.0" - "Flask-WTF>=1.0.0" - "WTForms>=3.0.0" - "cryptography>=3.4.0" - "bcrypt>=3.2.0" - "psutil>=5.8.0" - "python-dateutil>=2.8.0" - "click>=8.0.0" - "colorlog>=6.6.0" - "watchdog>=2.1.0" - "schedule>=1.1.0" - "Pillow>=8.3.0" - ) - - progress "Installiere essentielle Pakete einzeln..." - - local install_count=0 - local total_count=${#essential_packages[@]} - - for package in "${essential_packages[@]}"; do - local package_name=$(echo "$package" | sed 's/[<>=!].*//') - progress "Installiere $package_name... ($((++install_count))/$total_count)" - - # Mehrere Installationsstrategien - if python3 -m pip install "$package" --break-system-packages --no-cache-dir >/dev/null 2>&1; then - log "✅ $package_name erfolgreich installiert" - elif python3 -m pip install "$package_name" --break-system-packages --no-cache-dir >/dev/null 2>&1; then - log "✅ $package_name erfolgreich installiert (ohne Version)" - elif python3 -m pip install "$package" --user --no-cache-dir >/dev/null 2>&1; then - log "✅ $package_name erfolgreich installiert (user)" - else - warning "⚠️ $package_name Installation fehlgeschlagen" - fi - done - - log "✅ Essentieller Pakete Installation abgeschlossen" -} - -install_python_packages() { - log "=== ROBUSTE PYTHON-PAKETE INSTALLATION ===" - - progress "Installiere Python-Pakete..." - - if [ ! -f "$CURRENT_DIR/requirements.txt" ]; then - error "requirements.txt nicht gefunden: $CURRENT_DIR/requirements.txt" - install_essential_packages_fallback - return - fi - - # Kopiere requirements.txt - cp "$CURRENT_DIR/requirements.txt" "$APP_DIR/" 2>/dev/null || true - - # Erstelle bereinigte requirements.txt - create_clean_requirements - - # Installiere bereinigte Pakete - progress "Installiere bereinigte requirements.txt..." - - local install_success=false - - # Strategie 1: Bereinigte requirements.txt mit --break-system-packages - if python3 -m pip install -r "$SOURCE_BACKEND_DIR/requirements_clean.txt" --break-system-packages --no-cache-dir; then - install_success=true - success "✅ Bereinigte requirements.txt erfolgreich installiert" - else - warning "⚠️ Bereinigte requirements.txt Installation fehlgeschlagen" - - # Strategie 2: Essentielle Pakete einzeln installieren - warning "Verwende Fallback: Essentielle Pakete einzeln installieren" - install_essential_packages_fallback - install_success=true - fi - - # Aufräumen - rm -f "$SOURCE_BACKEND_DIR/requirements_clean.txt" 2>/dev/null || true - - # Validiere essenzielle Module - progress "Validiere essenzielle Python-Module..." - - local essential_modules=("flask" "requests" "werkzeug" "jinja2" "sqlalchemy") - local validation_success=true - - for module in "${essential_modules[@]}"; do - if python3 -c "import $module; print(f'✅ $module verfügbar')" 2>/dev/null; then - debug "$module erfolgreich importiert" - else - warning "⚠️ $module nicht verfügbar - versuche nachinstallation..." - python3 -m pip install "$module" --break-system-packages --no-cache-dir >/dev/null 2>&1 || true - fi - done - - # Finale Validierung - for module in "${essential_modules[@]}"; do - if python3 -c "import $module" 2>/dev/null; then - log "✅ $module verfügbar" - else - warning "⚠️ $module fehlt" - validation_success=false - fi - done - - if [ "$validation_success" = true ]; then - success "✅ Alle essentiellen Python-Module verfügbar" - else - warning "⚠️ Einige essenzielle Module fehlen - Fallback verwendet" - fi - - log "✅ Python-Pakete Installation abgeschlossen" - - # Zeige installierte Pakete - progress "Zeige installierte Python-Pakete..." - echo "" - echo "📦 Installierte Python-Pakete:" - python3 -m pip list 2>/dev/null | grep -E "(Flask|requests|Werkzeug|Jinja2|SQLAlchemy)" | head -10 || echo " Keine relevanten Pakete gefunden" - echo "" -} - -# =========================== PYTHON-PAKETE MIT BREAK-SYSTEM-PACKAGES =========================== -install_python_packages_with_break_system() { - log "🐍 PYTHON-PAKETE MIT BREAK-SYSTEM-PACKAGES INSTALLATION" - - progress "Installiere Python-Pakete mit --break-system-packages..." - - if [ ! -f "$SOURCE_BACKEND_DIR/requirements.txt" ]; then - error "requirements.txt nicht gefunden: $SOURCE_BACKEND_DIR/requirements.txt" - return 1 - fi - - # Kopiere requirements.txt - cp "$SOURCE_BACKEND_DIR/requirements.txt" "$APP_DIR/" 2>/dev/null || true - - # Installiere alle Pakete aus requirements.txt mit --break-system-packages - progress "Installiere requirements.txt mit --break-system-packages..." - - # Mehrere Installationsversuche mit verschiedenen Strategien - local install_success=false - - # Erstelle bereinigte requirements.txt für Installation - if [ ! -f "$SOURCE_BACKEND_DIR/requirements_clean.txt" ]; then - create_clean_requirements - fi - - # Strategie 1: Mit --break-system-packages und bereinigter requirements.txt - if python3.11 -m pip install -r "$SOURCE_BACKEND_DIR/requirements_clean.txt" --break-system-packages --force-reinstall --no-cache-dir; then - install_success=true - success "✅ Bereinigte requirements.txt mit --break-system-packages erfolgreich installiert" - else - warning "⚠️ Strategie 1 fehlgeschlagen, versuche Alternative..." - - # Strategie 2: Bereinigte Einzelinstallation - progress "Installiere bereinigte Pakete einzeln..." - - # Erstelle bereinigte requirements.txt falls nicht vorhanden - if [ ! -f "$SOURCE_BACKEND_DIR/requirements_clean.txt" ]; then - create_clean_requirements - fi - - while IFS= read -r package || [ -n "$package" ]; do - # Überspringe Kommentare und leere Zeilen - if [[ "$package" =~ ^[[:space:]]*# ]] || [[ -z "${package// }" ]]; then - continue - fi - - # Entferne Whitespace - package=$(echo "$package" | xargs) - - if [ -n "$package" ]; then - local package_name=$(echo "$package" | sed 's/[<>=!].*//') - progress "Installiere: $package_name" - if python3.11 -m pip install "$package" --break-system-packages --no-cache-dir; then - debug "✅ $package_name erfolgreich installiert" - else - warning "⚠️ $package_name Installation fehlgeschlagen" - fi - fi - done < "$SOURCE_BACKEND_DIR/requirements_clean.txt" - - # Aufräumen - rm -f "$SOURCE_BACKEND_DIR/requirements_clean.txt" 2>/dev/null || true - install_success=true - fi - - if [ "$install_success" = false ]; then - error "❌ Python-Pakete Installation komplett fehlgeschlagen" - return 1 - fi - - # Validiere essenzielle Module mit Python 3.11 - progress "Validiere essenzielle Python-Module mit Python 3.11..." - - local essential_modules=("flask" "requests" "werkzeug" "jinja2") - local validation_success=true - - for module in "${essential_modules[@]}"; do - if python3.11 -c "import $module; print(f'✅ $module verfügbar')" 2>/dev/null; then - debug "$module erfolgreich importiert" - else - warning "⚠️ $module nicht verfügbar - versuche Installation..." - python3.11 -m pip install "$module" --break-system-packages --no-cache-dir 2>/dev/null || true - fi - done - - # Finale Validierung - progress "Finale Modul-Validierung..." - for module in "${essential_modules[@]}"; do - if python3.11 -c "import $module" 2>/dev/null; then - success "✅ $module verfügbar" - else - warning "⚠️ $module immer noch nicht verfügbar" - validation_success=false - fi - done - - if [ "$validation_success" = true ]; then - success "✅ Alle essentiellen Python-Module verfügbar" - else - warning "⚠️ Einige essenzielle Module fehlen - Installation kann trotzdem funktionieren" - fi - - # Zeige installierte Pakete mit Python 3.11 - progress "Zeige installierte Python-Pakete (Python 3.11)..." - echo "" - echo "📦 Installierte Python-Pakete (Python 3.11):" - python3.11 -m pip list 2>/dev/null | grep -E "(Flask|requests|Werkzeug|Jinja2|gunicorn|psutil)" | head -15 || echo " Keine relevanten Pakete gefunden" - echo "" - - success "✅ Python-Pakete mit --break-system-packages Installation abgeschlossen" -} - -# =========================== ROBUSTE NODE.JS INSTALLATION =========================== -install_nodejs_npm() { - log "=== ROBUSTE NODE.JS UND NPM INSTALLATION ===" - - # Alte Installationen entfernen - progress "Bereinige alte Node.js-Installationen..." - apt-get remove --purge -y nodejs npm 2>/dev/null || true - apt-get autoremove -y 2>/dev/null || true - rm -rf /usr/local/bin/node /usr/local/bin/npm 2>/dev/null || true - - # NodeSource Repository mit Fallback - progress "Installiere Node.js mit Fallback-Strategie..." - - local nodejs_installed=false - - # Strategie 1: NodeSource Repository - if curl -fsSL https://deb.nodesource.com/setup_lts.x 2>/dev/null | bash - 2>/dev/null; then - if apt-get update -y && apt_install_retry nodejs; then - nodejs_installed=true - log "✅ Node.js via NodeSource Repository installiert" - fi - fi - - # Strategie 2: Snap (falls verfügbar) - if [ "$nodejs_installed" = false ] && command -v snap >/dev/null 2>&1; then - progress "Versuche Node.js Installation via Snap..." - if snap install node --classic 2>/dev/null; then - nodejs_installed=true - log "✅ Node.js via Snap installiert" - fi - fi - - # Strategie 3: Debian Repository (Fallback) - if [ "$nodejs_installed" = false ]; then - progress "Verwende Debian Repository als Fallback..." - apt_install_retry nodejs npm - nodejs_installed=true - log "✅ Node.js via Debian Repository installiert" - fi - - # Validierung - progress "Validiere Node.js Installation..." - if command -v node >/dev/null 2>&1; then - local node_version=$(node --version) - log "✅ Node.js Version: $node_version" - else - error "❌ Node.js nicht verfügbar nach Installation" - fi - - if command -v npm >/dev/null 2>&1; then - local npm_version=$(npm --version) - log "✅ npm Version: $npm_version" - - # npm optimieren - progress "Optimiere npm-Konfiguration..." - npm config set fund false 2>/dev/null || true - npm config set audit-level moderate 2>/dev/null || true - npm config set progress false 2>/dev/null || true - npm config set loglevel warn 2>/dev/null || true - else - # Versuche npm separat zu installieren - progress "Installiere npm separat..." - apt_install_retry npm - fi - - log "✅ Node.js und npm erfolgreich installiert" -} - -# =========================== NETZWERK-SICHERHEIT =========================== -configure_network_security() { - log "=== SIMPLE NETZWERK-SICHERHEIT (ANTI-HÄNGE VERSION) ===" - - # Standardmäßig überspringen um Hänger zu vermeiden - if [ "${SKIP_NETWORK_SECURITY:-1}" = "1" ]; then - info "🚀 Netzwerk-Sicherheit übersprungen für schnellere Installation" - info "📝 Kann später manuell aktiviert werden mit: SKIP_NETWORK_SECURITY=0" - return - fi - - # Komplette Funktion mit aggressivem Timeout - if ! timeout 30 bash -c ' - # Nur essenzielle IPv6-Deaktivierung - progress() { echo "[FORTSCHRITT] $1"; } - warning() { echo "[WARNUNG] $1"; } - success() { echo "[ERFOLG] $1"; } - - progress "Deaktiviere IPv6 (essentiell, max 30s)..." - - # 1. Einfache sysctl IPv6-Deaktivierung (schnell) - echo "net.ipv6.conf.all.disable_ipv6=1" > /etc/sysctl.d/99-myp-ipv6.conf 2>/dev/null || true - echo "net.ipv6.conf.default.disable_ipv6=1" >> /etc/sysctl.d/99-myp-ipv6.conf 2>/dev/null || true - - # 2. IPv6 in /etc/hosts auskommentieren (schnell) - if [ -f /etc/hosts ]; then - sed -i.backup "s/^::1/#::1/" /etc/hosts 2>/dev/null || true - fi - - # 3. GRUB nur wenn schnell verfügbar - if [ -f /etc/default/grub ] && command -v update-grub >/dev/null 2>&1; then - if ! grep -q "ipv6.disable=1" /etc/default/grub 2>/dev/null; then - cp /etc/default/grub /etc/default/grub.backup 2>/dev/null || true - sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT=\"/&ipv6.disable=1 /" /etc/default/grub 2>/dev/null || true - # update-grub nur mit 10s timeout - if timeout 10 update-grub >/dev/null 2>&1; then - success "GRUB IPv6 deaktiviert" - else - warning "GRUB-Update timeout - wird beim nächsten Boot aktiv" - fi - fi - fi - - success "IPv6-Deaktivierung abgeschlossen" - '; then - warning "⚠️ Netzwerk-Sicherheit timeout (30s) - überspringe" - info " → System funktioniert trotzdem normal" - info " → IPv6-Deaktivierung kann später manuell durchgeführt werden" - else - log "✅ Basis-Netzwerk-Sicherheit konfiguriert:" - log " 🚫 IPv6 deaktiviert" - log " 📝 Konfiguration in /etc/sysctl.d/99-myp-ipv6.conf" - log " 🔄 Wird beim nächsten Boot vollständig aktiv" - fi -} - -# =========================== DESKTOP-ENVIRONMENT ENTFERNUNG =========================== -remove_desktop_environments() { - log "=== ENTFERNE DESKTOP ENVIRONMENTS FÜR KIOSK-MODUS ===" - - progress "Stoppe alle Desktop-Services..." - local desktop_services=("lightdm" "gdm3" "sddm" "xdm" "nodm") - - for service in "${desktop_services[@]}"; do - systemctl stop "$service" 2>/dev/null || true - systemctl disable "$service" 2>/dev/null || true - done - - progress "Entferne Desktop-Pakete vollständig..." - - # Raspberry Pi OS Desktop-Pakete - apt-get remove --purge -y \ - raspberrypi-ui-mods \ - pi-package \ - desktop-base \ - lxde* \ - xfce4* \ - gnome* \ - kde* \ - mate* \ - cinnamon* \ - openbox \ - pcmanfm \ - file-manager* \ - task-lxde-desktop \ - task-xfce-desktop \ - task-gnome-desktop \ - task-kde-desktop \ - 2>/dev/null || true - - # Display Manager entfernen - apt-get remove --purge -y \ - lightdm* \ - gdm3* \ - sddm* \ - xdm* \ - nodm* \ - 2>/dev/null || true - - # Unnötige Anwendungen entfernen - apt-get remove --purge -y \ - libreoffice* \ - thunderbird* \ - firefox* \ - vlc* \ - gimp* \ - scratch* \ - minecraft-pi \ - sonic-pi \ - 2>/dev/null || true - - # Aufräumen - apt-get autoremove --purge -y - apt-get autoclean - - log "✅ Desktop Environments vollständig entfernt" -} - -# =========================== AGGRESSIVE VOLLSTÄNDIGE UMGEBUNGSBEREINIGUNG =========================== -complete_environment_cleanup() { - log "🧹 AGGRESSIVE VOLLSTÄNDIGE UMGEBUNGSBEREINIGUNG..." - - # SCHRITT 1: Alle laufenden Desktop-Services sofort stoppen und MASKIEREN - progress "Stoppe und maskiere ALLE Desktop-Services aggressiv..." - local desktop_services=( - "gdm3" "gdm" "lightdm" "sddm" "xdm" "nodm" "wdm" "kdm" "lxdm" - "display-manager" "graphical-session.target" - "gnome-session-manager" "kde-session" "xfce4-session" "lxsession" - "desktop-session" "x11-session" "wayland-session" - ) - - for service in "${desktop_services[@]}"; do - systemctl stop "$service" 2>/dev/null || true - systemctl disable "$service" 2>/dev/null || true - systemctl mask "$service" 2>/dev/null || true - progress "Service $service: gestoppt, deaktiviert, MASKIERT" - done - - # SCHRITT 2: Boot-Target auf multi-user setzen (KEIN automatisches GUI) - progress "🚫 Setze Boot-Target auf multi-user - KEIN automatisches GUI mehr!" - systemctl set-default multi-user.target - systemctl disable graphical.target 2>/dev/null || true - systemctl mask graphical.target 2>/dev/null || true - systemctl disable graphical-session.target 2>/dev/null || true - systemctl mask graphical-session.target 2>/dev/null || true - - warning "⚠️ WICHTIG: Kein Desktop-Environment startet mehr automatisch nach Reboot!" - - # SCHRITT 3: Alle Desktop-Prozesse brutal beenden - progress "💀 Beende alle laufenden Desktop-Prozesse brutal..." - local desktop_processes=( - "gnome-session" "kde-session" "xfce4-session" "lxsession" "mate-session" - "cinnamon-session" "unity" "compiz" "metacity" "kwin" "mutter" - "X :0" "Xorg" "xfce4-panel" "gnome-panel" "kde-panel" "lxpanel" - "nautilus" "dolphin" "thunar" "pcmanfm" "caja" - ) - - for process in "${desktop_processes[@]}"; do - pkill -f "$process" 2>/dev/null || true - progress "Prozess $process: beendet" - done - - # SCHRITT 4: Display Manager KOMPLETT deinstallieren - progress "🗑️ Entferne ALLE Display Manager komplett..." - apt-get remove --purge -y \ - gdm3* gdm* lightdm* sddm* xdm* nodm* wdm* kdm* lxdm* \ - display-manager-service* slim* entrance* \ - 2>/dev/null || true - - # SCHRITT 5: Desktop-Environments AGGRESSIV entfernen - progress "🔥 Entferne ALLE Desktop-Environments AGGRESSIV..." - - # GNOME - komplett vernichten - progress "Vernichte GNOME komplett..." - apt-get remove --purge -y \ - gnome* gdm3* ubuntu-desktop* ubuntu-session* \ - gnome-shell* gnome-desktop* gnome-session* gnome-control-center* \ - nautilus* gedit* evince* totem* rhythmbox* \ - gnome-calculator* gnome-calendar* gnome-contacts* \ - 2>/dev/null || true - - # KDE - komplett vernichten - progress "Vernichte KDE komplett..." - apt-get remove --purge -y \ - kde* plasma* kubuntu-desktop* kdebase* kdelibs* \ - dolphin* konqueror* kate* okular* \ - 2>/dev/null || true - - # XFCE - komplett vernichten - progress "Vernichte XFCE komplett..." - apt-get remove --purge -y \ - xfce4* xubuntu-desktop* thunar* xfce4-panel* \ - xfce4-terminal* xfce4-appfinder* \ - 2>/dev/null || true - - # LXDE/LXQt - komplett vernichten - progress "Vernichte LXDE/LXQt komplett..." - apt-get remove --purge -y \ - lxde* lxqt* lubuntu-desktop* pcmanfm* lxpanel* \ - lxterminal* lxsession* \ - 2>/dev/null || true - - # MATE - komplett vernichten - progress "Vernichte MATE komplett..." - apt-get remove --purge -y \ - mate* ubuntu-mate-desktop* caja* pluma* \ - mate-panel* mate-desktop* \ - 2>/dev/null || true - - # Cinnamon - komplett vernichten - progress "Vernichte Cinnamon komplett..." - apt-get remove --purge -y \ - cinnamon* nemo* \ - 2>/dev/null || true - - # Unity (falls noch vorhanden) - progress "Vernichte Unity..." - apt-get remove --purge -y \ - unity* ubuntu-unity-desktop* \ - 2>/dev/null || true - - # SCHRITT 6: Desktop-Meta-Pakete entfernen - progress "🗑️ Entferne Desktop-Meta-Pakete..." - apt-get remove --purge -y \ - ubuntu-desktop* kubuntu-desktop* xubuntu-desktop* \ - lubuntu-desktop* ubuntu-mate-desktop* ubuntu-unity-desktop* \ - desktop-base* tasksel* task-desktop* \ - 2>/dev/null || true - - # SCHRITT 7: Autostart-Verzeichnisse bereinigen - progress "🧹 Bereinige Autostart-Verzeichnisse..." - rm -rf /etc/xdg/autostart/* 2>/dev/null || true - rm -rf /usr/share/xsessions/* 2>/dev/null || true - rm -rf /usr/share/wayland-sessions/* 2>/dev/null || true - rm -rf ~/.config/autostart/* 2>/dev/null || true - - # SCHRITT 8: Python-Installationen bereinigen - progress "🐍 Bereinige alte Python-Installationen..." - apt-get remove --purge -y python3-pip python3-venv python3-virtualenv - rm -rf /usr/local/lib/python3.*/dist-packages/* 2>/dev/null || true - rm -rf ~/.local/lib/python3.*/site-packages/* 2>/dev/null || true - rm -rf /home/*/.local/lib/python3.*/site-packages/* 2>/dev/null || true - - # SCHRITT 9: Snap-Pakete komplett entfernen - if command -v snap >/dev/null 2>&1; then - progress "📦 Entferne alle Snap-Pakete..." - snap list 2>/dev/null | awk 'NR>1 {print $1}' | while read snapname; do - snap remove "$snapname" --purge 2>/dev/null || true - done - apt-get remove --purge -y snapd 2>/dev/null || true - fi - - # SCHRITT 10: Flatpak-Pakete komplett entfernen - if command -v flatpak >/dev/null 2>&1; then - progress "📦 Entferne alle Flatpak-Pakete..." - flatpak uninstall --all -y 2>/dev/null || true - apt-get remove --purge -y flatpak* 2>/dev/null || true - fi - - # SCHRITT 11: AGGRESSIVE Bereinigung - progress "🧽 Führe aggressive System-Bereinigung durch..." - apt-get autoremove --purge -y - apt-get autoclean - apt-get clean - - # Alle Caches leeren - rm -rf /var/cache/apt/archives/* - rm -rf /tmp/* - rm -rf /var/tmp/* - rm -rf /var/cache/fontconfig/* - rm -rf /home/*/.cache/* 2>/dev/null || true - rm -rf /root/.cache/* 2>/dev/null || true - - # SCHRITT 12: Desktop-Konfigurationen entfernen - progress "🗑️ Entferne Desktop-Konfigurationen..." - rm -rf /etc/gdm3/ 2>/dev/null || true - rm -rf /etc/lightdm/ 2>/dev/null || true - rm -rf /etc/sddm/ 2>/dev/null || true - rm -rf /etc/xdg/ 2>/dev/null || true - rm -rf /home/*/.config/autostart/ 2>/dev/null || true - rm -rf /home/*/.config/xfce4/ 2>/dev/null || true - rm -rf /home/*/.config/lxsession/ 2>/dev/null || true - rm -rf /home/*/.gnome/ 2>/dev/null || true - rm -rf /home/*/.kde/ 2>/dev/null || true - - success "✅ AGGRESSIVE Umgebungsbereinigung abgeschlossen!" - warning "⚠️ WICHTIG: Nach Reboot startet KEIN Desktop automatisch mehr!" - warning "⚠️ Nur noch Kiosk-Modus wird automatisch gestartet!" -} - -# =========================== SAUBERE PYTHON-UMGEBUNG =========================== -setup_clean_python_environment() { - log "🐍 PYTHON-UMGEBUNG NEU EINRICHTEN..." - - # Python 3.11 Repository hinzufügen (falls nicht vorhanden) - progress "Füge Python 3.11 Repository hinzu..." - if ! grep -q "deadsnakes" /etc/apt/sources.list.d/* 2>/dev/null; then - add-apt-repository ppa:deadsnakes/ppa -y - apt-get update - fi - - # Python 3.11 und essenzielle Pakete installieren - progress "Installiere Python 3.11 und essenzielle Pakete..." - apt-get install -y \ - python3.11 \ - python3.11-dev \ - python3.11-venv \ - python3.11-distutils \ - python3-pip \ - build-essential \ - pkg-config \ - libffi-dev \ - libssl-dev \ - libxml2-dev \ - libxslt1-dev \ - libjpeg-dev \ - libpng-dev \ - zlib1g-dev - - # Python 3.11 als Standard setzen - progress "Setze Python 3.11 als Standard..." - update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 1 - update-alternatives --set python3 /usr/bin/python3.11 - - # pip für Python 3.11 aktualisieren - progress "Aktualisiere pip für Python 3.11..." - python3.11 -m pip install --upgrade pip setuptools wheel - - # pip-Konfiguration für --break-system-packages erstellen - progress "Konfiguriere pip für System-Pakete..." - mkdir -p /etc/pip - cat > /etc/pip/pip.conf << 'EOF' -[global] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -timeout = 60 -retries = 3 -EOF - - # Benutzer-spezifische pip-Konfiguration - mkdir -p ~/.config/pip - cp /etc/pip/pip.conf ~/.config/pip/pip.conf - - # Python-Version validieren - local python_version=$(python3.11 --version 2>&1) - if [[ "$python_version" == *"3.11"* ]]; then - success "✅ Python 3.11 erfolgreich installiert: $python_version" - else - error "❌ Python 3.11 Installation fehlgeschlagen" - return 1 - fi - - success "✅ Saubere Python-Umgebung eingerichtet" -} - -# =========================== MINIMALES DESKTOP-ENVIRONMENT =========================== -install_minimal_desktop_environment() { - log "🖥️ MINIMALES DESKTOP-ENVIRONMENT INSTALLIEREN..." - - # Basis X11 und Window Manager - progress "Installiere X11 und minimalen Window Manager..." - apt-get install -y \ - xorg \ - xserver-xorg \ - xserver-xorg-video-fbdev \ - xinit \ - x11-xserver-utils \ - openbox \ - lightdm \ - lightdm-gtk-greeter \ - lightdm-gtk-greeter-settings - - # Chromium für Kiosk-Modus - progress "Installiere Chromium Browser..." - apt-get install -y \ - chromium-browser \ - chromium-codecs-ffmpeg-extra - - # Essenzielle Desktop-Tools - progress "Installiere essenzielle Desktop-Tools..." - apt-get install -y \ - pcmanfm \ - lxterminal \ - leafpad \ - gvfs \ - gvfs-backends \ - udisks2 \ - policykit-1 \ - network-manager \ - network-manager-gnome - - # Audio-Support - progress "Installiere Audio-Support..." - apt-get install -y \ - pulseaudio \ - pulseaudio-utils \ - alsa-utils \ - pavucontrol - - # Schriftarten - progress "Installiere Schriftarten..." - apt-get install -y \ - fonts-dejavu \ - fonts-liberation \ - fonts-noto \ - ttf-mscorefonts-installer - - # LightDM konfigurieren - progress "Konfiguriere LightDM..." - cat > /etc/lightdm/lightdm.conf << 'EOF' -[Seat:*] -autologin-user=kiosk -autologin-user-timeout=0 -user-session=openbox -greeter-session=lightdm-gtk-greeter -greeter-hide-users=false -greeter-allow-guest=false -greeter-show-manual-login=true -EOF - - # LightDM GTK Greeter konfigurieren - cat > /etc/lightdm/lightdm-gtk-greeter.conf << 'EOF' -[greeter] -background=/usr/share/pixmaps/debian-logo.png -theme-name=Adwaita -icon-theme-name=Adwaita -font-name=Sans 11 -xft-antialias=true -xft-dpi=96 -xft-hintstyle=slight -xft-rgba=rgb -show-indicators=~host;~spacer;~clock;~spacer;~session;~language;~a11y;~power -show-clock=true -clock-format=%H:%M -EOF - - success "✅ Minimales Desktop-Environment installiert" -} - -# =========================== MINIMALE X11-UMGEBUNG =========================== -install_minimal_x11() { - log "=== INSTALLIERE MINIMALE X11-UMGEBUNG FÜR KIOSK ===" - - progress "Installiere minimale X11-Pakete..." - apt-get install -y \ - xserver-xorg-core \ - xserver-xorg-input-all \ - xserver-xorg-video-fbdev \ - xserver-xorg-video-vesa \ - xinit \ - x11-xserver-utils \ - xdotool \ - unclutter \ - openbox \ - || error "X11 Installation fehlgeschlagen" - - # Browser-Installation mit Fallback-Mechanismus - progress "Installiere Browser für Kiosk-Modus..." - local browser_installed=false - - # Versuche Chromium zu installieren - if apt-get install -y chromium 2>/dev/null; then - log "✅ Chromium erfolgreich installiert" - browser_installed=true - elif apt-get install -y chromium-browser 2>/dev/null; then - log "✅ Chromium-Browser erfolgreich installiert" - browser_installed=true - elif apt-get install -y firefox-esr 2>/dev/null; then - warning "⚠️ Chromium nicht verfügbar - Firefox ESR als Fallback installiert" - browser_installed=true - fi - - if [ "$browser_installed" = false ]; then - error "❌ Kein Browser verfügbar (chromium, chromium-browser, firefox-esr)" - fi - - log "✅ Minimale X11-Umgebung installiert" -} - -# =========================== X11 KONFIGURATION FÜR RASPBERRY PI =========================== -configure_x11_for_raspberry_pi() { - log "=== KONFIGURIERE X11 FÜR RASPBERRY PI ===" - - progress "Erstelle X11-Konfiguration für Raspberry Pi..." - - # Erstelle xorg.conf.d Verzeichnis - mkdir -p /etc/X11/xorg.conf.d - - # Erstelle 99-fbdev.conf um Framebuffer-Fehler zu beheben - cat > /etc/X11/xorg.conf.d/99-fbdev.conf << 'XORGEOF' -# X11 Konfiguration für Raspberry Pi - behebt Framebuffer-Fehler -Section "Device" - Identifier "Raspberry Pi FBDEV" - Driver "fbdev" - Option "fbdev" "/dev/fb0" - Option "SwapbuffersWait" "true" -EndSection - -Section "Screen" - Identifier "Primary Screen" - Device "Raspberry Pi FBDEV" - DefaultDepth 24 - SubSection "Display" - Depth 24 - Modes "1920x1080" "1680x1050" "1600x900" "1280x1024" "1280x800" "1024x768" - EndSubSection -EndSection - -Section "ServerLayout" - Identifier "Default Layout" - Screen "Primary Screen" -EndSection - -Section "ServerFlags" - Option "BlankTime" "0" - Option "StandbyTime" "0" - Option "SuspendTime" "0" - Option "OffTime" "0" - Option "DPMS" "false" -EndSection -XORGEOF - - # Alternative: Verwende modesetting Treiber statt fbdev - cat > /etc/X11/xorg.conf.d/20-modesetting.conf << 'MODESETEOF' -# Alternative Modesetting-Konfiguration -Section "Device" - Identifier "Raspberry Pi Modesetting" - Driver "modesetting" - Option "AccelMethod" "none" -EndSection -MODESETEOF - - # Erstelle Wrapper-Skript für X11-Start mit korrekten Parametern - cat > /usr/local/bin/start-x11-kiosk << 'KIOSKSTARTEOF' -#!/bin/bash - -# X11 Kiosk-Start-Wrapper für Raspberry Pi -# Behebt Framebuffer und Permission-Probleme - -export DISPLAY=:0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# Erstelle .Xauthority falls nicht vorhanden -if [ ! -f "$XAUTHORITY" ]; then - touch "$XAUTHORITY" - chown kiosk:kiosk "$XAUTHORITY" - chmod 600 "$XAUTHORITY" -fi - -# Stoppe eventuell laufende X-Server -pkill -f "X :0" 2>/dev/null || true -pkill -f "Xorg" 2>/dev/null || true -sleep 2 - -# Versuche verschiedene X-Server Start-Methoden -echo "Starte X-Server für Kiosk-Modus..." - -# Methode 1: Mit vt und novtswitch (empfohlen für Raspberry Pi) -if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -novtswitch -nolisten tcp -dpi 96 2>/tmp/x11-error.log; then - echo "Methode 1 fehlgeschlagen, versuche Alternative..." - - # Methode 2: Mit config und ignoreABI - if ! xinit /home/kiosk/.xinitrc -- :0 vt7 -config /etc/X11/xorg.conf.d/99-fbdev.conf -ignoreABI 2>>/tmp/x11-error.log; then - echo "Methode 2 fehlgeschlagen, versuche Fallback..." - - # Methode 3: Minimaler Start - xinit /home/kiosk/.xinitrc -- :0 2>>/tmp/x11-error.log - fi -fi - -# Fehlerlog anzeigen bei Problem -if [ -f /tmp/x11-error.log ]; then - echo "X11 Fehler-Log:" - tail -20 /tmp/x11-error.log -fi -KIOSKSTARTEOF - - chmod +x /usr/local/bin/start-x11-kiosk - - # Installiere fehlende Video-Treiber - progress "Installiere Video-Treiber für Raspberry Pi..." - apt-get install -y xserver-xorg-video-fbturbo 2>/dev/null || { - # Fallback zu Standard-Treibern - apt-get install -y xserver-xorg-video-all 2>/dev/null || true - } - - # Raspberry Pi spezifische Video-Treiber - if [ -f /boot/config.txt ]; then - progress "Konfiguriere Raspberry Pi GPU-Einstellungen..." - - # Backup config.txt - cp /boot/config.txt /boot/config.txt.backup - - # GPU-Speicher erhöhen für bessere Grafik-Performance - if ! grep -q "^gpu_mem=" /boot/config.txt; then - echo "gpu_mem=128" >> /boot/config.txt - fi - - # HDMI-Einstellungen für bessere Kompatibilität - if ! grep -q "^hdmi_force_hotplug=" /boot/config.txt; then - cat >> /boot/config.txt << 'BOOTEOF' - -# X11 Kiosk-Modus Optimierungen -hdmi_force_hotplug=1 -hdmi_drive=2 -config_hdmi_boost=4 -disable_overscan=1 -framebuffer_width=1920 -framebuffer_height=1080 -framebuffer_depth=32 -framebuffer_ignore_alpha=1 -BOOTEOF - fi - fi - - # Erstelle alternatives .xinitrc für kiosk User - cat > /home/kiosk/.xinitrc-fixed << 'XINITRCEOF' -#!/bin/bash - -# Fehlerbehandlung -set -e -exec 2>/tmp/xinitrc-error.log - -# X11 Einstellungen -xset s off -xset s noblank -xset -dpms - -# Mauszeiger verstecken -unclutter -idle 0.1 -root -noevents & - -# Window Manager starten (lightweight) -openbox-session & - -# Warte kurz -sleep 2 - -# Browser starten -if command -v chromium >/dev/null 2>&1; then - BROWSER="chromium" -elif command -v chromium-browser >/dev/null 2>&1; then - BROWSER="chromium-browser" -else - BROWSER="firefox-esr" -fi - -# Starte Browser im Kiosk-Modus -exec $BROWSER \ - --kiosk \ - --no-sandbox \ - --disable-gpu-sandbox \ - --disable-software-rasterizer \ - --disable-dev-shm-usage \ - --disable-setuid-sandbox \ - --disable-gpu \ - --no-first-run \ - --noerrdialogs \ - --disable-infobars \ - --start-fullscreen \ - http://localhost:5000 -XINITRCEOF - - chmod +x /home/kiosk/.xinitrc-fixed - chown kiosk:kiosk /home/kiosk/.xinitrc-fixed - - # Aktualisiere die .bashrc für den alternativen Start - cat > /home/kiosk/.bashrc-kiosk << 'BASHRCEOF4' -# Kiosk-Autostart mit X11-Fixes -if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then - echo "Starte Kiosk-Modus mit X11-Fixes..." - - # Verwende das neue Start-Skript - exec /usr/local/bin/start-x11-kiosk -fi -BASHRCEOF4 - - log "✅ X11-Konfiguration für Raspberry Pi erstellt" - info " 📁 Konfiguration: /etc/X11/xorg.conf.d/" - info " 🚀 Start-Skript: /usr/local/bin/start-x11-kiosk" - info " 🔧 Alternative .xinitrc: /home/kiosk/.xinitrc-fixed" -} - -# =========================== KIOSK-BENUTZER MANAGEMENT =========================== -create_kiosk_user() { - log "=== KIOSK-BENUTZER SETUP ===" - - if ! id "$KIOSK_USER" &>/dev/null; then - progress "Erstelle Kiosk-Benutzer: $KIOSK_USER" - useradd -m -s /bin/bash "$KIOSK_USER" || error "Kann Kiosk-Benutzer nicht erstellen" - - # Gruppen hinzufügen - usermod -aG audio,video,input,dialout,plugdev,users "$KIOSK_USER" 2>/dev/null || true - - # pip-Konfiguration für Kiosk-Benutzer - local kiosk_home="/home/$KIOSK_USER" - mkdir -p "$kiosk_home/.pip" 2>/dev/null || true - cat > "$kiosk_home/.pip/pip.conf" << 'EOF' -[global] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -timeout = 60 -retries = 3 - -[install] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -EOF - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.pip/pip.conf" 2>/dev/null || true - else - info "Kiosk-Benutzer $KIOSK_USER existiert bereits" - fi - - # Passwort entfernen für automatischen Login - passwd -d "$KIOSK_USER" || warning "Konnte Passwort nicht entfernen" - - log "✅ Kiosk-Benutzer konfiguriert: $KIOSK_USER" -} - -configure_autologin() { - log "=== KONFIGURIERE AUTOLOGIN FÜR KIOSK-BENUTZER ===" - - # Getty-Service für automatischen Login konfigurieren - progress "Konfiguriere automatischen Login auf tty1..." - - local getty_override_dir="/etc/systemd/system/getty@tty1.service.d" - mkdir -p "$getty_override_dir" - - cat > "$getty_override_dir/override.conf" << EOF -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin $KIOSK_USER --noclear %I \$TERM -EOF - - # Systemd-Konfiguration neu laden - systemctl daemon-reload - systemctl enable getty@tty1.service - - log "✅ Autologin für $KIOSK_USER konfiguriert" -} - -configure_kiosk_autostart() { - log "=== KONFIGURIERE AUTOMATISCHEN KIOSK-START ===" - - # Erstelle .bashrc für automatischen X-Server und Browser-Start - progress "Konfiguriere automatischen Kiosk-Start für $KIOSK_USER..." - - local kiosk_home="/home/$KIOSK_USER" - - # .bashrc für automatischen Start erstellen - cat > "$kiosk_home/.bashrc" << 'EOF' -# Automatischer Kiosk-Start beim Login -if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then - echo "Starte Kiosk-Modus..." - - # X-Server im Hintergrund starten - startx /home/kiosk/.xinitrc -- :0 vt1 & - - # Warte bis X-Server bereit ist - sleep 5 - - # Setze DISPLAY-Variable - export DISPLAY=:0 - - # Warte auf HTTP-Backend - echo "Warte auf HTTP-Backend..." - for i in {1..60}; do - if curl -s http://localhost:5000 >/dev/null 2>&1; then - echo "HTTP-Backend erreichbar" - break - fi - echo "Warte... ($i/60)" - sleep 2 - done - - # Bildschirmschoner deaktivieren - xset s off - xset s noblank - xset -dpms - - # Mauszeiger verstecken - unclutter -idle 0.1 -root -noevents & - - # Browser im Kiosk-Modus starten - if command -v chromium >/dev/null 2>&1; then - BROWSER="chromium" - elif command -v chromium-browser >/dev/null 2>&1; then - BROWSER="chromium-browser" - else - BROWSER="firefox-esr" - fi - - echo "Starte $BROWSER im Kiosk-Modus..." - - if [[ "$BROWSER" == "chromium"* ]]; then - exec $BROWSER \ - --kiosk \ - --no-sandbox \ - --disable-infobars \ - --disable-session-crashed-bubble \ - --disable-restore-session-state \ - --disable-features=TranslateUI \ - --disable-extensions \ - --disable-plugins \ - --disable-popup-blocking \ - --disable-prompt-on-repost \ - --disable-sync \ - --disable-translate \ - --noerrdialogs \ - --no-first-run \ - --no-default-browser-check \ - --autoplay-policy=no-user-gesture-required \ - --start-fullscreen \ - --start-maximized \ - --user-data-dir=/home/kiosk/.chromium-kiosk \ - --disable-background-mode \ - --force-device-scale-factor=1.0 \ - --disable-pinch \ - --overscroll-history-navigation=0 \ - --disable-dev-shm-usage \ - --memory-pressure-off \ - --max_old_space_size=512 \ - --disable-background-timer-throttling \ - --disable-backgrounding-occluded-windows \ - --disable-renderer-backgrounding \ - --disable-features=VizDisplayCompositor \ - --enable-features=OverlayScrollbar \ - --hide-scrollbars \ - --ignore-certificate-errors \ - --ignore-ssl-errors \ - --ignore-certificate-errors-spki-list \ - --disable-web-security \ - --allow-running-insecure-content \ - http://localhost:5000 - else - exec firefox-esr \ - --kiosk \ - http://localhost:5000 - fi -fi -EOF - - # .xinitrc für X-Server-Konfiguration erstellen - cat > "$kiosk_home/.xinitrc" << 'EOF' -#!/bin/bash -# Minimale X-Session für Kiosk-Modus -exec openbox-session -EOF - - # Berechtigungen setzen - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.xinitrc" - chmod +x "$kiosk_home/.xinitrc" - - # Erstelle Kiosk-Verzeichnisse - mkdir -p "$kiosk_home/.chromium-kiosk" - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.chromium-kiosk" - - # X11-Autorisierung für kiosk-User konfigurieren - progress "Konfiguriere X11-Autorisierung für kiosk-User..." - - # Erstelle .Xauthority Datei - touch "$kiosk_home/.Xauthority" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.Xauthority" - chmod 600 "$kiosk_home/.Xauthority" - - # Füge DISPLAY-Variable zum .bashrc hinzu - if ! grep -q "export DISPLAY=" "$kiosk_home/.bashrc" 2>/dev/null; then - cat >> "$kiosk_home/.bashrc" << 'BASHRCEOF3' - -# X11 Display Konfiguration -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# X11 Session Management -if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then - export DISPLAY=:0.0 -fi - -BASHRCEOF3 - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - fi - - # Erstelle X11-Startup-Hilfsskript - cat > "$kiosk_home/start-x11.sh" << 'EOF' -#!/bin/bash - -# X11-Startup-Hilfsskript für kiosk-User -# Behebt .Xauthority und DISPLAY-Probleme - -export HOME=/home/kiosk -export USER=kiosk -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# Erstelle .Xauthority falls nicht vorhanden -if [ ! -f "$XAUTHORITY" ]; then - touch "$XAUTHORITY" - chmod 600 "$XAUTHORITY" -fi - -# Prüfe ob X11-Server läuft -if ! pgrep -x "X" > /dev/null && ! pgrep -x "Xorg" > /dev/null; then - echo "Starte X11-Server..." - startx /home/kiosk/.xinitrc -- :0 vt1 & - sleep 3 -fi - -# Warte bis X11-Server verfügbar ist -timeout=30 -elapsed=0 -while [ $elapsed -lt $timeout ]; do - if xset q >/dev/null 2>&1; then - echo "X11-Server ist bereit" - break - fi - sleep 1 - elapsed=$((elapsed + 1)) -done - -if [ $elapsed -ge $timeout ]; then - echo "FEHLER: X11-Server nicht verfügbar nach ${timeout}s" - exit 1 -fi - -echo "X11-Session erfolgreich gestartet" -EOF - - chmod +x "$kiosk_home/start-x11.sh" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/start-x11.sh" - - log "✅ Automatischer Kiosk-Start konfiguriert" - info "Der Kiosk-Modus startet automatisch beim Login des $KIOSK_USER" - - # Wenn X11-Konfiguration für Raspberry Pi vorhanden ist, verwende sie - if [ -f /usr/local/bin/start-x11-kiosk ]; then - progress "Aktualisiere .bashrc für X11-Fix-Integration..." - - # Backup der aktuellen .bashrc - cp "$kiosk_home/.bashrc" "$kiosk_home/.bashrc.backup" - - # Verwende die korrigierte Version - cat > "$kiosk_home/.bashrc" << 'BASHRCFIXED' -# Automatischer Kiosk-Start beim Login mit X11-Fixes -if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then - echo "Starte Kiosk-Modus mit X11-Fixes..." - - # Verwende das X11-Fix Start-Skript wenn vorhanden - if [ -x /usr/local/bin/start-x11-kiosk ]; then - exec /usr/local/bin/start-x11-kiosk - else - # Fallback zum normalen Start - startx /home/kiosk/.xinitrc -- :0 vt1 & - sleep 5 - export DISPLAY=:0 - - # Warte auf HTTP-Backend - echo "Warte auf HTTP-Backend..." - for i in {1..60}; do - if curl -s http://localhost:5000 >/dev/null 2>&1; then - echo "HTTP-Backend erreichbar" - break - fi - echo "Warte... ($i/60)" - sleep 2 - done - - # Bildschirmschoner deaktivieren - xset s off - xset s noblank - xset -dpms - - # Mauszeiger verstecken - unclutter -idle 0.1 -root -noevents & - - # Browser im Kiosk-Modus starten - if command -v chromium >/dev/null 2>&1; then - BROWSER="chromium" - elif command -v chromium-browser >/dev/null 2>&1; then - BROWSER="chromium-browser" - else - BROWSER="firefox-esr" - fi - - echo "Starte $BROWSER im Kiosk-Modus..." - - if [[ "$BROWSER" == "chromium"* ]]; then - exec $BROWSER \ - --kiosk \ - --no-sandbox \ - --disable-infobars \ - --disable-session-crashed-bubble \ - --disable-restore-session-state \ - --disable-features=TranslateUI \ - --disable-extensions \ - --disable-plugins \ - --disable-popup-blocking \ - --disable-prompt-on-repost \ - --disable-sync \ - --disable-translate \ - --noerrdialogs \ - --no-first-run \ - --no-default-browser-check \ - --autoplay-policy=no-user-gesture-required \ - --start-fullscreen \ - --start-maximized \ - --user-data-dir=/home/kiosk/.chromium-kiosk \ - --disable-background-mode \ - --force-device-scale-factor=1.0 \ - --disable-pinch \ - --overscroll-history-navigation=0 \ - --disable-dev-shm-usage \ - --memory-pressure-off \ - --max_old_space_size=512 \ - --disable-background-timer-throttling \ - --disable-backgrounding-occluded-windows \ - --disable-renderer-backgrounding \ - --disable-features=VizDisplayCompositor \ - --enable-features=OverlayScrollbar \ - --hide-scrollbars \ - --ignore-certificate-errors \ - --ignore-ssl-errors \ - --ignore-certificate-errors-spki-list \ - --disable-web-security \ - --allow-running-insecure-content \ - http://localhost:5000 - else - exec firefox-esr \ - --kiosk \ - http://localhost:5000 - fi - fi -fi -BASHRCFIXED - - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - log "✅ .bashrc für X11-Fix-Integration aktualisiert" - fi -} - -# =========================== ROBUSTE AUTOLOGIN-KONFIGURATION =========================== -configure_autologin_robust() { - log "🔐 ROBUSTE AUTOLOGIN-KONFIGURATION" - - progress "Konfiguriere robusten automatischen Login..." - - # Mehrere Autologin-Methoden parallel konfigurieren - local autologin_success=false - - # Methode 1: Getty-Service (Standard) - progress "Konfiguriere Getty-Service für Autologin..." - local getty_override_dir="/etc/systemd/system/getty@tty1.service.d" - mkdir -p "$getty_override_dir" - - cat > "$getty_override_dir/override.conf" << EOF -[Service] -ExecStart= -ExecStart=-/sbin/agetty --autologin $KIOSK_USER --noclear %I \$TERM -Type=idle -Restart=always -RestartSec=0 -EOF - - # Methode 2: LightDM Autologin (falls installiert) - if [ -f /etc/lightdm/lightdm.conf ]; then - progress "Konfiguriere LightDM Autologin..." - - # Backup erstellen - cp /etc/lightdm/lightdm.conf /etc/lightdm/lightdm.conf.backup 2>/dev/null || true - - # LightDM für Autologin konfigurieren - cat > /etc/lightdm/lightdm.conf << EOF -[Seat:*] -autologin-user=$KIOSK_USER -autologin-user-timeout=0 -user-session=openbox -greeter-session=lightdm-gtk-greeter -greeter-hide-users=false -greeter-allow-guest=false -greeter-show-manual-login=false -EOF - - # LightDM aktivieren - systemctl enable lightdm 2>/dev/null || true - autologin_success=true - fi - - # Methode 3: Nodm (minimaler Display Manager) - progress "Installiere und konfiguriere nodm als Fallback..." - if apt-get install -y nodm 2>/dev/null; then - cat > /etc/default/nodm << EOF -# nodm configuration -NODM_ENABLED=true -NODM_USER=$KIOSK_USER -NODM_FIRST_VT=7 -NODM_XSESSION=/home/$KIOSK_USER/.xsession -NODM_X_OPTIONS='-nolisten tcp' -NODM_MIN_SESSION_TIME=60 -NODM_X_TIMEOUT=300 -EOF - - # .xsession für nodm erstellen - cat > "/home/$KIOSK_USER/.xsession" << 'EOF' -#!/bin/bash -exec openbox-session -EOF - chmod +x "/home/$KIOSK_USER/.xsession" - chown "$KIOSK_USER:$KIOSK_USER" "/home/$KIOSK_USER/.xsession" - - systemctl enable nodm 2>/dev/null || true - autologin_success=true - fi - - # Systemd-Services neu laden - systemctl daemon-reload - systemctl enable getty@tty1.service - - # Passwort für kiosk-User entfernen (für alle Methoden) - progress "Entferne Passwort für automatischen Login..." - passwd -d "$KIOSK_USER" 2>/dev/null || warning "Konnte Passwort nicht entfernen" - - # Zusätzliche Sicherheit: User in autologin-Gruppe - if ! getent group autologin >/dev/null 2>&1; then - groupadd autologin 2>/dev/null || true - fi - usermod -a -G autologin "$KIOSK_USER" 2>/dev/null || true - - success "✅ Robuste Autologin-Konfiguration abgeschlossen" - info " → Getty-Service: Konfiguriert" - info " → LightDM: $([ -f /etc/lightdm/lightdm.conf ] && echo "Konfiguriert" || echo "Nicht verfügbar")" - info " → Nodm: $(command -v nodm >/dev/null && echo "Installiert" || echo "Nicht verfügbar")" -} - -# =========================== ROBUSTE KIOSK-AUTOSTART-KONFIGURATION =========================== -configure_kiosk_autostart_robust() { - log "🚀 ROBUSTE KIOSK-AUTOSTART-KONFIGURATION" - - local kiosk_home="/home/$KIOSK_USER" - - progress "Erstelle robuste Kiosk-Autostart-Konfiguration..." - - # Erstelle robuste .bashrc mit mehreren Fallback-Strategien - cat > "$kiosk_home/.bashrc" << 'BASHRC_ROBUST' -#!/bin/bash - -# Robuste Kiosk-Autostart-Konfiguration -# Mehrere Fallback-Strategien für maximale Zuverlässigkeit - -# Nur auf tty1 ausführen -if [ "$XDG_VTNR" != "1" ] && [ "$(tty)" != "/dev/tty1" ]; then - return -fi - -# Verhindere mehrfache Ausführung -if [ -f /tmp/kiosk-starting ]; then - echo "Kiosk-Start bereits in Bearbeitung..." - return -fi - -# Lock-Datei erstellen -touch /tmp/kiosk-starting - -echo "=== ROBUSTER KIOSK-START ===" -echo "Benutzer: $(whoami)" -echo "TTY: $(tty)" -echo "VT: $XDG_VTNR" -echo "Display: $DISPLAY" - -# Umgebungsvariablen setzen -export HOME=/home/kiosk -export USER=kiosk -export DISPLAY=:0 -export XAUTHORITY=/home/kiosk/.Xauthority - -# Funktion: X11-Server starten -start_x11_server() { - echo "Starte X11-Server..." - - # Alte X-Prozesse beenden - pkill -f "X :0" 2>/dev/null || true - pkill -f "Xorg" 2>/dev/null || true - sleep 2 - - # .Xauthority erstellen - if [ ! -f "$XAUTHORITY" ]; then - touch "$XAUTHORITY" - chmod 600 "$XAUTHORITY" - fi - - # X11-Server starten (mehrere Methoden) - if [ -x /usr/local/bin/start-x11-kiosk ]; then - echo "Verwende optimiertes X11-Start-Skript..." - /usr/local/bin/start-x11-kiosk & - else - echo "Verwende Standard X11-Start..." - startx /home/kiosk/.xinitrc -- :0 vt7 -novtswitch & - fi - - # Warte auf X11-Server - local timeout=30 - local elapsed=0 - while [ $elapsed -lt $timeout ]; do - if xset q >/dev/null 2>&1; then - echo "✅ X11-Server ist bereit" - return 0 - fi - sleep 1 - elapsed=$((elapsed + 1)) - echo "Warte auf X11-Server... ($elapsed/$timeout)" - done - - echo "❌ X11-Server timeout nach ${timeout}s" - return 1 -} - -# Funktion: Backend-Verfügbarkeit prüfen -wait_for_backend() { - echo "Warte auf MYP-Backend..." - - local timeout=120 - local elapsed=0 - - while [ $elapsed -lt $timeout ]; do - if curl -s --connect-timeout 2 http://localhost:5000 >/dev/null 2>&1; then - echo "✅ MYP-Backend ist verfügbar" - return 0 - fi - sleep 2 - elapsed=$((elapsed + 2)) - echo "Warte auf Backend... ($elapsed/$timeout)" - done - - echo "⚠️ Backend nicht verfügbar nach ${timeout}s - starte trotzdem" - return 1 -} - -# Funktion: Browser starten -start_browser() { - echo "Starte Browser im Kiosk-Modus..." - - # Browser-Auswahl - local browser="" - if command -v chromium >/dev/null 2>&1; then - browser="chromium" - elif command -v chromium-browser >/dev/null 2>&1; then - browser="chromium-browser" - elif command -v firefox-esr >/dev/null 2>&1; then - browser="firefox-esr" - else - echo "❌ Kein Browser verfügbar" - return 1 - fi - - echo "Verwende Browser: $browser" - - # Bildschirmschoner deaktivieren - xset s off 2>/dev/null || true - xset s noblank 2>/dev/null || true - xset -dpms 2>/dev/null || true - - # Mauszeiger verstecken - unclutter -idle 0.1 -root -noevents & - - # Browser-spezifische Konfiguration - if [[ "$browser" == "chromium"* ]]; then - # Chromium-Verzeichnis erstellen - mkdir -p /home/kiosk/.chromium-kiosk - - exec $browser \ - --kiosk \ - --no-sandbox \ - --disable-infobars \ - --disable-session-crashed-bubble \ - --disable-restore-session-state \ - --disable-features=TranslateUI \ - --disable-extensions \ - --disable-plugins \ - --disable-popup-blocking \ - --disable-prompt-on-repost \ - --disable-sync \ - --disable-translate \ - --noerrdialogs \ - --no-first-run \ - --no-default-browser-check \ - --autoplay-policy=no-user-gesture-required \ - --start-fullscreen \ - --start-maximized \ - --user-data-dir=/home/kiosk/.chromium-kiosk \ - --disable-background-mode \ - --force-device-scale-factor=1.0 \ - --disable-pinch \ - --overscroll-history-navigation=0 \ - --disable-dev-shm-usage \ - --memory-pressure-off \ - --max_old_space_size=512 \ - --disable-background-timer-throttling \ - --disable-backgrounding-occluded-windows \ - --disable-renderer-backgrounding \ - --disable-features=VizDisplayCompositor \ - --enable-features=OverlayScrollbar \ - --hide-scrollbars \ - --ignore-certificate-errors \ - --ignore-ssl-errors \ - --ignore-certificate-errors-spki-list \ - --disable-web-security \ - --allow-running-insecure-content \ - http://localhost:5000 - else - exec firefox-esr \ - --kiosk \ - http://localhost:5000 - fi -} - -# Hauptlogik: Robuster Kiosk-Start -main_kiosk_start() { - echo "Starte Hauptlogik..." - - # X11-Server starten - if ! start_x11_server; then - echo "❌ X11-Server Start fehlgeschlagen" - rm -f /tmp/kiosk-starting - return 1 - fi - - # Kurz warten für X11-Stabilisierung - sleep 3 - - # Backend-Verfügbarkeit prüfen (nicht blockierend) - wait_for_backend - - # Browser starten - start_browser - - # Lock-Datei entfernen - rm -f /tmp/kiosk-starting -} - -# Nur ausführen wenn DISPLAY nicht gesetzt ist (verhindert Rekursion) -if [ -z "$DISPLAY" ]; then - main_kiosk_start -fi -BASHRC_ROBUST - - # .xinitrc für minimale X-Session erstellen - cat > "$kiosk_home/.xinitrc" << 'XINITRC_ROBUST' -#!/bin/bash - -# Robuste .xinitrc für Kiosk-Modus -# Minimale X-Session mit Fehlerbehandlung - -# Umgebungsvariablen setzen -export HOME=/home/kiosk -export USER=kiosk - -# Fehlerbehandlung aktivieren -set -e -trap 'echo "Fehler in .xinitrc: $?" >&2' ERR - -# X11-Ressourcen laden (falls vorhanden) -if [ -f "$HOME/.Xresources" ]; then - xrdb -merge "$HOME/.Xresources" 2>/dev/null || true -fi - -# Openbox-Session starten -exec openbox-session -XINITRC_ROBUST - - # Berechtigungen setzen - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.xinitrc" - chmod +x "$kiosk_home/.xinitrc" - - # Kiosk-Verzeichnisse erstellen - mkdir -p "$kiosk_home/.chromium-kiosk" - mkdir -p "$kiosk_home/.config" - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.chromium-kiosk" - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.config" - - # X11-Autorisierung konfigurieren - touch "$kiosk_home/.Xauthority" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.Xauthority" - chmod 600 "$kiosk_home/.Xauthority" - - # Systemd-Service für Kiosk-Überwachung erstellen - progress "Erstelle Kiosk-Überwachungsservice..." - cat > /etc/systemd/system/kiosk-watchdog.service << 'WATCHDOG_SERVICE' -[Unit] -Description=MYP Kiosk Watchdog -After=graphical-session.target -Wants=graphical-session.target - -[Service] -Type=simple -User=root -ExecStart=/usr/local/bin/kiosk-watchdog.sh -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target -WATCHDOG_SERVICE - - # Kiosk-Watchdog-Skript erstellen - cat > /usr/local/bin/kiosk-watchdog.sh << 'WATCHDOG_SCRIPT' -#!/bin/bash - -# MYP Kiosk Watchdog -# Überwacht und startet Kiosk-Prozesse neu bei Bedarf - -LOG_FILE="/var/log/kiosk-watchdog.log" - -log() { - echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" -} - -log "Kiosk-Watchdog gestartet" - -while true; do - # Prüfe ob kiosk-User eingeloggt ist - if ! who | grep -q "kiosk"; then - log "Kiosk-User nicht eingeloggt - warte..." - sleep 30 - continue - fi - - # Prüfe ob X11-Server läuft - if ! pgrep -x "X" >/dev/null && ! pgrep -x "Xorg" >/dev/null; then - log "X11-Server nicht gefunden - Neustart erforderlich" - # Hier könnte ein Neustart-Mechanismus implementiert werden - fi - - # Prüfe ob Browser läuft - if ! pgrep -f "chromium.*kiosk" >/dev/null && ! pgrep -f "firefox.*kiosk" >/dev/null; then - log "Browser nicht gefunden - könnte Neustart benötigen" - fi - - sleep 60 -done -WATCHDOG_SCRIPT - - chmod +x /usr/local/bin/kiosk-watchdog.sh - systemctl enable kiosk-watchdog.service 2>/dev/null || true - - success "✅ Robuste Kiosk-Autostart-Konfiguration abgeschlossen" - info " → Mehrfache Fallback-Strategien implementiert" - info " → X11-Server-Überwachung aktiviert" - info " → Browser-Neustart-Mechanismus konfiguriert" - info " → Watchdog-Service installiert" -} - -# =========================== ROBUSTE SSL-ZERTIFIKATE INSTALLATION =========================== -install_ssl_certificates() { - log "=== ANTI-HÄNGE SSL-ZERTIFIKATE KONFIGURATION ===" - - progress "Installiere SSL-Grundkomponenten (timeout-gesichert)..." - if timeout 60 apt-get install -y ca-certificates openssl 2>/dev/null; then - success "✅ SSL-Grundkomponenten installiert" - else - warning "⚠️ SSL-Installation timeout - verwende bestehende" - fi - - progress "Überspringe CA-Update um Hänger zu vermeiden..." - info "💡 CA-Zertifikate werden beim nächsten Boot automatisch aktualisiert" - - # SSL-Verzeichnisse sicherstellen (timeout-gesichert) - timeout 10 mkdir -p /usr/local/share/ca-certificates/myp 2>/dev/null || true - - # Mercedes Corporate Zertifikate (ultra-vereinfacht) - if [ -d "$CURRENT_DIR/certs/mercedes" ] && [ "$(ls -A $CURRENT_DIR/certs/mercedes 2>/dev/null)" ]; then - progress "Kopiere Mercedes-Zertifikate (max 30s)..." - - # Sehr einfacher und schneller Ansatz - timeout 30 bash -c ' - cert_count=0 - find "$1/certs/mercedes" -name "*.crt" -o -name "*.pem" | head -5 | while read cert_file; do - cert_count=$((cert_count + 1)) - cert_name="mercedes-$(basename "$cert_file" | cut -d. -f1)" - if cp "$cert_file" "/usr/local/share/ca-certificates/myp/${cert_name}.crt" 2>/dev/null; then - echo "Zertifikat kopiert: $cert_name" - fi - [ $cert_count -ge 5 ] && break - done - ' -- "$CURRENT_DIR" 2>/dev/null || warning "Mercedes-Zertifikate timeout - überspringe" - - info "Mercedes-Zertifikate werden beim nächsten Boot aktiv" - else - info "Keine Mercedes-Zertifikate gefunden" - fi - - # SSL-Umgebungsvariablen setzen (timeout-gesichert) - progress "Konfiguriere SSL-Umgebungsvariablen (schnell)..." - timeout 10 bash -c 'cat >> /etc/environment << "EOF" - -# SSL Certificate Configuration für MYP -SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt -REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt -CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt -EOF' || warning "SSL-Umgebungsvariablen timeout" - - # SSL-Umgebungsvariablen für aktuelle Session - export SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt" 2>/dev/null || true - export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" 2>/dev/null || true - export CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" 2>/dev/null || true - - log "✅ SSL-Zertifikate anti-hänge konfiguriert" - info "📝 CA-Updates werden automatisch beim nächsten Boot durchgeführt" -} - -# =========================== ROBUSTES ANWENDUNGS-DEPLOYMENT =========================== -deploy_application() { - log "=== ROBUSTES ANWENDUNGS-DEPLOYMENT ===" - - if [ "$GIT_CLONE_MODE" = true ]; then - log "📦 GIT-CLONE zu PRODUKTIONS-DEPLOYMENT" - log " 📂 Quelle: $SOURCE_BACKEND_DIR" - log " 🎯 Ziel: $APP_DIR" - - # Prüfe ob wir bereits im Zielverzeichnis sind (Schutz vor Selbst-Überschreibung) - if [[ "$SOURCE_BACKEND_DIR" == "$APP_DIR"* ]]; then - log "✅ Bereits im Produktions-Verzeichnis - überspringe Deployment" - return 0 - fi - else - log "🏠 PRODUKTIONS-VERZEICHNIS-UPDATE" - fi - - progress "Erstelle sicheres Zielverzeichnis: $APP_DIR" - mkdir -p "$APP_DIR" || error "Konnte Zielverzeichnis nicht erstellen" - - # Validiere Source-Verzeichnis (angepasst für Git-Clone-Modus) - progress "Validiere Source-Dateien..." - local source_app_py="$SOURCE_BACKEND_DIR/app.py" - local source_requirements="$SOURCE_BACKEND_DIR/requirements.txt" - - if [ ! -f "$source_app_py" ]; then - error "Kritische Datei nicht gefunden: $source_app_py" - fi - - if [ ! -f "$source_requirements" ]; then - error "Kritische Datei nicht gefunden: $source_requirements" - fi - - progress "Kopiere Anwendungsdateien (Git-Clone-bewusst)..." - - # Kritische Backend-Dateien zuerst (mit Validierung) - local critical_files=( - "app.py" - "models.py" - "requirements.txt" - "setup.sh" - ) - - for file in "${critical_files[@]}"; do - local source_file="$SOURCE_BACKEND_DIR/$file" - if [ -f "$source_file" ]; then - progress "Kopiere kritische Datei: $file" - if cp "$source_file" "$APP_DIR/" 2>/dev/null; then - success "✅ $file erfolgreich kopiert" - else - error "❌ Fehler beim Kopieren der kritischen Datei: $file" - fi - else - error "❌ Kritische Datei fehlt: $source_file" - fi - done - - # Backend-Verzeichnisse mit robuster Behandlung - local directories=( - "blueprints" - "config" - "database" - "static" - "templates" - "uploads" - "utils" - "logs" - "certs" - "systemd" - "scripts" - ) - - for dir in "${directories[@]}"; do - local source_dir="$SOURCE_BACKEND_DIR/$dir" - if [ -d "$source_dir" ]; then - progress "Kopiere Backend-Verzeichnis: $dir" - if cp -r "$source_dir" "$APP_DIR/" 2>/dev/null; then - success "✅ $dir erfolgreich kopiert" - else - warning "⚠️ Fehler beim Kopieren von $dir (möglicherweise nicht kritisch)" - fi - else - info "Backend-Verzeichnis nicht vorhanden: $source_dir" - fi - done - - # Optionale Backend-Dateien - local optional_files=( - "package.json" - "package-lock.json" - "tailwind.config.js" - "postcss.config.js" - "README.md" - ".gitignore" - "requirements_clean.txt" - "fix_ssl_raspberry.sh" - "COMMON_ERRORS.md" - "RASPBERRY_PI_SSL_FIX.md" - ) - - for file in "${optional_files[@]}"; do - local source_file="$SOURCE_BACKEND_DIR/$file" - if [ -f "$source_file" ]; then - progress "Kopiere optionale Backend-Datei: $file" - cp "$source_file" "$APP_DIR/" 2>/dev/null || warning "⚠️ Kopieren von $file fehlgeschlagen" - fi - done - - # Git-Clone-Modus: Kopiere auch wichtige Root-Projekt-Dateien - if [ "$GIT_CLONE_MODE" = true ]; then - progress "Kopiere Projekt-Root-Dateien..." - - local root_files=( - "README.md" - "CLAUDE.md" - ) - - for file in "${root_files[@]}"; do - local source_file="$PROJECT_ROOT_DIR/$file" - if [ -f "$source_file" ]; then - progress "Kopiere Root-Datei: $file" - cp "$source_file" "$APP_DIR/" 2>/dev/null || warning "⚠️ Kopieren von Root-$file fehlgeschlagen" - fi - done - - # Dokumentationsverzeichnis falls vorhanden - if [ -d "$PROJECT_ROOT_DIR/docs" ]; then - progress "Kopiere Dokumentation..." - cp -r "$PROJECT_ROOT_DIR/docs" "$APP_DIR/" 2>/dev/null || warning "⚠️ Kopieren der Dokumentation fehlgeschlagen" - fi - fi - - # Erstelle alle notwendigen Verzeichnisse mit korrekter Struktur - progress "Erstelle Verzeichnisstruktur..." - local required_dirs=( - "database/backups" - "logs/app" - "logs/auth" - "logs/errors" - "logs/system" - "uploads/temp" - "uploads/assets" - "uploads/avatars" - "uploads/backups" - "uploads/jobs" - "certs/localhost" - "instance" - "instance/ssl" - ) - - for dir in "${required_dirs[@]}"; do - mkdir -p "$APP_DIR/$dir" 2>/dev/null || warning "⚠️ Verzeichnis $dir konnte nicht erstellt werden" - done - - # Sichere Berechtigungen setzen (robuster) - progress "Setze sichere Berechtigungen..." - - # Basis-Berechtigungen - chown -R root:root "$APP_DIR" 2>/dev/null || warning "⚠️ Ownership konnte nicht gesetzt werden" - chmod 755 "$APP_DIR" 2>/dev/null || warning "⚠️ Verzeichnis-Permissions konnten nicht gesetzt werden" - - # Ausführbare Dateien - if [ -f "$APP_DIR/app.py" ]; then - chmod +x "$APP_DIR/app.py" 2>/dev/null || warning "⚠️ app.py Ausführberechtigung konnte nicht gesetzt werden" - fi - - # Sensitive Verzeichnisse - chmod 750 "$APP_DIR/database" 2>/dev/null || true - chmod 750 "$APP_DIR/logs" 2>/dev/null || true - chmod 750 "$APP_DIR/certs" 2>/dev/null || true - chmod 750 "$APP_DIR/instance" 2>/dev/null || true - - # Upload-Verzeichnisse - chmod 755 "$APP_DIR/uploads" 2>/dev/null || true - chmod 755 "$APP_DIR/static" 2>/dev/null || true - - # Python-Umgebung robust konfigurieren - progress "Konfiguriere robuste Python-Umgebung..." - - # Ermittle Python site-packages Verzeichnis (robust) - local python_site_packages="" - for possible_path in \ - "$(python3 -c "import site; print(site.getsitepackages()[0])" 2>/dev/null)" \ - "/usr/local/lib/python3/dist-packages" \ - "/usr/lib/python3/dist-packages" \ - "/usr/local/lib/python$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null)/dist-packages"; do - - if [ -d "$possible_path" ]; then - python_site_packages="$possible_path" - break - fi - done - - if [ -n "$python_site_packages" ]; then - echo "$APP_DIR" > "$python_site_packages/myp-app.pth" 2>/dev/null || warning "⚠️ Python-Pfad konnte nicht konfiguriert werden" - log "✅ Python-Pfad konfiguriert: $python_site_packages/myp-app.pth" - else - warning "⚠️ Python site-packages Verzeichnis nicht gefunden" - fi - - # Systemweite Umgebungsvariablen robust setzen - progress "Konfiguriere Umgebungsvariablen..." - cat >> /etc/environment << EOF - -# MYP Application Environment -MYP_APP_DIR=$APP_DIR -PYTHONPATH=$APP_DIR:\${PYTHONPATH:-} -FLASK_APP=$APP_DIR/app.py -FLASK_ENV=production -EOF - - # Bash-Profile Updates (optional - überspringen bei Problemen) - progress "Versuche Bash-Profile zu aktualisieren (optional)..." - - # Führe Updates nur in einem Subshell mit Timeout aus - ( - # Setze eine maximale Laufzeit von 10 Sekunden für alle Bash-Profile Updates - export BASH_PROFILE_TIMEOUT=10 - - # Starte einen Background-Timer - (sleep $BASH_PROFILE_TIMEOUT && kill -TERM $$ 2>/dev/null) & - local timer_pid=$! - - # Nur /root/.bashrc aktualisieren (schnell und sicher) - if [ -f "/root/.bashrc" ] && [ -w "/root/.bashrc" ]; then - if ! grep -q "MYP Application Environment" "/root/.bashrc" 2>/dev/null; then - echo "" >> "/root/.bashrc" - echo "# MYP Application Environment" >> "/root/.bashrc" - echo 'if [ -d "/opt/myp" ]; then' >> "/root/.bashrc" - echo ' export MYP_APP_DIR="/opt/myp"' >> "/root/.bashrc" - echo ' export FLASK_APP="/opt/myp/app.py"' >> "/root/.bashrc" - echo ' export FLASK_ENV="production"' >> "/root/.bashrc" - echo ' export PYTHONPATH="/opt/myp:${PYTHONPATH:-}"' >> "/root/.bashrc" - echo 'fi' >> "/root/.bashrc" - log "✅ Root Bash-Profile aktualisiert" - fi - fi - - # Timer beenden - kill $timer_pid 2>/dev/null || true - - ) 2>/dev/null || { - warning "⚠️ Bash-Profile Update übersprungen (Timeout oder Fehler)" - debug "Bash-Profile Updates sind optional - Installation wird fortgesetzt" - } - - # Validiere Deployment - progress "Validiere Application Deployment..." - local validation_errors=0 - - # Prüfe kritische Dateien - for file in "app.py" "models.py" "requirements.txt"; do - if [ ! -f "$APP_DIR/$file" ]; then - warning "❌ Kritische Datei fehlt: $file" - ((validation_errors++)) - fi - done - - # Prüfe wichtige Verzeichnisse - for dir in "static" "templates" "blueprints"; do - if [ ! -d "$APP_DIR/$dir" ]; then - warning "❌ Wichtiges Verzeichnis fehlt: $dir" - ((validation_errors++)) - fi - done - - if [ $validation_errors -eq 0 ]; then - success "✅ Application Deployment vollständig validiert" - else - warning "⚠️ $validation_errors Probleme beim Deployment gefunden" - fi - - log "✅ Robustes Anwendungs-Deployment abgeschlossen" - log " 📁 App-Verzeichnis: $APP_DIR" - log " 🐍 Python-Pfad konfiguriert" - log " 🔧 Bash-Profile konfiguriert" - log " 🛡️ Sichere Berechtigungen gesetzt" -} - -# =========================== BERECHTIGEN-MANAGEMENT =========================== -fix_project_permissions() { - log "=== BERECHTIGEN-MANAGEMENT FÜR KIOSK-USER ===" - - progress "Korrigiere Projekt-Berechtigungen für kiosk-User..." - - # Prüfe ob kiosk User existiert - if ! id "$KIOSK_USER" &>/dev/null; then - warning "⚠️ Kiosk-User '$KIOSK_USER' existiert nicht - erstelle ihn zuerst" - create_kiosk_user - fi - - local kiosk_home="/home/$KIOSK_USER" - - # Erstelle Entwicklungs-/Arbeitsverzeichnis im kiosk home - local kiosk_project_dir="$kiosk_home/manage-your-printer" - - progress "Erstelle kiosk-Arbeitsverzeichnis: $kiosk_project_dir" - if [ ! -d "$kiosk_project_dir" ]; then - mkdir -p "$kiosk_project_dir" 2>/dev/null || true - fi - - # Kopiere/Synchronisiere Projekt-Dateien zum kiosk-Verzeichnis - progress "Synchronisiere Projekt-Dateien für kiosk-User..." - - # Verwende rsync wenn verfügbar, sonst cp - if command -v rsync >/dev/null 2>&1; then - rsync -av --exclude='.git' --exclude='__pycache__' --exclude='*.pyc' \ - --exclude='instance/ssl/*' --exclude='logs/*' \ - "$CURRENT_DIR/" "$kiosk_project_dir/" 2>/dev/null || { - warning "⚠️ rsync fehlgeschlagen - verwende cp als Fallback" - cp -r "$CURRENT_DIR"/* "$kiosk_project_dir/" 2>/dev/null || true - } - else - cp -r "$CURRENT_DIR"/* "$kiosk_project_dir/" 2>/dev/null || true - fi - - # Setze kiosk als Besitzer des Arbeitsverzeichnisses - progress "Setze kiosk-User als Besitzer des Arbeitsverzeichnisses..." - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_project_dir" 2>/dev/null || warning "⚠️ Ownership konnte nicht vollständig gesetzt werden" - - # Spezielle Berechtigungen für verschiedene Bereiche - progress "Konfiguriere spezielle Berechtigungen..." - - # node_modules: kiosk User soll vollen Zugriff haben - if [ -d "$kiosk_project_dir/node_modules" ]; then - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_project_dir/node_modules" 2>/dev/null || true - chmod -R 755 "$kiosk_project_dir/node_modules" 2>/dev/null || true - success "✅ node_modules Berechtigungen für kiosk-User gesetzt" - fi - - # package.json und package-lock.json: kiosk User soll schreiben können - for file in package.json package-lock.json; do - if [ -f "$kiosk_project_dir/$file" ]; then - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_project_dir/$file" 2>/dev/null || true - chmod 664 "$kiosk_project_dir/$file" 2>/dev/null || true - fi - done - - # logs Verzeichnis: kiosk User soll schreiben können - if [ -d "$kiosk_project_dir/logs" ]; then - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_project_dir/logs" 2>/dev/null || true - chmod -R 755 "$kiosk_project_dir/logs" 2>/dev/null || true - fi - - # uploads Verzeichnis: kiosk User soll schreiben können - if [ -d "$kiosk_project_dir/uploads" ]; then - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_project_dir/uploads" 2>/dev/null || true - chmod -R 755 "$kiosk_project_dir/uploads" 2>/dev/null || true - fi - - # Auch die Original node_modules in APP_DIR korrigieren - progress "Korrigiere node_modules Berechtigungen in $APP_DIR..." - if [ -d "$APP_DIR/node_modules" ]; then - # Erstelle kiosk-Gruppe und füge root hinzu für geteilten Zugriff - groupadd -f kiosk-shared 2>/dev/null || true - usermod -a -G kiosk-shared root 2>/dev/null || true - usermod -a -G kiosk-shared "$KIOSK_USER" 2>/dev/null || true - - # Setze Gruppe auf kiosk-shared für geteilten Zugriff - chgrp -R kiosk-shared "$APP_DIR/node_modules" 2>/dev/null || true - chmod -R 775 "$APP_DIR/node_modules" 2>/dev/null || true - success "✅ node_modules geteilte Berechtigungen gesetzt" - fi - - # Erstelle npm-Konfiguration für kiosk User - progress "Konfiguriere npm für kiosk-User..." - if [ ! -d "$kiosk_home/.npm" ]; then - mkdir -p "$kiosk_home/.npm" 2>/dev/null || true - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.npm" 2>/dev/null || true - fi - - # Erstelle .npmrc für kiosk User - cat > "$kiosk_home/.npmrc" << 'NPMRCEOF' -# npm-Konfiguration für kiosk User -fund=false -audit-level=moderate -progress=false -loglevel=warn -cache=/home/kiosk/.npm -prefix=/home/kiosk/.npm-global -NPMRCEOF - - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.npmrc" 2>/dev/null || true - - # npm global Verzeichnis erstellen - mkdir -p "$kiosk_home/.npm-global" 2>/dev/null || true - chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.npm-global" 2>/dev/null || true - - # X11-Autorisierung sicherstellen - progress "Sicherstelle X11-Autorisierung für kiosk-User..." - if [ ! -f "$kiosk_home/.Xauthority" ]; then - touch "$kiosk_home/.Xauthority" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.Xauthority" - chmod 600 "$kiosk_home/.Xauthority" - success "✅ .Xauthority Datei erstellt" - fi - - # DISPLAY-Variable in bashrc sicherstellen - if ! grep -q "export DISPLAY=" "$kiosk_home/.bashrc" 2>/dev/null; then - cat >> "$kiosk_home/.bashrc" << 'EOF' - -# X11 Display Konfiguration -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -EOF - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - success "✅ X11-Variablen zu .bashrc hinzugefügt" - fi - - success "✅ Projekt-Berechtigungen für kiosk-User konfiguriert" - info " 📁 Kiosk-Arbeitsverzeichnis: $kiosk_project_dir" - info " 👤 Besitzer: $KIOSK_USER" - info " 🔧 npm-Konfiguration erstellt" -} - -create_permission_fix_script() { - log "=== ERSTELLE BERECHTIGEN-REPARATUR-SKRIPT ===" - - local fix_script="$CURRENT_DIR/fix-permissions.sh" - - progress "Erstelle automatisches Berechtigen-Reparatur-Skript..." - - cat > "$fix_script" << 'FIXSCRIPTEOF' -#!/bin/bash - -# =================================================================== -# MYP Berechtigen-Reparatur-Skript -# Behebt Berechtigungsprobleme nach npm install als root -# Kann von jedem User ausgeführt werden -# =================================================================== - -set -euo pipefail - -KIOSK_USER="kiosk" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -# Farben für Ausgabe -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -log() { - echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}" -} - -warning() { - echo -e "${YELLOW}[WARNUNG] $1${NC}" -} - -error() { - echo -e "${RED}[FEHLER] $1${NC}" - exit 1 -} - -info() { - echo -e "${BLUE}[INFO] $1${NC}" -} - -# Prüfe root-Berechtigung -if [ "$EUID" -ne 0 ]; then - error "Dieses Skript muss als Root ausgeführt werden: sudo $0" -fi - -log "=== MYP BERECHTIGEN-REPARATUR ===" -log "Arbeitsverzeichnis: $SCRIPT_DIR" - -# Prüfe ob kiosk User existiert -if ! id "$KIOSK_USER" &>/dev/null; then - error "Kiosk-User '$KIOSK_USER' existiert nicht!" -fi - -# Lösche node_modules wenn vorhanden (für saubere Neuinstallation) -if [ -d "$SCRIPT_DIR/node_modules" ]; then - log "Entferne bestehende node_modules für saubere Neuinstallation..." - rm -rf "$SCRIPT_DIR/node_modules" -fi - -# Erstelle kiosk-shared Gruppe für geteilten Zugriff -log "Erstelle geteilte Berechtigen-Gruppe..." -groupadd -f kiosk-shared 2>/dev/null || true -usermod -a -G kiosk-shared root 2>/dev/null || true -usermod -a -G kiosk-shared "$KIOSK_USER" 2>/dev/null || true - -# Führe npm install als kiosk User aus -log "Führe npm install als kiosk-User aus..." -if [ -f "$SCRIPT_DIR/package.json" ]; then - # Wechsle zu kiosk User für npm install - sudo -u "$KIOSK_USER" bash -c " - cd '$SCRIPT_DIR' - export HOME=/home/$KIOSK_USER - if npm install --no-optional --no-audit --no-fund 2>/dev/null; then - echo 'npm install erfolgreich (Standard)' - elif npm install --legacy-peer-deps --no-optional 2>/dev/null; then - echo 'npm install erfolgreich (Legacy-Modus)' - elif npm install --force 2>/dev/null; then - echo 'npm install erfolgreich (Force-Modus)' - else - echo 'npm install fehlgeschlagen' - exit 1 - fi - " - - if [ $? -eq 0 ]; then - log "✅ npm install als kiosk-User erfolgreich" - else - warning "⚠️ npm install als kiosk-User fehlgeschlagen - versuche als root mit Berechtigen-Korrektur" - - # Fallback: npm install als root, dann Berechtigungen korrigieren - if npm install --no-optional --no-audit --no-fund 2>/dev/null; then - log "npm install als root erfolgreich - korrigiere Berechtigungen..." - - # Korrigiere node_modules Berechtigungen - if [ -d "$SCRIPT_DIR/node_modules" ]; then - chown -R "$KIOSK_USER:kiosk-shared" "$SCRIPT_DIR/node_modules" 2>/dev/null || true - chmod -R 775 "$SCRIPT_DIR/node_modules" 2>/dev/null || true - log "✅ node_modules Berechtigungen korrigiert" - fi - else - error "npm install auch als root fehlgeschlagen" - fi - fi -else - warning "Keine package.json gefunden" -fi - -# Korrigiere allgemeine Projekt-Berechtigungen -log "Korrigiere allgemeine Projekt-Berechtigungen..." - -# package.json und package-lock.json -for file in package.json package-lock.json; do - if [ -f "$SCRIPT_DIR/$file" ]; then - chown "$KIOSK_USER:kiosk-shared" "$SCRIPT_DIR/$file" 2>/dev/null || true - chmod 664 "$SCRIPT_DIR/$file" 2>/dev/null || true - fi -done - -# logs Verzeichnis -if [ -d "$SCRIPT_DIR/logs" ]; then - chown -R "$KIOSK_USER:kiosk-shared" "$SCRIPT_DIR/logs" 2>/dev/null || true - chmod -R 775 "$SCRIPT_DIR/logs" 2>/dev/null || true -fi - -# uploads Verzeichnis -if [ -d "$SCRIPT_DIR/uploads" ]; then - chown -R "$KIOSK_USER:kiosk-shared" "$SCRIPT_DIR/uploads" 2>/dev/null || true - chmod -R 775 "$SCRIPT_DIR/uploads" 2>/dev/null || true -fi - -# static Verzeichnis (falls der User dort Änderungen macht) -if [ -d "$SCRIPT_DIR/static" ]; then - chgrp -R kiosk-shared "$SCRIPT_DIR/static" 2>/dev/null || true - chmod -R 775 "$SCRIPT_DIR/static" 2>/dev/null || true -fi - -# X11-Autorisierung für kiosk-User sicherstellen -log "Sicherstelle X11-Autorisierung..." -kiosk_home="/home/$KIOSK_USER" - -if [ ! -f "$kiosk_home/.Xauthority" ]; then - touch "$kiosk_home/.Xauthority" - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.Xauthority" - chmod 600 "$kiosk_home/.Xauthority" - log "✅ .Xauthority Datei erstellt" -fi - -# DISPLAY-Variable in bashrc sicherstellen -if [ -f "$kiosk_home/.bashrc" ] && ! grep -q "export DISPLAY=" "$kiosk_home/.bashrc" 2>/dev/null; then - cat >> "$kiosk_home/.bashrc" << 'BASHRCEOF' - -# X11 Display Konfiguration -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -BASHRCEOF - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - log "✅ X11-Variablen zu .bashrc hinzugefügt" -fi - -log "✅ Berechtigen-Reparatur abgeschlossen" -info "" -info "📋 Zusammenfassung:" -info " - node_modules gehört jetzt dem kiosk-User" -info " - Geteilte kiosk-shared Gruppe erstellt" -info " - Entwicklungs-Dateien für kiosk-User beschreibbar" -info "" -info "🔧 Verwendung:" -info " - Als kiosk-User: cd $SCRIPT_DIR && npm install" -info " - Als root bei Problemen: sudo $0" -info "" - -FIXSCRIPTEOF - - # Mache Skript ausführbar - chmod +x "$fix_script" 2>/dev/null || warning "⚠️ Konnte fix-permissions.sh nicht ausführbar machen" - - success "✅ Berechtigen-Reparatur-Skript erstellt: $fix_script" - info " 💡 Verwendung nach Setup: sudo ./fix-permissions.sh" - - # Erstelle zusätzliches X11-Fix-Skript - local x11_fix_script="$CURRENT_DIR/fix-x11.sh" - - progress "Erstelle X11-Reparatur-Skript..." - - cat > "$x11_fix_script" << 'X11FIXSCRIPTEOF' -#!/bin/bash - -# =================================================================== -# MYP X11-Reparatur-Skript -# Behebt X11/.Xauthority-Probleme für kiosk-User -# Kann als root oder kiosk-User ausgeführt werden -# =================================================================== - -set -euo pipefail - -KIOSK_USER="kiosk" - -# Farben für Ausgabe -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' - -log() { - echo -e "${GREEN}[$(date '+%H:%M:%S')] $1${NC}" -} - -warning() { - echo -e "${YELLOW}[WARNUNG] $1${NC}" -} - -error() { - echo -e "${RED}[FEHLER] $1${NC}" - exit 1 -} - -info() { - echo -e "${BLUE}[INFO] $1${NC}" -} - -log "=== MYP X11-REPARATUR ===" - -# Prüfe ob kiosk User existiert -if ! id "$KIOSK_USER" &>/dev/null; then - error "Kiosk-User '$KIOSK_USER' existiert nicht!" -fi - -kiosk_home="/home/$KIOSK_USER" - -# Stoppe laufende X11-Prozesse -log "Stoppe laufende X11-Prozesse..." -pkill -f "startx" 2>/dev/null || true -pkill -f "X " 2>/dev/null || true -pkill -f "Xorg" 2>/dev/null || true -pkill -f "chromium" 2>/dev/null || true -sleep 2 - -# Bereinige alte X11-Session-Dateien -log "Bereinige alte X11-Session-Dateien..." -rm -f /tmp/.X0-lock 2>/dev/null || true -rm -f /tmp/.X11-unix/X0 2>/dev/null || true - -# X11-Autorisierung neu erstellen -log "Erstelle X11-Autorisierung neu..." - -# Entferne alte .Xauthority -if [ -f "$kiosk_home/.Xauthority" ]; then - rm -f "$kiosk_home/.Xauthority" -fi - -# Erstelle neue .Xauthority -touch "$kiosk_home/.Xauthority" - -# Setze korrekte Berechtigungen (funktioniert sowohl als root als auch als kiosk) -if [ "$EUID" -eq 0 ]; then - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.Xauthority" -fi -chmod 600 "$kiosk_home/.Xauthority" - -log "✅ .Xauthority neu erstellt" - -# Prüfe und korrigiere .bashrc -log "Prüfe X11-Umgebungsvariablen..." - -if [ -f "$kiosk_home/.bashrc" ]; then - if ! grep -q "export DISPLAY=" "$kiosk_home/.bashrc" 2>/dev/null; then - log "Füge X11-Variablen zu .bashrc hinzu..." - cat >> "$kiosk_home/.bashrc" << 'BASHEOF2' - -# X11 Display Konfiguration -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -BASHEOF2 - - if [ "$EUID" -eq 0 ]; then - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/.bashrc" - fi - log "✅ X11-Variablen hinzugefügt" - else - log "✅ X11-Variablen bereits konfiguriert" - fi -else - warning "⚠️ .bashrc nicht gefunden" -fi - -# Erstelle X11-Test-Skript -log "Erstelle X11-Test-Skript..." -cat > "$kiosk_home/test-x11.sh" << 'TESTEOF' -#!/bin/bash - -# X11-Test für kiosk-User - -export DISPLAY=:0.0 -export XAUTHORITY=/home/kiosk/.Xauthority - -echo "=== X11-Test ===" -echo "DISPLAY: $DISPLAY" -echo "XAUTHORITY: $XAUTHORITY" -echo "" - -if [ -f "$XAUTHORITY" ]; then - echo "✅ .Xauthority existiert" - ls -la "$XAUTHORITY" -else - echo "❌ .Xauthority fehlt" - exit 1 -fi - -echo "" -echo "Teste X11-Verbindung..." - -if command -v xset >/dev/null 2>&1; then - if xset q >/dev/null 2>&1; then - echo "✅ X11-Server erreichbar" - xset q | head -3 - else - echo "❌ X11-Server nicht erreichbar" - echo "Versuche X11-Server zu starten..." - startx /home/kiosk/.xinitrc -- :0 vt1 & - sleep 5 - - if xset q >/dev/null 2>&1; then - echo "✅ X11-Server nach Start erreichbar" - else - echo "❌ X11-Server konnte nicht gestartet werden" - exit 1 - fi - fi -else - echo "⚠️ xset nicht verfügbar - kann X11 nicht testen" -fi - -echo "" -echo "✅ X11-Test abgeschlossen" -TESTEOF - -chmod +x "$kiosk_home/test-x11.sh" -if [ "$EUID" -eq 0 ]; then - chown "$KIOSK_USER:$KIOSK_USER" "$kiosk_home/test-x11.sh" -fi - -log "✅ X11-Reparatur abgeschlossen" -info "" -info "📋 Was wurde behoben:" -info " - Alte .Xauthority entfernt und neu erstellt" -info " - X11-Umgebungsvariablen konfiguriert" -info " - X11-Test-Skript erstellt" -info "" -info "🔧 Nächste Schritte:" -info " - Als kiosk-User einloggen: su - kiosk" -info " - X11 testen: ./test-x11.sh" -info " - Kiosk-Modus starten: ./start-x11.sh" -info "" -info "💡 Bei weiteren Problemen:" -info " - Neustart: sudo reboot" -info " - Manual X11 start: startx" -info "" - -X11FIXSCRIPTEOF - - chmod +x "$x11_fix_script" 2>/dev/null || warning "⚠️ Konnte fix-x11.sh nicht ausführbar machen" - - success "✅ X11-Reparatur-Skript erstellt: $x11_fix_script" - info " 💡 Verwendung bei X11-Problemen: sudo ./fix-x11.sh" -} - -install_npm_dependencies() { - log "=== NPM-ABHÄNGIGKEITEN INSTALLATION ===" - - if [ -f "$APP_DIR/package.json" ]; then - progress "Installiere npm-Abhängigkeiten..." - - cd "$APP_DIR" - - # npm install mit verschiedenen Fallback-Strategien - if npm install --no-optional --no-audit --no-fund 2>/dev/null; then - log "✅ npm install erfolgreich (Standard)" - elif npm install --legacy-peer-deps --no-optional 2>/dev/null; then - log "✅ npm install erfolgreich (Legacy-Modus)" - elif npm install --force 2>/dev/null; then - log "✅ npm install erfolgreich (Force-Modus)" - else - warning "⚠️ npm install fehlgeschlagen - überspringe" - fi - - # WICHTIG: Korrigiere Berechtigungen nach npm install - progress "Korrigiere npm-Berechtigungen für kiosk-User..." - if [ -d "$APP_DIR/node_modules" ]; then - # Erstelle geteilte Gruppe wenn noch nicht vorhanden - groupadd -f kiosk-shared 2>/dev/null || true - usermod -a -G kiosk-shared root 2>/dev/null || true - if id "$KIOSK_USER" &>/dev/null; then - usermod -a -G kiosk-shared "$KIOSK_USER" 2>/dev/null || true - chown -R "$KIOSK_USER:kiosk-shared" "$APP_DIR/node_modules" 2>/dev/null || true - success "✅ node_modules Berechtigungen für kiosk-User korrigiert" - else - warning "⚠️ Kiosk-User nicht gefunden - Berechtigungen werden später korrigiert" - fi - chmod -R 775 "$APP_DIR/node_modules" 2>/dev/null || true - fi - - cd "$CURRENT_DIR" - else - info "Keine package.json gefunden - überspringe npm-Installation" - fi - - log "✅ NPM-Abhängigkeiten verarbeitet" -} - -# =========================== SSL-ZERTIFIKAT GENERIERUNG (ENTFERNT) =========================== -# SSL-Zertifikate nicht mehr benötigt - verwende HTTP statt HTTPS - -# =========================== ROBUSTE SYSTEMD-SERVICES INSTALLATION =========================== -install_systemd_services() { - log "=== ROBUSTE SYSTEMD-SERVICES INSTALLATION ===" - - # Prüfe ob systemd verfügbar ist - if ! command -v systemctl >/dev/null 2>&1; then - warning "⚠️ systemctl nicht gefunden - überspringe Service-Installation" - info " → System läuft möglicherweise ohne systemd (WSL, Docker, etc.)" - return - fi - - # Validiere systemd-Verzeichnis - if [ ! -d "$SYSTEMD_DIR" ]; then - warning "⚠️ systemd-Verzeichnis nicht gefunden: $SYSTEMD_DIR" - info " → Überspringe Service-Installation" - return - fi - - progress "Validiere und kopiere Service-Dateien..." - - # Definiere Service-Dateien mit Priorität - local essential_services=( - "$HTTP_SERVICE_NAME.service" - ) - - local optional_services=( - "$KIOSK_SERVICE_NAME.service" - "$WATCHDOG_SERVICE_NAME.service" - "$WATCHDOG_PYTHON_SERVICE_NAME.service" - "$FIREWALL_SERVICE_NAME.service" - ) - - local installed_services=0 - local essential_errors=0 - - # Essenzielle Services zuerst - for service_file in "${essential_services[@]}"; do - if [ -f "$SYSTEMD_DIR/$service_file" ]; then - progress "Kopiere essenziellen Service: $service_file" - if cp "$SYSTEMD_DIR/$service_file" "$SYSTEM_SYSTEMD_DIR/" 2>/dev/null; then - success "✅ $service_file erfolgreich installiert" - ((installed_services++)) - else - error "❌ Fehler beim Kopieren des essenziellen Service: $service_file" - ((essential_errors++)) - fi - else - error "❌ Essenzieller Service nicht gefunden: $service_file" - ((essential_errors++)) - fi - done - - # Optionale Services - for service_file in "${optional_services[@]}"; do - if [ -f "$SYSTEMD_DIR/$service_file" ]; then - progress "Kopiere optionalen Service: $service_file" - if cp "$SYSTEMD_DIR/$service_file" "$SYSTEM_SYSTEMD_DIR/" 2>/dev/null; then - success "✅ $service_file erfolgreich installiert" - ((installed_services++)) - else - warning "⚠️ Fehler beim Kopieren des optionalen Service: $service_file" - fi - else - info "Optionaler Service nicht gefunden: $service_file" - fi - done - - # Prüfe auf kritische Fehler - if [ $essential_errors -gt 0 ]; then - error "❌ $essential_errors essenzielle Services konnten nicht installiert werden!" - fi - - # Validiere kopierte Service-Dateien - progress "Validiere Service-Dateien..." - for service_file in "${essential_services[@]}" "${optional_services[@]}"; do - if [ -f "$SYSTEM_SYSTEMD_DIR/$service_file" ]; then - # Syntaxprüfung für systemd-Services - if systemd-analyze verify "$SYSTEM_SYSTEMD_DIR/$service_file" 2>/dev/null; then - success "✅ $service_file Syntax-Validierung erfolgreich" - else - warning "⚠️ $service_file hat möglicherweise Syntax-Probleme" - fi - fi - done - - # Systemd-Konfiguration neu laden - progress "Lade systemd-Konfiguration neu..." - retry_command "systemctl daemon-reload" "systemd daemon-reload" - - log "✅ Systemd-Services installiert: $installed_services Services" -} - -enable_and_start_services() { - log "=== ROBUSTE SERVICES AKTIVIERUNG UND START ===" - - # Prüfe ob systemd verfügbar ist - if ! command -v systemctl >/dev/null 2>&1; then - warning "⚠️ systemctl nicht gefunden - überspringe Service-Aktivierung" - return - fi - - # Service-Status tracking - local successful_services=0 - local failed_services=0 - - # HTTP-Backend-Service (kritisch) - progress "Aktiviere und starte HTTP-Backend-Service (kritisch)..." - - if systemctl enable "$HTTP_SERVICE_NAME" 2>/dev/null; then - success "✅ HTTP-Backend-Service erfolgreich aktiviert" - - if systemctl start "$HTTP_SERVICE_NAME" 2>/dev/null; then - success "✅ HTTP-Backend-Service erfolgreich gestartet" - - # Warte und prüfe Status gründlich - local startup_timeout=15 - local check_interval=2 - local elapsed=0 - - while [ $elapsed -lt $startup_timeout ]; do - if systemctl is-active --quiet "$HTTP_SERVICE_NAME"; then - success "✅ HTTP-Backend-Service läuft stabil nach ${elapsed}s" - ((successful_services++)) - break - fi - sleep $check_interval - elapsed=$((elapsed + check_interval)) - progress "Warte auf HTTP-Backend-Service Startup... (${elapsed}/${startup_timeout}s)" - done - - if [ $elapsed -ge $startup_timeout ]; then - error "❌ HTTP-Backend-Service Timeout nach ${startup_timeout}s - Service nicht verfügbar" - - # Debugging-Informationen - info "HTTP-Backend-Service Status-Debug:" - systemctl status "$HTTP_SERVICE_NAME" --no-pager -l || true - journalctl -u "$HTTP_SERVICE_NAME" --no-pager -n 10 || true - ((failed_services++)) - fi - else - error "❌ HTTP-Backend-Service konnte nicht gestartet werden" - ((failed_services++)) - fi - else - error "❌ HTTP-Backend-Service konnte nicht aktiviert werden" - ((failed_services++)) - fi - - # Kiosk-Service (für Produktionsinstallation) - if [ -f "$SYSTEM_SYSTEMD_DIR/$KIOSK_SERVICE_NAME.service" ]; then - progress "Aktiviere Kiosk-Service (startet beim nächsten Boot)..." - if systemctl enable "$KIOSK_SERVICE_NAME" 2>/dev/null; then - success "✅ Kiosk-Service erfolgreich aktiviert" - ((successful_services++)) - else - warning "⚠️ Kiosk-Service konnte nicht aktiviert werden" - ((failed_services++)) - fi - fi - - # Watchdog-Service (optional) - if [ -f "$SYSTEM_SYSTEMD_DIR/$WATCHDOG_SERVICE_NAME.service" ]; then - progress "Aktiviere und starte Watchdog-Service..." - if systemctl enable "$WATCHDOG_SERVICE_NAME" 2>/dev/null; then - if systemctl start "$WATCHDOG_SERVICE_NAME" 2>/dev/null; then - success "✅ Watchdog-Service erfolgreich aktiviert und gestartet" - ((successful_services++)) - else - warning "⚠️ Watchdog-Service aktiviert, aber Start fehlgeschlagen" - fi - else - warning "⚠️ Watchdog-Service konnte nicht aktiviert werden" - fi - fi - - # Python Watchdog-Service (optional) - if [ -f "$SYSTEM_SYSTEMD_DIR/$WATCHDOG_PYTHON_SERVICE_NAME.service" ]; then - progress "Aktiviere Python Watchdog-Service..." - if systemctl enable "$WATCHDOG_PYTHON_SERVICE_NAME" 2>/dev/null; then - success "✅ Python Watchdog-Service erfolgreich aktiviert" - ((successful_services++)) - else - warning "⚠️ Python Watchdog-Service konnte nicht aktiviert werden" - fi - fi - - # Firewall-Service (optional) - if [ -f "$SYSTEM_SYSTEMD_DIR/$FIREWALL_SERVICE_NAME.service" ]; then - progress "Aktiviere Firewall-Service..." - if systemctl enable "$FIREWALL_SERVICE_NAME" 2>/dev/null; then - success "✅ Firewall-Service erfolgreich aktiviert" - ((successful_services++)) - else - warning "⚠️ Firewall-Service konnte nicht aktiviert werden" - fi - fi - - # Zusammenfassung - log "📊 Service-Aktivierung Zusammenfassung:" - log " ✅ Erfolgreich: $successful_services Services" - log " ❌ Fehlgeschlagen: $failed_services Services" - - if [ $failed_services -eq 0 ]; then - success "✅ Alle verfügbaren Services erfolgreich konfiguriert" - elif [ $successful_services -gt 0 ]; then - warning "⚠️ $failed_services Services fehlgeschlagen, aber $successful_services Services funktionieren" - info "→ System ist grundsätzlich funktionsfähig" - else - error "❌ Alle Services fehlgeschlagen - System möglicherweise nicht funktionsfähig" - fi -} - -# =========================== ROBUSTE SYSTEM-TESTS =========================== -test_application() { - log "=== UMFASSENDE SYSTEM-TESTS ===" - - echo "" - echo -e "${BLUE}🔍 Führe System-Tests durch...${NC}" - echo "" - - local test_errors=0 - local test_warnings=0 - - # Test 1: Service-Status prüfen - progress "Teste Service-Status..." - if systemctl is-active --quiet "$HTTP_SERVICE_NAME"; then - success "✅ HTTP-Backend-Service ist aktiv" - else - warning "⚠️ HTTP-Backend-Service ist nicht aktiv" - ((test_warnings++)) - - # Debug-Informationen - info "Service-Status Debug:" - systemctl status "$HTTP_SERVICE_NAME" --no-pager -l || true - fi - - # Test 2: Port-Verfügbarkeit - progress "Teste Port-Verfügbarkeit..." - if ss -tlnp | grep -q ":5000 "; then - success "✅ Port 5000 ist geöffnet" - else - warning "⚠️ Port 5000 ist nicht geöffnet" - ((test_warnings++)) - fi - - # Test 3: HTTP-Backend-Verbindung (robust mit mehreren Methoden) - progress "Teste HTTP-Backend-Verbindung (robust)..." - - local max_attempts=20 - local attempt=1 - local connection_successful=false - - while [ $attempt -le $max_attempts ]; do - # Methode 1: curl mit verschiedenen Optionen - if curl -s --connect-timeout 3 --max-time 8 "$HTTP_URL" >/dev/null 2>&1; then - connection_successful=true - break - fi - - # Methode 2: wget als Fallback - if command -v wget >/dev/null 2>&1; then - if wget -q --timeout=3 --tries=1 "$HTTP_URL" -O /dev/null 2>/dev/null; then - connection_successful=true - break - fi - fi - - # Methode 3: nc als direkter Port-Test - if command -v nc >/dev/null 2>&1; then - if echo "GET / HTTP/1.0" | nc -w 3 localhost 5000 2>/dev/null | grep -q "HTTP"; then - connection_successful=true - break - fi - fi - - progress "Warte auf HTTP-Backend... ($attempt/$max_attempts)" - sleep 3 - ((attempt++)) - done - - if [ "$connection_successful" = true ]; then - success "✅ HTTP-Backend erreichbar unter $HTTP_URL" - - # Erweiterte Verbindungstests - progress "Führe erweiterte HTTP-Tests durch..." - - # Test Antwortzeit - local response_time=$(curl -s -w "%{time_total}" -o /dev/null "$HTTP_URL" 2>/dev/null || echo "timeout") - if [ "$response_time" != "timeout" ]; then - info "🕐 HTTP Antwortzeit: ${response_time}s" - - # Bewerte Antwortzeit (ohne bc für bessere Kompatibilität) - local response_ms=$(echo "$response_time * 1000" | awk '{print int($1)}' 2>/dev/null || echo "9999") - if [ "$response_ms" -lt 2000 ]; then - success "✅ Gute Antwortzeit" - elif [ "$response_ms" -lt 5000 ]; then - info "ℹ️ Akzeptable Antwortzeit" - else - warning "⚠️ Langsame Antwortzeit" - ((test_warnings++)) - fi - fi - - # Test HTTP-Status - local http_status=$(curl -s -o /dev/null -w "%{http_code}" "$HTTP_URL" 2>/dev/null || echo "000") - if [ "$http_status" = "200" ]; then - success "✅ HTTP Status 200 OK" - else - info "ℹ️ HTTP Status: $http_status (möglicherweise Redirect oder Login-Seite)" - fi - - else - error "❌ HTTP-Backend nicht erreichbar nach $max_attempts Versuchen" - ((test_errors++)) - - # Debugging-Informationen - info "HTTP-Debug Informationen:" - netstat -tlnp | grep ":5000" || info "Port 5000 nicht gefunden" - ss -tlnp | grep ":5000" || info "Port 5000 nicht in ss gefunden" - fi - - # Test 4: HTTP-Header und Content-Type Prüfung - progress "Teste HTTP-Header und Content-Type..." - - if [ "$connection_successful" = true ]; then - # Test Content-Type Header - local content_type=$(curl -s -I "$HTTP_URL" 2>/dev/null | grep -i "content-type:" | head -1 | cut -d: -f2 | tr -d ' \r\n' || echo "unknown") - if [[ "$content_type" == *"text/html"* ]]; then - success "✅ Korrekte HTML-Antwort erkannt" - else - info "ℹ️ Content-Type: $content_type" - fi - - # Test Server Header - local server_header=$(curl -s -I "$HTTP_URL" 2>/dev/null | grep -i "server:" | head -1 | cut -d: -f2 | tr -d ' \r\n' || echo "unknown") - if [ "$server_header" != "unknown" ]; then - info "🖥️ Server: $server_header" - fi - else - info "ℹ️ HTTP-Header Test übersprungen (Backend nicht erreichbar)" - fi - - # Test 5: Python-Anwendung Import-Test - progress "Teste Python-Anwendung Import..." - - cd "$APP_DIR" 2>/dev/null || true - - # Setze Test-Umgebung - export FLASK_ENV=testing - export MYP_TESTING=1 - export PYTHONPATH="$APP_DIR:${PYTHONPATH:-}" - - if timeout 15 python3 -c " -import sys -import os -sys.path.insert(0, '$APP_DIR') -os.chdir('$APP_DIR') - -try: - import app - print('✅ Flask-App Import erfolgreich') - - # Test ob Flask-App-Objekt verfügbar - if hasattr(app, 'app'): - print('✅ Flask-App-Objekt verfügbar') - else: - print('⚠️ Flask-App-Objekt nicht gefunden') - -except Exception as e: - print(f'⚠️ App-Import-Problem: {e}') - exit(1) -" 2>&1; then - success "✅ Python-Anwendung kann erfolgreich importiert werden" - else - warning "⚠️ Python-Anwendung Import-Probleme (möglicherweise nicht kritisch)" - ((test_warnings++)) - fi - - cd "$CURRENT_DIR" 2>/dev/null || true - - # Test 6: Verzeichnisstruktur-Validierung - progress "Validiere Verzeichnisstruktur..." - - local structure_ok=true - local required_files=("$APP_DIR/app.py" "$APP_DIR/models.py" "$APP_DIR/requirements.txt") - local required_dirs=("$APP_DIR/static" "$APP_DIR/templates" "$APP_DIR/blueprints") - - for file in "${required_files[@]}"; do - if [ ! -f "$file" ]; then - warning "❌ Wichtige Datei fehlt: $file" - structure_ok=false - ((test_warnings++)) - fi - done - - for dir in "${required_dirs[@]}"; do - if [ ! -d "$dir" ]; then - warning "❌ Wichtiges Verzeichnis fehlt: $dir" - structure_ok=false - ((test_warnings++)) - fi - done - - if [ "$structure_ok" = true ]; then - success "✅ Verzeichnisstruktur vollständig" - fi - - # Zusammenfassung der Tests - echo "" - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} SYSTEM-TEST ERGEBNISSE${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${BLUE}📊 Test-Zusammenfassung:${NC}" - echo -e " ❌ Fehler: $test_errors" - echo -e " ⚠️ Warnungen: $test_warnings" - echo "" - - if [ $test_errors -eq 0 ] && [ $test_warnings -eq 0 ]; then - echo -e "${GREEN}✅ Alle System-Tests erfolgreich!${NC}" - echo -e "${GREEN} → System vollständig funktionsfähig${NC}" - echo "" - return 0 - elif [ $test_errors -eq 0 ]; then - echo -e "${YELLOW}⚠️ System-Tests mit $test_warnings Warnungen abgeschlossen${NC}" - echo -e "${YELLOW} → System grundsätzlich funktionsfähig${NC}" - echo "" - return 0 - else - echo -e "${RED}❌ System-Tests mit $test_errors Fehlern fehlgeschlagen${NC}" - echo -e "${RED} → System möglicherweise nicht funktionsfähig${NC}" - echo "" - return 1 - fi -} - -# =========================== AUFRÄUMEN =========================== -cleanup_old_files() { - log "=== AUFRÄUMEN ALTE DATEIEN ===" - - progress "Entferne alte Shell-Skripte..." - - # Entferne alte Skripte (falls vorhanden) - local old_scripts=("combined.sh" "installer.sh") - - for script in "${old_scripts[@]}"; do - if [ -f "$CURRENT_DIR/$script" ]; then - progress "Entferne: $script" - rm -f "$CURRENT_DIR/$script" || warning "Fehler beim Entfernen von $script" - fi - done - - log "✅ Aufräumen abgeschlossen" -} - -# =========================== CREDENTIALS DEPLOYMENT =========================== -deploy_credentials() { - log "=== DEPLOYE CREDENTIALS KONFIGURATION ===" - - # Erstelle .env-Datei für die Anwendung - progress "Erstelle .env-Datei mit Credentials..." - - local env_file="$APP_DIR/.env" - - cat > "$env_file" << EOF -# MYP Druckerverwaltung - Automatisch generierte Credentials -# Generiert am: $(date '+%Y-%m-%d %H:%M:%S') -# Setup-Version: $APP_VERSION - -# Backend-Konfiguration -SECRET_KEY=$MYP_SECRET_KEY -KIOSK_DEACTIVATION_PASSWORD=$MYP_MAIN_PASSWORD - -# Admin-Zugangsdaten -ADMIN_EMAIL=$MYP_ADMIN_EMAIL -ADMIN_PASSWORD=$MYP_MAIN_PASSWORD - -# TP-Link Tapo Konfiguration -TAPO_USERNAME=$MYP_TAPO_EMAIL -TAPO_PASSWORD=$MYP_TAPO_PASSWORD - -# GitHub OAuth -GITHUB_CLIENT_ID=$MYP_GITHUB_CLIENT_ID -GITHUB_CLIENT_SECRET=$MYP_GITHUB_CLIENT_SECRET - -# System-Zugangsdaten (nur für Dokumentation) -SSH_USER=user -SSH_PASSWORD=$MYP_SSH_PASSWORD -RDP_USER=root -RDP_PASSWORD=$MYP_MAIN_PASSWORD - -# Router-Zugangsdaten (nur für Dokumentation) -ROUTER_USER=$MYP_ROUTER_USER -ROUTER_PASSWORD=$MYP_ROUTER_PASSWORD - -# SSL-Konfiguration -SSL_CERT_PATH=instance/ssl/myp.crt -SSL_KEY_PATH=instance/ssl/myp.key - -# Produktions-Konfiguration -FLASK_ENV=production -DEBUG=False -TESTING=False -EOF - - # Sichere Berechtigungen setzen - chmod 600 "$env_file" || warning "Konnte Berechtigungen für .env-Datei nicht setzen" - chown root:root "$env_file" 2>/dev/null || warning "Konnte Besitzer für .env-Datei nicht setzen" - - # Backup der CREDENTIALS.md erstellen falls vorhanden - if [ -f "$CURRENT_DIR/../docs/CREDENTIALS.md" ]; then - progress "Erstelle Backup der CREDENTIALS.md..." - cp "$CURRENT_DIR/../docs/CREDENTIALS.md" "$APP_DIR/CREDENTIALS_backup.md" 2>/dev/null || true - fi - - # Erstelle lokale Credentials-Dokumentation - progress "Erstelle lokale Credentials-Dokumentation..." - - cat > "$APP_DIR/CREDENTIALS_LOCAL.md" << EOF -# MYP Druckerverwaltung - Lokale Credentials - -**Automatisch generiert am:** $(date '+%Y-%m-%d %H:%M:%S') -**Setup-Version:** $APP_VERSION -**Hostname:** $(hostname) - -## 🔐 System-Zugangsdaten - -### SSH-Zugang -- **Benutzer:** user -- **Passwort:** $MYP_SSH_PASSWORD -- **Port:** 22 -- **Verbindung:** \`ssh user@$(hostname)\` - -### RDP-Zugang -- **Benutzer:** root -- **Passwort:** $MYP_MAIN_PASSWORD -- **Port:** 3389 -- **Verbindung:** RDP-Client zu \`$(hostname):3389\` - -## 🌐 Anwendungs-Credentials - -### Backend-Konfiguration -- **SECRET_KEY:** \`${MYP_SECRET_KEY:0:8}...\` (${#MYP_SECRET_KEY} Zeichen) -- **Kiosk-Deaktivierung:** $MYP_MAIN_PASSWORD - -### Admin-Zugang -- **E-Mail:** $MYP_ADMIN_EMAIL -- **Passwort:** $MYP_MAIN_PASSWORD - -### TP-Link Tapo Steckdosen -- **E-Mail:** $MYP_TAPO_EMAIL -- **Passwort:** $MYP_TAPO_PASSWORD - -### GitHub OAuth -- **Client ID:** ${MYP_GITHUB_CLIENT_ID:0:8}... -- **Client Secret:** ${MYP_GITHUB_CLIENT_SECRET:0:8}... - -## 🔧 Netzwerk-Konfiguration - -### Router-Zugang -- **Benutzer:** $MYP_ROUTER_USER -- **Passwort:** $MYP_ROUTER_PASSWORD - -## 📁 Dateien - -- **Anwendung:** $APP_DIR -- **SSL-Zertifikat:** $APP_DIR/instance/ssl/myp.crt -- **SSL-Schlüssel:** $APP_DIR/instance/ssl/myp.key -- **Umgebungsvariablen:** $APP_DIR/.env - -## ⚠️ Sicherheitshinweise - -1. Diese Datei enthält sensible Informationen -2. Zugriff nur für autorisierte Personen -3. Regelmäßige Passwort-Updates empfohlen -4. Backup der Credentials an sicherem Ort - ---- -**Erstellt durch:** MYP Setup-Skript v$APP_VERSION -EOF - - # Sichere Berechtigungen für Dokumentation - chmod 600 "$APP_DIR/CREDENTIALS_LOCAL.md" || warning "Konnte Berechtigungen für Credentials-Dokumentation nicht setzen" - chown root:root "$APP_DIR/CREDENTIALS_LOCAL.md" 2>/dev/null || warning "Konnte Besitzer für Credentials-Dokumentation nicht setzen" - - success "✅ Credentials erfolgreich deployed:" - log " 📄 .env-Datei: $env_file" - log " 📋 Lokale Dokumentation: $APP_DIR/CREDENTIALS_LOCAL.md" - log " 🔒 Sichere Berechtigungen gesetzt (600, root:root)" -} - -# =========================== AUTOMATISCHE SYSTEM-ERKENNUNG =========================== -# Menü-System entfernt - vollautomatische Installation basierend auf System-Erkennung - -# =========================== AUTOMATISCHE INSTALLATIONS-MODI =========================== -# Alte manuelle Installationsfunktionen entfernt - ersetzt durch automatische Varianten - -# =========================== RDP & SSH ZUGANG =========================== -install_remote_access() { - log "=== INSTALLIERE REMOTE-ZUGANG (RDP & SSH) ===" - - # SSH-Server installieren und konfigurieren - progress "Installiere und konfiguriere SSH-Server..." - apt-get install -y openssh-server || error "SSH-Server Installation fehlgeschlagen" - - # SSH-Service aktivieren - systemctl enable ssh - systemctl start ssh - - # SSH-Benutzer 'user' erstellen (falls nicht vorhanden) - if ! id "user" &>/dev/null; then - progress "Erstelle SSH-Benutzer: user" - useradd -m -s /bin/bash user || error "Kann SSH-Benutzer nicht erstellen" - echo "user:$MYP_SSH_PASSWORD" | chpasswd || error "Kann Passwort für SSH-Benutzer nicht setzen" - usermod -aG sudo user 2>/dev/null || true - - # pip-Konfiguration für SSH-Benutzer - mkdir -p "/home/user/.pip" 2>/dev/null || true - cat > "/home/user/.pip/pip.conf" << 'EOF' -[global] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -timeout = 60 -retries = 3 - -[install] -break-system-packages = true -trusted-host = pypi.org - pypi.python.org - files.pythonhosted.org -EOF - chown "user:user" "/home/user/.pip/pip.conf" 2>/dev/null || true - - log "✅ SSH-Benutzer 'user' erstellt mit Passwort '$MYP_SSH_PASSWORD'" - else - info "SSH-Benutzer 'user' existiert bereits" - echo "user:$MYP_SSH_PASSWORD" | chpasswd || warning "Konnte Passwort für SSH-Benutzer nicht aktualisieren" - fi - - # RDP-Server (xrdp) installieren - vereinfachter Ansatz - progress "Installiere RDP-Server (xrdp) - vereinfachte Installation..." - - # Alle bestehenden xrdp-Installationen entfernen - progress "Entferne vorherige xrdp-Installationen..." - systemctl stop xrdp xrdp-sesman 2>/dev/null || true - systemctl disable xrdp xrdp-sesman 2>/dev/null || true - apt-get remove --purge -y xrdp 2>/dev/null || true - rm -rf /etc/xrdp /var/log/xrdp* 2>/dev/null || true - - # XFCE Desktop installieren (minimal) - progress "Installiere minimale XFCE-Umgebung..." - if ! apt-get install -y xfce4-session xfce4-panel xfce4-terminal xfce4-settings xfdesktop4 dbus-x11; then - warning "Minimale XFCE-Installation fehlgeschlagen - verwende Fallback..." - apt-get install -y xfce4 dbus-x11 || error "XFCE Installation fehlgeschlagen" - fi - - # xrdp neu installieren - progress "Installiere xrdp neu..." - apt-get update - apt-get install -y xrdp || error "xrdp Installation fehlgeschlagen" - - # Benutzer zur xrdp-Gruppe hinzufügen - usermod -aG xrdp root 2>/dev/null || true - if id "user" &>/dev/null; then - usermod -aG xrdp user 2>/dev/null || true - fi - - # Erstelle minimale xrdp-Konfiguration - progress "Erstelle minimale xrdp-Konfiguration..." - - # Backup der Original-Konfiguration - cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.original 2>/dev/null || true - - # Sehr einfache xrdp.ini - cat > /etc/xrdp/xrdp.ini << 'EOF' -[Globals] -ini_version=1 -fork=true -port=3389 -tcp_nodelay=true -tcp_keepalive=true -security_layer=rdp -autorun= -allow_channels=true -allow_multimon=false -bitmap_cache=true -bitmap_compression=true -bulk_compression=false -max_bpp=24 -new_cursors=true -use_fastpath=both -require_credentials=true -ask_for_reconnect_reason=false -enable_token_login=false - -[Xorg] -name=Xorg -lib=libxup.so -username=ask -password=ask -ip=127.0.0.1 -port=-1 -code=20 -EOF - - # Einfache sesman.ini - cp /etc/xrdp/sesman.ini /etc/xrdp/sesman.ini.original 2>/dev/null || true - - cat > /etc/xrdp/sesman.ini << 'EOF' -[Globals] -ListenAddress=127.0.0.1 -ListenPort=3350 -EnableUserWindowManager=true -UserWindowManager=startxfce4 -DefaultWindowManager=startxfce4 - -[Security] -AllowRootLogin=true -MaxLoginRetry=4 -AlwaysGroupCheck=false - -[Sessions] -X11DisplayOffset=10 -MaxSessions=10 -KillDisconnected=false -IdleTimeLimit=0 -DisconnectedTimeLimit=0 - -[Logging] -LogFile=xrdp-sesman.log -LogLevel=INFO -EnableSyslog=true -SyslogLevel=INFO - -[Xorg] -param1=-bs -param2=-nolisten -param3=tcp -param4=-dpi -param5=96 -EOF - - # Erstelle .xsession für XFCE - progress "Konfiguriere XFCE-Sessions..." - - # Root .xsession - cat > /root/.xsession << 'EOF' -#!/bin/bash -export XDG_SESSION_DESKTOP=xfce -export XDG_DATA_DIRS=/usr/share/xfce4:/usr/local/share:/usr/share -export XDG_CONFIG_DIRS=/etc/xdg/xdg-xfce:/etc/xdg -exec startxfce4 -EOF - chmod +x /root/.xsession - - # User .xsession (falls user existiert) - if id "user" &>/dev/null; then - cat > /home/user/.xsession << 'EOF' -#!/bin/bash -export XDG_SESSION_DESKTOP=xfce -export XDG_DATA_DIRS=/usr/share/xfce4:/usr/local/share:/usr/share -export XDG_CONFIG_DIRS=/etc/xdg/xdg-xfce:/etc/xdg -exec startxfce4 -EOF - chown user:user /home/user/.xsession - chmod +x /home/user/.xsession - fi - - # Root-Passwort setzen - progress "Setze Root-Passwort für RDP..." - echo "root:$MYP_MAIN_PASSWORD" | chpasswd || error "Kann Root-Passwort nicht setzen" - - # Log-Verzeichnisse erstellen mit korrekten Berechtigungen - progress "Erstelle Log-Verzeichnisse..." - mkdir -p /var/log - touch /var/log/xrdp.log /var/log/xrdp-sesman.log 2>/dev/null || true - chown xrdp:xrdp /var/log/xrdp*.log 2>/dev/null || true - chmod 644 /var/log/xrdp*.log 2>/dev/null || true - - # Erstelle xrdp-Konfigurationsverzeichnisse - mkdir -p /etc/xrdp/cert /var/run/xrdp - chown xrdp:xrdp /etc/xrdp/cert /var/run/xrdp 2>/dev/null || true - - # Services aktivieren und starten - progress "Starte xrdp-Services..." - - # systemd daemon reload - systemctl daemon-reload - - # Services aktivieren - systemctl enable xrdp-sesman - systemctl enable xrdp - - # Services starten (sesman zuerst) - systemctl start xrdp-sesman - sleep 3 - - # Prüfe sesman-Status - if systemctl is-active --quiet xrdp-sesman; then - success "✅ xrdp-sesman erfolgreich gestartet" - - # Jetzt xrdp starten - systemctl start xrdp - sleep 3 - - if systemctl is-active --quiet xrdp; then - success "✅ xrdp erfolgreich gestartet" - else - warning "⚠️ xrdp konnte nicht gestartet werden" - journalctl -u xrdp --no-pager -l | tail -10 - fi - else - warning "⚠️ xrdp-sesman konnte nicht gestartet werden" - journalctl -u xrdp-sesman --no-pager -l | tail -10 - fi - - cd "$CURRENT_DIR" - - # Finaler Status-Check - if systemctl is-active --quiet xrdp && systemctl is-active --quiet xrdp-sesman; then - log "✅ Remote-Zugang vollständig konfiguriert:" - log " 📡 SSH: user:$MYP_SSH_PASSWORD (Port 22)" - log " 🖥️ RDP: root:$MYP_MAIN_PASSWORD (Port 3389)" - log " 🖥️ RDP: user:$MYP_SSH_PASSWORD (Port 3389)" - elif systemctl is-active --quiet ssh; then - log "✅ SSH-Zugang konfiguriert:" - log " 📡 SSH: user:$MYP_SSH_PASSWORD (Port 22)" - warning "⚠️ RDP-Installation unvollständig" - info "Manuelle Überprüfung erforderlich:" - info " systemctl status xrdp" - info " systemctl status xrdp-sesman" - info " journalctl -u xrdp -f" - else - error "❌ Weder SSH noch RDP konnten konfiguriert werden" - fi -} - -# =========================== FIREWALL KONFIGURATION =========================== -configure_firewall() { - log "=== KONFIGURIERE FIREWALL (firewalld) ===" - - # firewalld installieren - progress "Installiere firewalld..." - apt-get install -y firewalld || error "firewalld Installation fehlgeschlagen" - - # firewalld aktivieren und starten - systemctl enable firewalld - systemctl start firewalld - - # Warte kurz bis firewalld vollständig gestartet ist - sleep 5 - - progress "Konfiguriere firewalld-Zonen und -Regeln..." - - # Firewall-Status prüfen - if ! firewall-cmd --state >/dev/null 2>&1; then - error "firewalld ist nicht aktiv oder reagiert nicht" - fi - - # Bestehende Zone entfernen falls vorhanden - progress "Entferne bestehende myp-backend Zone falls vorhanden..." - if firewall-cmd --permanent --get-zones | grep -q "myp-backend"; then - log "Entferne bestehende myp-backend Zone..." - firewall-cmd --permanent --delete-zone=myp-backend 2>/dev/null || true - firewall-cmd --reload - sleep 2 - fi - - # Zone neu erstellen - progress "Erstelle neue myp-backend Zone..." - if ! firewall-cmd --permanent --new-zone=myp-backend; then - error "Fehler beim Erstellen der myp-backend Zone" - fi - - # Konfiguration neu laden - firewall-cmd --reload - sleep 2 - - # Erweiterte Netzwerk-Quellen definieren (nur IPv4) - progress "Füge Netzwerk-Quellen hinzu..." - firewall-cmd --permanent --zone=myp-backend --add-source=192.168.0.0/16 || error "Fehler beim Hinzufügen des 192.168.0.0/16 Netzwerks" - firewall-cmd --permanent --zone=myp-backend --add-source=127.0.0.1/32 || error "Fehler beim Hinzufügen von localhost" - - # Lokaler Hostname "raspberrypi" hinzufügen - local local_hostname="raspberrypi" - progress "Füge lokalen Hostname hinzu: $local_hostname" - local local_ip=$(getent hosts "$local_hostname" | awk '{print $1}' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 2>/dev/null || true) - if [ -n "$local_ip" ]; then - firewall-cmd --permanent --zone=myp-backend --add-source="$local_ip/32" 2>/dev/null || warning "Konnte lokalen Hostname nicht hinzufügen" - log "✅ Lokaler Hostname $local_hostname hinzugefügt: $local_ip" - else - info "Lokaler Hostname $local_hostname nicht auflösbar - wird beim nächsten Boot verfügbar sein" - fi - - # Frontend-Server m040tbaraspi001 hinzufügen (falls auflösbar) - progress "Füge Frontend-Server hinzu: m040tbaraspi001" - local frontend_ip=$(getent hosts "m040tbaraspi001" | awk '{print $1}' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 2>/dev/null || true) - if [ -n "$frontend_ip" ]; then - firewall-cmd --permanent --zone=myp-backend --add-source="$frontend_ip/32" 2>/dev/null || warning "Konnte Frontend-Server IP nicht hinzufügen" - log "✅ Frontend-Server m040tbaraspi001 hinzugefügt: $frontend_ip" - else - # Versuche auch mit FQDN - local frontend_fqdn_ip=$(getent hosts "m040tbaraspi001.de040.corpintra.net" | awk '{print $1}' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -1 2>/dev/null || true) - if [ -n "$frontend_fqdn_ip" ]; then - firewall-cmd --permanent --zone=myp-backend --add-source="$frontend_fqdn_ip/32" 2>/dev/null || warning "Konnte Frontend-Server FQDN nicht hinzufügen" - log "✅ Frontend-Server m040tbaraspi001.de040.corpintra.net hinzugefügt: $frontend_fqdn_ip" - else - info "Frontend-Server m040tbaraspi001 nicht auflösbar - überspringe" - fi - fi - - # Ports und Services hinzufügen - progress "Konfiguriere Ports und Services..." - - # HTTPS für API & Kiosk zulassen - firewall-cmd --permanent --zone=myp-backend --add-port=443/tcp || error "Fehler beim Hinzufügen von Port 443" - - # SSH für Wartung - firewall-cmd --permanent --zone=myp-backend --add-service=ssh || error "Fehler beim Hinzufügen des SSH-Service" - - # RDP für Remote-Desktop - firewall-cmd --permanent --zone=myp-backend --add-port=3389/tcp || error "Fehler beim Hinzufügen von Port 3389" - - # IPv6 in firewalld deaktivieren - progress "Deaktiviere IPv6 in firewalld..." - firewall-cmd --permanent --set-target=DROP --zone=public --family=ipv6 2>/dev/null || warning "IPv6 konnte nicht in public Zone deaktiviert werden" - firewall-cmd --permanent --set-target=DROP --zone=myp-backend --family=ipv6 2>/dev/null || warning "IPv6 konnte nicht in myp-backend Zone deaktiviert werden" - - # Default-Zone setzen - progress "Setze Default-Zone..." - firewall-cmd --set-default-zone=myp-backend || error "Fehler beim Setzen der Default-Zone" - - # Änderungen übernehmen - progress "Lade Firewall-Konfiguration neu..." - firewall-cmd --reload || error "Fehler beim Neuladen der Firewall-Konfiguration" - - # Kurz warten und Status prüfen - sleep 3 - - # Firewall-Status anzeigen - progress "Firewall-Konfiguration:" - if firewall-cmd --list-all --zone=myp-backend 2>/dev/null; then - log "✅ Firewall-Konfiguration erfolgreich angezeigt" - else - warning "⚠️ Firewall-Status konnte nicht angezeigt werden" - fi - - # Finale Validierung - progress "Validiere Firewall-Konfiguration..." - local validation_errors=0 - - # Prüfe ob Zone existiert - if ! firewall-cmd --get-zones | grep -q "myp-backend"; then - error "Zone myp-backend wurde nicht korrekt erstellt" - ((validation_errors++)) - fi - - # Prüfe Default-Zone - if [ "$(firewall-cmd --get-default-zone)" != "myp-backend" ]; then - warning "Default-Zone ist nicht myp-backend" - ((validation_errors++)) - fi - - # Prüfe Ports - if ! firewall-cmd --zone=myp-backend --query-port=443/tcp 2>/dev/null; then - warning "Port 443 nicht korrekt konfiguriert" - ((validation_errors++)) - fi - - if ! firewall-cmd --zone=myp-backend --query-port=3389/tcp 2>/dev/null; then - warning "Port 3389 nicht korrekt konfiguriert" - ((validation_errors++)) - fi - - if ! firewall-cmd --zone=myp-backend --query-service=ssh 2>/dev/null; then - warning "SSH-Service nicht korrekt konfiguriert" - ((validation_errors++)) - fi - - if [ $validation_errors -eq 0 ]; then - log "✅ Firewall konfiguriert und validiert:" - log " 🔒 Zone: myp-backend (als Default gesetzt)" - log " 🌐 Netzwerk: 192.168.0.0/16 (nur IPv4)" - log " 🏠 Localhost: 127.0.0.1" - log " 🖥️ Lokaler Host: raspberrypi" - log " 📡 Frontend-Server: m040tbaraspi001" - log " 🔌 Ports: 443/tcp (HTTPS), 22/tcp (SSH), 3389/tcp (RDP)" - log " 🚫 IPv6 vollständig blockiert" - else - warning "⚠️ Firewall-Konfiguration mit $validation_errors Fehlern abgeschlossen" - info "System funktioniert möglicherweise trotzdem - manuelle Überprüfung empfohlen" - fi -} - -# =========================== REMOTE-ZUGANG TESTEN =========================== -test_remote_access() { - log "=== TESTE REMOTE-ZUGANG ===" - - # SSH-Service testen - progress "Teste SSH-Service..." - if systemctl is-active --quiet ssh; then - success "✅ SSH-Service läuft" - - # SSH-Port testen - if ss -tlnp | grep -q ":22 "; then - success "✅ SSH-Port 22 ist offen" - else - warning "⚠️ SSH-Port 22 nicht erreichbar" - fi - else - warning "⚠️ SSH-Service läuft nicht" - fi - - # RDP-Services testen - progress "Teste RDP-Services..." - - local xrdp_sesman_status="❌" - local xrdp_status="❌" - - if systemctl is-active --quiet xrdp-sesman; then - xrdp_sesman_status="✅" - success "✅ xrdp-sesman läuft" - else - warning "⚠️ xrdp-sesman läuft nicht" - fi - - if systemctl is-active --quiet xrdp; then - xrdp_status="✅" - success "✅ xrdp läuft" - - # RDP-Port testen - if ss -tlnp | grep -q ":3389 "; then - success "✅ RDP-Port 3389 ist offen" - else - warning "⚠️ RDP-Port 3389 nicht erreichbar" - fi - else - warning "⚠️ xrdp läuft nicht" - fi - - # Firewall-Status testen - progress "Teste Firewall-Status..." - if systemctl is-active --quiet firewalld; then - success "✅ Firewall läuft" - - # Prüfe ob Ports offen sind - if firewall-cmd --zone=myp-backend --query-port=22/tcp 2>/dev/null; then - success "✅ SSH-Port in Firewall freigegeben" - else - warning "⚠️ SSH-Port nicht in Firewall freigegeben" - fi - - if firewall-cmd --zone=myp-backend --query-port=3389/tcp 2>/dev/null; then - success "✅ RDP-Port in Firewall freigegeben" - else - warning "⚠️ RDP-Port nicht in Firewall freigegeben" - fi - else - warning "⚠️ Firewall läuft nicht" - fi - - # Netzwerk-Interface testen - progress "Teste Netzwerk-Konfiguration..." - local ip_address=$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7}' | head -1 || echo "Unbekannt") - if [ "$ip_address" != "Unbekannt" ]; then - success "✅ Netzwerk-Interface aktiv: $ip_address" - info "Zugang-URLs:" - info " SSH: ssh user@$ip_address" - if [ "$xrdp_status" = "✅" ]; then - info " RDP: $ip_address:3389 (root:$MYP_MAIN_PASSWORD oder user:$MYP_SSH_PASSWORD)" - fi - else - warning "⚠️ Keine Netzwerk-IP ermittelt" - fi - - # Status-Zusammenfassung - log "📊 Service-Status:" - log " SSH: $(systemctl is-active --quiet ssh && echo "✅ Aktiv" || echo "❌ Inaktiv")" - log " xrdp-sesman: $xrdp_sesman_status $(systemctl is-active --quiet xrdp-sesman && echo "Aktiv" || echo "Inaktiv")" - log " xrdp: $xrdp_status $(systemctl is-active --quiet xrdp && echo "Aktiv" || echo "Inaktiv")" - - log "✅ Remote-Zugang-Test abgeschlossen" -} - -# =========================== HOSTNAME KONFIGURATION =========================== -configure_hostname() { - log "=== KONFIGURIERE HOSTNAME ===" - - local target_hostname="m040tbaraspi001" - local current_hostname=$(hostname) - - if [ "$current_hostname" != "$target_hostname" ]; then - progress "Setze Hostname von '$current_hostname' auf '$target_hostname'..." - - # Hostname sofort setzen - hostnamectl set-hostname "$target_hostname" || error "Fehler beim Setzen des Hostnames" - - # /etc/hostname aktualisieren - echo "$target_hostname" > /etc/hostname - - # /etc/hosts aktualisieren - cp /etc/hosts /etc/hosts.backup - sed -i "s/127.0.1.1.*/127.0.1.1\t$target_hostname/" /etc/hosts - - # Falls kein 127.0.1.1 Eintrag existiert, hinzufügen - if ! grep -q "127.0.1.1" /etc/hosts; then - echo "127.0.1.1 $target_hostname" >> /etc/hosts - fi - - # Intranet-Eintrag hinzufügen für Corporate Network Access - if ! grep -q "m040tbaraspi001.de040.corpintra.net" /etc/hosts; then - echo "127.0.1.1 $target_hostname.de040.corpintra.net" >> /etc/hosts - fi - - log "✅ Hostname erfolgreich auf '$target_hostname' gesetzt" - log "✅ Intranet-Zugang konfiguriert: https://m040tbaraspi001.de040.corpintra.net" - else - log "✅ Hostname bereits korrekt: '$target_hostname'" - fi - - # Hostname-Auflösung testen - if getent hosts "$target_hostname" >/dev/null 2>&1; then - local resolved_ip=$(getent hosts "$target_hostname" | awk '{print $1}' | head -1) - log "✅ Hostname-Auflösung funktioniert: $target_hostname -> $resolved_ip" - else - warning "⚠️ Hostname-Auflösung für '$target_hostname' fehlgeschlagen" - fi -} - -# =========================== WEBAPP PERFORMANCE-OPTIMIERUNG =========================== -optimize_webapp_performance() { - log "=== WEBAPP PERFORMANCE-OPTIMIERUNG FÜR RASPBERRY PI ===" - - # Python/Flask spezifische Optimierungen - progress "Konfiguriere Python-Performance-Optimierungen..." - - # Python Bytecode Optimierung aktivieren - cat > /etc/environment << 'EOF' -# Python Performance Optimierungen -PYTHONOPTIMIZE=2 -PYTHONDONTWRITEBYTECODE=1 -PYTHONUNBUFFERED=1 -PYTHONHASHSEED=random - -# Flask/SQLite Optimierungen -FLASK_ENV=production -FLASK_DEBUG=0 -SQLITE_TMPDIR=/tmp - -# Memory Optimierungen -MALLOC_ARENA_MAX=2 -MALLOC_MMAP_THRESHOLD=131072 -MALLOC_TRIM_THRESHOLD=131072 - -EOF - - # Systemd Service-Optimierungen - progress "Optimiere Systemd-Services für bessere Performance..." - - # Stoppe unnötige Services - local unnecessary_services=( - "bluetooth.service" - "hciuart.service" - "avahi-daemon.service" - "cups.service" - "cups-browsed.service" - "ModemManager.service" - "wpa_supplicant.service" - ) - - for service in "${unnecessary_services[@]}"; do - if systemctl is-enabled "$service" 2>/dev/null; then - systemctl disable "$service" 2>/dev/null || true - systemctl stop "$service" 2>/dev/null || true - log "✅ Service deaktiviert: $service" - fi - done - - # Tmpfs für temporäre Dateien - progress "Konfiguriere tmpfs für bessere I/O Performance..." - - cat >> /etc/fstab << 'EOF' - -# MYP Performance Optimierungen - tmpfs für temporäre Dateien -tmpfs /tmp tmpfs defaults,noatime,nosuid,size=256m 0 0 -tmpfs /var/tmp tmpfs defaults,noatime,nosuid,size=128m 0 0 -tmpfs /var/log tmpfs defaults,noatime,nosuid,size=64m 0 0 - -EOF - - # Logrotate für tmpfs-Logs konfigurieren - cat > /etc/logrotate.d/myp-tmpfs << 'EOF' -/var/log/*.log { - daily - missingok - rotate 2 - compress - notifempty - create 0644 root root - copytruncate -} -EOF - - # Systemd Journal Einstellungen optimieren - progress "Optimiere systemd Journal für bessere Performance..." - - mkdir -p /etc/systemd/journald.conf.d - cat > /etc/systemd/journald.conf.d/myp-performance.conf << 'EOF' -[Journal] -# Journal Optimierungen für Raspberry Pi -Storage=volatile -RuntimeMaxUse=32M -RuntimeKeepFree=16M -RuntimeMaxFileSize=8M -RuntimeMaxFiles=4 -MaxRetentionSec=1day -MaxFileSec=1hour -ForwardToSyslog=no -ForwardToKMsg=no -ForwardToConsole=no -ForwardToWall=no -EOF - - # Crontab für regelmäßige Cache-Bereinigung - progress "Installiere automatische Cache-Bereinigung..." - - cat > /etc/cron.d/myp-cache-cleanup << 'EOF' -# MYP Cache und Memory Cleanup -# Alle 6 Stunden Cache bereinigen -0 */6 * * * root /bin/echo 3 > /proc/sys/vm/drop_caches -# Täglich um 3 Uhr temporäre Dateien bereinigen -0 3 * * * root /usr/bin/find /tmp -type f -atime +1 -delete 2>/dev/null -# Wöchentlich Python Cache bereinigen -0 2 * * 0 root /usr/bin/find /opt/myp -name "*.pyc" -delete 2>/dev/null -0 2 * * 0 root /usr/bin/find /opt/myp -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null -EOF - - # Limits für bessere Ressourcen-Verwaltung - progress "Konfiguriere System-Limits..." - - cat >> /etc/security/limits.conf << 'EOF' - -# MYP Performance Limits -* soft nofile 65536 -* hard nofile 65536 -* soft nproc 32768 -* hard nproc 32768 -root soft nofile 65536 -root hard nofile 65536 - -EOF - - # Apache/Nginx entfernen falls vorhanden (Konflikt mit Flask) - progress "Entferne konfliktbehaftete Webserver..." - - local webservers=("apache2" "nginx" "lighttpd") - for webserver in "${webservers[@]}"; do - if systemctl is-enabled "$webserver" 2>/dev/null; then - systemctl stop "$webserver" 2>/dev/null || true - systemctl disable "$webserver" 2>/dev/null || true - apt-get remove --purge -y "$webserver" 2>/dev/null || true - log "✅ Webserver entfernt: $webserver" - fi - done - - log "✅ Webapp Performance-Optimierung abgeschlossen:" - log " 🚀 Python Bytecode-Optimierung aktiviert" - log " 💾 tmpfs für temporäre Dateien konfiguriert" - log " 📝 Journal-Logging optimiert" - log " 🧹 Automatische Cache-Bereinigung installiert" - log " ⚡ Unnötige Services deaktiviert" - log " 📊 System-Limits für bessere Performance gesetzt" -} - -# =========================== CSS/JS OPTIMIERUNG =========================== -optimize_static_assets() { - log "=== STATISCHE DATEIEN OPTIMIERUNG ===" - - # Stelle sicher, dass APP_DIR existiert - if [ -z "$APP_DIR" ] || [ ! -d "$APP_DIR" ]; then - warning "⚠️ APP_DIR nicht definiert oder nicht vorhanden - überspringe Asset-Optimierung" - return - fi - - if [ ! -d "$APP_DIR/static" ]; then - warning "⚠️ Static-Ordner nicht gefunden: $APP_DIR/static - überspringe Asset-Optimierung" - return - fi - - progress "Analysiere und optimiere CSS/JS Dateien..." - - # Speichere aktuelles Verzeichnis - local original_dir=$(pwd) - - # Wechsle zu static Verzeichnis - cd "$APP_DIR/static" 2>/dev/null || { - warning "⚠️ Konnte nicht zu $APP_DIR/static wechseln" - return - } - - # Erstelle optimierte CSS-Datei durch Kombination kritischer Styles - progress "Erstelle optimierte CSS-Kombination..." - - cat > css/critical.min.css << 'EOF' -/* Kritische Styles für ersten Seitenaufbau - Inline-optimiert */ -*{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;line-height:1.5} -.container{max-width:1200px;margin:0 auto;padding:0 1rem} -.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0} -.btn{display:inline-flex;align-items:center;padding:0.5rem 1rem;border:none;border-radius:0.375rem;font-weight:500;text-decoration:none;cursor:pointer;transition:all 0.15s} -.btn-primary{background:#3b82f6;color:white}.btn-primary:hover{background:#2563eb} -.card{background:white;border-radius:0.5rem;padding:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,0.1)} -.flex{display:flex}.items-center{align-items:center}.justify-between{justify-content:space-between} -.hidden{display:none}.block{display:block}.inline-block{display:inline-block} -.text-sm{font-size:0.875rem}.text-lg{font-size:1.125rem} -.font-medium{font-weight:500}.font-bold{font-weight:700} -.text-gray-600{color:#4b5563}.text-gray-900{color:#111827} -.mb-4{margin-bottom:1rem}.mt-6{margin-top:1.5rem}.p-4{padding:1rem} -.w-full{width:100%}.h-full{height:100%} -@media(max-width:768px){.container{padding:0 0.5rem}.card{padding:1rem}} -EOF - - # Erstelle minimale JavaScript-Loader - progress "Erstelle optimierten JavaScript-Loader..." - - cat > js/loader.min.js << 'EOF' -/*Minimaler Async Loader für bessere Performance*/ -(function(){var d=document,w=window;function loadCSS(href){var l=d.createElement('link');l.rel='stylesheet';l.href=href;l.media='print';l.onload=function(){this.media='all'};d.head.appendChild(l)}function loadJS(src,cb){var s=d.createElement('script');s.async=true;s.src=src;if(cb)s.onload=cb;d.head.appendChild(s)}w.loadAssets=function(){if(w.assetsLoaded)return;w.assetsLoaded=true;loadCSS('/static/css/tailwind.min.css');loadJS('/static/js/app.min.js')};if(d.readyState==='loading'){d.addEventListener('DOMContentLoaded',w.loadAssets)}else{w.loadAssets()}})(); -EOF - - # Service Worker für besseres Caching - progress "Erstelle optimierten Service Worker..." - - cat > sw-optimized.js << 'EOF' -const CACHE_NAME = 'myp-webapp-v1'; -const ASSETS_TO_CACHE = [ - '/', - '/static/css/critical.min.css', - '/static/js/loader.min.js', - '/static/favicon.svg' -]; - -self.addEventListener('install', event => { - event.waitUntil( - caches.open(CACHE_NAME) - .then(cache => cache.addAll(ASSETS_TO_CACHE)) - ); -}); - -self.addEventListener('fetch', event => { - if (event.request.destination === 'image' || - event.request.url.includes('/static/')) { - event.respondWith( - caches.match(event.request) - .then(response => response || fetch(event.request)) - ); - } -}); -EOF - - # Gzip-Kompression für statische Dateien - progress "Komprimiere statische Dateien..." - - find . -name "*.css" -o -name "*.js" -o -name "*.html" | while read file; do - if [ -f "$file" ] && [ ! -f "$file.gz" ]; then - gzip -c "$file" > "$file.gz" 2>/dev/null || true - fi - done - - # Zurück zum Original-Verzeichnis - cd "$original_dir" 2>/dev/null || cd "$CURRENT_DIR" 2>/dev/null || true - - log "✅ Statische Dateien optimiert:" - log " 📦 Kritische CSS-Styles kombiniert" - log " ⚡ Asynchroner Asset-Loader erstellt" - log " 🗜️ Gzip-Kompression angewendet" - log " 🔄 Service Worker für Caching installiert" -} - -# =========================== INTERAKTIVES AUSWAHLMENÜ =========================== -show_main_menu() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} $APP_NAME - Setup-Skript v$APP_VERSION${NC}" - echo -e "${CYAN} Hostname: m040tbaraspi001${NC}" - echo -e "${CYAN} Intranet: https://m040tbaraspi001.de040.corpintra.net${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}🚀 INSTALLATIONS-OPTIONEN:${NC}" - echo "" - echo -e "${GREEN}[1]${NC} ${BLUE}Abhängigkeiten installieren${NC}" - echo -e " → Python 3.11, Node.js, SSL-Zertifikate" - echo -e " → Flask-Anwendung deployen und konfigurieren" - echo -e " → System für manuelle Tests vorbereiten" - echo "" - echo -e "${GREEN}[2]${NC} ${BLUE}Produktionsbetrieb einrichten${NC}" - echo -e " → Vollständige Kiosk-Installation mit Autostart" - echo -e " → Remote-Zugang (RDP/SSH) konfigurieren" - echo -e " → Automatischer Browser-Start beim Boot" - echo -e " → Performance-Optimierungen für Raspberry Pi" - echo "" - echo -e "${GREEN}[3]${NC} ${YELLOW}System-Status anzeigen${NC}" - echo -e " → Aktuelle Konfiguration prüfen" - echo -e " → Services und Logs anzeigen" - echo "" - echo -e "${GREEN}[4]${NC} ${YELLOW}Credentials anpassen${NC}" - echo -e " → Passwörter und Zugangsdaten ändern" - echo "" - echo -e "${GREEN}[5]${NC} ${PURPLE}Desktop-Verknüpfung erstellen${NC}" - echo -e " → Mercedes-Icon auf Desktop für Kiosk-Start" - echo -e " → Manuelle Kiosk-Aktivierung per Klick" - echo "" - echo -e "${GREEN}[0]${NC} ${RED}Beenden${NC}" - echo "" - echo -e "${CYAN}=================================================================${NC}" - echo -n "Ihre Auswahl [0-5]: " -} - -handle_menu_selection() { - local choice=$1 - - case $choice in - 1) - log "🔧 Benutzer wählte: Abhängigkeiten installieren" - install_dependencies_interactive - ;; - 2) - log "🚀 Benutzer wählte: Produktionsbetrieb einrichten" - install_production_interactive - ;; - 3) - log "📊 Benutzer wählte: System-Status anzeigen" - show_system_status - ;; - 4) - log "🔑 Benutzer wählte: Credentials anpassen" - interactive_credentials_setup - save_credentials_override - ;; - 5) - log "🖥️ Benutzer wählte: Desktop-Verknüpfung erstellen" - create_desktop_shortcut_interactive - ;; - 0) - log "👋 Benutzer beendet das Setup" - echo -e "\n${GREEN}Auf Wiedersehen! 👋${NC}" - exit 0 - ;; - *) - warning "❌ Ungültige Auswahl: $choice" - echo -e "\n${RED}Bitte wählen Sie eine Zahl zwischen 0 und 5.${NC}" - sleep 2 - ;; - esac -} - -install_dependencies_interactive() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} ABHÄNGIGKEITEN INSTALLIEREN${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}📦 Was wird installiert:${NC}" - echo -e " • Python 3.11 und Flask-Abhängigkeiten" - echo -e " • Node.js und npm" - echo -e " • SSL-Zertifikate für HTTPS" - echo -e " • MYP-Anwendung nach /opt/myp" - echo -e " • Systemd-Services für automatischen Start" - echo "" - echo -n "Möchten Sie fortfahren? (j/N): " - read -r confirm - - if [[ "$confirm" =~ ^[jJyY]$ ]]; then - log "✅ Benutzer bestätigte Abhängigkeiten-Installation" - install_dependencies_only_auto - echo "" - echo -e "${GREEN}✅ Abhängigkeiten erfolgreich installiert!${NC}" - echo -e "${BLUE}🌐 Anwendung verfügbar unter: $HTTP_URL${NC}" - echo "" - echo -n "Drücken Sie Enter um zum Hauptmenü zurückzukehren..." - read - else - log "❌ Benutzer brach Abhängigkeiten-Installation ab" - echo -e "${YELLOW}Installation abgebrochen.${NC}" - sleep 1 - fi -} - -install_production_interactive() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} PRODUKTIONSBETRIEB EINRICHTEN${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}🚀 Was wird konfiguriert:${NC}" - echo -e " • Vollständige Kiosk-Installation" - echo -e " • Automatischer Browser-Start beim Boot" - echo -e " • Remote-Zugang (RDP/SSH)" - echo -e " • Firewall und Sicherheitskonfiguration" - echo -e " • Performance-Optimierungen" - echo -e " • Hostname: m040tbaraspi001" - echo -e " • Intranet-Zugang: https://m040tbaraspi001.de040.corpintra.net" - echo "" - echo -e "${RED}⚠️ WARNUNG: System wird nach Installation automatisch neu gestartet!${NC}" - echo "" - echo -n "Möchten Sie den Produktionsbetrieb einrichten? (j/N): " - read -r confirm - - if [[ "$confirm" =~ ^[jJyY]$ ]]; then - log "✅ Benutzer bestätigte Produktions-Installation" - install_full_production_system_auto - else - log "❌ Benutzer brach Produktions-Installation ab" - echo -e "${YELLOW}Installation abgebrochen.${NC}" - sleep 1 - fi -} - -show_system_status() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} SYSTEM-STATUS${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - - # Grundlegende System-Informationen - echo -e "${YELLOW}🖥️ System-Informationen:${NC}" - echo -e " Hostname: $(hostname)" - echo -e " Betriebssystem: $(lsb_release -d 2>/dev/null | cut -f2 || echo 'Unbekannt')" - echo -e " Kernel: $(uname -r)" - echo -e " Architektur: $(uname -m)" - echo -e " RAM: $(free -h | awk '/^Mem:/ {print $2}')" - echo "" - - # Anwendungs-Status - echo -e "${YELLOW}📦 Anwendungs-Status:${NC}" - if [ -d "$APP_DIR" ]; then - echo -e " ✅ Anwendung installiert: $APP_DIR" - if [ -f "$APP_DIR/app.py" ]; then - echo -e " ✅ Flask-App gefunden" - else - echo -e " ❌ Flask-App nicht gefunden" - fi - else - echo -e " ❌ Anwendung nicht installiert" - fi - echo "" - - # Service-Status - echo -e "${YELLOW}⚙️ Service-Status:${NC}" - local services=("$HTTP_SERVICE_NAME" "$KIOSK_SERVICE_NAME" "ssh" "xrdp") - for service in "${services[@]}"; do - if systemctl is-active --quiet "$service" 2>/dev/null; then - echo -e " ✅ $service: Aktiv" - elif systemctl list-unit-files | grep -q "$service" 2>/dev/null; then - echo -e " ❌ $service: Inaktiv" - else - echo -e " ⚪ $service: Nicht installiert" - fi - done - echo "" - - # Netzwerk-Status - echo -e "${YELLOW}🌐 Netzwerk-Status:${NC}" - local ip=$(ip route get 1 2>/dev/null | awk '{print $7}' | head -1) - if [ -n "$ip" ]; then - echo -e " IP-Adresse: $ip" - echo -e " Webapp-URL: http://$ip:5000" - echo -e " Intranet-URL: https://m040tbaraspi001.de040.corpintra.net" - else - echo -e " ❌ Keine Netzwerkverbindung" - fi - echo "" - - # Log-Dateien - echo -e "${YELLOW}📄 Log-Dateien:${NC}" - if [ -f "$INSTALL_LOG" ]; then - echo -e " 📄 Installation: $INSTALL_LOG" - fi - if [ -f "$ERROR_LOG" ] && [ -s "$ERROR_LOG" ]; then - echo -e " 🚨 Fehler: $ERROR_LOG" - fi - echo "" - - echo -n "Drücken Sie Enter um zum Hauptmenü zurückzukehren..." - read -} - -create_desktop_shortcut_interactive() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} DESKTOP-VERKNÜPFUNG ERSTELLEN${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}🖥️ Was wird erstellt:${NC}" - echo -e " • Desktop-Icon mit Mercedes-Logo" - echo -e " • Kiosk-Start per Doppelklick" - echo -e " • Automatische Browser-Erkennung" - echo -e " • Intelligente URL-Ermittlung" - echo "" - echo -e "${PURPLE}📍 Verfügbare Desktop-Umgebungen:${NC}" - - # Erkenne verfügbare Desktop-Umgebungen - local desktops_found=() - if [ -d "/home/$USER/Desktop" ]; then - desktops_found+=("Aktueller Benutzer: /home/$USER/Desktop") - fi - if [ -d "/home/kiosk/Desktop" ]; then - desktops_found+=("Kiosk-Benutzer: /home/kiosk/Desktop") - fi - if [ -d "/etc/skel/Desktop" ]; then - desktops_found+=("System-Standard: /etc/skel/Desktop") - fi - - if [ ${#desktops_found[@]} -eq 0 ]; then - echo -e " ${RED}❌ Keine Desktop-Verzeichnisse gefunden${NC}" - echo -e " ${YELLOW}💡 Desktop-Environment möglicherweise nicht installiert${NC}" - echo "" - echo -n "Trotzdem fortfahren und Desktop-Verzeichnisse erstellen? (j/N): " - read -r create_desktop - if [[ ! "$create_desktop" =~ ^[jJyY]$ ]]; then - echo -e "${YELLOW}Abgebrochen.${NC}" - sleep 1 - return - fi - else - for desktop in "${desktops_found[@]}"; do - echo -e " ✅ $desktop" - done - fi - - echo "" - echo -n "Desktop-Verknüpfung erstellen? (j/N): " - read -r confirm - - if [[ "$confirm" =~ ^[jJyY]$ ]]; then - log "✅ Benutzer bestätigte Desktop-Verknüpfung-Erstellung" - create_desktop_shortcut - echo "" - echo -e "${GREEN}✅ Desktop-Verknüpfung erfolgreich erstellt!${NC}" - echo -e "${BLUE}🖱️ Doppelklick auf das Mercedes-Icon zum Starten${NC}" - echo "" - echo -n "Drücken Sie Enter um zum Hauptmenü zurückzukehren..." - read - else - log "❌ Benutzer brach Desktop-Verknüpfung-Erstellung ab" - echo -e "${YELLOW}Erstellung abgebrochen.${NC}" - sleep 1 - fi -} - -create_desktop_shortcut() { - log "=== ERSTELLE DESKTOP-VERKNÜPFUNG ===" - - # Erstelle Kiosk-Start-Skript - create_kiosk_launcher_script - - # Erstelle Desktop-Einträge für alle verfügbaren Benutzer - create_desktop_entries - - # Setze korrekte Berechtigungen - fix_desktop_permissions - - log "✅ Desktop-Verknüpfung erfolgreich erstellt" -} - -create_kiosk_launcher_script() { - log "=== ERSTELLE KIOSK-LAUNCHER-SKRIPT ===" - - mkdir -p "$APP_DIR/scripts" - - cat > "$APP_DIR/scripts/launch_kiosk.sh" << 'EOF' -#!/bin/bash -# MYP Kiosk-Modus Launcher -# Startet die MYP-Anwendung im Kiosk-Modus - -# Logging-Setup -LOG_FILE="/var/log/myp-desktop-launcher.log" -exec 1> >(tee -a "$LOG_FILE") -exec 2>&1 - -echo "=== MYP Kiosk Desktop-Start $(date) ===" - -# Prüfe ob bereits ein Kiosk-Prozess läuft -if pgrep -f "chromium.*kiosk.*localhost:5000" >/dev/null 2>&1; then - echo "⚠️ Kiosk-Modus bereits aktiv - bringe Fenster in den Vordergrund" - # Versuche existierendes Fenster zu aktivieren - if command -v wmctrl >/dev/null 2>&1; then - wmctrl -a "MYP Druckerverwaltung" 2>/dev/null || true - fi - exit 0 -fi - -# Ermittle optimale URL -if [ -x /opt/myp/scripts/get_kiosk_url.sh ]; then - TARGET_URL=$(/opt/myp/scripts/get_kiosk_url.sh) -else - TARGET_URL="http://localhost:5000" -fi - -echo "🔗 Verwende URL: $TARGET_URL" - -# Prüfe Backend-Verfügbarkeit -echo "🔍 Prüfe Backend-Verfügbarkeit..." -for i in {1..30}; do - if curl -s --connect-timeout 3 --max-time 5 "$TARGET_URL" >/dev/null 2>&1; then - echo "✅ Backend erreichbar" - break - fi - echo "⏳ Warte auf Backend... ($i/30)" - sleep 2 -done - -# Browser-Auswahl -BROWSER="" -if command -v chromium >/dev/null 2>&1; then - BROWSER="chromium" -elif command -v chromium-browser >/dev/null 2>&1; then - BROWSER="chromium-browser" -elif command -v google-chrome >/dev/null 2>&1; then - BROWSER="google-chrome" -elif command -v firefox-esr >/dev/null 2>&1; then - BROWSER="firefox-esr" -elif command -v firefox >/dev/null 2>&1; then - BROWSER="firefox" -else - echo "❌ Kein unterstützter Browser gefunden!" - zenity --error --text="Kein unterstützter Browser gefunden!\n\nBitte installieren Sie Chromium oder Firefox." --title="MYP Kiosk-Fehler" 2>/dev/null || \ - notify-send "MYP Kiosk-Fehler" "Kein unterstützter Browser gefunden!" 2>/dev/null || \ - echo "FEHLER: Kein Browser verfügbar" - exit 1 -fi - -echo "🌐 Verwende Browser: $BROWSER" - -# Bildschirmauflösung ermitteln -if [ -n "$DISPLAY" ]; then - RESOLUTION=$(xrandr 2>/dev/null | grep -E '\*|\+' | head -1 | awk '{print $1}' || echo "1920x1080") - WIDTH=$(echo $RESOLUTION | cut -d'x' -f1) - HEIGHT=$(echo $RESOLUTION | cut -d'x' -f2) - echo "📺 Bildschirmauflösung: ${WIDTH}x${HEIGHT}" -else - WIDTH=1920 - HEIGHT=1080 - echo "📺 Verwende Standard-Auflösung: ${WIDTH}x${HEIGHT}" -fi - -# Browser-spezifische Argumente -if [[ "$BROWSER" == "chromium"* ]] || [[ "$BROWSER" == "google-chrome"* ]]; then - BROWSER_ARGS=( - --kiosk - --no-sandbox - --disable-dev-shm-usage - --disable-gpu-sandbox - --disable-software-rasterizer - --disable-background-timer-throttling - --disable-backgrounding-occluded-windows - --disable-renderer-backgrounding - --disable-features=TranslateUI - --force-device-scale-factor=1.0 - --window-size=$WIDTH,$HEIGHT - --window-position=0,0 - --user-data-dir=/tmp/myp-kiosk-desktop - --disable-infobars - --disable-session-crashed-bubble - --disable-restore-session-state - --disable-extensions - --disable-plugins - --disable-popup-blocking - --disable-sync - --disable-translate - --noerrdialogs - --no-first-run - --no-default-browser-check - --autoplay-policy=no-user-gesture-required - --disable-background-mode - --disable-pinch - --hide-scrollbars - --ignore-certificate-errors - --ignore-ssl-errors - --disable-web-security - --allow-running-insecure-content - --app="$TARGET_URL" - ) -else - # Firefox-Argumente - BROWSER_ARGS=( - --kiosk - --width=$WIDTH - --height=$HEIGHT - --no-remote - --new-instance - "$TARGET_URL" - ) -fi - -echo "🚀 Starte $BROWSER im Kiosk-Modus..." - -# Browser starten -"$BROWSER" "${BROWSER_ARGS[@]}" & -BROWSER_PID=$! - -echo "✅ Browser gestartet (PID: $BROWSER_PID)" -echo "🎯 Kiosk-Modus aktiv für URL: $TARGET_URL" - -# Optional: Warte auf Browser-Beendigung -wait $BROWSER_PID -echo "🔚 Kiosk-Modus beendet" -EOF - - chmod +x "$APP_DIR/scripts/launch_kiosk.sh" - - log "✅ Kiosk-Launcher-Skript erstellt: $APP_DIR/scripts/launch_kiosk.sh" -} - -create_desktop_entries() { - log "=== ERSTELLE DESKTOP-EINTRÄGE ===" - - # Mercedes-Icon kopieren an zentrale Stelle - local icon_dir="/usr/share/pixmaps" - local icon_source="$CURRENT_DIR/static/mercedes.svg" - # Fallback-Pfade für das Mercedes-Icon - if [ ! -f "$icon_source" ]; then - icon_source="$APP_DIR/static/mercedes.svg" - fi - if [ ! -f "$icon_source" ]; then - icon_source="$(find "$CURRENT_DIR" -name "mercedes.svg" 2>/dev/null | head -1)" - fi - local icon_target="$icon_dir/myp-mercedes.svg" - - if [ -f "$icon_source" ]; then - cp "$icon_source" "$icon_target" 2>/dev/null || { - # Fallback: Icon in App-Verzeichnis - mkdir -p "$APP_DIR/static" - cp "$icon_source" "$APP_DIR/static/mercedes.svg" - icon_target="$APP_DIR/static/mercedes.svg" - } - log "✅ Mercedes-Icon kopiert: $icon_target" - else - warning "⚠️ Mercedes-Icon nicht gefunden: $icon_source" - icon_target="applications-graphics" # Fallback-Icon - fi - - # Desktop-Entry-Inhalt - local desktop_content="[Desktop Entry] -Version=1.0 -Type=Application -Name=MYP Druckerverwaltung (Kiosk) -Comment=Starte MYP Druckerverwaltung im Kiosk-Modus -Exec=$APP_DIR/scripts/launch_kiosk.sh -Icon=$icon_target -Terminal=false -Categories=Office;Graphics;3DGraphics;Engineering; -StartupNotify=true -StartupWMClass=chromium-browser -Keywords=3D;Printing;Drucker;Kiosk;MYP;Mercedes; -MimeType=model/stl;model/obj;text/x.gcode; -Actions=OpenBrowser;OpenSettings; - -[Desktop Action OpenBrowser] -Name=Im Browser öffnen -Exec=xdg-open http://localhost:5000 - -[Desktop Action OpenSettings] -Name=Einstellungen -Exec=$APP_DIR/scripts/launch_kiosk.sh --settings" - - # Desktop-Einträge für verschiedene Benutzer erstellen - local desktop_dirs=( - "/home/$USER/Desktop" - "/home/kiosk/Desktop" - "/etc/skel/Desktop" - "/usr/share/applications" # System-weit verfügbar - ) - - for desktop_dir in "${desktop_dirs[@]}"; do - if [ "$desktop_dir" = "/usr/share/applications" ] || [ -d "$(dirname "$desktop_dir")" ]; then - mkdir -p "$desktop_dir" 2>/dev/null || continue - - local desktop_file="$desktop_dir/myp-kiosk.desktop" - echo "$desktop_content" > "$desktop_file" 2>/dev/null && { - chmod +x "$desktop_file" 2>/dev/null || true - log "✅ Desktop-Eintrag erstellt: $desktop_file" - } - fi - done - - # Spezielle Behandlung für aktuellen Benutzer-Desktop - if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then - local user_desktop="/home/$SUDO_USER/Desktop" - mkdir -p "$user_desktop" 2>/dev/null || true - if [ -d "$user_desktop" ]; then - local user_desktop_file="$user_desktop/myp-kiosk.desktop" - echo "$desktop_content" > "$user_desktop_file" 2>/dev/null && { - chmod +x "$user_desktop_file" 2>/dev/null || true - chown "$SUDO_USER:$SUDO_USER" "$user_desktop_file" 2>/dev/null || true - log "✅ Benutzer-Desktop-Eintrag erstellt: $user_desktop_file" - } - fi - fi -} - -fix_desktop_permissions() { - log "=== KORRIGIERE DESKTOP-BERECHTIGUNGEN ===" - - # Desktop-Dateien für verschiedene Benutzer korrigieren - local users=("$USER" "kiosk") - if [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then - users+=("$SUDO_USER") - fi - - for user in "${users[@]}"; do - if id "$user" >/dev/null 2>&1; then - local user_desktop="/home/$user/Desktop" - if [ -d "$user_desktop" ]; then - chown -R "$user:$user" "$user_desktop" 2>/dev/null || true - find "$user_desktop" -name "*.desktop" -exec chmod +x {} \; 2>/dev/null || true - log "✅ Berechtigungen korrigiert für: $user" - fi - fi - done - - # System-weite Desktop-Datei - if [ -f "/usr/share/applications/myp-kiosk.desktop" ]; then - chmod 644 "/usr/share/applications/myp-kiosk.desktop" 2>/dev/null || true - log "✅ System-weite Desktop-Datei konfiguriert" - fi - - # Update Desktop-Datenbank - if command -v update-desktop-database >/dev/null 2>&1; then - update-desktop-database /usr/share/applications 2>/dev/null || true - log "✅ Desktop-Datenbank aktualisiert" - fi -} - -install_desktop_tools() { - log "=== INSTALLIERE DESKTOP-TOOLS ===" - - # Tools für bessere Desktop-Integration installieren - local desktop_packages=( - "wmctrl" # Fenster-Management - "xdotool" # X11-Automatisierung - "zenity" # GUI-Dialoge - "notify-osd" # Desktop-Benachrichtigungen - "libnotify-bin" # notify-send Kommando - "unclutter" # Mauszeiger verstecken - ) - - progress "Installiere Desktop-Integration-Tools..." - - for package in "${desktop_packages[@]}"; do - if ! dpkg -l | grep -q "^ii.*$package" 2>/dev/null; then - if apt-get install -y "$package" 2>/dev/null; then - log "✅ $package installiert" - else - warning "⚠️ $package konnte nicht installiert werden" - fi - else - log "✅ $package bereits installiert" - fi - done - - log "✅ Desktop-Tools-Installation abgeschlossen" -} - -# =========================== HAUPTPROGRAMM (INTERAKTIV) =========================== -main() { - # Stelle sicher, dass wir im richtigen Verzeichnis sind - cd "$CURRENT_DIR" 2>/dev/null || true - - # Logging initialisieren - init_logging - - log "=== MYP INTERAKTIVES SETUP GESTARTET ===" - log "Version: $APP_VERSION" - log "Arbeitsverzeichnis: $CURRENT_DIR" - - # Grundlegende Validierung - check_root - - # Credentials laden - load_dynamic_credentials - validate_credentials_comprehensive - - # Automatische Modus-Erkennung nur für Parameter - detect_installation_mode "$@" - - # Falls Kommandozeilen-Parameter gesetzt sind, direkt ausführen - if [ "$FORCE_PRODUCTION" = true ]; then - log "🚀 Starte PRODUKTIONS-INSTALLATION (Parameter)..." - install_full_production_system_auto - show_final_summary - log "✅ MYP SETUP ABGESCHLOSSEN" - return - elif [ "$FORCE_DEVELOPMENT" = true ]; then - log "🔧 Starte ENTWICKLUNGS-INSTALLATION (Parameter)..." - install_dependencies_only_auto - show_final_summary - log "✅ MYP SETUP ABGESCHLOSSEN" - return - fi - - # Interaktives Menü - while true; do - show_main_menu - read -r choice - echo "" - handle_menu_selection "$choice" - echo "" - done -} - -show_installation_banner() { - clear - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} $APP_NAME - Automatisches Setup v$APP_VERSION${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - echo -e "${YELLOW}🤖 VOLLAUTOMATISCHE INSTALLATION${NC}" - echo "" - case "$AUTO_INSTALL_MODE" in - "production") - echo -e "${GREEN}📋 MODUS: PRODUKTIONS-INSTALLATION${NC}" - echo -e " ✅ Vollständige Kiosk-Installation" - echo -e " ✅ Remote-Zugang (RDP/SSH)" - echo -e " ✅ Automatischer Kiosk-Start beim Boot" - echo -e " ✅ Firewall und Sicherheit" - ;; - "development") - echo -e "${BLUE}📋 MODUS: ENTWICKLUNGS-INSTALLATION${NC}" - echo -e " ✅ Python, Node.js, SSL-Zertifikate" - echo -e " ✅ Anwendung deployed und getestet" - echo -e " ✅ System bereit für manuelle Tests" - echo -e " ✅ Entwicklungsfreundliche Konfiguration" - ;; - esac - echo "" - echo -e "${PURPLE}⏱️ Installation startet in 5 Sekunden...${NC}" - echo -e "${PURPLE} (Drücken Sie Ctrl+C zum Abbrechen)${NC}" - echo "" - echo -e "${CYAN}=================================================================${NC}" - - # 5 Sekunden Countdown - for i in 5 4 3 2 1; do - echo -ne "\r${PURPLE}⏱️ Installation startet in $i Sekunden...${NC}" - sleep 1 - done - echo -ne "\r${GREEN}🚀 Installation gestartet! ${NC}\n" - echo "" -} - -install_dependencies_only_auto() { - log "=== AUTOMATISCHE ENTWICKLUNGS-INSTALLATION ===" - - # Grundlegende System-Validierung - check_system_resources - check_debian_system - check_internet_connection - - # System-Konfiguration - configure_hostname - update_system - configure_network_security - - # Core-Abhängigkeiten installieren - install_python_dependencies - install_nodejs_npm - install_ssl_certificates - install_python_packages - - # Anwendung deployen - deploy_application - install_npm_dependencies - - # Desktop-Tools für bessere Benutzererfahrung installieren - install_desktop_tools - - # Credentials deployen - deploy_credentials - - # Berechtigungen für kiosk-User korrigieren - fix_project_permissions - create_permission_fix_script - - # Services für manuelles Testen vorbereiten - install_systemd_services - enable_and_start_services - - # Intelligente Kiosk-URL-Ermittlung erstellen - create_smart_kiosk_url_script - - # Desktop-Verknüpfung für einfachen Zugang erstellen - if [ -n "$DISPLAY" ] || [ -d "/home/*/Desktop" ] 2>/dev/null; then - if create_desktop_shortcut 2>/dev/null; then - info "✅ Desktop-Verknüpfung mit Mercedes-Icon erstellt" - else - warning "⚠️ Desktop-Verknüpfung konnte nicht erstellt werden" - fi - else - info "ℹ️ Keine Desktop-Umgebung erkannt - Desktop-Verknüpfung übersprungen" - fi - - # Performance-Optimierungen auch für manuelles Testen - optimize_webapp_performance - optimize_static_assets - - # Umfassende System-Tests - progress "Starte umfassende System-Tests..." - if test_application; then - success "✅ Alle System-Tests erfolgreich!" - else - warning "⚠️ System-Tests mit Problemen - System möglicherweise eingeschränkt funktionsfähig" - fi - - # Cleanup - cleanup_old_files - - success "✅ Entwicklungs-Installation abgeschlossen!" -} - -install_full_production_system_auto() { - log "=== AUTOMATISCHE PRODUKTIONS-INSTALLATION ===" - - # Umfassende System-Validierung - check_system_resources - check_debian_system - check_internet_connection - - # Dynamische Credentials laden - load_dynamic_credentials - - # System-Grundkonfiguration - configure_hostname - - # PHASE 1: VOLLSTÄNDIGE UMGEBUNGSBEREINIGUNG UND -VORBEREITUNG - log "🧹 PHASE 1: UMGEBUNGSBEREINIGUNG UND -VORBEREITUNG" - - # Alle Desktop-Environments vollständig entfernen - complete_environment_cleanup - - # System-Updates und Basis-Pakete - update_system - configure_network_security - - # Python-Umgebung vollständig neu aufsetzen - setup_clean_python_environment - - # PHASE 2: DESKTOP-ENVIRONMENT UND X11 INSTALLATION - log "🖥️ PHASE 2: DESKTOP-ENVIRONMENT UND X11 INSTALLATION" - - # Minimales aber funktionales Desktop-Environment installieren - install_minimal_desktop_environment - configure_x11_for_raspberry_pi - - # PHASE 3: ANWENDUNGS-INSTALLATION - log "📦 PHASE 3: ANWENDUNGS-INSTALLATION" - - # Intelligente Abhängigkeiten-Installation - if [ ! -d "$APP_DIR" ] || [ ! -f "$APP_DIR/app.py" ]; then - warning "Anwendung noch nicht deployed - führe vollständige Installation durch..." - - install_nodejs_npm - install_ssl_certificates - install_python_packages_with_break_system - deploy_application - install_npm_dependencies - - # Desktop-Tools für bessere Benutzererfahrung installieren - install_desktop_tools - - # Credentials deployen - deploy_credentials - - # Berechtigungen für kiosk-User korrigieren - fix_project_permissions - create_permission_fix_script - else - info "Anwendung bereits deployed - aktualisiere Python-Pakete" - install_python_packages_with_break_system - deploy_credentials - fi - - # PHASE 4: KIOSK-SYSTEM KONFIGURATION - log "🖥️ PHASE 4: KIOSK-SYSTEM KONFIGURATION" - - # Remote-Zugang konfigurieren (robust) - install_remote_access - configure_firewall - - # Kiosk-System konfigurieren - create_kiosk_user - configure_autologin_robust - configure_kiosk_autostart_robust - - # PHASE 5: SERVICES UND OPTIMIERUNG - log "⚡ PHASE 5: SERVICES UND OPTIMIERUNG" - - # Services installieren und aktivieren (robust) - install_systemd_services - enable_and_start_services - - # Intelligente Kiosk-URL-Ermittlung erstellen - create_smart_kiosk_url_script - - # Desktop-Verknüpfung für einfachen Zugang erstellen - if create_desktop_shortcut 2>/dev/null; then - info "✅ Desktop-Verknüpfung mit Mercedes-Icon erstellt" - else - warning "⚠️ Desktop-Verknüpfung konnte nicht erstellt werden" - fi - - # Performance-Optimierungen für Raspberry Pi Webapp - optimize_webapp_performance - - # Static Assets nur optimieren wenn App deployed wurde - if [ -d "$APP_DIR" ] && [ -d "$APP_DIR/static" ]; then - optimize_static_assets - else - info "⏭️ Static Asset Optimierung übersprungen - App noch nicht deployed" - fi - - # PHASE 6: SYSTEM-TESTS UND VALIDIERUNG - log "🧪 PHASE 6: SYSTEM-TESTS UND VALIDIERUNG" - - # Umfassende System-Tests - progress "Führe umfassende Produktions-System-Tests durch..." - local system_tests_passed=true - - if test_application; then - success "✅ Anwendungs-Tests erfolgreich" - else - warning "⚠️ Anwendungs-Tests mit Problemen" - system_tests_passed=false - fi - - # Cleanup - cleanup_old_files - - success "✅ Produktions-Installation abgeschlossen!" - warning "🔄 AUTOMATISCHER NEUSTART in 10 Sekunden für vollständige Kiosk-Aktivierung!" - - # FINALE PHASE: AUTOMATISCHER NEUSTART - log "🔄 FINALE PHASE: AUTOMATISCHER NEUSTART" - - # Zusammenfassung der Installation - log "" - log "📋 INSTALLATIONS-ZUSAMMENFASSUNG:" - log " ✅ Vollständige Umgebungsbereinigung durchgeführt" - log " ✅ Python 3.11 mit --break-system-packages installiert" - log " ✅ Minimales Desktop-Environment konfiguriert" - log " ✅ Robuste Autologin-Konfiguration implementiert" - log " ✅ Kiosk-Autostart mit Watchdog aktiviert" - log " ✅ Alle Desktop-Environments deaktiviert" - log " ✅ Boot-Target auf multi-user gesetzt" - log "" - log "🎯 NACH DEM NEUSTART:" - log " → System startet automatisch ohne Desktop" - log " → Kiosk-User loggt sich automatisch ein (tty1)" - log " → X11-Server startet automatisch" - log " → Browser öffnet MYP-Anwendung im Kiosk-Modus" - log " → Vollautomatischer Betrieb ohne Benutzerinteraktion" - log "" - - # Countdown für automatischen Reboot - progress "Starte automatischen Neustart in 10 Sekunden..." - for i in {10..1}; do - echo -ne "\r🔄 Neustart in $i Sekunden... (Ctrl+C zum Abbrechen)" - sleep 1 - done - echo "" - - log "🚀 STARTE NEUSTART FÜR KIOSK-AKTIVIERUNG..." - sync - - # Automatischer Neustart - reboot -} - -show_final_summary() { - echo "" - echo -e "${CYAN}=================================================================${NC}" - echo -e "${CYAN} INSTALLATION ERFOLGREICH ABGESCHLOSSEN!${NC}" - echo -e "${CYAN}=================================================================${NC}" - echo "" - - case "$AUTO_INSTALL_MODE" in - "production") - echo -e "${GREEN}🎯 PRODUKTIONS-SYSTEM BEREIT${NC}" - echo "" - echo -e "${BLUE}📋 Was wurde installiert:${NC}" - echo -e " ✅ Vollständige Kiosk-Installation" - echo -e " ✅ Remote-Zugang (RDP: root:$MYP_MAIN_PASSWORD)" - echo -e " ✅ SSH-Zugang (user: $MYP_SSH_PASSWORD)" - echo -e " ✅ Automatischer Kiosk-Start beim Boot" - echo -e " ✅ Firewall und Sicherheitskonfiguration" - echo -e " ✅ Performance-Optimierungen" - echo -e " ✅ Desktop-Verknüpfung mit Mercedes-Icon" - echo "" - echo -e "${YELLOW}🚀 System-Status:${NC}" - echo -e " 🌐 Webapp: $HTTP_URL" - echo -e " 🖥️ Kiosk startet automatisch beim Boot" - echo -e " 🔒 Remote-Zugang konfiguriert" - echo "" - echo -e "${PURPLE}💡 Nächste Schritte:${NC}" - echo -e " 1. System neu starten für vollständige Kiosk-Aktivierung" - echo -e " 2. Remote-Zugang testen (RDP/SSH)" - echo -e " 3. Webapp über Browser testen" - ;; - "development") - echo -e "${BLUE}🔧 ENTWICKLUNGS-SYSTEM BEREIT${NC}" - echo "" - echo -e "${BLUE}📋 Was wurde installiert:${NC}" - echo -e " ✅ Python 3 und alle Abhängigkeiten" - echo -e " ✅ Node.js und npm" - echo -e " ✅ SSL-Zertifikate" - echo -e " ✅ Anwendung deployed nach: $APP_DIR" - echo -e " ✅ Systemd-Services installiert" - echo -e " ✅ Performance-Optimierungen" - echo -e " ✅ Desktop-Verknüpfung mit Mercedes-Icon" - echo "" - echo -e "${YELLOW}🚀 System-Status:${NC}" - echo -e " 🌐 Webapp: $HTTP_URL" - echo -e " ⚙️ Services: sudo systemctl status $HTTP_SERVICE_NAME" - echo "" - echo -e "${PURPLE}💡 Nächste Schritte:${NC}" - echo -e " 1. Webapp testen: $HTTP_URL" - echo -e " 2. Kiosk-Modus testen: Doppelklick auf Mercedes-Icon" - echo -e " 3. Manuelle Tests durchführen" - echo -e " 4. Entwicklung starten: cd $APP_DIR" - echo -e " 5. Für Produktions-Kiosk: sudo $0 --production" - ;; - esac - - echo "" - echo -e "${BLUE}📁 Log-Dateien:${NC}" - echo -e " 📄 Vollständiges Log: $INSTALL_LOG" - [ $ERROR_COUNT -gt 0 ] && echo -e " 🚨 Fehler-Log: $ERROR_LOG" - [ $WARNING_COUNT -gt 0 ] && echo -e " ⚠️ Warnungs-Log: $WARNING_LOG" - echo -e " 🔍 Debug-Log: $DEBUG_LOG" - echo -e " 📊 Zusammenfassung: logs/install-summary.txt" - - # Fehler-Zusammenfassung anzeigen - show_error_summary - - echo "" - echo -e "${GREEN}✅ MYP Druckerverwaltung erfolgreich installiert!${NC}" - echo -e "${CYAN}=================================================================${NC}" -} - -# =========================== INTELLIGENTE KIOSK-URL KONFIGURATION =========================== -get_kiosk_url() { - log "=== ERMITTLE OPTIMALE KIOSK-URL ===" - - local kiosk_url="http://localhost:5000" - local intranet_url="https://m040tbaraspi001.de040.corpintra.net" - - # Prüfe ob localhost erreichbar ist - if curl -s --connect-timeout 3 --max-time 5 "http://localhost:5000" >/dev/null 2>&1; then - log "✅ Localhost erreichbar - verwende lokale URL" - echo "$kiosk_url" - return - fi - - # Prüfe ob Intranet erreichbar ist - if curl -s --connect-timeout 5 --max-time 10 "$intranet_url" >/dev/null 2>&1; then - log "✅ Intranet erreichbar - verwende Intranet-URL" - echo "$intranet_url" - return - fi - - # Fallback: Versuche lokale IP-Adresse - local local_ip=$(ip route get 1 2>/dev/null | awk '{print $7}' | head -1) - if [ -n "$local_ip" ] && [ "$local_ip" != "127.0.0.1" ]; then - local ip_url="http://$local_ip:5000" - if curl -s --connect-timeout 3 --max-time 5 "$ip_url" >/dev/null 2>&1; then - log "✅ Lokale IP erreichbar - verwende IP-URL: $ip_url" - echo "$ip_url" - return - fi - fi - - # Finaler Fallback: localhost - log "⚠️ Fallback auf localhost - Backend möglicherweise noch nicht gestartet" - echo "$kiosk_url" -} - -create_smart_kiosk_url_script() { - log "=== ERSTELLE INTELLIGENTE KIOSK-URL ERMITTLUNG ===" - - cat > "$APP_DIR/scripts/get_kiosk_url.sh" << 'EOF' -#!/bin/bash -# Intelligente Kiosk-URL-Ermittlung für MYP -# Priorisiert lokale Verbindung, fällt auf Intranet zurück - -LOCALHOST_URL="http://localhost:5000" -INTRANET_URL="https://m040tbaraspi001.de040.corpintra.net" - -# Funktion: URL testen -test_url() { - local url="$1" - local timeout="${2:-5}" - - curl -s --connect-timeout "$timeout" --max-time "$timeout" "$url" >/dev/null 2>&1 - return $? -} - -# Priorisierte URL-Tests -echo "[$(date)] Ermittle optimale Kiosk-URL..." >> /var/log/kiosk-url.log - -# 1. Priorität: Localhost (schnellste Option für Kiosk) -if test_url "$LOCALHOST_URL" 3; then - echo "[$(date)] Localhost verfügbar: $LOCALHOST_URL" >> /var/log/kiosk-url.log - echo "$LOCALHOST_URL" - exit 0 -fi - -# 2. Priorität: Intranet-URL (für Remote-Zugang) -if test_url "$INTRANET_URL" 8; then - echo "[$(date)] Intranet verfügbar: $INTRANET_URL" >> /var/log/kiosk-url.log - echo "$INTRANET_URL" - exit 0 -fi - -# 3. Priorität: Lokale IP-Adresse -LOCAL_IP=$(ip route get 1 2>/dev/null | awk '{print $7}' | head -1) -if [ -n "$LOCAL_IP" ] && [ "$LOCAL_IP" != "127.0.0.1" ]; then - IP_URL="http://$LOCAL_IP:5000" - if test_url "$IP_URL" 5; then - echo "[$(date)] Lokale IP verfügbar: $IP_URL" >> /var/log/kiosk-url.log - echo "$IP_URL" - exit 0 - fi -fi - -# 4. Fallback: Hostname-URL -HOSTNAME_URL="http://$(hostname):5000" -if test_url "$HOSTNAME_URL" 5; then - echo "[$(date)] Hostname verfügbar: $HOSTNAME_URL" >> /var/log/kiosk-url.log - echo "$HOSTNAME_URL" - exit 0 -fi - -# Finaler Fallback: Localhost (auch wenn nicht erreichbar) -echo "[$(date)] Fallback auf Localhost: $LOCALHOST_URL" >> /var/log/kiosk-url.log -echo "$LOCALHOST_URL" -EOF - - chmod +x "$APP_DIR/scripts/get_kiosk_url.sh" - - log "✅ Intelligente Kiosk-URL-Ermittlung erstellt: $APP_DIR/scripts/get_kiosk_url.sh" -} - -# =========================== KIOSK-KONFIGURATION MIT INTELLIGENTER URL =========================== - -# Skript starten mit automatischer Modus-Erkennung -main "$@" \ No newline at end of file diff --git a/backend/setup_https_only.sh b/backend/setup_https_only.sh index f643d7e38..ec75a9c21 100644 --- a/backend/setup_https_only.sh +++ b/backend/setup_https_only.sh @@ -329,6 +329,33 @@ else exit 1 fi +# Intelligente Kiosk-URL-Konfiguration +echo " Konfiguriere intelligente Kiosk-URL..." +if [[ -f "$MYP_DIR/systemd/myp-kiosk.service" ]]; then + # Intelligent URL detection function direkt in Service einbauen + cat > /tmp/url_detect_function << 'EOF' + # Intelligente URL-Ermittlung + detect_kiosk_url() { + # Prioritäten: 1. Intranet-Domain 2. Hostname 3. Localhost + if curl -k -s --connect-timeout 2 --max-time 3 "https://m040tbaraspi001.de040.corpintra.net" >/dev/null 2>&1; then + echo "https://m040tbaraspi001.de040.corpintra.net" + elif curl -k -s --connect-timeout 2 --max-time 3 "https://$(hostname)" >/dev/null 2>&1; then + echo "https://$(hostname)" + elif curl -k -s --connect-timeout 2 --max-time 3 "https://localhost:443" >/dev/null 2>&1; then + echo "https://localhost:443" + else + echo "https://localhost" + fi + } + TARGET_URL=$(detect_kiosk_url); +EOF + + # Ersetze URL-Ermittlung im Kiosk-Service + sed -i '/TARGET_URL=.*get_kiosk_url/c\ TARGET_URL=$(detect_kiosk_url);' /etc/systemd/system/myp-kiosk.service 2>/dev/null || true + + echo -e "${GREEN} ✅ Intelligente Kiosk-URL konfiguriert${NC}" +fi + # Kiosk Service starten echo " Starte myp-kiosk..." systemctl start myp-kiosk diff --git a/backend/syntax_check.sh b/backend/syntax_check.sh deleted file mode 100644 index 7810598ac..000000000 --- a/backend/syntax_check.sh +++ /dev/null @@ -1,43 +0,0 @@ -w#!/bin/bash - -# Einfacher Syntax-Check für das Setup-Skript -echo "Prüfe Bash-Syntax von setup.sh..." - -# Zähle if und fi Statements -if_count=$(grep -c "^\s*if\s\|^\s\+if\s" setup.sh) -fi_count=$(grep -c "^\s*fi\s*$\|^\s\+fi\s*$" setup.sh) - -echo "if-Statements gefunden: $if_count" -echo "fi-Statements gefunden: $fi_count" - -if [ "$if_count" -eq "$fi_count" ]; then - echo "✅ if/fi Balance: OK" -else - echo "❌ if/fi Balance: FEHLER - Ungleiche Anzahl" - echo "Differenz: $((fi_count - if_count))" -fi - -# Prüfe auf verwaiste fi ohne Einrückung (außerhalb von Funktionen) -orphaned_fi=$(grep -n "^fi\s*$" setup.sh) -if [ -n "$orphaned_fi" ]; then - echo "❌ Verwaiste fi-Statements gefunden:" - echo "$orphaned_fi" -else - echo "✅ Keine verwaisten fi-Statements" -fi - -# Prüfe auf ungeschlossene Funktionen -function_starts=$(grep -c "^[a-zA-Z_][a-zA-Z0-9_]*\s*()\s*{" setup.sh) -function_ends=$(grep -c "^}" setup.sh) - -echo "Funktions-Starts: $function_starts" -echo "Funktions-Ends: $function_ends" - -if [ "$function_starts" -eq "$function_ends" ]; then - echo "✅ Funktions-Balance: OK" -else - echo "❌ Funktions-Balance: FEHLER" -fi - -echo "" -echo "Syntax-Check abgeschlossen." \ No newline at end of file