v1.0.86: per-user per-stand tracker — /tmp/instances-{client_id}-{stand}.json, no _INITIAL
This commit is contained in:
+28
-8
@@ -3,12 +3,11 @@ import uuid
|
||||
import os
|
||||
import fcntl
|
||||
|
||||
from api.http_client import HttpClient, detect_endpoint
|
||||
from api.http_client import HttpClient, detect_endpoint, stand_name
|
||||
from operations.get_services import get_services, get_service_detail
|
||||
from operations.get_instances import get_instances
|
||||
from operations.tracker import add as tracker_add, list_all as tracker_list
|
||||
from operations.tracker import remove as tracker_remove
|
||||
from operations.get_params import get_params_with_current_values
|
||||
|
||||
bp = Blueprint("api_test", __name__)
|
||||
|
||||
@@ -74,6 +73,27 @@ def _client():
|
||||
return HttpClient(endpoint, token)
|
||||
|
||||
|
||||
def _client_id():
|
||||
"""Извлечь ClientID из JWT токена (из cookie или env)."""
|
||||
import base64, json
|
||||
token = request.cookies.get("token") or current_app.config["NUBES_API_TOKEN"]
|
||||
try:
|
||||
parts = token.split(".")
|
||||
if len(parts) >= 2:
|
||||
payload = base64.urlsafe_b64decode(parts[1] + "==")
|
||||
return json.loads(payload).get("ClientID", "?")
|
||||
except Exception:
|
||||
pass
|
||||
return "?"
|
||||
|
||||
|
||||
def _stand():
|
||||
"""dev/test — по токену."""
|
||||
token = request.cookies.get("token") or current_app.config["NUBES_API_TOKEN"]
|
||||
endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"]
|
||||
return stand_name(endpoint)
|
||||
|
||||
|
||||
@bp.route("/api/services")
|
||||
def api_services():
|
||||
try:
|
||||
@@ -101,7 +121,7 @@ def api_operations(svc_id):
|
||||
detail = get_service_detail(_client(), svc_id)
|
||||
ops = detail.get("operations", [])
|
||||
# только отслеживаемые инстансы этого сервиса
|
||||
tracked = tracker_list()
|
||||
tracked = tracker_list(_client_id(), _stand())
|
||||
tracked_by_uid = {t["instanceUid"]: t for t in tracked if t["svcId"] == svc_id}
|
||||
tracked_uids = set(tracked_by_uid.keys())
|
||||
instances = get_instances(_client())
|
||||
@@ -203,7 +223,7 @@ def api_test():
|
||||
# Записать в трекер СРАЗУ после получения instanceUid, до params/run
|
||||
# (если params упадут — инстанс уже отслежен, сирот не будет)
|
||||
try:
|
||||
tracker_add(instance_uid, svc_id, display_name)
|
||||
tracker_add(_client_id(), _stand(), instance_uid, svc_id, display_name)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"[TRACKER ERROR] add failed: {e}", flush=True)
|
||||
@@ -215,7 +235,7 @@ def api_test():
|
||||
client.post(f"/instanceOperations/{op_uid}/run")
|
||||
|
||||
# фоном ждать завершения
|
||||
threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, True), daemon=True).start()
|
||||
threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, True, _client_id(), _stand()), daemon=True).start()
|
||||
return jsonify({"status": "RUNNING", "opUid": op_uid, "instanceUid": instance_uid, "displayName": display_name})
|
||||
|
||||
else:
|
||||
@@ -245,7 +265,7 @@ def api_test():
|
||||
# Получить реальное имя инстанса из API (не UUID!)
|
||||
if not display_name:
|
||||
display_name = _get_instance_display_name(client, instance_uid)
|
||||
threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, False, is_delete), daemon=True).start()
|
||||
threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, False, _client_id(), _stand(), is_delete), daemon=True).start()
|
||||
return jsonify({"status": "RUNNING", "opUid": op_uid, "instanceUid": instance_uid, "displayName": display_name})
|
||||
|
||||
except Exception as e:
|
||||
@@ -267,7 +287,7 @@ def _get_instance_display_name(client, instance_uid):
|
||||
return instance_uid
|
||||
|
||||
|
||||
def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, is_create, is_delete=False):
|
||||
def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, is_create, client_id, stand, is_delete=False):
|
||||
"""Фоном ждать dtFinish и сохранить результат."""
|
||||
import time
|
||||
t0 = time.time()
|
||||
@@ -294,7 +314,7 @@ def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_
|
||||
print(f"[DEBUG] _finish_op op_uid={op_uid} isSuccessful={is_ok!r}", flush=True)
|
||||
# tracker_add для create уже вызван синхронно в api_test()
|
||||
if is_ok and is_delete:
|
||||
tracker_remove(instance_uid)
|
||||
tracker_remove(client_id, stand, instance_uid)
|
||||
_op_results[op_uid] = {
|
||||
"status": "OK" if is_ok else "FAIL",
|
||||
"displayName": display_name,
|
||||
|
||||
+2
-2
@@ -155,10 +155,10 @@ def api_operations(svc_id):
|
||||
result = create_client(active_token, current_app.config["NUBES_API_ENDPOINT"])
|
||||
if not result:
|
||||
return jsonify({"error": "Не удалось определить стенд"}), 500
|
||||
client, _ = result
|
||||
client, endpoint = result
|
||||
detail = get_service_detail(client, svc_id)
|
||||
ops = detail.get("operations", [])
|
||||
tracked = tracker_list()
|
||||
tracked = tracker_list(_client_id(active_token), stand_name(endpoint))
|
||||
tracked_by_uid = {t["instanceUid"]: t for t in tracked if t["svcId"] == svc_id}
|
||||
instances = get_instances(client)
|
||||
nubes_uids = {i["instanceUid"] for i in instances}
|
||||
|
||||
Reference in New Issue
Block a user