#!/bin/bash # =================================================================== # MYP Druckerverwaltung - KONSOLIDIERTES INSTALLATIONS-SKRIPT # Kombiniert alle Installationsfunktionen in einer einzigen Datei # 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: 3.6.1 # =================================================================== set -euo pipefail # =========================== GLOBALE KONFIGURATION =========================== readonly APP_NAME="MYP Druckerverwaltung" readonly APP_VERSION="3.6.1" readonly APP_DIR="/opt/myp" readonly HTTPS_SERVICE_NAME="myp-https" readonly KIOSK_SERVICE_NAME="myp-kiosk" readonly KIOSK_USER="kiosk" readonly CURRENT_DIR="$(pwd)" readonly INSTALL_LOG="/var/log/myp-install.log" readonly HTTPS_PORT="443" readonly HTTPS_URL="https://localhost:${HTTPS_PORT}" # 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' # =========================== LOGGING-FUNKTIONEN =========================== 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" } success() { echo -e "${CYAN}[ERFOLG] $1${NC}" | tee -a "$INSTALL_LOG" } # =========================== 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_debian_system() { if [ ! -f /etc/debian_version ]; then error "Dieses Skript ist nur für Debian/Raspbian-Systeme geeignet!" fi local debian_version=$(cat /etc/debian_version 2>/dev/null || echo "Unbekannt") log "✅ Debian/Raspbian-System erkannt (Version: $debian_version)" # Prüfe auf Raspberry Pi if [ -f /proc/device-tree/model ]; then local pi_model=$(cat /proc/device-tree/model 2>/dev/null || echo "Unbekannt") info "Raspberry Pi Modell: $pi_model" fi } check_internet_connection() { progress "Prüfe Internetverbindung..." local test_urls=("8.8.8.8" "1.1.1.1" "google.com") local connection_ok=false for url in "${test_urls[@]}"; do if ping -c 1 -W 3 "$url" >/dev/null 2>&1; then connection_ok=true break fi done if [ "$connection_ok" = true ]; then log "✅ Internetverbindung verfügbar" else warning "⚠️ Keine Internetverbindung - Installation könnte fehlschlagen" fi } # =========================== SYSTEM-VORBEREITUNG =========================== update_system() { log "=== SYSTEM-UPDATE ===" progress "Aktualisiere Paketlisten..." apt-get update -y || error "APT Update fehlgeschlagen" progress "Führe System-Upgrade durch..." apt-get upgrade -y || warning "System-Upgrade teilweise fehlgeschlagen" progress "Installiere grundlegende System-Tools..." apt-get install -y \ curl \ wget \ git \ nano \ htop \ rsync \ unzip \ sudo \ systemd \ ca-certificates \ gnupg \ lsb-release \ apt-transport-https \ software-properties-common \ || error "Grundlegende Tools Installation fehlgeschlagen" log "✅ System-Update abgeschlossen" } # =========================== 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" } # =========================== 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" } # =========================== 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 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" } # =========================== PYTHON & NODE.JS INSTALLATION =========================== install_python_dependencies() { log "=== PYTHON-ABHÄNGIGKEITEN INSTALLATION ===" progress "Installiere Python 3 und Entwicklungstools..." apt-get install -y \ python3 \ python3-pip \ python3-dev \ python3-setuptools \ python3-venv \ build-essential \ libssl-dev \ libffi-dev \ sqlite3 \ || error "Python Installation fehlgeschlagen" # pip auf neueste Version aktualisieren progress "Aktualisiere pip..." python3 -m pip install --upgrade pip --break-system-packages || warning "pip Update fehlgeschlagen" # SSL-Konfiguration für pip 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 = 60 retries = 3 no-cache-dir = true [install] trusted-host = pypi.org pypi.python.org files.pythonhosted.org no-warn-script-location = true EOF log "✅ Python-Umgebung vorbereitet" } install_nodejs_npm() { log "=== NODE.JS UND NPM INSTALLATION ===" # Alte Node.js-Installationen entfernen progress "Entferne alte Node.js-Installationen..." apt-get remove --purge -y nodejs npm 2>/dev/null || true apt-get autoremove -y 2>/dev/null || true # NodeSource Repository für Node.js LTS hinzufügen progress "Installiere Node.js LTS..." if curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - 2>/dev/null; then apt-get update -y apt-get install -y nodejs || error "Node.js Installation fehlgeschlagen" else warning "NodeSource Repository nicht verfügbar - verwende Debian-Repository" apt-get install -y nodejs npm || error "Node.js Fallback Installation fehlgeschlagen" fi # Versionen prüfen if command -v node >/dev/null 2>&1; then local node_version=$(node --version) log "✅ Node.js installiert: $node_version" else error "❌ Node.js Installation fehlgeschlagen" fi if command -v npm >/dev/null 2>&1; then local npm_version=$(npm --version) log "✅ npm installiert: $npm_version" # npm-Konfiguration optimieren npm config set fund false 2>/dev/null || true npm config set audit-level moderate 2>/dev/null || true else error "❌ npm Installation fehlgeschlagen" fi log "✅ Node.js und npm erfolgreich installiert" } install_python_packages() { log "=== PYTHON-PAKETE INSTALLATION ===" local pip_opts="--break-system-packages --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org --timeout 60 --retries 3" progress "Installiere Flask-Framework..." pip3 install $pip_opts Flask==3.1.1 || pip3 install $pip_opts Flask || error "Flask Installation fehlgeschlagen" pip3 install $pip_opts Flask-Login==0.6.3 || pip3 install $pip_opts Flask-Login || error "Flask-Login Installation fehlgeschlagen" pip3 install $pip_opts Flask-WTF==1.2.1 || pip3 install $pip_opts Flask-WTF || error "Flask-WTF Installation fehlgeschlagen" progress "Installiere Datenbank-Komponenten..." pip3 install $pip_opts SQLAlchemy==2.0.36 || pip3 install $pip_opts SQLAlchemy || error "SQLAlchemy Installation fehlgeschlagen" progress "Installiere Sicherheits-Komponenten..." pip3 install $pip_opts bcrypt==4.2.1 || pip3 install $pip_opts bcrypt || error "bcrypt Installation fehlgeschlagen" pip3 install $pip_opts cryptography==44.0.0 || pip3 install $pip_opts cryptography || error "cryptography Installation fehlgeschlagen" pip3 install $pip_opts Werkzeug==3.1.3 || pip3 install $pip_opts Werkzeug || error "Werkzeug Installation fehlgeschlagen" progress "Installiere weitere Abhängigkeiten..." pip3 install $pip_opts requests==2.32.3 || pip3 install $pip_opts requests || error "requests Installation fehlgeschlagen" pip3 install $pip_opts psutil==6.1.1 || pip3 install $pip_opts psutil || error "psutil Installation fehlgeschlagen" pip3 install $pip_opts MarkupSafe==3.0.2 || pip3 install $pip_opts MarkupSafe || error "MarkupSafe Installation fehlgeschlagen" pip3 install $pip_opts gunicorn==23.0.0 || pip3 install $pip_opts gunicorn || error "gunicorn Installation fehlgeschlagen" # Optionale Pakete pip3 install $pip_opts PyP100 || warning "PyP100 Installation fehlgeschlagen (optional)" pip3 install $pip_opts redis==5.2.1 || warning "redis Installation fehlgeschlagen (optional)" log "✅ Python-Pakete erfolgreich installiert" } # =========================== SSL-ZERTIFIKATE =========================== install_ssl_certificates() { log "=== SSL-ZERTIFIKATE KONFIGURATION ===" progress "Aktualisiere CA-Zertifikate..." apt-get install -y ca-certificates openssl || error "CA-Zertifikate Installation fehlgeschlagen" update-ca-certificates || warning "CA-Zertifikate Update fehlgeschlagen" # Mercedes Corporate Zertifikate (falls vorhanden) if [ -d "$CURRENT_DIR/certs/mercedes" ] && [ "$(ls -A $CURRENT_DIR/certs/mercedes 2>/dev/null)" ]; then progress "Installiere Mercedes Corporate Zertifikate..." find "$CURRENT_DIR/certs/mercedes" -type f \( -name "*.crt" -o -name "*.pem" -o -name "*.cer" \) | while read cert_file; do local cert_basename=$(basename "$cert_file") local cert_name="${cert_basename%.*}" progress "Verarbeite Mercedes-Zertifikat: $cert_basename" # Zertifikat validieren und installieren if openssl x509 -in "$cert_file" -text -noout >/dev/null 2>&1; then cp "$cert_file" "/usr/local/share/ca-certificates/${cert_name}.crt" log "✅ Zertifikat installiert: ${cert_name}.crt" elif openssl x509 -in "$cert_file" -inform DER -text -noout >/dev/null 2>&1; then openssl x509 -in "$cert_file" -inform DER -out "/usr/local/share/ca-certificates/${cert_name}.crt" -outform PEM log "✅ DER-Zertifikat konvertiert und installiert: ${cert_name}.crt" else warning "⚠️ Ungültiges Zertifikat übersprungen: $cert_file" fi done update-ca-certificates || warning "Mercedes Zertifikate Update fehlgeschlagen" fi # SSL-Umgebungsvariablen setzen export SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt" export REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" export CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" log "✅ SSL-Zertifikate konfiguriert" } # =========================== ANWENDUNGS-DEPLOYMENT =========================== deploy_application() { log "=== ANWENDUNGS-DEPLOYMENT ===" progress "Erstelle Zielverzeichnis: $APP_DIR" mkdir -p "$APP_DIR" || error "Konnte Zielverzeichnis nicht erstellen" progress "Kopiere Anwendungsdateien..." # Liste der zu kopierenden Dateien/Ordner local copy_items=( "app.py" "models.py" "requirements.txt" "blueprints/" "config/" "database/" "static/" "templates/" "uploads/" "utils/" "logs/" "certs/" ) # Sichere selektive Kopie for item in "${copy_items[@]}"; do if [ -e "$CURRENT_DIR/$item" ]; then progress "Kopiere: $item" cp -r "$CURRENT_DIR/$item" "$APP_DIR/" || warning "Fehler beim Kopieren von $item" else info "Überspringe nicht vorhandenes Element: $item" fi done # Spezielle Dateien for file in "package.json" "package-lock.json" "tailwind.config.js" "postcss.config.js"; do if [ -f "$CURRENT_DIR/$file" ]; then cp "$CURRENT_DIR/$file" "$APP_DIR/" || warning "Fehler beim Kopieren von $file" fi done # Erstelle notwendige Verzeichnisse mkdir -p "$APP_DIR"/{database/backups,logs/{app,auth,errors},uploads/temp,certs/localhost} # Berechtigungen setzen chown -R root:root "$APP_DIR" chmod -R 755 "$APP_DIR" chmod 750 "$APP_DIR"/{database,logs,certs} chmod +x "$APP_DIR/app.py" log "✅ Anwendung erfolgreich deployed" } 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 --no-optional --no-audit --no-fund --legacy-peer-deps 2>/dev/null; then log "✅ npm install erfolgreich (mit --legacy-peer-deps)" elif npm install --no-optional --no-audit --no-fund --force 2>/dev/null; then log "✅ npm install erfolgreich (mit --force)" else warning "⚠️ npm install fehlgeschlagen - versuche manuelle Installation..." # Manuelle Installation wichtiger Pakete npm install tailwindcss --no-audit --no-fund --force 2>/dev/null || warning "TailwindCSS Installation fehlgeschlagen" npm install @tailwindcss/forms --no-audit --no-fund --force 2>/dev/null || warning "@tailwindcss/forms Installation fehlgeschlagen" npm install chart.js --no-audit --no-fund --force 2>/dev/null || warning "Chart.js Installation fehlgeschlagen" fi # TailwindCSS Build if npx tailwindcss --help >/dev/null 2>&1; then progress "Kompiliere TailwindCSS..." if npm run build:css 2>/dev/null || npx tailwindcss -i ./static/css/input.css -o ./static/css/tailwind.min.css --minify 2>/dev/null; then log "✅ TailwindCSS erfolgreich kompiliert" else warning "⚠️ TailwindCSS Build fehlgeschlagen" fi fi cd "$CURRENT_DIR" else info "Keine package.json gefunden - überspringe npm-Abhängigkeiten" fi log "✅ Frontend-Dependencies verarbeitet" } # =========================== SYSTEMD-SERVICES =========================== create_https_service() { log "=== HTTPS-SERVICE KONFIGURATION ===" progress "Erstelle systemd-Service für HTTPS Backend..." # Service-Datei aus dem Projekt kopieren oder erstellen if [ -f "$CURRENT_DIR/myp-https.service" ]; then cp "$CURRENT_DIR/myp-https.service" "/etc/systemd/system/${HTTPS_SERVICE_NAME}.service" else # Fallback: Service-Datei erstellen cat > "/etc/systemd/system/${HTTPS_SERVICE_NAME}.service" << EOF [Unit] Description=MYP Druckerverwaltung HTTPS Backend (Port 443) After=network.target network-online.target Wants=network-online.target Requires=network.target [Service] Type=simple User=root Group=root WorkingDirectory=$APP_DIR ExecStartPre=/usr/bin/python3 -c "import sys; sys.path.insert(0, '$APP_DIR'); from utils.ssl_config import ensure_ssl_certificates; ensure_ssl_certificates('$APP_DIR')" ExecStart=/usr/bin/python3 -c "import sys; sys.path.insert(0, '$APP_DIR'); from app import app; from utils.ssl_config import get_ssl_context; ssl_ctx = get_ssl_context('$APP_DIR'); app.run(host='0.0.0.0', port=443, debug=False, ssl_context=ssl_ctx, threaded=True)" Restart=always RestartSec=10 StartLimitBurst=5 StartLimitInterval=300 Environment=PYTHONUNBUFFERED=1 Environment=FLASK_ENV=production Environment=FLASK_HOST=0.0.0.0 Environment=FLASK_PORT=443 Environment=PYTHONPATH=$APP_DIR Environment=LC_ALL=C.UTF-8 Environment=LANG=C.UTF-8 StandardOutput=journal StandardError=journal SyslogIdentifier=myp-https NoNewPrivileges=true PrivateTmp=false ProtectSystem=strict ReadWritePaths=$APP_DIR ReadWritePaths=/var/log ReadWritePaths=/tmp AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target EOF fi log "✅ HTTPS-Service erstellt: ${HTTPS_SERVICE_NAME}.service" } create_kiosk_service() { log "=== KIOSK-SERVICE KONFIGURATION ===" progress "Erstelle systemd-Service für Kiosk-Browser..." # Service-Datei aus dem Projekt kopieren oder erstellen if [ -f "$CURRENT_DIR/myp-kiosk.service" ]; then cp "$CURRENT_DIR/myp-kiosk.service" "/etc/systemd/system/${KIOSK_SERVICE_NAME}.service" else # Fallback: Service-Datei erstellen cat > "/etc/systemd/system/${KIOSK_SERVICE_NAME}.service" << EOF [Unit] Description=MYP Kiosk Browser Autostart (Chromium HTTPS) After=graphical-session.target ${HTTPS_SERVICE_NAME}.service Wants=${HTTPS_SERVICE_NAME}.service Requires=graphical-session.target [Service] Type=simple User=$KIOSK_USER Group=$KIOSK_USER Environment=DISPLAY=:0 Environment=XAUTHORITY=/home/$KIOSK_USER/.Xauthority WorkingDirectory=/home/$KIOSK_USER ExecStartPre=/bin/bash -c 'for i in {1..60}; do if curl -k -s $HTTPS_URL >/dev/null 2>&1; then break; fi; sleep 2; done' ExecStart=/bin/bash -c 'DISPLAY=:0 xset s off; DISPLAY=:0 xset -dpms; DISPLAY=:0 unclutter -idle 0.1 -root & exec chromium --kiosk --no-sandbox --ignore-certificate-errors $HTTPS_URL' Restart=always RestartSec=15 StartLimitBurst=3 StartLimitInterval=300 StandardOutput=journal StandardError=journal SyslogIdentifier=myp-kiosk [Install] WantedBy=graphical-session.target EOF fi log "✅ Kiosk-Service erstellt: ${KIOSK_SERVICE_NAME}.service" } configure_kiosk_environment() { log "=== KIOSK-UMGEBUNG KONFIGURATION ===" local kiosk_home="/home/$KIOSK_USER" # .bashrc für automatischen X-Start progress "Konfiguriere automatischen X-Start..." cat >> "$kiosk_home/.bashrc" << 'EOF' # Automatischer X-Start für Kiosk-Modus if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then exec startx fi EOF # .xinitrc für Kiosk-Session progress "Erstelle Kiosk X-Session..." cat > "$kiosk_home/.xinitrc" << EOF #!/bin/bash # Bildschirmschoner deaktivieren xset s off xset s noblank xset -dpms # Mauszeiger verstecken unclutter -idle 0.1 -root -noevents & # Openbox starten openbox & # Warte auf HTTPS Backend und starte Browser sleep 5 systemctl --user start ${KIOSK_SERVICE_NAME} || true # Session am Leben halten wait EOF chmod +x "$kiosk_home/.xinitrc" chown -R "$KIOSK_USER:$KIOSK_USER" "$kiosk_home" log "✅ Kiosk-Umgebung konfiguriert" } # =========================== SERVICE-MANAGEMENT =========================== enable_and_start_services() { log "=== SERVICE-AKTIVIERUNG ===" progress "Lade systemd-Konfiguration neu..." systemctl daemon-reload || error "Systemd Reload fehlgeschlagen" progress "Aktiviere HTTPS-Service..." systemctl enable "${HTTPS_SERVICE_NAME}.service" || error "HTTPS-Service Enable fehlgeschlagen" progress "Starte HTTPS-Service..." systemctl start "${HTTPS_SERVICE_NAME}.service" || error "HTTPS-Service Start fehlgeschlagen" # Service-Status prüfen sleep 5 if systemctl is-active --quiet "${HTTPS_SERVICE_NAME}.service"; then log "✅ ${HTTPS_SERVICE_NAME} Service läuft erfolgreich" else warning "⚠️ ${HTTPS_SERVICE_NAME} Service läuft nicht - prüfen Sie: journalctl -u ${HTTPS_SERVICE_NAME} -f" fi # HTTPS-Erreichbarkeit testen progress "Teste HTTPS-Erreichbarkeit..." sleep 3 if curl -k -s "$HTTPS_URL" >/dev/null 2>&1; then log "✅ HTTPS Backend erreichbar: $HTTPS_URL" else warning "⚠️ HTTPS Backend nicht erreichbar: $HTTPS_URL" fi log "✅ Services erfolgreich konfiguriert" } # =========================== SYSTEM-TESTS =========================== run_system_tests() { log "=== SYSTEM-TESTS ===" progress "Teste Python-Installation..." if python3 -c "import flask, sqlalchemy, bcrypt; print('✅ Python-Pakete OK')" 2>/dev/null; then log "✅ Python-Umgebung funktional" else warning "⚠️ Python-Umgebung problematisch" fi progress "Teste SSL-Zertifikate..." if [ -f "$APP_DIR/certs/localhost/localhost.crt" ]; then local cert_expiry=$(openssl x509 -in "$APP_DIR/certs/localhost/localhost.crt" -noout -enddate | cut -d= -f2) log "✅ SSL-Zertifikat vorhanden (läuft ab: $cert_expiry)" else warning "⚠️ SSL-Zertifikat nicht gefunden" fi progress "Teste Browser-Installation..." if command -v chromium >/dev/null 2>&1 || command -v chromium-browser >/dev/null 2>&1; then log "✅ Chromium Browser verfügbar" elif command -v firefox-esr >/dev/null 2>&1; then log "✅ Firefox ESR Browser verfügbar" else warning "⚠️ Kein Browser gefunden" fi log "✅ System-Tests abgeschlossen" } # =========================== HAUPTINSTALLATIONS-FUNKTIONEN =========================== install_system_dependencies() { log "=== SYSTEM-ABHÄNGIGKEITEN INSTALLATION ===" check_internet_connection update_system install_python_dependencies install_nodejs_npm install_ssl_certificates install_python_packages log "✅ System-Abhängigkeiten vollständig installiert" } # =========================== WATCHDOG-SERVICES =========================== create_watchdog_service() { log "=== WATCHDOG-SERVICE KONFIGURATION ===" progress "Erstelle intelligenten Watchdog-Service..." # Prüfe Python-Dependencies für erweiterten Watchdog local python_watchdog_available=false if python3 -c "import psutil, requests" 2>/dev/null; then python_watchdog_available=true log "✅ Python-Dependencies für erweiterten Watchdog verfügbar" else warning "⚠️ Python-Dependencies fehlen - verwende Bash-Watchdog" fi # Kopiere Watchdog-Service-Dateien if [ -f "$CURRENT_DIR/kiosk-watchdog.service" ]; then cp "$CURRENT_DIR/kiosk-watchdog.service" "/etc/systemd/system/kiosk-watchdog.service" log "✅ Bash-Watchdog-Service installiert" fi if [ "$python_watchdog_available" = true ] && [ -f "$CURRENT_DIR/kiosk-watchdog-python.service" ]; then cp "$CURRENT_DIR/kiosk-watchdog-python.service" "/etc/systemd/system/kiosk-watchdog-python.service" log "✅ Python-Watchdog-Service installiert" # Installiere Python-Dependencies falls nicht vorhanden local pip_opts="--break-system-packages --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org" pip3 install $pip_opts psutil requests 2>/dev/null || warning "Python-Watchdog-Dependencies Installation fehlgeschlagen" fi # Aktiviere bevorzugten Watchdog-Service if [ "$python_watchdog_available" = true ]; then progress "Aktiviere Python-Watchdog-Service..." systemctl enable kiosk-watchdog-python.service || warning "Python-Watchdog Enable fehlgeschlagen" systemctl disable kiosk-watchdog.service 2>/dev/null || true log "✅ Python-Watchdog als primärer Service konfiguriert" else progress "Aktiviere Bash-Watchdog-Service..." systemctl enable kiosk-watchdog.service || warning "Bash-Watchdog Enable fehlgeschlagen" systemctl disable kiosk-watchdog-python.service 2>/dev/null || true log "✅ Bash-Watchdog als primärer Service konfiguriert" fi log "✅ Watchdog-Service erfolgreich konfiguriert" } start_watchdog_service() { log "=== WATCHDOG-SERVICE START ===" # Prüfe welcher Watchdog-Service aktiviert ist if systemctl is-enabled --quiet kiosk-watchdog-python.service 2>/dev/null; then progress "Starte Python-Watchdog-Service..." systemctl start kiosk-watchdog-python.service || warning "Python-Watchdog Start fehlgeschlagen" sleep 5 if systemctl is-active --quiet kiosk-watchdog-python.service; then log "✅ Python-Watchdog-Service läuft erfolgreich" else warning "⚠️ Python-Watchdog-Service läuft nicht - prüfen Sie: journalctl -u kiosk-watchdog-python -f" fi elif systemctl is-enabled --quiet kiosk-watchdog.service 2>/dev/null; then progress "Starte Bash-Watchdog-Service..." systemctl start kiosk-watchdog.service || warning "Bash-Watchdog Start fehlgeschlagen" sleep 5 if systemctl is-active --quiet kiosk-watchdog.service; then log "✅ Bash-Watchdog-Service läuft erfolgreich" else warning "⚠️ Bash-Watchdog-Service läuft nicht - prüfen Sie: journalctl -u kiosk-watchdog -f" fi else warning "⚠️ Kein Watchdog-Service aktiviert" fi log "✅ Watchdog-Service-Start abgeschlossen" } # =========================== AKTUALISIERTE HAUPTFUNKTIONEN =========================== setup_production_kiosk() { log "=== PRODUKTIONS-KIOSK SETUP ===" # Vollständige Installation install_system_dependencies remove_desktop_environments install_minimal_x11 create_kiosk_user configure_autologin deploy_application install_npm_dependencies create_https_service create_kiosk_service create_watchdog_service configure_kiosk_environment enable_and_start_services start_watchdog_service run_system_tests log "✅ PRODUKTIONS-KIOSK ERFOLGREICH EINGERICHTET" } # =========================== MENÜ-SYSTEM =========================== show_main_menu() { clear echo -e "${BLUE}=================================================================${NC}" echo -e "${GREEN} $APP_NAME - KONSOLIDIERTER INSTALLER${NC}" echo -e "${CYAN} Version: $APP_VERSION${NC}" echo -e "${BLUE}=================================================================${NC}" echo "" echo -e "${YELLOW}Aktuelles Verzeichnis:${NC} $CURRENT_DIR" echo -e "${YELLOW}Zielverzeichnis:${NC} $APP_DIR" echo -e "${YELLOW}HTTPS-URL:${NC} $HTTPS_URL" echo -e "${YELLOW}Kiosk-Benutzer:${NC} $KIOSK_USER" echo -e "${YELLOW}System:${NC} $(uname -m) - $(cat /etc/debian_version 2>/dev/null || echo 'Unbekannt')" echo "" # Watchdog-Status anzeigen if systemctl is-active --quiet kiosk-watchdog-python.service 2>/dev/null; then echo -e "${GREEN}🔍 Watchdog:${NC} Python-Watchdog aktiv" elif systemctl is-active --quiet kiosk-watchdog.service 2>/dev/null; then echo -e "${GREEN}🔍 Watchdog:${NC} Bash-Watchdog aktiv" else echo -e "${RED}🔍 Watchdog:${NC} Nicht aktiv" fi echo "" echo -e "${PURPLE}Installationsoptionen:${NC}" echo "" echo -e "${GREEN}1)${NC} System-Abhängigkeiten installieren" echo -e " → Python 3, Node.js, npm, SSL-Zertifikate" echo -e " → Verwendet: pip install --break-system-packages" echo -e " → Kein virtuelles Environment" echo "" echo -e "${GREEN}2)${NC} VOLLSTÄNDIGER KIOSK-MODUS (HTTPS Port 443)" echo -e " → ${RED}ENTFERNT ALLE DESKTOP-ENVIRONMENTS!${NC}" echo -e " → Installiert minimale X11-Umgebung" echo -e " → Erstellt SSL-Zertifikate automatisch" echo -e " → Konfiguriert Autologin und Chromium-Kiosk" echo -e " → ${CYAN}Intelligenter Watchdog-Service${NC}" echo -e " → ${YELLOW}NEUSTART ERFORDERLICH!${NC}" echo "" echo -e "${GREEN}3)${NC} Nur SSL-Zertifikate generieren" echo -e " → Erstellt selbstsignierte Zertifikate für localhost" echo -e " → Fügt Zertifikate zum System CA-Store hinzu" echo "" echo -e "${GREEN}4)${NC} Services verwalten" echo -e " → Start/Stop/Restart HTTPS, Kiosk und Watchdog Services" echo -e " → Service-Status anzeigen" echo -e " → ${CYAN}Erweiterte Watchdog-Verwaltung${NC}" echo "" echo -e "${GREEN}5)${NC} System-Tests ausführen" echo -e " → Prüft Installation und Konfiguration" echo -e " → Testet HTTPS-Erreichbarkeit" echo -e " → Watchdog-Funktionalität testen" echo "" echo -e "${RED}0)${NC} Beenden" echo "" echo -e "${RED}⚠️ WARNUNG: Option 2 macht das System zu einem reinen Kiosk!${NC}" echo -e "${GREEN}🔐 HTTPS: Automatische SSL-Zertifikat-Generierung${NC}" echo -e "${CYAN}🔍 WATCHDOG: Intelligente Python/Bash-basierte Überwachung${NC}" echo -e "${BLUE}=================================================================${NC}" echo -n "Ihre Wahl [0-5]: " } manage_services_menu() { while true; do clear echo -e "${BLUE}=== SERVICE-MANAGEMENT ===${NC}" echo "" echo -e "${GREEN}1)${NC} HTTPS-Service starten" echo -e "${GREEN}2)${NC} HTTPS-Service stoppen" echo -e "${GREEN}3)${NC} HTTPS-Service neustarten" echo -e "${GREEN}4)${NC} Kiosk-Service starten" echo -e "${GREEN}5)${NC} Kiosk-Service stoppen" echo -e "${GREEN}6)${NC} Watchdog-Service verwalten" echo -e "${GREEN}7)${NC} Service-Status anzeigen" echo -e "${GREEN}8)${NC} Service-Logs anzeigen" echo -e "${RED}0)${NC} Zurück zum Hauptmenü" echo "" echo -n "Ihre Wahl [0-8]: " read -r choice case $choice in 1) systemctl start "${HTTPS_SERVICE_NAME}.service" echo -e "${GREEN}HTTPS-Service gestartet${NC}" ;; 2) systemctl stop "${HTTPS_SERVICE_NAME}.service" echo -e "${YELLOW}HTTPS-Service gestoppt${NC}" ;; 3) systemctl restart "${HTTPS_SERVICE_NAME}.service" echo -e "${GREEN}HTTPS-Service neugestartet${NC}" ;; 4) systemctl start "${KIOSK_SERVICE_NAME}.service" echo -e "${GREEN}Kiosk-Service gestartet${NC}" ;; 5) systemctl stop "${KIOSK_SERVICE_NAME}.service" echo -e "${YELLOW}Kiosk-Service gestoppt${NC}" ;; 6) manage_watchdog_services ;; 7) echo -e "${BLUE}=== SERVICE-STATUS ===${NC}" systemctl status "${HTTPS_SERVICE_NAME}.service" --no-pager || true echo "" systemctl status "${KIOSK_SERVICE_NAME}.service" --no-pager || true echo "" # Watchdog-Status if systemctl is-enabled --quiet kiosk-watchdog-python.service 2>/dev/null; then systemctl status kiosk-watchdog-python.service --no-pager || true elif systemctl is-enabled --quiet kiosk-watchdog.service 2>/dev/null; then systemctl status kiosk-watchdog.service --no-pager || true fi ;; 8) echo -e "${BLUE}=== SERVICE-LOGS (letzte 20 Zeilen) ===${NC}" echo -e "${CYAN}HTTPS-Service:${NC}" journalctl -u "${HTTPS_SERVICE_NAME}.service" -n 20 --no-pager || true echo "" echo -e "${CYAN}Kiosk-Service:${NC}" journalctl -u "${KIOSK_SERVICE_NAME}.service" -n 20 --no-pager || true echo "" echo -e "${CYAN}Watchdog-Service:${NC}" if systemctl is-active --quiet kiosk-watchdog-python.service 2>/dev/null; then journalctl -u kiosk-watchdog-python.service -n 20 --no-pager || true elif systemctl is-active --quiet kiosk-watchdog.service 2>/dev/null; then journalctl -u kiosk-watchdog.service -n 20 --no-pager || true fi ;; 0) break ;; *) echo -e "${RED}Ungültige Eingabe${NC}" ;; esac echo "" echo -e "${YELLOW}Drücken Sie Enter, um fortzufahren...${NC}" read -r done } manage_watchdog_services() { while true; do clear echo -e "${BLUE}=== WATCHDOG-SERVICE MANAGEMENT ===${NC}" echo "" # Status anzeigen if systemctl is-active --quiet kiosk-watchdog-python.service 2>/dev/null; then echo -e "${GREEN}✅ Python-Watchdog aktiv${NC}" elif systemctl is-enabled --quiet kiosk-watchdog-python.service 2>/dev/null; then echo -e "${YELLOW}⚠️ Python-Watchdog aktiviert aber nicht laufend${NC}" else echo -e "${RED}❌ Python-Watchdog nicht aktiviert${NC}" fi if systemctl is-active --quiet kiosk-watchdog.service 2>/dev/null; then echo -e "${GREEN}✅ Bash-Watchdog aktiv${NC}" elif systemctl is-enabled --quiet kiosk-watchdog.service 2>/dev/null; then echo -e "${YELLOW}⚠️ Bash-Watchdog aktiviert aber nicht laufend${NC}" else echo -e "${RED}❌ Bash-Watchdog nicht aktiviert${NC}" fi echo "" echo -e "${GREEN}1)${NC} Python-Watchdog aktivieren und starten" echo -e "${GREEN}2)${NC} Bash-Watchdog aktivieren und starten" echo -e "${GREEN}3)${NC} Aktiven Watchdog stoppen" echo -e "${GREEN}4)${NC} Aktiven Watchdog neustarten" echo -e "${GREEN}5)${NC} Watchdog-Logs anzeigen" echo -e "${GREEN}6)${NC} Watchdog-Konfiguration testen" echo -e "${RED}0)${NC} Zurück" echo "" echo -n "Ihre Wahl [0-6]: " read -r choice case $choice in 1) # Python-Watchdog aktivieren systemctl stop kiosk-watchdog.service 2>/dev/null || true systemctl disable kiosk-watchdog.service 2>/dev/null || true systemctl enable kiosk-watchdog-python.service systemctl start kiosk-watchdog-python.service echo -e "${GREEN}Python-Watchdog aktiviert und gestartet${NC}" ;; 2) # Bash-Watchdog aktivieren systemctl stop kiosk-watchdog-python.service 2>/dev/null || true systemctl disable kiosk-watchdog-python.service 2>/dev/null || true systemctl enable kiosk-watchdog.service systemctl start kiosk-watchdog.service echo -e "${GREEN}Bash-Watchdog aktiviert und gestartet${NC}" ;; 3) # Aktiven Watchdog stoppen systemctl stop kiosk-watchdog-python.service 2>/dev/null || true systemctl stop kiosk-watchdog.service 2>/dev/null || true echo -e "${YELLOW}Watchdog-Services gestoppt${NC}" ;; 4) # Aktiven Watchdog neustarten if systemctl is-enabled --quiet kiosk-watchdog-python.service 2>/dev/null; then systemctl restart kiosk-watchdog-python.service echo -e "${GREEN}Python-Watchdog neugestartet${NC}" elif systemctl is-enabled --quiet kiosk-watchdog.service 2>/dev/null; then systemctl restart kiosk-watchdog.service echo -e "${GREEN}Bash-Watchdog neugestartet${NC}" else echo -e "${RED}Kein Watchdog-Service aktiviert${NC}" fi ;; 5) # Watchdog-Logs anzeigen echo -e "${BLUE}=== WATCHDOG-LOGS ===${NC}" if systemctl is-active --quiet kiosk-watchdog-python.service 2>/dev/null; then echo -e "${CYAN}Python-Watchdog (systemd):${NC}" journalctl -u kiosk-watchdog-python.service -n 30 --no-pager || true echo "" echo -e "${CYAN}Python-Watchdog (Datei):${NC}" tail -n 20 /var/log/kiosk-watchdog-python.log 2>/dev/null || echo "Log-Datei nicht gefunden" elif systemctl is-active --quiet kiosk-watchdog.service 2>/dev/null; then echo -e "${CYAN}Bash-Watchdog:${NC}" journalctl -u kiosk-watchdog.service -n 30 --no-pager || true echo "" tail -n 20 /var/log/kiosk-watchdog.log 2>/dev/null || echo "Log-Datei nicht gefunden" else echo -e "${RED}Kein aktiver Watchdog-Service${NC}" fi ;; 6) # Watchdog-Konfiguration testen echo -e "${BLUE}=== WATCHDOG-KONFIGURATION TEST ===${NC}" # Teste Python-Watchdog if python3 -c "import sys; sys.path.insert(0, '$APP_DIR'); from utils.watchdog_manager import WatchdogManager; print('✅ Python-Watchdog importierbar')" 2>/dev/null; then echo -e "${GREEN}✅ Python-Watchdog-Konfiguration OK${NC}" else echo -e "${RED}❌ Python-Watchdog-Konfiguration fehlerhaft${NC}" fi # Teste SSL-Zertifikate if [ -f "$APP_DIR/certs/localhost/localhost.crt" ]; then echo -e "${GREEN}✅ SSL-Zertifikat vorhanden${NC}" else echo -e "${RED}❌ SSL-Zertifikat fehlt${NC}" fi # Teste HTTPS-Erreichbarkeit if curl -k -s --connect-timeout 5 "$HTTPS_URL" >/dev/null 2>&1; then echo -e "${GREEN}✅ HTTPS Backend erreichbar${NC}" else echo -e "${RED}❌ HTTPS Backend nicht erreichbar${NC}" fi ;; 0) break ;; *) echo -e "${RED}Ungültige Eingabe${NC}" ;; esac echo "" echo -e "${YELLOW}Drücken Sie Enter, um fortzufahren...${NC}" read -r done } # =========================== HAUPTPROGRAMM =========================== main() { # System-Checks check_root check_debian_system # Log-Datei erstellen mkdir -p "$(dirname "$INSTALL_LOG")" touch "$INSTALL_LOG" log "=== MYP KONSOLIDIERTER INSTALLER GESTARTET ===" log "Version: $APP_VERSION" log "Arbeitsverzeichnis: $CURRENT_DIR" log "Zielverzeichnis: $APP_DIR" log "HTTPS-URL: $HTTPS_URL" log "System: $(uname -a)" while true; do show_main_menu read -r choice case $choice in 1) clear log "=== OPTION 1: SYSTEM-ABHÄNGIGKEITEN ===" install_system_dependencies success "✅ System-Abhängigkeiten erfolgreich installiert!" ;; 2) clear echo -e "${RED}⚠️ WARNUNG: Vollständiger Kiosk-Modus!${NC}" echo -e "${YELLOW}Das System wird zu einem reinen HTTPS-Kiosk umgebaut.${NC}" echo -e "${BLUE}Alle Desktop-Environments werden entfernt!${NC}" echo "" echo -n "Sind Sie sicher? [ja/NEIN]: " read -r confirm if [ "$confirm" = "ja" ] || [ "$confirm" = "JA" ]; then clear log "=== OPTION 2: VOLLSTÄNDIGER KIOSK-MODUS ===" setup_production_kiosk success "✅ KIOSK-MODUS ERFOLGREICH EINGERICHTET!" echo "" echo -e "${RED}🔄 NEUSTART JETZT ERFORDERLICH: sudo reboot${NC}" echo -e "${BLUE}🔐 HTTPS-URL: $HTTPS_URL${NC}" else echo -e "${BLUE}Installation abgebrochen.${NC}" fi ;; 3) clear log "=== OPTION 3: SSL-ZERTIFIKATE GENERIEREN ===" python3 -c "import sys; sys.path.insert(0, '$CURRENT_DIR'); from utils.ssl_config import ensure_ssl_certificates; ensure_ssl_certificates('$APP_DIR', True)" success "✅ SSL-Zertifikate generiert!" ;; 4) manage_services_menu continue ;; 5) clear log "=== OPTION 5: SYSTEM-TESTS ===" run_system_tests success "✅ System-Tests abgeschlossen!" ;; 0) log "=== KONSOLIDIERTER INSTALLER BEENDET ===" echo -e "${GREEN}Auf Wiedersehen!${NC}" echo -e "${BLUE}Log-Datei: $INSTALL_LOG${NC}" exit 0 ;; *) echo -e "${RED}Ungültige Eingabe. Bitte wählen Sie 0-5.${NC}" sleep 2 continue ;; esac echo "" echo -e "${YELLOW}Drücken Sie Enter, um fortzufahren...${NC}" read -r done } # Script starten main "$@"