polyaxon 2.1.0rc9__py3-none-any.whl → 2.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. polyaxon/_auxiliaries/default_scheduling.py +17 -7
  2. polyaxon/_auxiliaries/init.py +14 -6
  3. polyaxon/_auxiliaries/sidecar.py +10 -8
  4. polyaxon/_cli/artifacts.py +96 -11
  5. polyaxon/_cli/components.py +96 -11
  6. polyaxon/_cli/config.py +31 -0
  7. polyaxon/_cli/dashboard.py +12 -2
  8. polyaxon/_cli/init.py +1 -1
  9. polyaxon/_cli/models.py +96 -11
  10. polyaxon/_cli/operations.py +133 -58
  11. polyaxon/_cli/project_versions.py +139 -6
  12. polyaxon/_cli/projects.py +23 -9
  13. polyaxon/_cli/run.py +43 -9
  14. polyaxon/_cli/services/agent.py +2 -2
  15. polyaxon/_cli/version.py +4 -1
  16. polyaxon/_client/mixin.py +39 -0
  17. polyaxon/_client/project.py +218 -23
  18. polyaxon/_client/run.py +84 -27
  19. polyaxon/_compiler/contexts/contexts.py +4 -0
  20. polyaxon/_compiler/contexts/ray_job.py +4 -2
  21. polyaxon/_compiler/resolver/agent.py +22 -10
  22. polyaxon/_compiler/resolver/runtime.py +7 -3
  23. polyaxon/_constants/metadata.py +1 -0
  24. polyaxon/_contexts/keys.py +1 -0
  25. polyaxon/_contexts/paths.py +1 -1
  26. polyaxon/_deploy/operators/compose.py +1 -27
  27. polyaxon/_deploy/schemas/auth.py +3 -3
  28. polyaxon/_deploy/schemas/celery.py +10 -8
  29. polyaxon/_deploy/schemas/deployment.py +148 -115
  30. polyaxon/_deploy/schemas/email.py +8 -8
  31. polyaxon/_deploy/schemas/ingress.py +7 -7
  32. polyaxon/_deploy/schemas/intervals.py +2 -7
  33. polyaxon/_deploy/schemas/operators.py +8 -8
  34. polyaxon/_deploy/schemas/proxy.py +9 -8
  35. polyaxon/_deploy/schemas/rbac.py +1 -1
  36. polyaxon/_deploy/schemas/root_user.py +5 -5
  37. polyaxon/_deploy/schemas/security_context.py +25 -15
  38. polyaxon/_deploy/schemas/service.py +75 -66
  39. polyaxon/_deploy/schemas/ssl.py +3 -3
  40. polyaxon/_deploy/schemas/ui.py +10 -6
  41. polyaxon/_docker/builder/builder.py +4 -1
  42. polyaxon/_docker/converter/base/containers.py +4 -7
  43. polyaxon/_docker/converter/base/env_vars.py +5 -5
  44. polyaxon/_docker/converter/base/mounts.py +2 -2
  45. polyaxon/_docker/docker_types.py +57 -30
  46. polyaxon/_env_vars/getters/owner_entity.py +4 -2
  47. polyaxon/_env_vars/getters/project.py +4 -2
  48. polyaxon/_env_vars/getters/run.py +5 -2
  49. polyaxon/_env_vars/keys.py +3 -0
  50. polyaxon/_flow/__init__.py +3 -2
  51. polyaxon/_flow/builds/__init__.py +8 -8
  52. polyaxon/_flow/cache/__init__.py +4 -4
  53. polyaxon/_flow/component/base.py +25 -18
  54. polyaxon/_flow/component/component.py +4 -3
  55. polyaxon/_flow/early_stopping/__init__.py +1 -1
  56. polyaxon/_flow/early_stopping/policies.py +12 -10
  57. polyaxon/_flow/environment/__init__.py +43 -25
  58. polyaxon/_flow/events/__init__.py +1 -1
  59. polyaxon/_flow/hooks/__init__.py +11 -11
  60. polyaxon/_flow/init/__init__.py +41 -25
  61. polyaxon/_flow/io/io.py +57 -47
  62. polyaxon/_flow/joins/__init__.py +5 -5
  63. polyaxon/_flow/matrix/bayes.py +23 -17
  64. polyaxon/_flow/matrix/grid_search.py +16 -7
  65. polyaxon/_flow/matrix/hyperband.py +10 -10
  66. polyaxon/_flow/matrix/hyperopt.py +14 -9
  67. polyaxon/_flow/matrix/iterative.py +14 -8
  68. polyaxon/_flow/matrix/mapping.py +4 -4
  69. polyaxon/_flow/matrix/params.py +138 -77
  70. polyaxon/_flow/matrix/random_search.py +10 -5
  71. polyaxon/_flow/matrix/tuner.py +4 -4
  72. polyaxon/_flow/mounts/artifacts_mounts.py +1 -1
  73. polyaxon/_flow/notifications/__init__.py +1 -1
  74. polyaxon/_flow/operations/base.py +10 -8
  75. polyaxon/_flow/operations/compiled_operation.py +5 -4
  76. polyaxon/_flow/operations/operation.py +57 -41
  77. polyaxon/_flow/optimization/__init__.py +2 -2
  78. polyaxon/_flow/params/params.py +10 -9
  79. polyaxon/_flow/plugins/__init__.py +19 -13
  80. polyaxon/_flow/run/dag.py +12 -9
  81. polyaxon/_flow/run/dask/dask.py +4 -4
  82. polyaxon/_flow/run/dask/replica.py +17 -11
  83. polyaxon/_flow/run/job.py +17 -11
  84. polyaxon/_flow/run/kubeflow/mpi_job.py +10 -5
  85. polyaxon/_flow/run/kubeflow/mx_job.py +25 -9
  86. polyaxon/_flow/run/kubeflow/paddle_job.py +16 -9
  87. polyaxon/_flow/run/kubeflow/pytorch_job.py +24 -17
  88. polyaxon/_flow/run/kubeflow/replica.py +17 -11
  89. polyaxon/_flow/run/kubeflow/scheduling_policy.py +7 -5
  90. polyaxon/_flow/run/kubeflow/tf_job.py +15 -8
  91. polyaxon/_flow/run/kubeflow/xgboost_job.py +9 -4
  92. polyaxon/_flow/run/ray/ray.py +9 -6
  93. polyaxon/_flow/run/ray/replica.py +25 -16
  94. polyaxon/_flow/run/resources.py +14 -13
  95. polyaxon/_flow/run/service.py +4 -4
  96. polyaxon/_flow/schedules/cron.py +4 -4
  97. polyaxon/_flow/schedules/interval.py +4 -4
  98. polyaxon/_flow/templates/__init__.py +3 -3
  99. polyaxon/_flow/termination/__init__.py +3 -3
  100. polyaxon/_fs/async_manager.py +1 -1
  101. polyaxon/_fs/fs.py +1 -1
  102. polyaxon/_fs/watcher.py +26 -27
  103. polyaxon/_k8s/converter/base/base.py +2 -1
  104. polyaxon/_k8s/converter/base/main.py +1 -0
  105. polyaxon/_k8s/converter/common/accelerators.py +7 -4
  106. polyaxon/_k8s/converter/converters/ray_job.py +4 -2
  107. polyaxon/_k8s/custom_resources/dask_job.py +3 -0
  108. polyaxon/_k8s/custom_resources/kubeflow/common.py +4 -1
  109. polyaxon/_k8s/custom_resources/ray_job.py +3 -0
  110. polyaxon/_k8s/custom_resources/setter.py +1 -1
  111. polyaxon/_k8s/executor/async_executor.py +2 -0
  112. polyaxon/_k8s/k8s_validation.py +1 -1
  113. polyaxon/_k8s/logging/async_monitor.py +82 -11
  114. polyaxon/_k8s/manager/async_manager.py +15 -0
  115. polyaxon/_k8s/manager/manager.py +16 -1
  116. polyaxon/_local_process/__init__.py +0 -0
  117. polyaxon/_local_process/agent.py +6 -0
  118. polyaxon/_local_process/converter/__init__.py +1 -0
  119. polyaxon/_local_process/converter/base/__init__.py +1 -0
  120. polyaxon/_local_process/converter/base/base.py +140 -0
  121. polyaxon/_local_process/converter/base/containers.py +66 -0
  122. polyaxon/_local_process/converter/base/env_vars.py +253 -0
  123. polyaxon/_local_process/converter/base/init.py +414 -0
  124. polyaxon/_local_process/converter/base/main.py +74 -0
  125. polyaxon/_local_process/converter/base/mounts.py +82 -0
  126. polyaxon/_local_process/converter/converters/__init__.py +8 -0
  127. polyaxon/_local_process/converter/converters/job.py +40 -0
  128. polyaxon/_local_process/converter/converters/service.py +41 -0
  129. polyaxon/_local_process/converter/mixins.py +38 -0
  130. polyaxon/_local_process/executor.py +132 -0
  131. polyaxon/_local_process/process_types.py +42 -0
  132. polyaxon/_polyaxonfile/specs/compiled_operation.py +1 -1
  133. polyaxon/_polyaxonfile/specs/libs/parser.py +1 -1
  134. polyaxon/_polyaxonfile/specs/libs/validator.py +1 -1
  135. polyaxon/_polyaxonfile/specs/operation.py +1 -1
  136. polyaxon/_polyaxonfile/specs/sections.py +8 -0
  137. polyaxon/_pql/manager.py +1 -1
  138. polyaxon/_runner/agent/async_agent.py +25 -11
  139. polyaxon/_runner/agent/base_agent.py +19 -10
  140. polyaxon/_runner/agent/sync_agent.py +24 -10
  141. polyaxon/_runner/converter/converter.py +12 -4
  142. polyaxon/_runner/executor.py +1 -1
  143. polyaxon/_schemas/agent.py +69 -37
  144. polyaxon/_schemas/authentication.py +4 -4
  145. polyaxon/_schemas/base.py +26 -2
  146. polyaxon/_schemas/checks.py +3 -3
  147. polyaxon/_schemas/cli.py +4 -6
  148. polyaxon/_schemas/client.py +20 -18
  149. polyaxon/_schemas/compatibility.py +4 -4
  150. polyaxon/_schemas/container_resources.py +1 -1
  151. polyaxon/_schemas/home.py +3 -3
  152. polyaxon/_schemas/installation.py +13 -9
  153. polyaxon/_schemas/lifecycle.py +23 -23
  154. polyaxon/_schemas/log_handler.py +2 -2
  155. polyaxon/_schemas/services.py +26 -14
  156. polyaxon/_schemas/types/artifacts.py +3 -3
  157. polyaxon/_schemas/types/dockerfile.py +14 -12
  158. polyaxon/_schemas/types/event.py +2 -2
  159. polyaxon/_schemas/types/file.py +3 -3
  160. polyaxon/_schemas/types/git.py +12 -4
  161. polyaxon/_schemas/types/tensorboard.py +14 -8
  162. polyaxon/_schemas/user.py +3 -3
  163. polyaxon/_schemas/version.py +2 -2
  164. polyaxon/_sdk/api/agents_v1_api.py +222 -43
  165. polyaxon/_sdk/api/artifacts_stores_v1_api.py +3 -3
  166. polyaxon/_sdk/api/auth_v1_api.py +13 -13
  167. polyaxon/_sdk/api/connections_v1_api.py +15 -15
  168. polyaxon/_sdk/api/dashboards_v1_api.py +15 -15
  169. polyaxon/_sdk/api/organizations_v1_api.py +85 -85
  170. polyaxon/_sdk/api/presets_v1_api.py +15 -15
  171. polyaxon/_sdk/api/project_dashboards_v1_api.py +29 -29
  172. polyaxon/_sdk/api/project_searches_v1_api.py +29 -29
  173. polyaxon/_sdk/api/projects_v1_api.py +284 -107
  174. polyaxon/_sdk/api/queues_v1_api.py +19 -19
  175. polyaxon/_sdk/api/runs_v1_api.py +313 -359
  176. polyaxon/_sdk/api/searches_v1_api.py +15 -15
  177. polyaxon/_sdk/api/service_accounts_v1_api.py +31 -31
  178. polyaxon/_sdk/api/tags_v1_api.py +17 -17
  179. polyaxon/_sdk/api/teams_v1_api.py +2854 -402
  180. polyaxon/_sdk/api/users_v1_api.py +254 -78
  181. polyaxon/_sdk/api/versions_v1_api.py +7 -7
  182. polyaxon/_sdk/async_client/api_client.py +4 -0
  183. polyaxon/_sdk/schemas/__init__.py +1 -1
  184. polyaxon/_sdk/schemas/v1_activity.py +8 -8
  185. polyaxon/_sdk/schemas/v1_agent.py +18 -16
  186. polyaxon/_sdk/schemas/v1_agent_state_response.py +4 -4
  187. polyaxon/_sdk/schemas/v1_agent_state_response_agent_state.py +10 -10
  188. polyaxon/_sdk/schemas/v1_agent_status_body_request.py +3 -3
  189. polyaxon/_sdk/schemas/v1_analytics_spec.py +4 -4
  190. polyaxon/_sdk/schemas/v1_artifact_tree.py +3 -3
  191. polyaxon/_sdk/schemas/v1_auth.py +1 -1
  192. polyaxon/_sdk/schemas/v1_cloning.py +3 -3
  193. polyaxon/_sdk/schemas/v1_connection_response.py +9 -9
  194. polyaxon/_sdk/schemas/v1_dashboard.py +9 -9
  195. polyaxon/_sdk/schemas/v1_dashboard_spec.py +5 -1
  196. polyaxon/_sdk/schemas/v1_entities_tags.py +2 -2
  197. polyaxon/_sdk/schemas/v1_entities_transfer.py +2 -2
  198. polyaxon/_sdk/schemas/v1_entity_notification_body.py +7 -7
  199. polyaxon/_sdk/schemas/v1_entity_stage_body_request.py +5 -5
  200. polyaxon/_sdk/schemas/v1_entity_status_body_request.py +5 -5
  201. polyaxon/_sdk/schemas/v1_events_response.py +2 -2
  202. polyaxon/_sdk/schemas/v1_list_activities_response.py +4 -4
  203. polyaxon/_sdk/schemas/v1_list_agents_response.py +4 -4
  204. polyaxon/_sdk/schemas/v1_list_bookmarks_response.py +4 -4
  205. polyaxon/_sdk/schemas/v1_list_connections_response.py +4 -4
  206. polyaxon/_sdk/schemas/v1_list_dashboards_response.py +4 -4
  207. polyaxon/_sdk/schemas/v1_list_organization_members_response.py +4 -4
  208. polyaxon/_sdk/schemas/v1_list_organizations_response.py +4 -4
  209. polyaxon/_sdk/schemas/v1_list_presets_response.py +4 -4
  210. polyaxon/_sdk/schemas/v1_list_project_versions_response.py +4 -4
  211. polyaxon/_sdk/schemas/v1_list_projects_response.py +4 -4
  212. polyaxon/_sdk/schemas/v1_list_queues_response.py +4 -4
  213. polyaxon/_sdk/schemas/v1_list_run_artifacts_response.py +4 -4
  214. polyaxon/_sdk/schemas/v1_list_run_connections_response.py +4 -4
  215. polyaxon/_sdk/schemas/v1_list_run_edges_response.py +4 -4
  216. polyaxon/_sdk/schemas/v1_list_runs_response.py +4 -4
  217. polyaxon/_sdk/schemas/v1_list_searches_response.py +4 -4
  218. polyaxon/_sdk/schemas/v1_list_service_accounts_response.py +4 -4
  219. polyaxon/_sdk/schemas/v1_list_tags_response.py +4 -4
  220. polyaxon/_sdk/schemas/v1_list_team_members_response.py +4 -4
  221. polyaxon/_sdk/schemas/v1_list_teams_response.py +4 -4
  222. polyaxon/_sdk/schemas/v1_list_token_response.py +4 -4
  223. polyaxon/_sdk/schemas/v1_operation_body.py +8 -8
  224. polyaxon/_sdk/schemas/v1_organization.py +16 -16
  225. polyaxon/_sdk/schemas/v1_organization_member.py +6 -6
  226. polyaxon/_sdk/schemas/v1_password_change.py +3 -3
  227. polyaxon/_sdk/schemas/v1_pipeline.py +3 -3
  228. polyaxon/_sdk/schemas/v1_preset.py +16 -9
  229. polyaxon/_sdk/schemas/v1_project.py +17 -17
  230. polyaxon/_sdk/schemas/v1_project_settings.py +12 -10
  231. polyaxon/_sdk/schemas/v1_project_version.py +20 -20
  232. polyaxon/_sdk/schemas/v1_queue.py +12 -12
  233. polyaxon/_sdk/schemas/v1_run.py +38 -38
  234. polyaxon/_sdk/schemas/v1_run_connection.py +3 -3
  235. polyaxon/_sdk/schemas/v1_run_edge.py +5 -5
  236. polyaxon/_sdk/schemas/v1_run_edge_lineage.py +3 -3
  237. polyaxon/_sdk/schemas/v1_run_edges_graph.py +1 -1
  238. polyaxon/_sdk/schemas/v1_run_reference_catalog.py +4 -4
  239. polyaxon/_sdk/schemas/v1_run_settings.py +9 -9
  240. polyaxon/_sdk/schemas/v1_search.py +10 -10
  241. polyaxon/_sdk/schemas/v1_search_spec.py +14 -14
  242. polyaxon/_sdk/schemas/v1_section_spec.py +12 -7
  243. polyaxon/_sdk/schemas/v1_service_account.py +9 -9
  244. polyaxon/_sdk/schemas/v1_settings_catalog.py +4 -3
  245. polyaxon/_sdk/schemas/v1_tag.py +6 -6
  246. polyaxon/_sdk/schemas/v1_team.py +11 -8
  247. polyaxon/_sdk/schemas/v1_team_member.py +6 -6
  248. polyaxon/_sdk/schemas/v1_team_settings.py +2 -2
  249. polyaxon/_sdk/schemas/v1_token.py +10 -10
  250. polyaxon/_sdk/schemas/v1_trial_start.py +6 -6
  251. polyaxon/_sdk/schemas/v1_user.py +6 -7
  252. polyaxon/_sdk/schemas/v1_user_access.py +17 -0
  253. polyaxon/_sdk/schemas/v1_user_email.py +1 -1
  254. polyaxon/_sdk/schemas/v1_user_singup.py +5 -5
  255. polyaxon/_sdk/schemas/v1_uuids.py +1 -1
  256. polyaxon/_sidecar/container/__init__.py +39 -20
  257. polyaxon/_sidecar/container/monitors/logs.py +10 -13
  258. polyaxon/_sidecar/ignore.py +0 -1
  259. polyaxon/_utils/cli_constants.py +2 -0
  260. polyaxon/_utils/fqn_utils.py +25 -2
  261. polyaxon/_utils/test_utils.py +2 -1
  262. polyaxon/pkg.py +1 -1
  263. polyaxon/schemas.py +1 -1
  264. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/METADATA +43 -43
  265. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/RECORD +269 -252
  266. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/WHEEL +1 -1
  267. polyaxon/_sdk/schemas/v1_project_user_access.py +0 -10
  268. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/LICENSE +0 -0
  269. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/entry_points.txt +0 -0
  270. {polyaxon-2.1.0rc9.dist-info → polyaxon-2.6.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import datetime
2
+ import logging
2
3
 
3
4
  from typing import List, Optional, Tuple
4
5
 
@@ -10,6 +11,8 @@ from polyaxon._flow import V1RunKind
10
11
  from polyaxon._k8s.manager.async_manager import AsyncK8sManager
11
12
  from traceml.logging import V1Log, V1Logs
12
13
 
14
+ _logger = logging.getLogger("haupt.k8s.logs")
15
+
13
16
 
14
17
  async def handle_container_logs(
15
18
  k8s_manager: AsyncK8sManager, pod: V1Pod, container_name: str, **params
@@ -23,8 +26,20 @@ async def handle_container_logs(
23
26
  timestamps=True,
24
27
  **params,
25
28
  )
26
- except ApiException:
27
- pass
29
+ except ApiException as e:
30
+ _logger.warning(
31
+ "Error collecting logs for %s - container %s: %s",
32
+ pod.metadata.name,
33
+ container_name,
34
+ e,
35
+ )
36
+ except Exception as e:
37
+ _logger.warning(
38
+ "Unexpected error collecting logs for %s - container %s: %s",
39
+ pod.metadata.name,
40
+ container_name,
41
+ e,
42
+ )
28
43
  if not resp:
29
44
  return []
30
45
 
@@ -66,7 +81,7 @@ async def query_k8s_operation_logs(
66
81
  new_time = now()
67
82
  params = {}
68
83
  if last_time:
69
- since_seconds = (new_time - last_time).total_seconds() - 1
84
+ since_seconds = (new_time - last_time).total_seconds()
70
85
  params["since_seconds"] = int(since_seconds)
71
86
  if stream:
72
87
  params["tail_lines"] = V1Logs._CHUNK_SIZE
@@ -83,6 +98,11 @@ async def query_k8s_operation_logs(
83
98
  **params,
84
99
  )
85
100
 
101
+ if logs and last_time:
102
+ # make sure to filter logs larger than last_time
103
+ logs = [log for log in logs if log.timestamp > last_time]
104
+ if logs and logs[-1].timestamp:
105
+ new_time = logs[-1].timestamp
86
106
  return logs, new_time
87
107
 
88
108
 
@@ -96,32 +116,35 @@ async def collect_agent_service_logs(
96
116
  k8s_manager=k8s_manager,
97
117
  pod=pod,
98
118
  container_name=container.name,
99
- tail_lines=V1Logs._CHUNK_SIZE * 3,
119
+ tail_lines=V1Logs._CHUNK_SIZE,
100
120
  )
101
121
 
102
122
 
103
123
  async def query_k8s_pod_logs(
104
124
  k8s_manager: AsyncK8sManager,
105
125
  pod: V1Pod,
106
- last_time: Optional[datetime.datetime],
126
+ last_time: Optional[datetime.datetime] = None,
107
127
  stream: bool = False,
108
128
  ) -> Tuple[List[V1Log], Optional[datetime.datetime]]:
109
129
  new_time = now()
110
130
  params = {}
111
131
  if last_time:
112
- since_seconds = (new_time - last_time).total_seconds() - 1
132
+ since_seconds = (new_time - last_time).total_seconds()
113
133
  params["since_seconds"] = int(since_seconds)
114
134
  if stream:
115
135
  params["tail_lines"] = V1Logs._CHUNK_SIZE
116
136
 
117
137
  logs = await handle_pod_logs(k8s_manager=k8s_manager, pod=pod, **params)
118
138
 
119
- if logs:
120
- last_time = logs[-1].timestamp
121
- return logs, last_time
139
+ if logs and last_time:
140
+ # make sure to filter logs larger than last_time
141
+ logs = [log for log in logs if log.timestamp > last_time]
142
+ if logs and logs[-1].timestamp:
143
+ new_time = logs[-1].timestamp
144
+ return logs, new_time
122
145
 
123
146
 
124
- async def get_op_pos_and_services(
147
+ async def get_op_pods_and_services(
125
148
  k8s_manager: AsyncK8sManager,
126
149
  run_uuid: str,
127
150
  run_kind: str,
@@ -138,12 +161,40 @@ async def get_op_pos_and_services(
138
161
  return pods, services
139
162
 
140
163
 
164
+ async def get_resource_events(
165
+ k8s_manager: AsyncK8sManager, resource_type: str, resource_name: str
166
+ ):
167
+ field_selector = (
168
+ f"involvedObject.kind={resource_type},involvedObject.name={resource_name}"
169
+ )
170
+ try:
171
+ events = await k8s_manager.list_namespaced_events(field_selector=field_selector)
172
+
173
+ all_events = []
174
+ for event in events:
175
+ event_data = {
176
+ "reason": event.reason,
177
+ "message": event.message,
178
+ "first_timestamp": event.first_timestamp,
179
+ "last_timestamp": event.last_timestamp,
180
+ "count": event.count,
181
+ "type": event.type,
182
+ }
183
+ all_events.append(event_data)
184
+
185
+ return all_events
186
+
187
+ except ApiException as e:
188
+ print(f"Exception when calling CoreV1Api->list_namespaced_event: {e}")
189
+ return []
190
+
191
+
141
192
  async def get_op_spec(
142
193
  k8s_manager: AsyncK8sManager,
143
194
  run_uuid: str,
144
195
  run_kind: str,
145
196
  ):
146
- pods, services = await get_op_pos_and_services(
197
+ pods, services = await get_op_pods_and_services(
147
198
  k8s_manager=k8s_manager,
148
199
  run_uuid=run_uuid,
149
200
  run_kind=run_kind,
@@ -153,11 +204,21 @@ async def get_op_spec(
153
204
  pods_list[
154
205
  pod.metadata.name
155
206
  ] = k8s_manager.api_client.sanitize_for_serialization(pod)
207
+ pods_list[pod.metadata.name]["events"] = await get_resource_events(
208
+ k8s_manager=k8s_manager,
209
+ resource_type="Pod",
210
+ resource_name=pod.metadata.name,
211
+ )
156
212
  services_list = {}
157
213
  for service in services or []:
158
214
  services_list[
159
215
  service.metadata.name
160
216
  ] = k8s_manager.api_client.sanitize_for_serialization(service)
217
+ services_list[service.metadata.name]["events"] = await get_resource_events(
218
+ k8s_manager=k8s_manager,
219
+ resource_type="Service",
220
+ resource_name=service.metadata.name,
221
+ )
161
222
  data = {"pods": pods_list, "services": services_list}
162
223
  return data, pods, services
163
224
 
@@ -185,11 +246,21 @@ async def get_agent_spec(
185
246
  pods_list[
186
247
  pod.metadata.name
187
248
  ] = k8s_manager.api_client.sanitize_for_serialization(pod)
249
+ pods_list[pod.metadata.name]["events"] = await get_resource_events(
250
+ k8s_manager=k8s_manager,
251
+ resource_type="Pod",
252
+ resource_name=pod.metadata.name,
253
+ )
188
254
  data = {"pods": pods_list}
189
255
  services_list = {}
190
256
  for service in services or []:
191
257
  services_list[
192
258
  service.metadata.name
193
259
  ] = k8s_manager.api_client.sanitize_for_serialization(service)
260
+ services_list[service.metadata.name]["events"] = await get_resource_events(
261
+ k8s_manager=k8s_manager,
262
+ resource_type="Service",
263
+ resource_name=service.metadata.name,
264
+ )
194
265
  data["services"] = services_list
195
266
  return data, pods, services
@@ -267,3 +267,18 @@ class AsyncK8sManager(BaseK8sManager):
267
267
  raise PolyaxonK8sError("Connection error: %s" % e) from e
268
268
  else:
269
269
  logger.debug("Custom object `{}` was not found".format(name))
270
+
271
+ async def list_namespaced_events(
272
+ self,
273
+ field_selector: str = None,
274
+ namespace: str = None,
275
+ reraise: bool = False,
276
+ **kwargs
277
+ ) -> List[client.CoreV1EventList]:
278
+ return await self._list_namespace_resource(
279
+ resource_api=self.k8s_api.list_namespaced_event, # type: ignore[attr-defined]
280
+ reraise=reraise,
281
+ namespace=namespace,
282
+ field_selector=field_selector,
283
+ **kwargs,
284
+ )
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from typing import List, Optional
2
2
 
3
3
  from kubernetes import client, config
4
4
  from kubernetes.client import Configuration
@@ -806,3 +806,18 @@ class K8sManager(BaseK8sManager):
806
806
  pod_id, namespace=namespace or self.namespace
807
807
  )
808
808
  return is_pod_running(event, container_id)
809
+
810
+ def list_namespaced_events(
811
+ self,
812
+ field_selector: str = None,
813
+ namespace: str = None,
814
+ reraise: bool = False,
815
+ **kwargs
816
+ ) -> List[client.CoreV1EventList]:
817
+ return self._list_namespace_resource(
818
+ resource_api=self.k8s_api.list_namespaced_event, # type: ignore[attr-defined]
819
+ reraise=reraise,
820
+ namespace=namespace,
821
+ field_selector=field_selector,
822
+ **kwargs,
823
+ )
File without changes
@@ -0,0 +1,6 @@
1
+ from polyaxon._local_process.executor import Executor
2
+ from polyaxon._runner.agent.sync_agent import BaseSyncAgent
3
+
4
+
5
+ class Agent(BaseSyncAgent):
6
+ EXECUTOR = Executor
@@ -0,0 +1 @@
1
+ from polyaxon._local_process.converter.base.base import BaseConverter
@@ -0,0 +1,140 @@
1
+ from typing import Dict, Iterable, List, Optional, Union
2
+
3
+ from polyaxon import settings
4
+ from polyaxon._auxiliaries import V1PolyaxonSidecarContainer
5
+ from polyaxon._connections import V1Connection, V1ConnectionResource
6
+ from polyaxon._flow import V1Environment, V1Init, V1Plugins
7
+ from polyaxon._k8s import k8s_schemas
8
+ from polyaxon._local_process import process_types
9
+ from polyaxon._local_process.converter.base.containers import ContainerMixin
10
+ from polyaxon._local_process.converter.base.env_vars import EnvMixin
11
+ from polyaxon._local_process.converter.base.init import InitConverter
12
+ from polyaxon._local_process.converter.base.main import MainConverter
13
+ from polyaxon._local_process.converter.base.mounts import MountsMixin
14
+ from polyaxon._runner.converter import BaseConverter as _BaseConverter
15
+ from polyaxon._runner.kinds import RunnerKind
16
+ from polyaxon.exceptions import PolyaxonConverterError
17
+
18
+
19
+ class BaseConverter(
20
+ MainConverter, InitConverter, ContainerMixin, EnvMixin, MountsMixin, _BaseConverter
21
+ ):
22
+ RUNNER_KIND = RunnerKind.PROCESS
23
+
24
+ @classmethod
25
+ def _get_sidecar_container(
26
+ cls,
27
+ container_id: str,
28
+ polyaxon_sidecar: V1PolyaxonSidecarContainer,
29
+ env: List[process_types.V1EnvVar],
30
+ artifacts_store: V1Connection,
31
+ plugins: V1Plugins,
32
+ run_path: Optional[str],
33
+ ) -> Optional[process_types.V1Container]:
34
+ return None
35
+
36
+ @classmethod
37
+ def _k8s_to_process_env_var(
38
+ cls,
39
+ env_var: List[k8s_schemas.V1EnvVar],
40
+ ) -> List[process_types.V1EnvVar]:
41
+ if not env_var:
42
+ return []
43
+
44
+ process_env_var = []
45
+ for item in env_var:
46
+ if isinstance(item, dict):
47
+ try:
48
+ item = k8s_schemas.V1EnvVar(**item)
49
+ except (ValueError, TypeError) as e:
50
+ raise PolyaxonConverterError(
51
+ f"Could not parse env var value `{item}` from the K8S schema in container section"
52
+ ) from e
53
+ process_env_var.append(cls._get_env_var(name=item.name, value=item.value))
54
+
55
+ return process_env_var
56
+
57
+ @staticmethod
58
+ def _new_container(name: str) -> process_types.V1Container:
59
+ return process_types.V1Container(name=name)
60
+
61
+ @classmethod
62
+ def _ensure_container(
63
+ cls,
64
+ container: Union[k8s_schemas.V1Container, process_types.V1Container],
65
+ volumes: List[k8s_schemas.V1Volume],
66
+ ) -> process_types.V1Container:
67
+ if not isinstance(container, k8s_schemas.V1Container):
68
+ return container
69
+ return process_types.V1Container(
70
+ name=container.name,
71
+ command=container.command,
72
+ args=container.args,
73
+ env=cls._k8s_to_process_env_var(container.env),
74
+ working_dir=container.working_dir,
75
+ )
76
+
77
+ def get_replica_resource(
78
+ self,
79
+ environment: V1Environment,
80
+ plugins: V1Plugins,
81
+ volumes: List[k8s_schemas.V1Volume],
82
+ init: List[V1Init],
83
+ sidecars: List[k8s_schemas.V1Container],
84
+ container: k8s_schemas.V1Container,
85
+ artifacts_store: V1Connection,
86
+ connections: List[str],
87
+ connection_by_names: Dict[str, V1Connection],
88
+ secrets: Optional[Iterable[V1ConnectionResource]],
89
+ config_maps: Optional[Iterable[V1ConnectionResource]],
90
+ kv_env_vars: List[List],
91
+ default_sa: Optional[str] = None,
92
+ ports: List[int] = None,
93
+ ) -> List[process_types.V1Container]:
94
+ volumes = volumes or []
95
+ init = init or []
96
+ sidecars = sidecars or []
97
+ connections = connections or []
98
+ environment = environment or V1Environment()
99
+ environment.service_account_name = (
100
+ environment.service_account_name
101
+ or default_sa
102
+ or settings.AGENT_CONFIG.runs_sa
103
+ )
104
+
105
+ init_connections = self.filter_connections_from_init(init=init)
106
+
107
+ init_containers = self.get_init_containers(
108
+ polyaxon_init=self.polyaxon_init,
109
+ plugins=plugins,
110
+ artifacts_store=artifacts_store,
111
+ init_connections=init_connections,
112
+ init_containers=self.filter_containers_from_init(init=init),
113
+ connection_by_names=connection_by_names,
114
+ log_level=plugins.log_level,
115
+ volumes=volumes,
116
+ )
117
+
118
+ sidecar_containers = self.get_sidecar_containers(
119
+ polyaxon_sidecar=self.polyaxon_sidecar,
120
+ plugins=plugins,
121
+ artifacts_store=artifacts_store,
122
+ sidecar_containers=sidecars,
123
+ log_level=plugins.log_level,
124
+ volumes=volumes,
125
+ )
126
+
127
+ main_container = self.get_main_container(
128
+ main_container=self._ensure_container(container, volumes=volumes),
129
+ plugins=plugins,
130
+ artifacts_store=artifacts_store,
131
+ connections=connections,
132
+ init_connections=init_connections,
133
+ connection_by_names=connection_by_names,
134
+ secrets=secrets,
135
+ config_maps=config_maps,
136
+ ports=ports,
137
+ kv_env_vars=kv_env_vars,
138
+ )
139
+
140
+ return init_containers + sidecar_containers + [main_container]
@@ -0,0 +1,66 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from clipped.utils.lists import to_list
4
+ from clipped.utils.sanitizers import sanitize_value
5
+
6
+ from polyaxon._containers.names import sanitize_container_name
7
+ from polyaxon._local_process import process_types
8
+ from polyaxon._runner.converter import BaseConverter
9
+ from polyaxon._runner.converter.common.containers import sanitize_container_command_args
10
+
11
+
12
+ class ContainerMixin(BaseConverter):
13
+ @classmethod
14
+ def _patch_container(
15
+ cls,
16
+ container: process_types.V1Container,
17
+ name: Optional[str] = None,
18
+ command: Optional[List[str]] = None,
19
+ args: Optional[List[str]] = None,
20
+ env: Optional[List[process_types.V1EnvVar]] = None,
21
+ env_from: Optional[List[Any]] = None,
22
+ **kwargs,
23
+ ) -> process_types.V1Container:
24
+ container.name = sanitize_container_name(name or container.name)
25
+ container.env = to_list(container.env, check_none=True) + to_list(
26
+ env, check_none=True
27
+ )
28
+ if not any([container.command, container.args]):
29
+ container.command = command
30
+ container.args = args
31
+
32
+ return cls._sanitize_container(container)
33
+
34
+ @staticmethod
35
+ def _sanitize_container_env(
36
+ env: List[process_types.V1EnvVar],
37
+ ) -> List[process_types.V1EnvVar]:
38
+ def sanitize_env_dict(d: Dict):
39
+ return process_types.V1EnvVar.make(
40
+ {d_k: sanitize_value(d_v, handle_dict=False) for d_k, d_v in d.items()}
41
+ )
42
+
43
+ results = []
44
+ for e in env or []:
45
+ if isinstance(e, dict):
46
+ e = sanitize_env_dict(e)
47
+ results.append(e)
48
+ elif isinstance(e, tuple):
49
+ if e[1] is not None:
50
+ e = process_types.V1EnvVar.make(
51
+ (e[0], sanitize_value(e[1], handle_dict=False))
52
+ )
53
+ results.append(e)
54
+ elif isinstance(e, process_types.V1EnvVar):
55
+ results.append(e)
56
+
57
+ return results
58
+
59
+ @classmethod
60
+ def _sanitize_container(
61
+ cls,
62
+ container: process_types.V1Container,
63
+ ) -> process_types.V1Container:
64
+ container = sanitize_container_command_args(container)
65
+ container.env = cls._sanitize_container_env(container.env)
66
+ return container