#!/bin/bash # =================================================================== # MYP Druckerverwaltung - Installer für Raspbian Kiosk-System # Entwickelt auf Windows, ausführbar auf Raspberry Pi / Debian # OHNE virtualenv - verwendet System-Python mit --break-system-packages # =================================================================== set -euo pipefail # =========================== KONFIGURATION =========================== APP_NAME="MYP Druckerverwaltung" APP_DIR="/opt/myp" SERVICE_NAME="myp-kiosk" CURRENT_DIR="$(pwd)" INSTALL_LOG="/var/log/myp-install.log" # 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" } check_debian_system() { if [ ! -f /etc/debian_version ]; then error "Dieses Skript ist nur für Debian/Raspbian-Systeme geeignet!" fi log "✅ Debian/Raspbian-System erkannt" } # ========================== ABHÄNGIGKEITEN INSTALLIEREN ========================== install_system_dependencies() { log "=== INSTALLIERE SYSTEM-ABHÄNGIGKEITEN ===" progress "Aktualisiere Paketlisten..." apt-get update -y || error "APT Update fehlgeschlagen" progress "Installiere Python 3 und grundlegende Pakete..." apt-get install -y \ python3 \ python3-pip \ python3-dev \ python3-setuptools \ build-essential \ libssl-dev \ libffi-dev \ git \ curl \ wget \ nano \ htop \ rsync \ unzip \ sudo \ systemd \ ca-certificates \ gnupg \ lsb-release \ sqlite3 \ || error "System-Pakete Installation fehlgeschlagen" progress "Installiere Python-Abhängigkeiten mit --break-system-packages..." # Core Flask Framework pip3 install --break-system-packages Flask==3.1.1 || error "Flask Installation fehlgeschlagen" pip3 install --break-system-packages Flask-Login==0.6.3 || error "Flask-Login Installation fehlgeschlagen" pip3 install --break-system-packages Flask-WTF==1.2.1 || error "Flask-WTF Installation fehlgeschlagen" # Datenbank pip3 install --break-system-packages SQLAlchemy==2.0.36 || error "SQLAlchemy Installation fehlgeschlagen" # Sicherheit pip3 install --break-system-packages bcrypt==4.2.1 || error "bcrypt Installation fehlgeschlagen" pip3 install --break-system-packages cryptography==44.0.0 || error "cryptography Installation fehlgeschlagen" pip3 install --break-system-packages Werkzeug==3.1.3 || error "Werkzeug Installation fehlgeschlagen" # Smart Plug Steuerung pip3 install --break-system-packages PyP100 || warning "PyP100 Installation fehlgeschlagen (optional)" # HTTP Requests pip3 install --break-system-packages requests==2.32.3 || error "requests Installation fehlgeschlagen" # System Monitoring pip3 install --break-system-packages psutil==6.1.1 || error "psutil Installation fehlgeschlagen" # Redis (optional) pip3 install --break-system-packages redis==5.2.1 || warning "redis Installation fehlgeschlagen (optional)" # Weitere Core-Abhängigkeiten pip3 install --break-system-packages MarkupSafe==3.0.2 || error "MarkupSafe Installation fehlgeschlagen" # Produktions-Server pip3 install --break-system-packages gunicorn==23.0.0 || error "gunicorn Installation fehlgeschlagen" log "✅ Alle Abhängigkeiten erfolgreich installiert" } # ========================== PRODUKTIONS-KIOSK SETUP ========================== setup_production_kiosk() { log "=== RICHTE PRODUKTIONS-KIOSK-MODUS EIN ===" # Zuerst Abhängigkeiten installieren install_system_dependencies progress "Erstelle Zielverzeichnis /opt/myp..." mkdir -p "$APP_DIR" || error "Konnte Zielverzeichnis nicht erstellen" progress "Kopiere Projektdateien selektiv nach $APP_DIR..." # Liste der zu kopierenden Dateien/Ordner (ohne unnötige Inhalte) declare -a COPY_ITEMS=( "app.py" "models.py" "requirements.txt" "blueprints/" "config/" "database/" "docs/" "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 einzeln kopieren (falls vorhanden) 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 # Stelle sicher, dass app.py ausführbar ist chmod +x "$APP_DIR/app.py" || error "Konnte app.py nicht ausführbar machen" # Erstelle notwendige Verzeichnisse falls sie nicht existieren mkdir -p "$APP_DIR/database/backups" mkdir -p "$APP_DIR/logs/app" mkdir -p "$APP_DIR/logs/auth" mkdir -p "$APP_DIR/logs/errors" mkdir -p "$APP_DIR/uploads/temp" # Berechtigungen setzen chown -R root:root "$APP_DIR" chmod -R 755 "$APP_DIR" chmod 750 "$APP_DIR/database" chmod 750 "$APP_DIR/logs" chmod 755 "$APP_DIR/uploads" progress "Erstelle Systemd-Service myp-kiosk.service..." cat > "/etc/systemd/system/${SERVICE_NAME}.service" << EOF [Unit] Description=MYP Druckerverwaltung Kiosk-Modus After=network.target network-online.target Wants=network-online.target Requires=network.target [Service] Type=simple User=root Group=root WorkingDirectory=$APP_DIR ExecStart=/usr/bin/python3 $APP_DIR/app.py --debug Restart=always RestartSec=5 StartLimitBurst=5 StartLimitInterval=60 # Umgebungsvariablen Environment=PYTHONUNBUFFERED=1 Environment=FLASK_ENV=production Environment=FLASK_HOST=0.0.0.0 Environment=FLASK_PORT=5000 Environment=PYTHONPATH=$APP_DIR Environment=LC_ALL=C.UTF-8 Environment=LANG=C.UTF-8 # Logging StandardOutput=journal StandardError=journal SyslogIdentifier=myp-kiosk # Security-Einstellungen NoNewPrivileges=true PrivateTmp=false ProtectSystem=strict ReadWritePaths=$APP_DIR [Install] WantedBy=multi-user.target EOF progress "Lade Systemd-Konfiguration neu..." systemctl daemon-reload || error "Systemd Reload fehlgeschlagen" progress "Aktiviere und starte $SERVICE_NAME Service..." systemctl enable "$SERVICE_NAME.service" || error "Service Enable fehlgeschlagen" systemctl start "$SERVICE_NAME.service" || error "Service Start fehlgeschlagen" # Service-Status prüfen sleep 5 if systemctl is-active --quiet "$SERVICE_NAME.service"; then log "✅ $SERVICE_NAME Service läuft erfolgreich" info "Service-Status: $(systemctl is-active $SERVICE_NAME.service)" info "Port 5000: Flask-App läuft im Debug-Modus" info "Projektverzeichnis: $APP_DIR" # Test der Anwendung progress "Teste Anwendungserreichbarkeit..." sleep 3 if curl -s http://localhost:5000 > /dev/null 2>&1; then log "✅ Anwendung ist unter http://localhost:5000 erreichbar" else warning "⚠️ Anwendung noch nicht erreichbar (möglicherweise noch beim Starten)" fi else error "$SERVICE_NAME Service konnte nicht gestartet werden - prüfen Sie die Logs: journalctl -u $SERVICE_NAME -f" fi log "✅ Produktions-Kiosk-Modus erfolgreich eingerichtet" log "🎯 Anwendung erreichbar unter: http://localhost:5000" log "📋 Service-Befehle:" log " • Status: sudo systemctl status $SERVICE_NAME" log " • Stoppen: sudo systemctl stop $SERVICE_NAME" log " • Starten: sudo systemctl start $SERVICE_NAME" log " • Neustarten: sudo systemctl restart $SERVICE_NAME" log " • Logs: sudo journalctl -u $SERVICE_NAME -f" log " • Service-Info: sudo journalctl -u $SERVICE_NAME --no-pager" } # ========================== HAUPTMENÜ ========================== show_menu() { clear echo -e "${BLUE}=================================================================${NC}" echo -e "${GREEN} $APP_NAME - Installer für Raspbian${NC}" echo -e "${BLUE}=================================================================${NC}" echo "" echo -e "${YELLOW}Aktuelles Verzeichnis:${NC} $CURRENT_DIR" echo -e "${YELLOW}Systemzeit:${NC} $(date)" echo -e "${YELLOW}Zielverzeichnis:${NC} $APP_DIR" echo "" echo -e "${PURPLE}Wählen Sie eine Option:${NC}" echo "" echo -e "${GREEN}1)${NC} System vorbereiten (Abhängigkeiten installieren)" echo -e " → Installiert Python 3, pip und alle benötigten Pakete" echo -e " → Verwendet: pip install --break-system-packages" echo -e " → Keine virtualenv, direktes System-Python" echo "" echo -e "${GREEN}2)${NC} Produktions-Kiosk-Modus installieren" echo -e " → Führt System-Vorbereitung durch" echo -e " → Verschiebt Dateien selektiv nach /opt/myp/" echo -e " → Erstellt systemd-Service: myp-kiosk.service" echo -e " → Startet Flask-App mit --debug auf Port 5000" echo -e " → Testet Anwendungserreichbarkeit" echo "" echo -e "${RED}0)${NC} Beenden" echo "" echo -e "${BLUE}=================================================================${NC}" echo -n "Ihre Wahl [0-2]: " } # ========================== MAIN LOGIC ========================== main() { # System-Checks check_root check_debian_system # Erstelle Log-Datei mkdir -p "$(dirname "$INSTALL_LOG")" touch "$INSTALL_LOG" log "=== MYP INSTALLER GESTARTET ===" log "Arbeitsverzeichnis: $CURRENT_DIR" log "Zielverzeichnis: $APP_DIR" log "Service-Name: $SERVICE_NAME" log "System: $(uname -a)" log "Debian-Version: $(cat /etc/debian_version 2>/dev/null || echo 'Unbekannt')" while true; do show_menu read -r choice case $choice in 1) clear log "=== OPTION 1: SYSTEM VORBEREITEN ===" install_system_dependencies echo "" echo -e "${GREEN}✅ System-Vorbereitung abgeschlossen!${NC}" echo -e "${YELLOW}Drücken Sie Enter, um fortzufahren...${NC}" read -r ;; 2) clear log "=== OPTION 2: PRODUKTIONS-KIOSK-MODUS ===" setup_production_kiosk echo "" echo -e "${GREEN}✅ Produktions-Kiosk-Modus erfolgreich eingerichtet!${NC}" echo -e "${BLUE}ℹ️ Die Anwendung startet automatisch bei jedem Systemstart.${NC}" echo -e "${YELLOW}Drücken Sie Enter, um fortzufahren...${NC}" read -r ;; 0) log "=== 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-2.${NC}" sleep 2 ;; esac done } # Script starten main "$@"