|
23 | 23 | from common_library.json_serialization import json_dumps, json_loads |
24 | 24 | from models_library.api_schemas_clusters_keeper.ec2_instances import EC2InstanceTypeGet |
25 | 25 | from models_library.api_schemas_directorv2.dynamic_services import ( |
| 26 | + DynamicServiceGet, |
26 | 27 | GetProjectInactivityResponse, |
27 | 28 | ) |
28 | 29 | from models_library.api_schemas_dynamic_scheduler.dynamic_services import ( |
|
34 | 35 | ProjectGet, |
35 | 36 | ProjectPatch, |
36 | 37 | ) |
| 38 | +from models_library.api_schemas_webserver.projects_nodes import ( |
| 39 | + NodeGet, |
| 40 | + NodeGetUnknown, |
| 41 | +) |
37 | 42 | from models_library.basic_types import KeyIDStr |
38 | 43 | from models_library.errors import ErrorDict |
39 | 44 | from models_library.groups import GroupID |
40 | 45 | from models_library.products import ProductName |
41 | 46 | from models_library.projects import Project, ProjectID, ProjectTemplateType |
42 | 47 | from models_library.projects import ProjectType as ProjectTypeAPI |
43 | 48 | from models_library.projects_access import Owner |
44 | | -from models_library.projects_nodes import Node, NodeState, PartialNode |
| 49 | +from models_library.projects_nodes import ( |
| 50 | + Node, |
| 51 | + NodeLockReason, |
| 52 | + NodeLockState, |
| 53 | + NodeState, |
| 54 | + PartialNode, |
| 55 | +) |
45 | 56 | from models_library.projects_nodes_io import NodeID, NodeIDStr, PortLink |
46 | 57 | from models_library.projects_state import ( |
47 | 58 | ProjectRunningState, |
@@ -1364,6 +1375,45 @@ async def is_node_id_present_in_any_project_workbench( |
1364 | 1375 | return await db.node_id_exists(node_id) |
1365 | 1376 |
|
1366 | 1377 |
|
| 1378 | +async def _get_node_lock_state( |
| 1379 | + app: web.Application, *, user_id: UserID, project_uuid: ProjectID, node_id: NodeID |
| 1380 | +) -> NodeLockState: |
| 1381 | + node = await _projects_nodes_repository.get( |
| 1382 | + app, project_id=project_uuid, node_id=node_id |
| 1383 | + ) |
| 1384 | + |
| 1385 | + if _is_node_dynamic(node.key): |
| 1386 | + # if the service is dynamic and running it is locked |
| 1387 | + service = await dynamic_scheduler_service.get_dynamic_service( |
| 1388 | + app, node_id=node_id |
| 1389 | + ) |
| 1390 | + |
| 1391 | + if isinstance(service, DynamicServiceGet | NodeGet): |
| 1392 | + # service is running |
| 1393 | + return NodeLockState( |
| 1394 | + is_locked=True, |
| 1395 | + locked_by=await users_service.get_user_primary_group_id( |
| 1396 | + app, TypeAdapter(UserID).validate_python(service.user_id) |
| 1397 | + ), |
| 1398 | + locked_reason=NodeLockReason.OPENED, |
| 1399 | + ) |
| 1400 | + if isinstance(service, NodeGetUnknown): |
| 1401 | + # service state is unknown |
| 1402 | + # we should raise an exception here |
| 1403 | + msg = "Node state is unknown" |
| 1404 | + raise RuntimeError(msg) |
| 1405 | + return NodeLockState(is_locked=False) |
| 1406 | + |
| 1407 | + # if the service is computational and no pipeline is running it is not locked |
| 1408 | + if await director_v2_service.is_pipeline_running(app, user_id, project_uuid): |
| 1409 | + return NodeLockState( |
| 1410 | + is_locked=True, |
| 1411 | + locked_by=await users_service.get_user_primary_group_id(app, user_id), |
| 1412 | + locked_reason=NodeLockReason.OPENED, |
| 1413 | + ) |
| 1414 | + return NodeLockState(is_locked=False) |
| 1415 | + |
| 1416 | + |
1367 | 1417 | async def _safe_retrieve( |
1368 | 1418 | app: web.Application, node_id: NodeID, port_keys: list[str] |
1369 | 1419 | ) -> None: |
|
0 commit comments