Files
Projektarbeit-MYP/backend/setup/modules/python_node.sh
Till Tomczak 0ef0c973f2 🔧 Update: Verbesserungen an der Benutzeranfrageverwaltung und Protokollierung
**Änderungen:**
-  Hinzugefügt: Neue Funktionalität zur Verwaltung von Benutzeranfragen, um die Benutzerfreundlichkeit zu erhöhen.
-  Optimierte Protokollierung für Benutzeranfragen, um detailliertere Informationen über den Status und die Verarbeitung bereitzustellen.

**Ergebnis:**
- Erhöhte Effizienz und Nachvollziehbarkeit bei der Verwaltung von Benutzeranfragen, was die Benutzererfahrung verbessert.

🤖 Generated with [Claude Code](https://claude.ai/code)
2025-06-16 06:56:46 +02:00

571 lines
16 KiB
Bash

#!/bin/bash
#######################################################################
# MYP AIO-Installer - Python & Node.js Module
#
# Dieses Modul behandelt die Installation von:
# - Python und pip mit --break-system-packages
# - Node.js und npm
# - Python-Abhängigkeiten aus requirements.txt
# - Node.js-Abhängigkeiten aus package.json
# - Build-Prozess für Frontend-Assets
#######################################################################
# Funktionsdeklarationen für Python & Node.js Setup
install_python_dependencies() {
log "INFO" "=== PYTHON-ABHÄNGIGKEITEN INSTALLIEREN ==="
# Python-Version überprüfen
verify_python_installation
# pip konfigurieren
configure_pip
# Virtuelle Umgebung erstellen (optional)
# create_python_venv
# Requirements installieren
install_python_requirements
# Python-Installation verifizieren
verify_python_dependencies
log "INFO" "Python-Abhängigkeiten Installation abgeschlossen"
}
install_node_dependencies() {
log "INFO" "=== NODE.JS-ABHÄNGIGKEITEN INSTALLIEREN ==="
# Node.js installieren
install_nodejs
# npm konfigurieren
configure_npm
# Package-Dependencies installieren
install_npm_packages
# Build-Prozess durchführen
build_frontend_assets
# Node.js-Installation verifizieren
verify_node_dependencies
log "INFO" "Node.js-Abhängigkeiten Installation abgeschlossen"
}
verify_python_installation() {
log "INFO" "Überprüfe Python-Installation..."
# Python3 Version prüfen
if ! command -v python3 >/dev/null 2>&1; then
log "ERROR" "Python3 ist nicht installiert"
return 1
fi
local python_version=$(python3 --version | cut -d' ' -f2)
log "INFO" "Python-Version: $python_version"
# Mindestversion prüfen (Python 3.8+)
if ! python3 -c "import sys; sys.exit(0 if sys.version_info >= (3, 8) else 1)"; then
log "ERROR" "Python-Version zu alt (mindestens 3.8 erforderlich)"
return 1
fi
# pip überprüfen
if ! command -v pip3 >/dev/null 2>&1; then
log "INFO" "pip3 nicht gefunden, installiere pip..."
apt-get install -y python3-pip
fi
local pip_version=$(pip3 --version | cut -d' ' -f2)
log "INFO" "pip-Version: $pip_version"
log "INFO" "Python-Installation verifiziert"
}
configure_pip() {
log "INFO" "Konfiguriere pip..."
# pip Konfigurationsverzeichnis erstellen
mkdir -p "/home/$PROJECT_USER/.config/pip"
mkdir -p "/root/.config/pip"
# pip.conf für bessere Performance und Sicherheit
cat > "/home/$PROJECT_USER/.config/pip/pip.conf" << 'EOF'
[global]
timeout = 60
retries = 5
trusted-host = pypi.org
pypi.python.org
files.pythonhosted.org
[install]
upgrade-strategy = only-if-needed
break-system-packages = true
EOF
# Kopiere für root
cp "/home/$PROJECT_USER/.config/pip/pip.conf" "/root/.config/pip/pip.conf"
# Berechtigungen setzen
chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.config"
# pip auf neueste Version aktualisieren
log "INFO" "Aktualisiere pip auf neueste Version..."
pip3 install --upgrade pip --break-system-packages || {
log "WARN" "pip-Update hatte Probleme"
}
log "INFO" "pip konfiguriert"
}
create_python_venv() {
log "INFO" "Erstelle Python Virtual Environment..."
local venv_path="$INSTALL_PATH/venv"
# Virtual Environment erstellen
python3 -m venv "$venv_path" || {
log "ERROR" "Virtual Environment konnte nicht erstellt werden"
return 1
}
# Aktivierungsscript für systemd erstellen
cat > "$INSTALL_PATH/activate_venv.sh" << EOF
#!/bin/bash
source "$venv_path/bin/activate"
exec "\$@"
EOF
chmod +x "$INSTALL_PATH/activate_venv.sh"
# Virtual Environment in systemd-Service nutzen
export PYTHON_VENV_PATH="$venv_path"
log "INFO" "Python Virtual Environment erstellt: $venv_path"
}
install_python_requirements() {
log "INFO" "Installiere Python-Requirements..."
# Requirements-Datei prüfen
local requirements_file="$INSTALL_PATH/requirements.txt"
if [[ ! -f "$requirements_file" ]]; then
log "ERROR" "Requirements-Datei nicht gefunden: $requirements_file"
return 1
fi
log "INFO" "Gefundene Requirements-Datei: $requirements_file"
# Anzahl der Requirements anzeigen
local req_count=$(grep -v '^#' "$requirements_file" | grep -v '^$' | wc -l)
log "INFO" "Installiere $req_count Python-Packages..."
# Installation mit --break-system-packages
log "INFO" "Führe pip install mit --break-system-packages aus..."
# Erstelle temporäres Install-Script für bessere Kontrolle
cat > "/tmp/pip_install.sh" << EOF
#!/bin/bash
set -e
cd "$INSTALL_PATH"
# Upgrade pip falls nötig
pip3 install --upgrade pip --break-system-packages
# Installiere Requirements
pip3 install -r requirements.txt --break-system-packages --no-cache-dir
# Erstelle Freeze-Liste für Debugging
pip3 freeze --break-system-packages > installed_packages.txt
EOF
chmod +x "/tmp/pip_install.sh"
# Installation ausführen
if /tmp/pip_install.sh; then
log "INFO" "Python-Requirements erfolgreich installiert"
else
log "ERROR" "Python-Requirements Installation fehlgeschlagen"
# Versuche einzelne Installation bei Fehlern
log "INFO" "Versuche einzelne Package-Installation..."
install_requirements_individually "$requirements_file"
fi
# Cleanup
rm -f "/tmp/pip_install.sh"
log "INFO" "Python-Requirements Installation abgeschlossen"
}
install_requirements_individually() {
local requirements_file="$1"
log "INFO" "Installiere Requirements einzeln..."
# Lese Requirements und installiere einzeln
while IFS= read -r line; do
# Überspringe Kommentare und leere Zeilen
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Package-Name extrahieren
local package=$(echo "$line" | cut -d'=' -f1 | cut -d'>' -f1 | cut -d'<' -f1 | tr -d ' ')
if [[ -n "$package" ]]; then
log "INFO" "Installiere: $package"
if pip3 install "$line" --break-system-packages --no-cache-dir; then
log "INFO" "$package installiert"
else
log "WARN" "$package Installation fehlgeschlagen"
fi
fi
done < "$requirements_file"
}
install_nodejs() {
log "INFO" "Installiere Node.js..."
# Prüfe ob Node.js bereits installiert ist
if command -v node >/dev/null 2>&1; then
local current_version=$(node --version)
log "INFO" "Node.js bereits installiert: $current_version"
# Prüfe Version (mindestens v16)
if node -e "process.exit(parseInt(process.version.slice(1)) >= 16 ? 0 : 1)"; then
log "INFO" "Node.js Version ist ausreichend"
return 0
else
log "WARN" "Node.js Version zu alt, aktualisiere..."
fi
fi
# Versuche Installation über APT (NodeSource Repository)
if install_nodejs_apt; then
log "INFO" "Node.js über APT installiert"
return 0
fi
# Fallback: Installation über NodeSource Script
if install_nodejs_nodesource; then
log "INFO" "Node.js über NodeSource installiert"
return 0
fi
# Letzter Fallback: Snap
if install_nodejs_snap; then
log "INFO" "Node.js über Snap installiert"
return 0
fi
log "ERROR" "Node.js Installation fehlgeschlagen"
return 1
}
install_nodejs_apt() {
log "INFO" "Versuche Node.js Installation über APT..."
# APT-Cache aktualisieren
apt-get update -y
# Node.js installieren
if DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs npm; then
# Version prüfen
local node_version=$(node --version 2>/dev/null || echo "v0.0.0")
local npm_version=$(npm --version 2>/dev/null || echo "0.0.0")
log "INFO" "Node.js installiert: $node_version"
log "INFO" "npm installiert: $npm_version"
return 0
else
log "WARN" "APT Node.js Installation fehlgeschlagen"
return 1
fi
}
install_nodejs_nodesource() {
log "INFO" "Versuche Node.js Installation über NodeSource..."
# NodeSource Setup-Script herunterladen und ausführen
if curl -fsSL https://deb.nodesource.com/setup_18.x | bash -; then
# Node.js installieren
if DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs; then
log "INFO" "Node.js über NodeSource erfolgreich installiert"
return 0
fi
fi
log "WARN" "NodeSource Installation fehlgeschlagen"
return 1
}
install_nodejs_snap() {
log "INFO" "Versuche Node.js Installation über Snap..."
# Snap installieren falls nicht vorhanden
if ! command -v snap >/dev/null 2>&1; then
DEBIAN_FRONTEND=noninteractive apt-get install -y snapd
systemctl enable --now snapd.socket
sleep 5
fi
# Node.js über Snap installieren
if snap install node --classic; then
# Symlinks erstellen
ln -sf /snap/bin/node /usr/local/bin/node
ln -sf /snap/bin/npm /usr/local/bin/npm
log "INFO" "Node.js über Snap erfolgreich installiert"
return 0
fi
log "WARN" "Snap Node.js Installation fehlgeschlagen"
return 1
}
configure_npm() {
log "INFO" "Konfiguriere npm..."
# npm Konfiguration für bessere Performance
npm config set audit-level moderate
npm config set fund false
npm config set update-notifier false
npm config set prefer-offline true
# Cache-Verzeichnis setzen
npm config set cache "/home/$PROJECT_USER/.npm"
# Registry auf https setzen
npm config set registry https://registry.npmjs.org/
# Timeout erhöhen
npm config set timeout 300000
# npm auf neueste Version aktualisieren
log "INFO" "Aktualisiere npm auf neueste Version..."
npm install -g npm@latest || {
log "WARN" "npm-Update hatte Probleme"
}
# Berechtigungen für npm-Cache
chown -R "$PROJECT_USER:$PROJECT_GROUP" "/home/$PROJECT_USER/.npm" 2>/dev/null || true
log "INFO" "npm konfiguriert"
}
install_npm_packages() {
log "INFO" "Installiere npm-Packages..."
# Package.json prüfen
local package_json="$INSTALL_PATH/package.json"
if [[ ! -f "$package_json" ]]; then
log "WARN" "package.json nicht gefunden: $package_json"
log "INFO" "Erstelle minimale package.json..."
create_minimal_package_json
fi
# Wechsle ins Installationsverzeichnis
cd "$INSTALL_PATH"
# npm install ausführen
log "INFO" "Führe npm install aus..."
if npm install --production; then
log "INFO" "npm-Packages erfolgreich installiert"
else
log "WARN" "npm install hatte Probleme, versuche --force..."
if npm install --production --force; then
log "INFO" "npm-Packages mit --force installiert"
else
log "ERROR" "npm install fehlgeschlagen"
return 1
fi
fi
# Package-Liste für Debugging
npm list --depth=0 > npm_packages.txt 2>/dev/null || true
log "INFO" "npm-Packages Installation abgeschlossen"
}
create_minimal_package_json() {
log "INFO" "Erstelle minimale package.json..."
cat > "$INSTALL_PATH/package.json" << 'EOF'
{
"name": "myp-system",
"version": "1.0.0",
"description": "Mercedes-Benz 3D Printer Management System",
"main": "app.py",
"scripts": {
"build:css": "tailwindcss -i static/css/input.css -o static/css/output.css --minify",
"watch:css": "tailwindcss -i static/css/input.css -o static/css/output.css --watch",
"dev": "npm run watch:css",
"build": "npm run build:css"
},
"dependencies": {
"tailwindcss": "^3.3.0",
"@tailwindcss/forms": "^0.5.0",
"@tailwindcss/typography": "^0.5.0",
"autoprefixer": "^10.4.0",
"postcss": "^8.4.0"
},
"keywords": ["3d-printing", "management", "mercedes-benz"],
"author": "Till Tomczak",
"license": "Proprietary"
}
EOF
log "INFO" "Minimale package.json erstellt"
}
build_frontend_assets() {
log "INFO" "Baue Frontend-Assets..."
cd "$INSTALL_PATH"
# Prüfe ob build-Script verfügbar ist
if npm run build --silent 2>/dev/null; then
log "INFO" "Frontend-Assets mit npm run build erstellt"
elif command -v tailwindcss >/dev/null 2>&1; then
log "INFO" "Verwende direkte TailwindCSS-Kommandos..."
build_tailwind_directly
else
log "WARN" "Kein Build-System verfügbar, überspringe Asset-Build"
return 0
fi
# Komprimiere Assets für Produktionsumgebung
compress_assets
log "INFO" "Frontend-Assets Build abgeschlossen"
}
build_tailwind_directly() {
log "INFO" "Baue TailwindCSS direkt..."
# Input-CSS erstellen falls nicht vorhanden
if [[ ! -f "static/css/input.css" ]]; then
mkdir -p "static/css"
cat > "static/css/input.css" << 'EOF'
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Custom MYP Styles */
.btn-primary {
@apply bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors;
}
.card {
@apply bg-white rounded-lg shadow-md p-6;
}
.form-input {
@apply border border-gray-300 rounded px-3 py-2 focus:outline-none focus:border-blue-500;
}
EOF
fi
# TailwindCSS Build
npx tailwindcss -i static/css/input.css -o static/css/output.css --minify || {
log "WARN" "TailwindCSS Build fehlgeschlagen"
}
}
compress_assets() {
log "INFO" "Komprimiere Assets..."
# CSS-Dateien komprimieren
find "$INSTALL_PATH/static/css" -name "*.css" -type f | while read -r css_file; do
if command -v gzip >/dev/null 2>&1; then
gzip -c "$css_file" > "${css_file}.gz"
log "INFO" "Komprimiert: $(basename "$css_file")"
fi
done
# JavaScript-Dateien komprimieren
find "$INSTALL_PATH/static/js" -name "*.js" -type f | while read -r js_file; do
if command -v gzip >/dev/null 2>&1; then
gzip -c "$js_file" > "${js_file}.gz"
log "INFO" "Komprimiert: $(basename "$js_file")"
fi
done
log "INFO" "Asset-Komprimierung abgeschlossen"
}
verify_python_dependencies() {
log "INFO" "Überprüfe Python-Dependencies..."
local errors=0
# Wichtige Packages prüfen
local critical_packages=(
"flask"
"flask-sqlalchemy"
"flask-login"
"flask-wtf"
"werkzeug"
"gunicorn"
)
for package in "${critical_packages[@]}"; do
if ! python3 -c "import $package" 2>/dev/null; then
log "ERROR" "Kritisches Python-Package fehlt: $package"
errors=$((errors + 1))
fi
done
# Erstelle Package-Report
python3 -c "import pkg_resources; print('\n'.join([str(d) for d in pkg_resources.working_set]))" > "$INSTALL_PATH/python_packages_installed.txt"
if [[ $errors -eq 0 ]]; then
log "INFO" "Python-Dependencies Verifikation erfolgreich"
return 0
else
log "ERROR" "Python-Dependencies Verifikation fehlgeschlagen ($errors Fehler)"
return 1
fi
}
verify_node_dependencies() {
log "INFO" "Überprüfe Node.js-Dependencies..."
local errors=0
# Node.js Version prüfen
if ! command -v node >/dev/null 2>&1; then
log "ERROR" "Node.js nicht verfügbar"
errors=$((errors + 1))
else
local node_version=$(node --version)
log "INFO" "Node.js Version: $node_version"
fi
# npm Version prüfen
if ! command -v npm >/dev/null 2>&1; then
log "ERROR" "npm nicht verfügbar"
errors=$((errors + 1))
else
local npm_version=$(npm --version)
log "INFO" "npm Version: $npm_version"
fi
# TailwindCSS prüfen
if ! npx tailwindcss --help >/dev/null 2>&1; then
log "WARN" "TailwindCSS nicht verfügbar"
fi
if [[ $errors -eq 0 ]]; then
log "INFO" "Node.js-Dependencies Verifikation erfolgreich"
return 0
else
log "ERROR" "Node.js-Dependencies Verifikation fehlgeschlagen ($errors Fehler)"
return 1
fi
}