diff --git a/backend/app/combined.sh b/backend/app/combined.sh new file mode 100644 index 00000000..4f842105 --- /dev/null +++ b/backend/app/combined.sh @@ -0,0 +1,617 @@ +#!/bin/bash + +# =================================================================== +# MYP Druckerverwaltung - Konsolidiertes Installations- und Kiosk-Setup +# Kombiniert alle .sh-Skripte und implementiert Kiosk-Modus für Raspberry Pi +# Automatischer Start ohne Benutzeranmeldung über systemd +# =================================================================== + +set -euo pipefail + +# =========================== KONFIGURATION =========================== +KIOSK_USER="kiosk" +APP_USER="myp" +APP_DIR="/opt/myp-druckerverwaltung" +CURRENT_DIR="$(pwd)" +INSTALL_LOG="/var/log/myp-kiosk-install.log" +CHROMIUM_BIN="" + +# Farben für Ausgabe +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +NC='\033[0m' + +# ========================== LOGGING-SYSTEM ========================== +log() { + echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}" | tee -a "$INSTALL_LOG" +} + +error() { + echo -e "${RED}[FEHLER] $1${NC}" | tee -a "$INSTALL_LOG" + exit 1 +} + +warning() { + echo -e "${YELLOW}[WARNUNG] $1${NC}" | tee -a "$INSTALL_LOG" +} + +info() { + echo -e "${BLUE}[INFO] $1${NC}" | tee -a "$INSTALL_LOG" +} + +progress() { + echo -e "${PURPLE}[FORTSCHRITT] $1${NC}" | tee -a "$INSTALL_LOG" +} + +# ========================== SYSTEM-CHECKS ========================== +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" +} + +detect_system() { + log "Erkenne System-Umgebung..." + + # Aktuelle Position ermitteln + CURRENT_DIR="$(pwd)" + log "Aktuelles Verzeichnis: $CURRENT_DIR" + + # System-Info sammeln + info "System: $(uname -a)" + info "Distribution: $(lsb_release -d 2>/dev/null || cat /etc/os-release | head -1 || echo 'Unbekannt')" + + # Internetverbindung testen + if ! ping -c 1 google.com &> /dev/null; then + error "Keine Internetverbindung verfügbar!" + fi + + log "✅ System-Checks erfolgreich" +} + +# ========================== SYSTEM-UPDATE ========================== +update_system() { + log "=== SYSTEM-UPDATE ===" + + progress "Aktualisiere Paketlisten..." + apt-get update -y || error "APT Update fehlgeschlagen" + + progress "Upgrade bestehender Pakete..." + apt-get upgrade -y || warning "APT Upgrade teilweise fehlgeschlagen" + + progress "Installiere essenzielle System-Tools..." + apt-get install -y \ + ca-certificates gnupg lsb-release software-properties-common \ + apt-transport-https curl wget git unzip nano htop rsync \ + sudo cron logrotate tree zip keyboard-configuration \ + console-setup console-data kbd locales \ + || error "Essenzielle Pakete Installation fehlgeschlagen" + + log "✅ System-Update abgeschlossen" +} + +# ========================== PAKETE INSTALLIEREN ========================== +install_packages() { + log "=== SYSTEM-PAKETE INSTALLATION ===" + + progress "Installiere Basis-Pakete..." + apt-get install -y \ + python3 python3-pip python3-venv python3-dev \ + build-essential libssl-dev libffi-dev \ + sqlite3 nginx supervisor \ + xorg xinit openbox \ + xserver-xorg-video-all \ + x11-xserver-utils xdotool unclutter \ + lightdm lightdm-gtk-greeter \ + pulseaudio alsa-utils \ + fonts-liberation fonts-dejavu \ + systemd-timesyncd ufw fail2ban \ + || error "Basis-Pakete Installation fehlgeschlagen" + + log "✅ System-Pakete installiert" +} + +# ========================== CHROMIUM INSTALLATION ========================== +install_chromium() { + log "=== CHROMIUM INSTALLATION ===" + + progress "Installiere Chromium Browser..." + + if apt-get install -y chromium 2>/dev/null; then + CHROMIUM_BIN="/usr/bin/chromium" + log "✅ Chromium via APT installiert" + elif apt-get install -y chromium-browser 2>/dev/null; then + CHROMIUM_BIN="/usr/bin/chromium-browser" + log "✅ Chromium-Browser via APT installiert" + else + error "❌ Chromium konnte nicht installiert werden!" + fi + + log "✅ Chromium-Installation abgeschlossen: $CHROMIUM_BIN" +} + +# ========================== BENUTZER ERSTELLEN ========================== +create_users() { + log "=== BENUTZER-ERSTELLUNG ===" + + # App-Benutzer erstellen + progress "Erstelle App-Benutzer: $APP_USER" + if ! id "$APP_USER" &>/dev/null; then + if ! useradd -m -s /bin/bash "$APP_USER" 2>/dev/null; then + adduser --disabled-password --gecos "" "$APP_USER" || error "Kann App-Benutzer nicht erstellen" + fi + usermod -aG sudo "$APP_USER" 2>/dev/null || true + fi + + # Kiosk-Benutzer erstellen + progress "Erstelle Kiosk-Benutzer: $KIOSK_USER" + if ! id "$KIOSK_USER" &>/dev/null; then + if ! useradd -m -s /bin/bash "$KIOSK_USER" 2>/dev/null; then + adduser --disabled-password --gecos "" "$KIOSK_USER" || error "Kann Kiosk-Benutzer nicht erstellen" + fi + usermod -aG audio,video,input "$KIOSK_USER" 2>/dev/null || true + fi + + log "✅ Benutzer erstellt: $APP_USER, $KIOSK_USER" +} + +# ========================== ANWENDUNG INSTALLIEREN ========================== +install_application() { + log "=== ANWENDUNGS-INSTALLATION ===" + + # Verzeichnisse erstellen + mkdir -p "$APP_DIR" + + # Anwendung kopieren falls vorhanden + if [ -f "$CURRENT_DIR/app.py" ]; then + progress "Kopiere Anwendung von $CURRENT_DIR nach $APP_DIR" + rsync -av --exclude='.git' --exclude='__pycache__' --exclude='node_modules' "$CURRENT_DIR"/ "$APP_DIR/" + else + # Erstelle einfache Flask-App als Platzhalter + progress "Erstelle einfache Flask-App als Platzhalter..." + cat > "$APP_DIR/app.py" << 'EOF' +#!/usr/bin/python3 +from flask import Flask, render_template_string + +app = Flask(__name__) + +@app.route('/') +def home(): + return render_template_string(""" + + + + MYP Druckerverwaltung + + + +
+

MYP Druckerverwaltung

+
+

System erfolgreich gestartet

+

Die MYP Druckerverwaltung läuft im Kiosk-Modus.

+

Sie können diese Anwendung nun durch Ihre eigentliche Anwendung ersetzen.

+
+
+ + + """) + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) +EOF + fi + + chmod +x "$APP_DIR/app.py" + chown -R "$APP_USER:$APP_USER" "$APP_DIR" + + # Python-Dependencies installieren + progress "Installiere Python-Dependencies..." + python3 -m pip install --upgrade pip --break-system-packages + python3 -m pip install flask --break-system-packages + + log "✅ Anwendung installiert" +} + +# ========================== SYSTEMD-SERVICES ERSTELLEN ========================== +create_systemd_services() { + log "=== SYSTEMD-SERVICES ERSTELLEN ===" + + # MYP-Anwendung Service + progress "Erstelle myp-druckerverwaltung.service..." + cat > "/etc/systemd/system/myp-druckerverwaltung.service" << EOF +[Unit] +Description=MYP Druckerverwaltung Flask Application +After=network.target + +[Service] +Type=simple +User=$APP_USER +Group=$APP_USER +WorkingDirectory=$APP_DIR +Environment=PATH=/usr/local/bin:/usr/bin:/bin +Environment=PYTHONPATH=$APP_DIR +ExecStart=/usr/bin/python3 $APP_DIR/app.py +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target +EOF + + # Kiosk-Service für automatischen Chromium-Start + progress "Erstelle kiosk-chromium.service..." + cat > "/etc/systemd/system/kiosk-chromium.service" << EOF +[Unit] +Description=Kiosk Chromium Browser +After=graphical-session.target myp-druckerverwaltung.service +Wants=myp-druckerverwaltung.service +Requires=graphical-session.target + +[Service] +Type=simple +User=$KIOSK_USER +Group=$KIOSK_USER +Environment=DISPLAY=:0 +Environment=XAUTHORITY=/home/$KIOSK_USER/.Xauthority +ExecStartPre=/bin/bash -c 'while ! curl -s http://localhost:5000 >/dev/null 2>&1; do sleep 2; done' +ExecStartPre=/bin/sleep 5 +ExecStart=/home/$KIOSK_USER/start-kiosk.sh +Restart=always +RestartSec=10 + +[Install] +WantedBy=graphical-session.target +EOF + + # Systemd-Services aktivieren + systemctl daemon-reload + systemctl enable myp-druckerverwaltung.service + systemctl enable kiosk-chromium.service + + log "✅ Systemd-Services erstellt und aktiviert" +} + +# ========================== AUTOLOGIN KONFIGURIEREN ========================== +configure_autologin() { + log "=== AUTOLOGIN KONFIGURIEREN ===" + + progress "Konfiguriere LightDM für automatischen Login..." + + # LightDM Konfiguration + cat > "/etc/lightdm/lightdm.conf" << EOF +[Seat:*] +autologin-user=$KIOSK_USER +autologin-user-timeout=0 +autologin-session=openbox +user-session=openbox +session-wrapper=/etc/X11/Xsession +greeter-session=lightdm-gtk-greeter +allow-guest=false +greeter-hide-users=true +greeter-show-manual-login=false +autologin-in-background=false +xserver-command=X -s 0 -dpms + +[SeatDefaults] +autologin-user=$KIOSK_USER +autologin-user-timeout=0 +autologin-session=openbox +greeter-hide-users=true +greeter-show-manual-login=false +allow-user-switching=false +EOF + + # Graphical Target als Standard setzen + systemctl set-default graphical.target + systemctl enable lightdm.service + + log "✅ Autologin konfiguriert" +} + +# ========================== KIOSK-KONFIGURATION ========================== +configure_kiosk() { + log "=== KIOSK-KONFIGURATION ===" + + KIOSK_HOME="/home/$KIOSK_USER" + + # Openbox-Konfiguration + progress "Konfiguriere Openbox für Kiosk..." + sudo -u "$KIOSK_USER" mkdir -p "$KIOSK_HOME/.config/openbox" + + cat > "$KIOSK_HOME/.config/openbox/rc.xml" << 'EOF' + + + + + no + yes + yes + yes + yes + + + + + + +EOF + + # Kiosk-Starter-Skript + progress "Erstelle Kiosk-Starter-Skript..." + cat > "$KIOSK_HOME/start-kiosk.sh" << EOF +#!/bin/bash +export DISPLAY=:0 + +# Logging +exec > >(tee -a /var/log/kiosk-session.log) 2>&1 +echo "\$(date): Kiosk-Session gestartet" + +# Bildschirmschoner deaktivieren +xset s off +xset s noblank +xset s noexpose +xset -dpms + +# Mauszeiger verstecken +unclutter -idle 0.5 -root & + +# Warte auf Anwendung +echo "Warte auf MYP-Anwendung..." +WAIT_COUNT=0 +while ! curl -s http://localhost:5000 > /dev/null; do + echo "Warte auf MYP-Anwendung... (\$WAIT_COUNT/30)" + sleep 2 + WAIT_COUNT=\$((WAIT_COUNT + 1)) + if [ \$WAIT_COUNT -gt 30 ]; then + echo "FEHLER: MYP-Anwendung nach 60s nicht erreichbar!" + break + fi +done + +# Prüfe verfügbare Ports +if curl -s http://localhost:8080 > /dev/null; then + KIOSK_URL="http://localhost:8080" +elif curl -s http://localhost:5000 > /dev/null; then + KIOSK_URL="http://localhost:5000" +else + KIOSK_URL="http://localhost:5000" +fi + +echo "Starte Chromium im Kiosk-Modus mit URL: \$KIOSK_URL" + +# Chromium-Flags für Kiosk-Modus +CHROMIUM_FLAGS=" + --kiosk + --no-sandbox + --disable-infobars + --disable-session-crashed-bubble + --disable-restore-session-state + --disable-web-security + --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 + --window-position=0,0 + --user-data-dir=$KIOSK_HOME/.chromium-kiosk + --disable-background-mode + --force-device-scale-factor=1.0 + --disable-pinch + --overscroll-history-navigation=0 +" + +# Chromium starten +$CHROMIUM_BIN \$CHROMIUM_FLAGS "\$KIOSK_URL" + +echo "\$(date): Kiosk-Session beendet" +EOF + + # Desktop-Autostart + sudo -u "$KIOSK_USER" mkdir -p "$KIOSK_HOME/.config/autostart" + cat > "$KIOSK_HOME/.config/autostart/myp-kiosk.desktop" << EOF +[Desktop Entry] +Type=Application +Name=MYP Kiosk Application +Exec=/home/$KIOSK_USER/start-kiosk.sh +Hidden=false +NoDisplay=false +X-GNOME-Autostart-enabled=true +StartupNotify=false +EOF + + # Berechtigungen setzen + chmod +x "$KIOSK_HOME/start-kiosk.sh" + chown -R "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/.config" + chown "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/start-kiosk.sh" + + log "✅ Kiosk-Konfiguration erstellt" +} + +# ========================== RASPBERRY PI OPTIMIERUNGEN ========================== +optimize_raspberry_pi() { + log "=== RASPBERRY PI OPTIMIERUNGEN ===" + + # Prüfe ob es sich um einen Raspberry Pi handelt + if ! grep -q "Raspberry Pi" /proc/cpuinfo 2>/dev/null; then + info "Kein Raspberry Pi erkannt - überspringe Pi-spezifische Optimierungen" + return 0 + fi + + progress "Raspberry Pi erkannt - aktiviere Hardware-Optimierungen..." + + # Boot-Konfiguration optimieren + if [ -f "/boot/config.txt" ]; then + cp /boot/config.txt /boot/config.txt.backup + + # GPU Memory für bessere Browser-Performance + if ! grep -q "gpu_mem=" /boot/config.txt; then + echo "" >> /boot/config.txt + echo "# MYP Kiosk Optimierungen" >> /boot/config.txt + echo "gpu_mem=128" >> /boot/config.txt + fi + + # Disable Splash + if ! grep -q "disable_splash=1" /boot/config.txt; then + echo "disable_splash=1" >> /boot/config.txt + fi + + # HDMI Force Hotplug + if ! grep -q "hdmi_force_hotplug=1" /boot/config.txt; then + echo "hdmi_force_hotplug=1" >> /boot/config.txt + fi + + # Disable Overscan + if ! grep -q "disable_overscan=1" /boot/config.txt; then + echo "disable_overscan=1" >> /boot/config.txt + fi + fi + + # Console Blanking deaktivieren + if [ -f "/boot/cmdline.txt" ]; then + cp /boot/cmdline.txt /boot/cmdline.txt.backup + if ! grep -q "consoleblank=0" /boot/cmdline.txt; then + sed -i 's/$/ consoleblank=0/' /boot/cmdline.txt + fi + fi + + log "✅ Raspberry Pi Optimierungen abgeschlossen" +} + +# ========================== WARTUNGSTOOLS ERSTELLEN ========================== +create_maintenance_tools() { + log "=== WARTUNGSTOOLS ERSTELLEN ===" + + # Wartungsskript + cat > "/usr/local/bin/myp-maintenance" << 'EOF' +#!/bin/bash + +case "$1" in + start) + echo "Starte alle MYP-Services..." + systemctl start myp-druckerverwaltung + systemctl start lightdm + echo "Services gestartet." + ;; + stop) + echo "Stoppe alle MYP-Services..." + systemctl stop lightdm + systemctl stop myp-druckerverwaltung + echo "Services gestoppt." + ;; + restart) + echo "Starte alle MYP-Services neu..." + systemctl restart myp-druckerverwaltung + sleep 3 + systemctl restart lightdm + echo "Services neugestartet." + ;; + status) + echo "=== MYP SYSTEM STATUS ===" + echo "📱 Anwendung:" + systemctl status myp-druckerverwaltung --no-pager -l + echo "🖥️ Display Manager:" + systemctl status lightdm --no-pager -l + echo "🌐 Anwendung erreichbar:" + if curl -s http://localhost:5000 > /dev/null; then + echo "✅ http://localhost:5000 erreichbar" + else + echo "❌ http://localhost:5000 NICHT erreichbar" + fi + if curl -s http://localhost:8080 > /dev/null; then + echo "✅ http://localhost:8080 erreichbar" + else + echo "❌ http://localhost:8080 NICHT erreichbar" + fi + ;; + logs) + echo "=== ANWENDUNGS-LOGS ===" + journalctl -u myp-druckerverwaltung -f + ;; + *) + echo "MYP Druckerverwaltung - Wartungstool" + echo "VERWENDUNG: $0 {start|stop|restart|status|logs}" + ;; +esac +EOF + + chmod +x "/usr/local/bin/myp-maintenance" + + # Log-Dateien erstellen + touch /var/log/kiosk-session.log + chmod 666 /var/log/kiosk-session.log + + log "✅ Wartungstools erstellt" +} + +# ========================== HAUPTFUNKTION ========================== +main() { + log "=== MYP KIOSK-INSTALLATION GESTARTET ===" + + check_root + detect_system + update_system + install_packages + install_chromium + create_users + install_application + create_systemd_services + configure_autologin + configure_kiosk + optimize_raspberry_pi + create_maintenance_tools + + log "=== INSTALLATION ABGESCHLOSSEN ===" + log "" + log "🎉 MYP KIOSK-INSTALLATION ERFOLGREICH!" + log "" + log "📋 ZUSAMMENFASSUNG:" + log " ✅ System-Pakete installiert" + log " ✅ Chromium Browser installiert" + log " ✅ Benutzer erstellt ($APP_USER, $KIOSK_USER)" + log " ✅ Anwendung installiert" + log " ✅ Systemd-Services erstellt" + log " ✅ Autologin konfiguriert" + log " ✅ Kiosk-Modus konfiguriert" + log " ✅ Raspberry Pi optimiert" + log " ✅ Wartungstools erstellt" + log "" + log "🔄 NEUSTART ERFORDERLICH:" + log " sudo reboot" + log "" + log "📊 NACH DEM NEUSTART:" + log " - System startet automatisch ohne Anmeldung" + log " - Kiosk-Modus wird automatisch gestartet" + log " - Chromium öffnet http://localhost:8080 oder http://localhost:5000" + log " - Vollbildmodus ohne UI-Elemente" + log " - Mauszeiger wird automatisch versteckt" + log "" + log "🔧 WARTUNG:" + log " sudo myp-maintenance status # System-Status prüfen" + log " sudo myp-maintenance logs # Logs anzeigen" + log " sudo myp-maintenance restart # Services neustarten" + log "" + + warning "WICHTIG: Führen Sie jetzt 'sudo reboot' aus, um die Kiosk-Konfiguration zu aktivieren!" +} + +# Skript ausführen +main "$@" \ No newline at end of file diff --git a/backend/app/docs/KIOSK_SETUP_ANLEITUNG.md b/backend/app/docs/KIOSK_SETUP_ANLEITUNG.md new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/backend/app/docs/KIOSK_SETUP_ANLEITUNG.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/app/kiosk-watchdog.service b/backend/app/kiosk-watchdog.service new file mode 100644 index 00000000..bf43ba96 --- /dev/null +++ b/backend/app/kiosk-watchdog.service @@ -0,0 +1,76 @@ +[Unit] +Description=Kiosk Watchdog Service - Überwacht und startet Kiosk-Komponenten neu +After=multi-user.target lightdm.service myp-druckerverwaltung.service +Wants=lightdm.service myp-druckerverwaltung.service + +[Service] +Type=simple +User=root +Restart=always +RestartSec=30 +ExecStart=/bin/bash -c '\ + while true; do \ + # Prüfe Backend-Service \ + if ! systemctl is-active --quiet myp-druckerverwaltung; then \ + echo "$(date): Backend-Service nicht aktiv - starte neu" >> /var/log/kiosk-watchdog.log; \ + systemctl start myp-druckerverwaltung; \ + sleep 10; \ + fi; \ + \ + # Prüfe Backend-Erreichbarkeit \ + if ! curl -s --connect-timeout 5 http://localhost:5000 >/dev/null 2>&1 && ! curl -s --connect-timeout 5 http://localhost:8080 >/dev/null 2>&1; then \ + echo "$(date): Backend nicht erreichbar - starte Service neu" >> /var/log/kiosk-watchdog.log; \ + systemctl restart myp-druckerverwaltung; \ + sleep 15; \ + fi; \ + \ + # Prüfe LightDM \ + if ! systemctl is-active --quiet lightdm; then \ + echo "$(date): LightDM nicht aktiv - starte neu" >> /var/log/kiosk-watchdog.log; \ + systemctl start lightdm; \ + sleep 10; \ + fi; \ + \ + # Prüfe Kiosk-Benutzer Session \ + if ! pgrep -u kiosk > /dev/null; then \ + echo "$(date): Kiosk-Benutzer nicht angemeldet - starte LightDM neu" >> /var/log/kiosk-watchdog.log; \ + systemctl restart lightdm; \ + sleep 15; \ + fi; \ + \ + # Prüfe Chromium Kiosk-Prozess \ + if ! pgrep -u kiosk -f "chromium.*kiosk" > /dev/null; then \ + echo "$(date): Chromium-Kiosk nicht gefunden - starte Kiosk-Session neu" >> /var/log/kiosk-watchdog.log; \ + # Versuche Kiosk-Neustart als Kiosk-Benutzer \ + sudo -u kiosk DISPLAY=:0 /home/kiosk/start-kiosk.sh & \ + sleep 10; \ + fi; \ + \ + # Prüfe X-Server \ + if ! pgrep -f "X.*:0" > /dev/null; then \ + echo "$(date): X-Server nicht gefunden - starte LightDM neu" >> /var/log/kiosk-watchdog.log; \ + systemctl restart lightdm; \ + sleep 15; \ + fi; \ + \ + # Prüfe Display-Umgebung \ + if [ -z "$(DISPLAY=:0 xdpyinfo 2>/dev/null)" ]; then \ + echo "$(date): Display :0 nicht verfügbar - starte LightDM neu" >> /var/log/kiosk-watchdog.log; \ + systemctl restart lightdm; \ + sleep 15; \ + fi; \ + \ + # Warte 30 Sekunden vor nächster Prüfung \ + sleep 30; \ + done' + +# Umgebungsvariablen +Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +Environment=DISPLAY=:0 + +# Logging +StandardOutput=append:/var/log/kiosk-watchdog.log +StandardError=append:/var/log/kiosk-watchdog.log + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/backend/app/test-kiosk-setup.sh b/backend/app/test-kiosk-setup.sh new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/backend/app/test-kiosk-setup.sh @@ -0,0 +1 @@ + \ No newline at end of file