mirror of
https://github.com/azaion/loader.git
synced 2026-04-22 10:26:33 +00:00
Add E2E tests, fix bugs
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Module: main
|
||||
|
||||
## Purpose
|
||||
|
||||
FastAPI application entry point providing HTTP endpoints for health checks, authentication, encrypted resource loading/uploading, and a multi-step Docker image unlock workflow.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### FastAPI Application
|
||||
|
||||
`app = FastAPI(title="Azaion.Loader")`
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Method | Path | Request Body | Response | Description |
|
||||
|--------|------------------|---------------------|----------------------------|----------------------------------------------------|
|
||||
| GET | `/health` | — | `{"status": "healthy"}` | Liveness probe |
|
||||
| GET | `/status` | — | `StatusResponse` | Auth status + model cache dir |
|
||||
| POST | `/login` | `LoginRequest` | `{"status": "ok"}` | Set credentials on API client |
|
||||
| POST | `/load/{filename}`| `LoadRequest` | binary (octet-stream) | Download + decrypt resource |
|
||||
| POST | `/upload/{filename}`| multipart (file + folder) | `{"status": "ok"}` | Encrypt + upload resource (big/small split) |
|
||||
| POST | `/unlock` | `LoginRequest` | `{"state": "..."}` | Start background unlock workflow |
|
||||
| GET | `/unlock/status` | — | `{"state": "...", "error": ...}` | Poll unlock progress |
|
||||
|
||||
### Pydantic Models
|
||||
|
||||
| Model | Fields |
|
||||
|-----------------|----------------------------------------------|
|
||||
| LoginRequest | email: str, password: str |
|
||||
| LoadRequest | filename: str, folder: str |
|
||||
| HealthResponse | status: str |
|
||||
| StatusResponse | status: str, authenticated: bool, modelCacheDir: str |
|
||||
|
||||
### Module-level State
|
||||
|
||||
| Name | Type | Description |
|
||||
|----------------|--------------------|------------------------------------------------|
|
||||
| api_client | ApiClient or None | Lazy-initialized singleton |
|
||||
| unlock_state | UnlockState | Current unlock workflow state |
|
||||
| unlock_error | Optional[str] | Last unlock error message |
|
||||
| unlock_lock | threading.Lock | Thread safety for unlock state mutations |
|
||||
|
||||
## Internal Logic
|
||||
|
||||
### `get_api_client()`
|
||||
Lazy singleton pattern: creates `ApiClient(RESOURCE_API_URL)` on first call.
|
||||
|
||||
### Unlock Workflow (`_run_unlock`)
|
||||
Background task (via FastAPI BackgroundTasks) that runs these steps:
|
||||
1. Check if Docker images already loaded → if yes, set `ready`
|
||||
2. Authenticate with API (login)
|
||||
3. Download key fragment from `/binary-split/key-fragment`
|
||||
4. Decrypt archive at `IMAGES_PATH` → `.tar`
|
||||
5. `docker load` the tar file
|
||||
6. Clean up tar file
|
||||
7. Set state to `ready` (or `error` on failure)
|
||||
|
||||
State transitions are guarded by `unlock_lock` (threading.Lock).
|
||||
|
||||
### `/unlock` Endpoint
|
||||
- If already `ready` → return immediately
|
||||
- If already in progress → return current state
|
||||
- If no encrypted archive found → check if images already loaded; if not, 404
|
||||
- Otherwise, starts `_run_unlock` as a background task
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Internal**: `unlock_state` (UnlockState enum), `api_client` (lazy import), `binary_split` (lazy import)
|
||||
- **External**: `os`, `threading` (stdlib), `fastapi`, `pydantic`
|
||||
|
||||
## Consumers
|
||||
|
||||
None — this is the entry point module.
|
||||
|
||||
## Data Models
|
||||
|
||||
`LoginRequest`, `LoadRequest`, `HealthResponse`, `StatusResponse` (Pydantic models defined inline).
|
||||
|
||||
## Configuration
|
||||
|
||||
| Env Variable | Default | Description |
|
||||
|------------------|--------------------------------|--------------------------------|
|
||||
| RESOURCE_API_URL | `https://api.azaion.com` | Azaion resource API base URL |
|
||||
| IMAGES_PATH | `/opt/azaion/images.enc` | Path to encrypted Docker images |
|
||||
| API_VERSION | `latest` | Expected Docker image version tag |
|
||||
|
||||
## External Integrations
|
||||
|
||||
- **Azaion Resource API**: via `ApiClient` (authenticated resource download/upload)
|
||||
- **Docker CLI**: via `binary_split` (docker load, image inspect)
|
||||
- **File system**: encrypted archive at `IMAGES_PATH`
|
||||
|
||||
## Security
|
||||
|
||||
- Login endpoint returns 401 on auth failure
|
||||
- All resource endpoints use authenticated API client
|
||||
- Unlock state is thread-safe via `threading.Lock`
|
||||
- Lazy imports of Cython modules (`api_client`, `binary_split`) to avoid import-time side effects
|
||||
|
||||
## Tests
|
||||
|
||||
No tests found.
|
||||
Reference in New Issue
Block a user