495 lines
14 KiB
Bash

#!/bin/bash
# ===================================================================
# MYP Druckerverwaltung - VOLLSTÄNDIGES SETUP-SKRIPT
# Optimiert für Raspberry Pi OS (Debian-basiert)
# Version: 5.0.0 - Komplett überarbeitet und getestet
# ===================================================================
set -euo pipefail
# =========================== GLOBALE KONFIGURATION ===========================
readonly APP_NAME="MYP Druckerverwaltung"
readonly APP_VERSION="5.0.0"
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="${CURRENT_DIR}/logs/myp-install.log"
readonly ERROR_LOG="${CURRENT_DIR}/logs/myp-install-errors.log"
readonly HTTPS_PORT="443"
# 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 ===========================
init_logging() {
mkdir -p "${CURRENT_DIR}/logs" 2>/dev/null || true
echo "MYP Installation Log - $(date '+%Y-%m-%d %H:%M:%S')" > "$INSTALL_LOG"
echo "MYP Installation Errors - $(date '+%Y-%m-%d %H:%M:%S')" > "$ERROR_LOG"
}
log() {
local message="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
echo -e "${GREEN}${message}${NC}" | tee -a "$INSTALL_LOG"
}
error() {
local message="[ERROR] $1"
echo -e "${RED}${message}${NC}" | tee -a "$INSTALL_LOG" | tee -a "$ERROR_LOG"
exit 1
}
warning() {
local message="[WARNING] $1"
echo -e "${YELLOW}${message}${NC}" | tee -a "$INSTALL_LOG"
}
info() {
echo -e "${BLUE}[INFO] $1${NC}" | tee -a "$INSTALL_LOG"
}
progress() {
echo -e "${PURPLE}[PROGRESS] $1${NC}" | tee -a "$INSTALL_LOG"
}
success() {
echo -e "${CYAN}[SUCCESS] $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
log "✅ Root-Berechtigung bestätigt"
}
check_debian_system() {
if [ ! -f /etc/debian_version ]; then
error "Dieses Skript ist nur für Debian/Raspberry Pi OS gedacht!"
fi
log "✅ Debian-basiertes System erkannt"
}
check_required_files() {
log "=== PRÜFE ERFORDERLICHE DATEIEN ==="
local required_files=(
"app.py"
"models.py"
"requirements.txt"
)
for file in "${required_files[@]}"; do
if [ ! -f "${CURRENT_DIR}/${file}" ]; then
error "Erforderliche Datei nicht gefunden: ${file}"
fi
success "${file} gefunden"
done
}
# =========================== SYSTEM-UPDATE ===========================
update_system() {
log "=== SYSTEM UPDATE ==="
progress "Aktualisiere Paketlisten..."
apt-get update || error "Fehler beim Update der Paketlisten"
progress "Aktualisiere System-Pakete..."
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y || warning "Einige Pakete konnten nicht aktualisiert werden"
success "✅ System aktualisiert"
}
# =========================== ABHÄNGIGKEITEN INSTALLATION ===========================
install_base_dependencies() {
log "=== INSTALLIERE BASIS-ABHÄNGIGKEITEN ==="
local packages=(
# Python und Entwicklung
"python3"
"python3-pip"
"python3-venv"
"python3-dev"
"build-essential"
# System-Tools
"git"
"curl"
"wget"
"nano"
"htop"
"net-tools"
# Datenbank
"sqlite3"
# SSL/Sicherheit
"openssl"
"ca-certificates"
# Kiosk-Modus
"chromium-browser"
"xserver-xorg"
"xinit"
"x11-xserver-utils"
"unclutter"
# Remote-Zugang
"openssh-server"
"xrdp"
# Firewall
"firewalld"
)
progress "Installiere Pakete..."
for package in "${packages[@]}"; do
progress "Installiere ${package}..."
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "$package" || warning "Fehler bei Installation von ${package}"
done
success "✅ Basis-Abhängigkeiten installiert"
}
# =========================== PYTHON-UMGEBUNG ===========================
setup_python_environment() {
log "=== PYTHON-UMGEBUNG EINRICHTEN ==="
# App-Verzeichnis erstellen
progress "Erstelle App-Verzeichnis..."
mkdir -p "$APP_DIR"
# Dateien kopieren
progress "Kopiere Anwendungsdateien..."
cp -r "${CURRENT_DIR}"/* "$APP_DIR/" 2>/dev/null || true
# Python-Abhängigkeiten installieren
progress "Installiere Python-Abhängigkeiten..."
cd "$APP_DIR"
if [ -f "requirements.txt" ]; then
pip3 install --no-cache-dir -r requirements.txt || error "Fehler beim Installieren der Python-Abhängigkeiten"
else
# Minimale Abhängigkeiten direkt installieren
pip3 install --no-cache-dir \
Flask==2.3.3 \
Flask-Login==0.6.2 \
Flask-WTF==1.1.1 \
SQLAlchemy==2.0.21 \
Werkzeug==2.3.7 \
python-dotenv==1.0.0 \
PyP100==0.1.2 \
|| error "Fehler beim Installieren der Python-Pakete"
fi
cd "$CURRENT_DIR"
success "✅ Python-Umgebung eingerichtet"
}
# =========================== NODE.JS INSTALLATION ===========================
install_nodejs() {
log "=== INSTALLIERE NODE.JS ==="
if command -v node >/dev/null 2>&1; then
log "Node.js bereits installiert: $(node --version)"
return
fi
progress "Installiere Node.js..."
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - || error "Fehler beim Hinzufügen des Node.js Repository"
apt-get install -y nodejs || error "Fehler bei der Node.js Installation"
success "✅ Node.js installiert: $(node --version)"
}
# =========================== FRONTEND BUILD ===========================
build_frontend() {
log "=== BAUE FRONTEND ==="
cd "$APP_DIR"
# Prüfe ob package.json existiert
if [ -f "package.json" ]; then
progress "Installiere Frontend-Abhängigkeiten..."
npm install || warning "Fehler bei npm install"
progress "Baue Frontend-Assets..."
npm run build || warning "Fehler beim Frontend-Build"
else
warning "package.json nicht gefunden - überspringe Frontend-Build"
fi
cd "$CURRENT_DIR"
success "✅ Frontend-Build abgeschlossen"
}
# =========================== SSL-ZERTIFIKATE ===========================
setup_ssl_certificates() {
log "=== SSL-ZERTIFIKATE EINRICHTEN ==="
local cert_dir="${APP_DIR}/instance/ssl"
mkdir -p "$cert_dir"
progress "Generiere selbstsigniertes SSL-Zertifikat..."
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "${cert_dir}/key.pem" \
-out "${cert_dir}/cert.pem" \
-subj "/C=DE/ST=NRW/L=Local/O=MYP/CN=localhost" \
2>/dev/null || error "Fehler beim Generieren des SSL-Zertifikats"
chmod 600 "${cert_dir}/key.pem"
chmod 644 "${cert_dir}/cert.pem"
success "✅ SSL-Zertifikate erstellt"
}
# =========================== SYSTEMD SERVICES ===========================
setup_systemd_services() {
log "=== SYSTEMD SERVICES EINRICHTEN ==="
# HTTPS Service
progress "Erstelle HTTPS Service..."
cat > "/etc/systemd/system/${HTTPS_SERVICE_NAME}.service" << EOF
[Unit]
Description=MYP HTTPS Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=${APP_DIR}
Environment="PYTHONUNBUFFERED=1"
Environment="FLASK_ENV=production"
ExecStart=/usr/bin/python3 ${APP_DIR}/app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Kiosk Service
progress "Erstelle Kiosk Service..."
cat > "/etc/systemd/system/${KIOSK_SERVICE_NAME}.service" << EOF
[Unit]
Description=MYP Kiosk Mode
After=network.target ${HTTPS_SERVICE_NAME}.service
[Service]
Type=simple
User=${KIOSK_USER}
Environment="DISPLAY=:0"
ExecStart=/usr/bin/xinit /usr/bin/chromium-browser --kiosk --no-sandbox --disable-dev-shm-usage --disable-gpu --disable-software-rasterizer --disable-features=TranslateUI --disable-infobars https://localhost:${HTTPS_PORT} -- :0 -nocursor -dpms
Restart=always
RestartSec=10
[Install]
WantedBy=graphical.target
EOF
systemctl daemon-reload
success "✅ Systemd Services erstellt"
}
# =========================== KIOSK-BENUTZER ===========================
setup_kiosk_user() {
log "=== KIOSK-BENUTZER EINRICHTEN ==="
if ! id "$KIOSK_USER" &>/dev/null; then
progress "Erstelle Kiosk-Benutzer..."
useradd -m -s /bin/bash "$KIOSK_USER"
usermod -aG video,audio "$KIOSK_USER"
fi
# Auto-Login konfigurieren
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_USER} --noclear %I \$TERM
EOF
success "✅ Kiosk-Benutzer konfiguriert"
}
# =========================== FIREWALL ===========================
configure_firewall() {
log "=== FIREWALL KONFIGURIEREN ==="
systemctl start firewalld
systemctl enable firewalld
# HTTPS Port öffnen
firewall-cmd --permanent --add-port=${HTTPS_PORT}/tcp
# SSH erlauben
firewall-cmd --permanent --add-service=ssh
# RDP für Remote-Desktop
firewall-cmd --permanent --add-port=3389/tcp
firewall-cmd --reload
success "✅ Firewall konfiguriert"
}
# =========================== DATENBANK INITIALISIERUNG ===========================
initialize_database() {
log "=== DATENBANK INITIALISIEREN ==="
cd "$APP_DIR"
progress "Initialisiere Datenbank..."
python3 << EOF
import sys
sys.path.append('${APP_DIR}')
from models import init_database, create_initial_admin
try:
init_database()
create_initial_admin()
print("✅ Datenbank erfolgreich initialisiert")
except Exception as e:
print(f"❌ Fehler bei Datenbank-Initialisierung: {e}")
sys.exit(1)
EOF
cd "$CURRENT_DIR"
}
# =========================== SERVICES STARTEN ===========================
start_services() {
log "=== SERVICES STARTEN ==="
# SSH aktivieren
systemctl enable ssh
systemctl start ssh
# HTTPS Service
systemctl enable "${HTTPS_SERVICE_NAME}"
systemctl start "${HTTPS_SERVICE_NAME}"
# Warte bis Service läuft
sleep 5
# Kiosk Service (optional)
# systemctl enable "${KIOSK_SERVICE_NAME}"
# systemctl start "${KIOSK_SERVICE_NAME}"
success "✅ Services gestartet"
}
# =========================== INSTALLATION TESTEN ===========================
test_installation() {
log "=== INSTALLATION TESTEN ==="
# Teste HTTPS Service
if systemctl is-active --quiet "${HTTPS_SERVICE_NAME}"; then
success "✅ HTTPS Service läuft"
else
warning "⚠️ HTTPS Service läuft nicht"
fi
# Teste Webserver
if curl -k -s -o /dev/null -w "%{http_code}" https://localhost:${HTTPS_PORT} | grep -q "200\|302"; then
success "✅ Webserver antwortet"
else
warning "⚠️ Webserver antwortet nicht"
fi
# Zeige Zugriffs-URLs
local ip_address=$(hostname -I | awk '{print $1}')
log ""
log "🌐 ZUGRIFFS-INFORMATIONEN:"
log " Local: https://localhost:${HTTPS_PORT}"
log " Netzwerk: https://${ip_address}:${HTTPS_PORT}"
log " SSH: ssh pi@${ip_address}"
log ""
log "📝 STANDARD-ANMELDEDATEN:"
log " Admin-Benutzer: admin"
log " Admin-Passwort: admin123"
log ""
}
# =========================== HAUPTMENÜ ===========================
show_menu() {
clear
echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ MYP DRUCKERVERWALTUNG - SETUP v${APP_VERSION}${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${BLUE}Wählen Sie eine Option:${NC}"
echo ""
echo -e "${GREEN}1)${NC} Vollständige Installation (Produktion)"
echo -e "${GREEN}2)${NC} Nur Abhängigkeiten installieren (Entwicklung)"
echo -e "${GREEN}3)${NC} Beenden"
echo ""
echo -n "Ihre Auswahl [1-3]: "
}
# =========================== HAUPTPROGRAMM ===========================
main() {
init_logging
while true; do
show_menu
read -r choice
case $choice in
1)
log "=== VOLLSTÄNDIGE INSTALLATION GESTARTET ==="
check_root
check_debian_system
check_required_files
update_system
install_base_dependencies
setup_python_environment
install_nodejs
build_frontend
setup_ssl_certificates
setup_systemd_services
setup_kiosk_user
configure_firewall
initialize_database
start_services
test_installation
log "✅ Installation erfolgreich abgeschlossen!"
echo ""
echo -n "Drücken Sie Enter um fortzufahren..."
read -r
;;
2)
log "=== NUR ABHÄNGIGKEITEN INSTALLATION ==="
check_root
check_debian_system
update_system
install_base_dependencies
setup_python_environment
install_nodejs
log "✅ Abhängigkeiten installiert!"
echo ""
echo -n "Drücken Sie Enter um fortzufahren..."
read -r
;;
3)
echo -e "${CYAN}Setup beendet.${NC}"
exit 0
;;
*)
echo -e "${RED}Ungültige Auswahl!${NC}"
sleep 2
;;
esac
done
}
# Skript starten
main "$@"