Files
kodi fba9b59445 docs: update documentatie voor app_volumes en tabs tree view
- CLAUDE.md: app_volumes.py in module-tabel, frontend tabs lijst, py_compile en smoke tests
- ARCHITECTURE.md: app_volumes.py in feature routers, py_compile en smoke tests
- API_GOLDEN.md: volumes endpoints gedocumenteerd (GET/POST/DELETE/prune/exists)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 18:26:08 +01:00

126 lines
5.5 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
podman-mvp is a Portainer-like web dashboard for managing rootless user-session Podman containers. It runs as a two-container Podman pod: a FastAPI backend (`mvp-backend`) that talks to Podman over a Unix socket, and a static Apache frontend (`mvp-webui`) that reverse-proxies `/api/` to the backend.
## Architecture
### Backend — FastAPI modular monolith (`control/`)
| File | Role |
|---|---|
| `app.py` | Bootstrap only — creates FastAPI app, wires routers, no feature logic |
| `common.py` | Shared helpers: Podman HTTP, systemctl, utilities |
| `app_system.py` | System/platform router: `/health`, `/daemon-reload`, systemctl unit actions |
| `app_containers.py` | Containers router: dashboard, inspect, logs, stats stream, exec sessions |
| `app_pods.py` | Pods router: dashboard, pod actions |
| `app_networks.py` | Networks router |
| `app_images.py` | Images router |
| `app_volumes.py` | Volumes router: list, create, delete, prune, exists |
| `app_files.py` | Files/workloads router: tree, read, save |
Backend communicates with Podman through the Unix socket at `/run/user/1000/podman/podman.sock` using `requests_unixsocket`. Podman API base: `http+unix://%2Frun%2Frun%2Fuser%2F1000%2Fpodman%2Fpodman.sock/v5.4.2`.
### Frontend — Static Apache (`webui/`)
- `webui/html/index.html` — single-page app shell
- `webui/html/assets/js/tabs/` — per-tab JavaScript modules (containers, networks, images, volumes, files)
- `webui/conf/httpd.conf` — Apache config, proxies `/api/``http://127.0.0.1:8000/api/`
## Build & Deploy
```bash
# Build backend image
podman build -t mvp-control:latest control/
# Create pod
podman pod create --name mvp-pod -p 8080:8000 -p 8081:8081 --userns=keep-id
# Run backend
podman run -d --pod mvp-pod --name mvp-backend \
--ipc=host --pid=host \
-e XDG_RUNTIME_DIR=/run/user/1000 \
-v /run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock:rw \
-v /run/user/1000/podman-mvp:/run/podman-mvp \
-v /home/kodi/.config/containers:/app/workloads:rw \
mvp-control:latest
# Run frontend
podman run -d --pod mvp-pod --name mvp-webui \
-v $HOME/.config/podman-mvp/webui/html:/usr/local/apache2/htdocs:ro \
-v $HOME/.config/podman-mvp/webui/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro \
docker.io/library/httpd:2.4
```
## Verification Commands
```bash
# Syntax check all backend modules
python3 -m py_compile control/app.py control/common.py control/app_system.py \
control/app_containers.py control/app_pods.py control/app_networks.py \
control/app_files.py control/app_images.py control/app_volumes.py
# Smoke test key endpoints (all via proxy on :8081)
curl -fsS http://127.0.0.1:8081/api/health | jq
curl -fsS http://127.0.0.1:8081/api/containers-dashboard >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/pods-dashboard >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/files/tree >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/volumes >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/networks/meta | jq
```
All test/verification URLs must target `127.0.0.1:8081` (the proxy), not port 8000 directly.
## Health Check (`/api/health`)
`GET /api/health` geeft drie deelresultaten terug:
| Veld | Wat het meet | Techniek |
|---|---|---|
| `podman.ok` | Podman API bereikbaar | HTTP GET `/libpod/info` op Unix socket |
| `helper.ok` | podman-helper socket bereikbaar | TCP connect op `/run/podman-mvp/podman-helper.sock` |
| `systemd_user.reachable` | Afgeleid van `helper.ok` | Identiek — helper draait als host-user en voert `systemctl --user` uit, dus bereikbaarheid van helper impliceert bereikbaarheid van systemd |
`ok` (toplevel) is `true` als én `podman.ok` én `helper.ok` waar zijn.
De container voert zelf **geen** `systemctl --user` of D-Bus aanroepen uit. Alle systemctl-acties (start/stop/restart/daemon-reload) gaan via de helper-socket. D-Bus en `/run/user/1000/bus` zijn niet gemount.
## Hard Rules
### Module placement
- `app.py` is bootstrap-only — no endpoints, no feature logic, no Podman/systemctl calls.
- New system/platform endpoints → `app_system.py`.
- New domain feature endpoints → the corresponding `app_<domain>.py`.
- Shared helpers → `common.py`, never duplicated into routers.
- `allow_list` / `allowed_units.txt` has been removed and must NOT be reintroduced.
- `app_system.py` broad wildcard routes (`/{action}/{unit}`) must be defined **last**.
### API contract (`contracts/API_GOLDEN.md`)
- Never remove or rename existing JSON response keys.
- Never change existing key data types.
- Extend via new optional fields or new endpoints only.
- UI-critical endpoints requiring pre-approval before any change: `/containers-dashboard`, `/pods-dashboard`, `/images`, `/networks/meta`.
### Security
- No `shell=True` in subprocess calls.
- All subprocess commands must be explicit lists.
### Infrastructure (propose before changing)
- Pod name, port mappings, `userns=keep-id`.
- DBus/XDG_RUNTIME_DIR mounts, Podman socket path, host PID/IPC namespaces.
- `control/Containerfile`, `webui/conf/httpd.conf`.
## Change Workflow
For non-trivial changes, follow PR_RULES.md:
1. Analyse existing behaviour with curl.
2. Propose minimal plan identifying affected files.
3. Confirm API contract safety.
4. Provide curl validation commands showing expected output change.
5. Implement after agreement.
Minimize diff size. Do not reformat unrelated code. No large rewrites or hidden refactors.