Files
zmb-webui/backend
patrick 0504b5b880 Read Samba config from registry instead of smb.conf
Use 'net conf list' to read global config parameters from Samba registry.
This is more reliable than parsing smb.conf, especially when using
'include = registry' in smb.conf.

Co-Authored-By: Patrick <patrick@perlbach24.de>
2026-04-22 01:08:15 +02:00
..

ZMB Webui Backend API

FastAPI backend for ZFS pool, dataset, and snapshot management.

Quick Start (Local Development)

Prerequisites

  • Python 3.11+
  • ZFS tools installed (zpool, zfs)

Setup

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

Server runs on http://localhost:8000

API Endpoints

Authentication

# Login
curl -X POST http://localhost:8000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}'

# Returns: {"access_token":"...", "token_type":"bearer"}

Pools

# 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"

Datasets

# 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"

Snapshots

# List snapshots
curl http://localhost:8000/api/snapshots \
  -H "Authorization: Bearer YOUR_TOKEN"

# Create snapshot
curl -X POST http://localhost:8000/api/snapshots \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"dataset":"tank/share"}'

# Delete snapshot
curl -X DELETE http://localhost:8000/api/snapshots/tank/share@2026-04-14-120000 \
  -H "Authorization: Bearer YOUR_TOKEN"

# 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"}'

File Manager (Browse /tank/share)

# Browse directory
curl "http://localhost:8000/api/files/browse?path=/" \
  -H "Authorization: Bearer YOUR_TOKEN"

# Get file info
curl "http://localhost:8000/api/files/info?path=/document.pdf" \
  -H "Authorization: Bearer YOUR_TOKEN"

# 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:
    sudo systemctl daemon-reload
    sudo systemctl enable zmb-webui-backend
    sudo systemctl start zmb-webui-backend
    

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

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

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

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)