495 lines
14 KiB
Bash
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 "$@" |