From 8dc4e8d698ae1b52ba8e319b36754760cbcf6792 Mon Sep 17 00:00:00 2001 From: Patrick Date: Fri, 5 Jun 2026 19:40:15 +0200 Subject: [PATCH] Docs: backend/README.md neu geschrieben (PAM-Auth, aktuelle Endpunkte) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit auth_service-Referenzen entfernt, Cookie-basierte Auth dokumentiert, Endpunkt-Tabellen für alle Router ergänzt. Co-Authored-By: Claude Sonnet 4.6 --- backend/README.md | 262 +++++++++++++--------------------------------- 1 file changed, 71 insertions(+), 191 deletions(-) diff --git a/backend/README.md b/backend/README.md index 42f4391..c381797 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,227 +1,107 @@ -# ZMB Webui Backend API +# ZMB Webui — Backend -FastAPI backend for ZFS pool, dataset, and snapshot management. +FastAPI-Backend für ZFS-, Samba- und NFS-Verwaltung. Läuft als root (PAM-Auth benötigt `/etc/shadow`). -## Quick Start (Local Development) - -### Prerequisites -- Python 3.11+ -- ZFS tools installed (`zpool`, `zfs`) - -### Setup +## Lokale Entwicklung ```bash cd backend - -# Create virtual environment python3 -m venv venv source venv/bin/activate - -# Install dependencies pip install -r requirements.txt -# Create default admin user (password: admin) -python3 -c "from services.auth import auth_service; auth_service.add_user('admin', 'admin')" - -# Run development server python3 main.py +# → http://localhost:8000 +# → http://localhost:8000/docs (API-Docs) ``` -Server runs on `http://localhost:8000` +Login mit jedem Linux-Systembenutzer der eine Login-Shell hat. -## API Endpoints +## API-Endpunkte + +Auth-Cookie wird beim Login automatisch gesetzt (`httpOnly`). Für curl-Tests: -### Authentication ```bash -# Login -curl -X POST http://localhost:8000/api/auth/login \ +# Login — setzt Cookie +curl -c cookies.txt -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ - -d '{"username":"admin","password":"admin"}' + -d '{"username":"user","password":"pass"}' -# Returns: {"access_token":"...", "token_type":"bearer"} +# Alle weiteren Requests mit Cookie +curl -b cookies.txt http://localhost:8000/api/pools/ ``` ### Pools -```bash -# List pools (requires auth) -curl http://localhost:8000/api/pools \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Get pool status -curl http://localhost:8000/api/pools/tank \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Start scrub -curl -X POST http://localhost:8000/api/pools/tank/scrub \ - -H "Authorization: Bearer YOUR_TOKEN" -``` +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/pools/` | Alle Pools auflisten | +| GET | `/api/pools/{name}` | Pool-Status | +| POST | `/api/pools/{name}/scrub` | Scrub starten | +| POST | `/api/pools/{name}/scrub/stop` | Scrub stoppen | ### Datasets -```bash -# List datasets -curl http://localhost:8000/api/datasets \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Create dataset -curl -X POST http://localhost:8000/api/datasets \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"name":"tank/backup","properties":{"compression":"lz4"}}' - -# Delete dataset -curl -X DELETE http://localhost:8000/api/datasets/tank/test \ - -H "Authorization: Bearer YOUR_TOKEN" -``` +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/datasets/` | Alle Datasets | +| POST | `/api/datasets/` | Dataset erstellen | +| DELETE | `/api/datasets/{name}` | Dataset löschen | ### Snapshots -```bash -# List snapshots -curl http://localhost:8000/api/snapshots \ - -H "Authorization: Bearer YOUR_TOKEN" +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/snapshots/` | Alle Snapshots | +| POST | `/api/snapshots/` | Snapshot erstellen | +| DELETE | `/api/snapshots/{name}` | Snapshot löschen | +| POST | `/api/snapshots/rollback` | Rollback | -# Create snapshot -curl -X POST http://localhost:8000/api/snapshots \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"dataset":"tank/share"}' +### Shares +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/shares/samba` | Samba-Shares auflisten | +| POST | `/api/shares/samba` | Share erstellen | +| DELETE | `/api/shares/samba/{name}` | Share löschen | +| GET | `/api/shares/nfs` | NFS-Exports auflisten | +| POST | `/api/shares/nfs` | Export erstellen | +| DELETE | `/api/shares/nfs/{path}` | Export löschen | +| GET | `/api/shares/samba/config` | Samba Global-Config | +| POST | `/api/shares/samba/config` | Parameter setzen | +| DELETE | `/api/shares/samba/config/{key}` | Parameter löschen | -# Delete snapshot -curl -X DELETE http://localhost:8000/api/snapshots/tank/share@2026-04-14-120000 \ - -H "Authorization: Bearer YOUR_TOKEN" +### System +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/system/info` | CPU, RAM, Disk | +| GET | `/api/system/logs` | Systemlogs | -# Rollback snapshot -curl -X POST http://localhost:8000/api/snapshots/rollback \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"snapshot":"tank/share@2026-04-14-120000"}' -``` +### Identities +| Methode | Pfad | Beschreibung | +|---------|------|--------------| +| GET | `/api/identities/users` | Systembenutzer auflisten | +| POST | `/api/identities/users` | Benutzer anlegen | +| DELETE | `/api/identities/users/{name}` | Benutzer löschen | +| GET | `/api/identities/groups` | Gruppen auflisten | -### File Manager (Browse /tank/share) -```bash -# Browse directory -curl "http://localhost:8000/api/files/browse?path=/" \ - -H "Authorization: Bearer YOUR_TOKEN" +## Caching -# Get file info -curl "http://localhost:8000/api/files/info?path=/document.pdf" \ - -H "Authorization: Bearer YOUR_TOKEN" +ZFS-Befehle sind mit TTL gecacht: +- Pools: 30s +- Datasets/Snapshots: 60s -# Read text file (< 10MB) -curl "http://localhost:8000/api/files/read?path=/config.json&limit=1000" \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Download file -curl "http://localhost:8000/api/files/download?path=/archive.tar.gz" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -O - -# Upload file -curl -X POST "http://localhost:8000/api/files/upload?path=/" \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -F "file=@/local/path/file.txt" - -# Create directory -curl -X POST http://localhost:8000/api/files/mkdir \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"path":"/new_folder"}' - -# Create file -curl -X POST http://localhost:8000/api/files/create \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"path":"/notes.txt","content":"Hello World"}' - -# Rename file -curl -X POST http://localhost:8000/api/files/rename \ - -H "Authorization: Bearer YOUR_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"old_path":"/oldname.txt","new_name":"newname.txt"}' - -# Delete file -curl -X DELETE "http://localhost:8000/api/files/delete?path=/file.txt" \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Delete directory (recursive) -curl -X DELETE "http://localhost:8000/api/files/delete?path=/folder&recursive=true" \ - -H "Authorization: Bearer YOUR_TOKEN" - -# Get space usage -curl http://localhost:8000/api/files/space \ - -H "Authorization: Bearer YOUR_TOKEN" -``` - -## Architecture - -### Services -- **zfs_runner.py**: Subprocess wrapper for ZFS commands with caching -- **auth.py**: JWT token generation and verification - -### Routers -- **auth.py**: Login endpoint -- **pools.py**: Pool list, status, scrub operations -- **datasets.py**: Dataset CRUD operations -- **snapshots.py**: Snapshot CRUD, rollback - -### Models -- **pool.py**: Pool, PoolStatus, PoolHealth -- **dataset.py**: Dataset, DatasetType -- **snapshot.py**: Snapshot -- **auth.py**: User, Token, TokenData - -## Caching Strategy - -- Pool status: 30s TTL -- Snapshots: 60s TTL -- Datasets: 60s TTL - -Cache is cleared on mutations (create/delete operations). - -## Performance Notes - -### For 4GB RAM Raspberry Pi: -- gunicorn: 2 workers -- Memory limit: 512M soft / 768M hard -- Connection timeout: 30s -- Max requests per worker: 500 (recycle to prevent memory leaks) - -### Optimizations: -- ZFS queries limited to max depth 2 -- Snapshots limited to 50 by default (can be increased with `?limit=N`) -- Subprocess timeout: 5s -- In-memory TTL cache (no Redis required) - -## Production Deployment - -1. Copy backend to `/opt/zmb-webui/backend` -2. Install systemd service: `sudo cp deploy/zmb-webui-backend.service /etc/systemd/system/` -3. Update users: `python3 -c "from services.auth import auth_service; auth_service.add_user('yourusername', 'strongpassword')"` -4. Start service: - ```bash - sudo systemctl daemon-reload - sudo systemctl enable zmb-webui-backend - sudo systemctl start zmb-webui-backend - ``` +Mutationen (erstellen/löschen) löschen den Cache sofort. ## Troubleshooting -### ZFS commands not working -- Check: `zpool list` runs without errors -- Check: Running as root or with proper sudo permissions -- Check: ZFS kernel module is loaded: `lsmod | grep zfs` +```bash +# Logs live +journalctl -u zmb-webui-backend -f -### Memory usage growing -- Check: `ps aux | grep uvicorn` for VSZ/RSS -- Restart service: `systemctl restart zmb-webui-backend` -- Increase frequency of restarts in crontab if needed +# Manuell starten (für Fehlerausgabe direkt im Terminal) +cd backend && source venv/bin/activate +python3 main.py -### Slow responses -- Check: `zpool status` output (large pool = slow scrub) -- Clear cache: `curl -X POST /api/pools/clear-cache` (with auth) -- Consider increasing cache TTLs in `zfs_runner.py` +# ZFS prüfen +zpool list -## Development Tips - -- Use `curl` or Postman for API testing -- Check logs: `journalctl -u zmb-webui-backend -f` -- Interactive API docs: `http://localhost:8000/docs` (after running) +# Samba Registry prüfen +net conf list +```