Local Models Yönetim
Yerel model atamalarını (cp_cluster_assignments) yönetmek için kullanılan admin API'leri. Operatör UI'sının (/cluster/assignments) altında bu uç noktalar çalışır — ama doğrudan curl / SDK ile de erişilebilir.
Tüm uç noktalar admin yetkisi gerektirir (Authorization: Bearer <ADMIN_KEY> ya da JWT). Yazma işlemleri (POST/PUT/DELETE) viewer rolünü reddeder.
Temel kavramlar
| Kavram | Anlamı |
|---|---|
| Assignment | (channel_id, model_name, node_id, gpu_index, runtime_key) beşlisi. Hangi modelin hangi sunucuda çalışacağını planlar. |
| Runtime | cp_cluster_runtimes kaydı (örn. vllm, blab-tts). requires_gpu ve default_vram_gb tier + öneri davranışı. |
| Node | cp_cluster_nodes kaydı. agent_endpoint ile qevron-agent çalıştırır; SSH veya agent collector ile telemetriyi qevron'a iletir. |
| Deploy | Atamayı node'a fiilen kurmak (systemd unit yaz + enable). |
| Move | Atamayı bir node'dan diğerine aktarmak (5-step atomik akış). |
Move — atama taşıma
Atomik 5 adım: deploy_target → wait_target_health → stop_source → undeploy_source → update_assignment. Adım 3/4 başarısız olursa target rollback edilir, source (varsa) eski durumuna döndürülür. Adım 5 (DB write) başarısız olursa target temizlenir.
curl -X POST https://app.qevron.ai/api/cluster/assignments/42/move \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"target_node_id": 2,
"target_gpu_index": 0,
"target_channel_id": 7,
"start_after_move": true
}'İstek alanları
| Alan | Tip | Açıklama |
|---|---|---|
target_node_id | int | Zorunlu. Hedef sunucu ID'si. Kaynakla aynı olamaz. |
target_gpu_index | int? | Opsiyonel. Belirsizse kaynak GPU index'i korunur. |
start_after_move | bool? | Opsiyonel (default true). false → hedefin active=active olmasını beklemez. |
target_channel_id | int? | Opsiyonel. Kanal değiştirme (promote/rebind). Yoksa kanal korunur. |
Validasyon hataları (taşıma öncesi)
| HTTP | data.reason | Açıklama |
|---|---|---|
| 400 | — | Target source ile aynı / target node yok |
| 422 | over_subscribed_target | Target GPU'nun VRAM toplamı aşıyor (data.target_gpu_index döner) |
| 422 | tier_mismatch | Runtime requires_gpu=true ama target node'da GPU yok (data.target_gpus: 0) |
| 400 | channel_not_found | target_channel_id mevcut değil |
| 400 | channel_disabled | Target kanal disabled durumda |
| 422 | channel_model_drift | Target kanal models[] array'i assignment.model_name'i içermiyor (data.target_channel_models döner) |
Yanıt — final_state enum'u
| Değer | Anlamı |
|---|---|
moved | Beş adım da temiz. Bağlama güncellendi. |
failed | Adım 1 veya 2 fail. Source dokunulmadı. |
failed_rolled_back | Adım 3 fail veya adım 5 DB write fail; target temiz şekilde geri alındı. |
failed_rolled_back_source_restarted | Adım 4 fail; target geri alındı, source önceden aktifse yeniden başlatıldı. |
failed_rollback_dirty | Bir adım fail VE rollback da fail. İki sunucuda manuel inceleme gerekir. |
Yanıt gövdesi steps[] array'i ile her adımın ok + ms + active (varsa) detayını da içerir.
Bulk Move — birden çok atamayı taşıma
Aynı target node'a birden fazla atamayı tek istekle taşıma. Backend sıralı çalıştırır — bir başarısız id diğerlerini iptal etmez.
curl -X POST https://app.qevron.ai/api/cluster/assignments/bulk-move \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"assignment_ids": [42, 43, 44],
"target_node_id": 2,
"target_gpu_index": 0,
"start_after_move": false
}'Yanıt:
{
"data": {
"total": 3,
"moved_count": 2,
"failed_count": 1,
"items": [
{ "id": 42, "ok": true, "response": { "final_state": "moved", "from_node": "SRV-1", "to_node": "SRV-2", "steps": [...] } },
{ "id": 43, "ok": false, "response": { "final_state": "failed_rolled_back", ... } },
{ "id": 44, "ok": false, "error": { "status": 422, "message": "blab-tts requires a GPU; SRV-3 has none", "details": { "reason": "tier_mismatch", ... } } }
]
},
"success": true
}Limit: assignment_ids 1–50 arası.
Control — start / stop / restart
Bir atamanın systemd unit'ini yönet.
curl -X POST "https://app.qevron.ai/api/cluster/assignments/42/control?action=restart" \
-H "Authorization: Bearer $ADMIN_KEY"action ∈ {start, stop, restart}. Atama deploy edilmemişse pre-flight 422 döner:
{
"success": false,
"message": "solab-stt is not deployed on SRV-4. Click Deploy first.",
"data": {
"action": "stop",
"unit": "solab-stt",
"node": "SRV-4",
"reason": "unit_not_deployed"
}
}Deploy / Undeploy
Runtime'ı node'a fiilen kur (systemd unit yaz + enable + opsiyonel start).
curl -X POST "https://app.qevron.ai/api/cluster/assignments/42/deploy?start_now=1&enable_now=1" \
-H "Authorization: Bearer $ADMIN_KEY"curl -X DELETE "https://app.qevron.ai/api/cluster/assignments/42/deploy" \
-H "Authorization: Bearer $ADMIN_KEY"Yanıt agent'ın /v1/services/<key>/install (veya DELETE) çıktısını yansıtır: {installed, enabled, started, unit, ...}. Hatalarda 502 + data.raw_error (exit status 5 → "systemd unit not found", exit status 4 → "unit failed to load", vb. yapısal çeviri).
Logs — anlık görüntü ve canlı akış
Snapshot (son N satır)
curl -G "https://app.qevron.ai/api/cluster/assignments/42/logs" \
-H "Authorization: Bearer $ADMIN_KEY" \
--data-urlencode tail=100Canlı akış (SSE)
İki adım: önce ticket al, sonra EventSource ile aç. Ticket tek-kullanımlık, 60 saniye TTL, Redis backed. Uzun ömürlü JWT URL'ye düşmez.
TICKET=$(curl -sS -X POST \
-H "Authorization: Bearer $ADMIN_KEY" \
"https://app.qevron.ai/api/cluster/assignments/42/logs/ticket" \
| jq -r '.data.ticket')curl -N "https://app.qevron.ai/api/cluster/assignments/42/logs/stream?tail=10&ticket=$TICKET"// fetch ticket via standard axios (header auth)
const t = await api.post(`/cluster/assignments/${id}/logs/ticket`)
const es = new EventSource(`/api/cluster/assignments/${id}/logs/stream?ticket=${t.ticket}`)
es.onmessage = (ev) => console.log(ev.data)
es.addEventListener('end', (ev) => console.log('stream ended:', ev.data))text/event-stream yanıt — her satır data: <line>\n\n. Her 25 saniyede bir : keepalive comment frame (reverse-proxy idle timeout'ları için). Client disconnect → server-side journalctl -f kill.
Service status
Live systemd durumu (active, enabled, sub_state, active_enter_timestamp, main_pid).
curl -H "Authorization: Bearer $ADMIN_KEY" \
"https://app.qevron.ai/api/cluster/assignments/42/service-status"{
"data": {
"unit": "vllm",
"active": "active",
"enabled": "enabled",
"sub_state": "running",
"main_pid": 12345,
"active_enter_timestamp": "2026-05-27T14:30:00Z"
},
"success": true
}Runtime — tier flag ve VRAM önerisi
cp_cluster_runtimes kayıtları iki opsiyonel alan taşır:
| Alan | Davranış |
|---|---|
requires_gpu | true ise CPU-only node'lara atama yapılamaz (Create/Update/Move 422 tier_mismatch döner). UI'da CPU-only sunucular gizlenir. |
default_vram_gb | Atama formunda otomatik öneri (Reserve VRAM input'u dolar). 0 = öneri yok. |
Seed default'ları: vllm=24, blab-tts=4, blab-fast=2, blab-stable=2, solab-stt=4, spook-vision=3 (hepsi requires_gpu=true). Operator UI'dan toggle edilir.
Agent push
Yeni node ekleyince ya da agent binary'sini güncelleyince:
curl -X POST "https://app.qevron.ai/api/cluster/nodes/2/agent/install" \
-H "Authorization: Bearer $ADMIN_KEY"SSH ile binary push + systemd unit yaz + restart + /v1/health probe. Yanıt stdout_tail ile install log'unu döner.
Hatalı durumlar — friendly mesaj örnekleri
Önceki sürümlerde operatör agent HTTP 502: {"error":"exit status 5"} gibi raw JSON görürdü. v2.10+ structured envelope ile:
| Senaryo | HTTP | message |
|---|---|---|
| Undeployed unit'e stop | 422 | solab-stt is not deployed on SRV-4. Click Deploy first. |
| GPU-required runtime CPU-only node'a | 422 | blab-tts requires a GPU; SRV-3 has none |
| Channel.models drift | 422 | target channel "prod-chat" does not list model "verinova"; add the model to the channel first |
| Agent unreachable | 502 | agent on SRV-1 is unreachable |
| Agent unit eksik (systemctl exit 5) | 502 | systemd unit not found on target server |
Her birinde data field'ı structured detay taşır (action, unit, node, reason, raw_error …) — UI'lar Cannot <action> <unit> on <node>: <message> cümle haline çevirir.
İlgili sayfalar
- Yerel Modeller Kataloğu — model envanteri + base URL bilgisi
- Hata yönetimi — genel API hata yapısı