ZMB Webui: Complete Project – Rebrand & Initial Clean Commit

ARCHITECTURE
============
Backend: FastAPI + uvicorn (port 8000)
  - JWT authentication with PAM system users
  - ZFS CLI wrapper with caching (30-60s TTL)
  - WebSocket pool status broadcaster (30s interval)
  - Services: auth, zfs_runner, file_manager, shares, identities, system_info
  - Routers: pools, datasets, snapshots, shares, identities, navigator, system

Frontend: Next.js 15 + TypeScript (static export)
  - Incremental Static Regeneration (ISR) for weak hardware
  - Type-safe API client (lib/api.ts)
  - Dark mode + custom Tailwind theme
  - Pages: Dashboard, Login, Snapshots, Datasets, Shares, etc.

DEPLOYMENT
==========
Test Target: 192.168.1.179:8090 (Debian LXC)
Production: 10.66.120.3:9090 (Raspberry Pi 4GB ARM64)
Updater: Automated Gitea-based deployment (update-test.sh, update-pi.sh)

FEATURES COMPLETED
==================
Phase 3a: Dashboard Quick Stats (System, CPU, Memory, Storage)
  - Real-time stats with color-coded progress bars
  - Responsive grid layout (mobile: 1, tablet: 2, desktop: 4 columns)
  - ISR-optimized for fast loads on weak hardware

REBRANDING
==========
Renamed throughout:
  - Project: 'ZFS Manager' → 'ZMB Webui'
  - Services: 'zfs-manager' → 'zmb-webui'
  - Systemd units: zfs-manager-backend → zmb-webui-backend
  - Configuration files and documentation

Co-Authored-By: Patrick <patrick@perlbach24.de>
This commit is contained in:
Claude Code
2026-04-22 00:26:23 +02:00
committed by Patrick
commit 92bed208e0
108 changed files with 29925 additions and 0 deletions
+197
View File
@@ -0,0 +1,197 @@
#!/bin/bash
# ZMB Webui Updater Lädt vom Gitea, baut neu und deployt
# Unterstützt: update-179 (Test) und update-pi (Produktion)
set -e
GITEA_URL="https://gitea.perlbach24.de/scripte/zmb-webui.git"
BRANCH="${1:-master}"
TARGET="${2:-179}" # 179 oder pi
# Farben für Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}${NC} $1"; }
log_warn() { echo -e "${YELLOW}${NC} $1"; }
log_error() { echo -e "${RED}${NC} $1"; }
# Target validieren
if [[ ! "$TARGET" =~ ^(179|pi)$ ]]; then
log_error "Invalid target. Use: 179 (test) or pi (production)"
exit 1
fi
# Deploy-Parameter basierend auf Target
if [ "$TARGET" = "179" ]; then
REMOTE_HOST="192.168.1.179"
BACKEND_PORT="8000"
FRONTEND_PORT="8090"
BACKEND_PATH="/opt/zmb-webui/backend"
FRONTEND_PATH="/opt/zmb-webui/frontend"
else
REMOTE_HOST="10.66.120.3"
BACKEND_PORT="8000"
FRONTEND_PORT="9090"
BACKEND_PATH="/opt/zmb-webui/backend"
FRONTEND_PATH="/opt/zmb-webui/frontend"
fi
echo ""
echo "═══════════════════════════════════════════════════════"
echo " ZMB Webui Updater Target: $TARGET ($REMOTE_HOST)"
echo "═══════════════════════════════════════════════════════"
echo ""
# 1. Gitea Pull
echo "📥 Pulling from Gitea ($BRANCH)..."
git fetch origin "$BRANCH" || {
log_error "Git fetch failed. Token valid?"
exit 1
}
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/$BRANCH)" ]; then
git pull origin "$BRANCH" || {
log_error "Git pull failed"
exit 1
}
log_info "Repository updated"
else
log_warn "Already up to date"
fi
# 2. Frontend Build
echo ""
echo "🔨 Building frontend..."
cd frontend
rm -rf .next out 2>/dev/null || true
if ! npm run build > /tmp/npm-build.log 2>&1; then
log_error "Frontend build failed"
cat /tmp/npm-build.log | tail -20
exit 1
fi
# next.config.js has output: 'export', so build creates ./out automatically
if [ ! -d "out" ]; then
log_error "Frontend export failed (out/ directory not created)"
exit 1
fi
log_info "Frontend built and exported to ./out"
cd ..
# 3. Backend Files
echo ""
echo "📦 Preparing backend files..."
BACKEND_FILES=(
"main.py"
"requirements.txt"
"services/auth.py"
"services/zfs_runner.py"
"services/file_manager.py"
"services/identities.py"
"services/shares.py"
"services/system_info.py"
"services/system_users.py"
"routers/auth.py"
"routers/pools.py"
"routers/datasets.py"
"routers/snapshots.py"
"routers/shares.py"
"routers/identities.py"
"routers/navigator.py"
"routers/system.py"
"models/auth.py"
"models/pool.py"
"models/dataset.py"
"models/snapshot.py"
)
# 4. Sync zu Remote
echo ""
echo "🚀 Deploying to $REMOTE_HOST..."
# SSH Connection test
if ! ssh -o ConnectTimeout=5 root@"$REMOTE_HOST" "echo 'SSH OK'" > /dev/null 2>&1; then
log_error "Cannot connect to $REMOTE_HOST via SSH"
exit 1
fi
# Backend sync
log_info "Syncing backend files..."
for file in "${BACKEND_FILES[@]}"; do
src="backend/$file"
dst_dir="${BACKEND_PATH}/${file%/*}"
# Only sync if file exists
if [ -f "$src" ]; then
ssh root@"$REMOTE_HOST" "mkdir -p $dst_dir" 2>/dev/null || true
scp -q "$src" "root@$REMOTE_HOST:$dst_dir/" 2>/dev/null || {
log_warn "Could not sync $file"
}
fi
done
# Frontend sync
log_info "Syncing frontend..."
rsync -q -r --delete frontend/out/ "root@$REMOTE_HOST:$FRONTEND_PATH/" || {
log_error "Frontend rsync failed"
exit 1
}
# 5. Services Restart
echo ""
echo "🔄 Restarting services..."
ssh root@"$REMOTE_HOST" "systemctl restart zmb-webui-backend 2>/dev/null || true; sleep 2; systemctl restart nginx 2>/dev/null || true; sleep 1" || {
log_error "Service restart failed"
exit 1
}
log_info "Backend restarted"
log_info "Nginx restarted"
# 6. Health Check
echo ""
echo "🏥 Health check..."
BACKEND_UP=false
FRONTEND_UP=false
# Backend check (max 10 Sekunden)
for i in {1..10}; do
if ssh root@"$REMOTE_HOST" "curl -s http://localhost:$BACKEND_PORT/health >/dev/null 2>&1" 2>/dev/null; then
BACKEND_UP=true
log_info "Backend responding"
break
fi
sleep 1
done
# Frontend check
if ssh root@"$REMOTE_HOST" "curl -s http://localhost:$FRONTEND_PORT/ | grep -q '<html'" 2>/dev/null; then
FRONTEND_UP=true
log_info "Frontend responding"
else
log_warn "Frontend health check incomplete (may still be syncing)"
fi
# 7. Summary
echo ""
echo "═══════════════════════════════════════════════════════"
if [ "$BACKEND_UP" = true ]; then
echo -e "${GREEN}✅ Update complete!${NC}"
echo ""
echo " Backend: http://$REMOTE_HOST:$BACKEND_PORT"
echo " Frontend: http://$REMOTE_HOST:$FRONTEND_PORT"
echo " Branch: $BRANCH"
echo ""
else
echo -e "${YELLOW}⚠ Update deployed but backend not responding yet${NC}"
echo " Check: ssh root@$REMOTE_HOST journalctl -u zmb-webui-backend -f"
fi
echo "═══════════════════════════════════════════════════════"
echo ""