Skip to content

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

KavramAnlamı
Assignment(channel_id, model_name, node_id, gpu_index, runtime_key) beşlisi. Hangi modelin hangi sunucuda çalışacağını planlar.
Runtimecp_cluster_runtimes kaydı (örn. vllm, blab-tts). requires_gpu ve default_vram_gb tier + öneri davranışı.
Nodecp_cluster_nodes kaydı. agent_endpoint ile qevron-agent çalıştırır; SSH veya agent collector ile telemetriyi qevron'a iletir.
DeployAtamayı node'a fiilen kurmak (systemd unit yaz + enable).
MoveAtamayı 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.

bash
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ı

AlanTipAçıklama
target_node_idintZorunlu. Hedef sunucu ID'si. Kaynakla aynı olamaz.
target_gpu_indexint?Opsiyonel. Belirsizse kaynak GPU index'i korunur.
start_after_movebool?Opsiyonel (default true). false → hedefin active=active olmasını beklemez.
target_channel_idint?Opsiyonel. Kanal değiştirme (promote/rebind). Yoksa kanal korunur.

Validasyon hataları (taşıma öncesi)

HTTPdata.reasonAçıklama
400Target source ile aynı / target node yok
422over_subscribed_targetTarget GPU'nun VRAM toplamı aşıyor (data.target_gpu_index döner)
422tier_mismatchRuntime requires_gpu=true ama target node'da GPU yok (data.target_gpus: 0)
400channel_not_foundtarget_channel_id mevcut değil
400channel_disabledTarget kanal disabled durumda
422channel_model_driftTarget kanal models[] array'i assignment.model_name'i içermiyor (data.target_channel_models döner)

Yanıt — final_state enum'u

DeğerAnlamı
movedBeş adım da temiz. Bağlama güncellendi.
failedAdım 1 veya 2 fail. Source dokunulmadı.
failed_rolled_backAdım 3 fail veya adım 5 DB write fail; target temiz şekilde geri alındı.
failed_rolled_back_source_restartedAdım 4 fail; target geri alındı, source önceden aktifse yeniden başlatıldı.
failed_rollback_dirtyBir 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.

bash
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:

json
{
  "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.

bash
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:

json
{
  "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).

bash
curl -X POST "https://app.qevron.ai/api/cluster/assignments/42/deploy?start_now=1&enable_now=1" \
  -H "Authorization: Bearer $ADMIN_KEY"
bash
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)

bash
curl -G "https://app.qevron.ai/api/cluster/assignments/42/logs" \
  -H "Authorization: Bearer $ADMIN_KEY" \
  --data-urlencode tail=100

Canlı 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.

bash
TICKET=$(curl -sS -X POST \
  -H "Authorization: Bearer $ADMIN_KEY" \
  "https://app.qevron.ai/api/cluster/assignments/42/logs/ticket" \
  | jq -r '.data.ticket')
bash
curl -N "https://app.qevron.ai/api/cluster/assignments/42/logs/stream?tail=10&ticket=$TICKET"
javascript
// 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).

bash
curl -H "Authorization: Bearer $ADMIN_KEY" \
  "https://app.qevron.ai/api/cluster/assignments/42/service-status"
json
{
  "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:

AlanDavranış
requires_gputrue ise CPU-only node'lara atama yapılamaz (Create/Update/Move 422 tier_mismatch döner). UI'da CPU-only sunucular gizlenir.
default_vram_gbAtama 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:

bash
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:

SenaryoHTTPmessage
Undeployed unit'e stop422solab-stt is not deployed on SRV-4. Click Deploy first.
GPU-required runtime CPU-only node'a422blab-tts requires a GPU; SRV-3 has none
Channel.models drift422target channel "prod-chat" does not list model "verinova"; add the model to the channel first
Agent unreachable502agent on SRV-1 is unreachable
Agent unit eksik (systemctl exit 5)502systemd 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

Qevron — AI gateway. Arpanet / OpenAI / Anthropic / Gemini uyumlu.