first commit
This commit is contained in:
34
docs/architecture.md
Normal file
34
docs/architecture.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Backend Architecture (MVP)
|
||||
|
||||
## Stack
|
||||
|
||||
- FastAPI
|
||||
- PostgreSQL + asyncpg
|
||||
- Celery + Redis
|
||||
- Jinja2 + HTMX-ready templates
|
||||
|
||||
## Execution flow
|
||||
|
||||
1. API receives a launch request and creates a job (`queued`).
|
||||
2. API starts an ephemeral runner runtime (`docker` container or `k8s` pod/service) with mini FastAPI service.
|
||||
3. API sends run payload directly to runner over HTTP (`/runs/*` endpoints).
|
||||
4. Runner executes `ansible-playbook` or `molecule test`.
|
||||
5. Main API monitors runner status with heartbeat/timeout and persists logs/status to DB.
|
||||
6. WebSocket clients subscribe to `/ws/jobs/{job_id}` and `/ws/tests/{test_id}`; API proxies realtime logs from runner WS.
|
||||
|
||||
## Test runs (Molecule)
|
||||
|
||||
- Test launch endpoint supports playbook tests and role tests.
|
||||
- Runtime creates dynamic ephemeral inventory based on requested host blueprint.
|
||||
- Each test run is isolated in its own dynamic runner runtime.
|
||||
|
||||
## Security
|
||||
|
||||
- JWT access token + refresh token
|
||||
- Password hash via `passlib`
|
||||
- Password reset token flow
|
||||
|
||||
## Runtime modes
|
||||
|
||||
- `docker`: runner starts as ephemeral container over Docker socket.
|
||||
- `k8s`: runner starts as ephemeral pod + ClusterIP service in configured namespace.
|
||||
74
docs/runbook.md
Normal file
74
docs/runbook.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Runbook
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker
|
||||
- Docker Compose plugin
|
||||
- GNU Make
|
||||
|
||||
No Python/Ansible/PostgreSQL/Redis installation is required on host machine.
|
||||
|
||||
## Start
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
make up
|
||||
```
|
||||
|
||||
## Stop
|
||||
|
||||
```bash
|
||||
make down
|
||||
```
|
||||
|
||||
## Logs
|
||||
|
||||
```bash
|
||||
make logs
|
||||
```
|
||||
|
||||
## Useful container shells
|
||||
|
||||
```bash
|
||||
make api-shell
|
||||
make db-shell
|
||||
```
|
||||
|
||||
## Dynamic workers
|
||||
|
||||
- There is no static `worker` service in `docker-compose.yml`.
|
||||
- When a job or test is launched, API starts an ephemeral runner runtime.
|
||||
- Each runner contains a mini FastAPI service (`app/runner/main.py`) for direct HTTP/WS communication.
|
||||
- `docker` mode: API requires Docker socket access (`/var/run/docker.sock`).
|
||||
- `k8s` mode: API requires Kubernetes API access and RBAC rights to create Pod/Service in `APP_K8S_NAMESPACE`.
|
||||
|
||||
## Selecting runtime mode
|
||||
|
||||
- Jobs: `POST /api/v1/jobs/launch` with `runtime_mode` (`docker` or `k8s`).
|
||||
- Tests: `POST /api/v1/tests/launch` with `runtime_mode` (`docker` or `k8s`).
|
||||
|
||||
## Runner lifecycle safety
|
||||
|
||||
- Runner is auto-stopped by API when run reaches terminal state.
|
||||
- Heartbeat is updated while API can poll runner status.
|
||||
- Timeout and fail-safe cleanup are controlled by:
|
||||
- `APP_RUNNER_POLL_INTERVAL_SEC`
|
||||
- `APP_RUNNER_TIMEOUT_SEC`
|
||||
- `APP_RUNNER_MAX_POLL_ERRORS`
|
||||
- Active runner list endpoint: `GET /api/v1/runners/active`.
|
||||
- Manual runner stop endpoint: `POST /api/v1/runners/{runner_name}/stop` with body `{ "runtime_mode": "docker" | "k8s" }`.
|
||||
|
||||
## Realtime test logs
|
||||
|
||||
- Launch test via `POST /api/v1/tests/launch`.
|
||||
- Follow logs via WebSocket endpoint `/ws/tests/{test_id}`.
|
||||
|
||||
## Database bootstrap
|
||||
|
||||
Schema bootstrap SQL file is stored in `app/sql/001_init.sql` and is mounted to PostgreSQL init directory by `docker-compose.yml`.
|
||||
|
||||
To apply it manually:
|
||||
|
||||
```bash
|
||||
make migrate
|
||||
```
|
||||
Reference in New Issue
Block a user