359afb3a59
Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI, control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve). Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
2.7 KiB
Markdown
85 lines
2.7 KiB
Markdown
# Server UI — File Explorer
|
|
|
|
**Data:** 2026-07-05
|
|
**Status:** wdrożone
|
|
|
|
Zakładka **Pliki** w panelu Server UI (`:8091`) — przeglądanie systemu plików, edycja tekstu, pełny CRUD.
|
|
|
|
## UI
|
|
|
|
- Zakładka **Pliki** (druga, po CLI)
|
|
- Hash URL: `http://<host>:8091/#files`
|
|
- Wymaga `X-API-Key` (ten sam co reszta panelu przy bind LAN)
|
|
|
|
## API
|
|
|
|
Wszystkie endpointy: nagłówek `X-API-Key` (gdy `API_KEY` ustawiony i bind LAN).
|
|
|
|
| Metoda | Ścieżka | Opis |
|
|
|--------|---------|------|
|
|
| GET | `/api/files?path=/` | Lista katalogu |
|
|
| GET | `/api/files/read?path=...` | Odczyt pliku (UTF-8 lub base64 dla binarnych) |
|
|
| PUT | `/api/files/write` | `{"path","content"}` — zapis tekstu |
|
|
| POST | `/api/files/mkdir` | `{"path"}` — nowy folder |
|
|
| POST | `/api/files/rename` | `{"old_path","new_path"}` |
|
|
| DELETE | `/api/files?path=...` | Usuń plik lub pusty katalog |
|
|
|
|
### Przykłady curl
|
|
|
|
```bash
|
|
API_KEY=$(sudo grep ^API_KEY= /opt/control-plane/.env | cut -d= -f2)
|
|
|
|
curl -s "http://127.0.0.1:8091/api/files?path=/tmp" \
|
|
-H "X-API-Key: ${API_KEY}"
|
|
|
|
curl -s "http://127.0.0.1:8091/api/files/read?path=/tmp/test.txt" \
|
|
-H "X-API-Key: ${API_KEY}"
|
|
|
|
curl -s -X PUT "http://127.0.0.1:8091/api/files/write" \
|
|
-H "X-API-Key: ${API_KEY}" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"path":"/tmp/test.txt","content":"hello"}'
|
|
```
|
|
|
|
## Konfiguracja
|
|
|
|
W [`/opt/control-plane/.env`](/opt/control-plane/.env) (opcjonalnie):
|
|
|
|
| Zmienna | Domyślnie | Opis |
|
|
|---------|-----------|------|
|
|
| `FILE_EXPLORER_ROOT` | `/` | Korzeń przeglądania |
|
|
| `FILE_EXPLORER_MAX_BYTES` | `2097152` | Limit odczytu/zapisu (2 MiB) |
|
|
|
|
## Uprawnienia POSIX
|
|
|
|
Server UI działa jako użytkownik **`tomasz-syn-grzegorza`** (`server-ui.service`). Explorer **nie omija** uprawnień systemowych:
|
|
|
|
- `/home/...`, repo, `/data/apps/...` — zwykle OK
|
|
- `/opt/control-plane/.env` (root 600) — odmowa w UI
|
|
- pliki root-only — komunikat „Brak uprawnień”
|
|
|
|
## Kod
|
|
|
|
| Plik | Rola |
|
|
|------|------|
|
|
| [`stacks/server-ui/file_explorer.py`](../stacks/server-ui/file_explorer.py) | Logika FS |
|
|
| [`stacks/server-ui/app.py`](../stacks/server-ui/app.py) | Endpointy `/api/files*` |
|
|
| [`stacks/server-ui/static/index.html`](../stacks/server-ui/static/index.html) | Zakładka Pliki |
|
|
|
|
## Bezpieczeństwo
|
|
|
|
- Path traversal: `Path.resolve()` + sprawdzenie względem `FILE_EXPLORER_ROOT`
|
|
- Pliki binarne: podgląd base64, zapis zablokowany (415)
|
|
- Usuwanie: potwierdzenie w UI (`confirm()`)
|
|
- Katalog niepusty: 409 przy DELETE
|
|
|
|
## Deploy
|
|
|
|
```bash
|
|
sudo bash stacks/server-ui/scripts/install.sh
|
|
# lub tylko restart po rsync:
|
|
sudo systemctl restart server-ui
|
|
```
|
|
|
|
Tutorial użytkownika: [`manual-tutorial/09-file-explorer.md`](../manual-tutorial/09-file-explorer.md)
|