Référence endpoint santé¶
Repod expose trois endpoints de santé compatibles Kubernetes
(backend/routers/health_router.py). Aucun ne requiert d'authentification.
| Endpoint | Objet | Codes de statut |
|---|---|---|
GET /health |
Rapport de santé complet — chaque sonde, groupée par criticité. | 200 (healthy/degraded), 503 (unhealthy) |
GET /health/live |
Sonde de liveness — le processus tourne. Intentionnellement minimale, aucune E/S ni verrou. | 200 toujours |
GET /health/ready |
Sonde de readiness — le service peut accepter du trafic. | 200 (ready), 503 (une sonde critique a échoué) |
Sémantique des statuts¶
| Statut | Signification | Code HTTP sur /health |
|---|---|---|
healthy |
Chaque sonde critique et non-critique a réussi. | 200 |
degraded |
Toutes les sondes critiques ont réussi ; au moins une sonde non-critique a échoué. | 200 |
unhealthy |
Au moins une sonde critique a échoué. | 503 |
Réponse GET /health¶
{
"status": "healthy | degraded | unhealthy",
"timestamp": "ISO 8601 UTC",
"version": "string (variable d'env APP_VERSION, défaut \"dev\")",
"checks": {
"critical": { "...": "..." },
"non_critical": { "...": "..." },
"info": { "...": "..." }
}
}
checks comporte trois groupes. Chaque résultat de sonde est un objet avec
au moins un champ "ok": bool.
checks.critical¶
Un échec sur l'une de ces quatre sondes fixe status = "unhealthy" et
GET /health / GET /health/ready retournent tous deux 503.
| Champ | Sonde | Forme de la réponse |
|---|---|---|
manifests |
Le répertoire /repos/manifests existe et est accessible. |
{ok, path, free_gb, total_gb, used_pct} |
pool |
Le répertoire /repos/pool existe et est accessible. |
{ok, path, free_gb, total_gb, used_pct} |
auth_db |
SELECT COUNT(*) FROM users réussit sur PostgreSQL. |
{ok, count} ou {ok: false, error} |
manifest_db |
SELECT COUNT(*) FROM manifests réussit sur PostgreSQL. |
{ok, count} ou {ok: false, error} |
GET /health/ready rapporte exactement ces quatre mêmes sondes sous checks,
plus un "ready": bool de premier niveau et, si non prêt, un tableau
"failing": [...] listant les noms des sondes en échec.
checks.non_critical¶
Un échec ici fixe status = "degraded" (jamais unhealthy à lui seul) —
/health retourne quand même 200.
| Champ | Sonde | Forme de la réponse |
|---|---|---|
audit |
Le répertoire /repos/audit existe et est accessible. |
{ok, path, free_gb, total_gb, used_pct} |
clamav |
clamscan --version s'exécute avec succès. |
{ok, version} ou {ok: false, version: null, error} |
reprepro |
Le binaire reprepro --version est dans le PATH. |
{ok: true, version} ou {ok: false, version: null, error} |
gpg |
Au moins une clé privée existe dans le trousseau GPG (GNUPGHOME). |
{ok, fingerprint} ou {ok: false, error} |
scheduler |
APScheduler tourne avec des jobs actifs. | {ok, jobs: [...]} — voir ci-dessous |
alembic |
La table alembic_version est peuplée (non vide alors que les tables applicatives existent déjà). |
{ok, version} ou {ok: false, version: null, error} |
Entrées de job scheduler¶
Chaque entrée dans jobs (quand le scheduler tourne) :
paused vaut true quand next_run_time est null.
Sur une réplique HA passive (voir Variables d'environnement et les sections HA de la documentation d'architecture), aucun scheduler ne tourne du tout — c'est attendu et ne dégrade pas le statut :
Si l'instance courante est le leader et que le scheduler n'a pas réussi à
démarrer, ceci devient {"ok": false, "jobs": [], "error": "scheduler non démarré"}.
checks.info¶
Données informatives en lecture seule. N'affecte jamais status.
| Champ | Objet | Forme de la réponse |
|---|---|---|
packages |
Nombre de fichiers du pool et taille, par format. | voir ci-dessous |
storage |
Utilisation du système de fichiers sur /repos plus une répartition de taille par répertoire. |
voir ci-dessous |
license |
Édition de licence active. | {ok, edition, active, issued_to} |
setup |
Si l'assistant de configuration du premier lancement s'est terminé. | {ok: bool, setup_done: bool} |
ha |
Statut actif-passif HA et backend d'état de job par flux. | voir ci-dessous |
cache_backend |
Backend de cache de réponses actif. | {ok: true, backend: "memory" \| "redis"} |
packages¶
{
"ok": true,
"total_manifests": 0,
"pool_files": 0,
"pool_size_mb": 0.0,
"by_format": {"deb": 0, "rpm": 0, "apk": 0}
}
storage¶
{
"ok": true,
"free_gb": 0.0,
"total_gb": 0.0,
"used_pct": 0.0,
"dirs": {
"pool": {"path": "/repos/pool", "size_mb": 0.0},
"manifests": {"path": "/repos/manifests", "size_mb": 0.0},
"audit": {"path": "/repos/audit", "size_mb": 0.0},
"grype_db": {"path": "/repos/grype-db", "size_mb": 0.0},
"clamav_db": {"path": "/var/lib/clamav", "size_mb": 0.0}
}
}
size_mb vaut null quand le répertoire n'existe pas.
ha¶
{
"ok": true,
"is_leader": "bool",
"instance_id": "string",
"scheduler_active": "bool",
"job_state_backend": {
"scan": "redis | local",
"install": "redis | local",
"mirror": "redis | local",
"sync": "redis | local",
"sse": "redis | local",
"logs": "redis | local"
}
}
is_leader— si cette instance détient le verrou consultatif ("advisory lock") PostgreSQL (services/leader_election.py). Seul le leader exécute les jobs cron APScheduler.job_state_backend.{scan,install,mirror,sync}—"redis"signifie que l'état de ce flux est réellement distribué entre les répliques en ce moment même (doncrequire_leader_for(flow)devient un no-op pour lui) ;"local"signifie le comportement historique mono-processus, soit par configuration par défaut, soit comme repli fail-soft (JOB_STATE_BACKEND=redisconfiguré mais Redis injoignable au démarrage) — les deux cas sont indiscernables à partir de ce seul champ, par conception.job_state_backend.sse/.logs—"redis"signifie que les événements live (GET /dashboard/events) ou les entrées de log (GET /logs,GET /logs/stream) sont diffusés à travers toutes les répliques via Redis pub/sub ;"local"signifie une livraison mono-réplique uniquement. Nissenilogsn'ont de verrourequire_leader—"local"signifie ici « diffusion mono-réplique uniquement », pas « réplique bloquée ».
cache_backend¶
ou, en cas d'erreur de résolution du module de cache :
Réponse GET /health/live¶
Toujours 200. Aucune E/S, aucun accès base de données — confirme
uniquement que le processus FastAPI tourne.
Réponse GET /health/ready¶
{
"ready": "bool",
"timestamp": "ISO 8601 UTC",
"checks": {
"manifests": {"ok": "bool", "...": "..."},
"pool": {"ok": "bool", "...": "..."},
"auth_db": {"ok": "bool", "...": "..."},
"manifest_db": {"ok": "bool", "...": "..."}
},
"failing": ["présent uniquement quand ready vaut false — liste des noms de sondes en échec"]
}