polyaxon 2.0.0rc49__py3-none-any.whl → 2.4.0rc1__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 (177) hide show
  1. polyaxon/_auxiliaries/cleaner.py +8 -3
  2. polyaxon/_auxiliaries/init.py +7 -2
  3. polyaxon/_auxiliaries/notifier.py +8 -2
  4. polyaxon/_auxiliaries/sidecar.py +30 -2
  5. polyaxon/_cli/artifacts.py +96 -11
  6. polyaxon/_cli/components.py +96 -11
  7. polyaxon/_cli/config.py +118 -22
  8. polyaxon/_cli/dashboard.py +15 -2
  9. polyaxon/_cli/init.py +1 -1
  10. polyaxon/_cli/models.py +96 -11
  11. polyaxon/_cli/operations.py +267 -90
  12. polyaxon/_cli/project_versions.py +139 -6
  13. polyaxon/_cli/projects.py +23 -9
  14. polyaxon/_cli/run.py +37 -9
  15. polyaxon/_cli/services/agent.py +2 -2
  16. polyaxon/_cli/services/clean_artifacts.py +1 -1
  17. polyaxon/_cli/services/sidecar.py +8 -1
  18. polyaxon/_client/client.py +17 -0
  19. polyaxon/_client/mixin.py +39 -0
  20. polyaxon/_client/project.py +218 -23
  21. polyaxon/_client/run.py +131 -33
  22. polyaxon/_compiler/contexts/contexts.py +2 -2
  23. polyaxon/_compiler/contexts/ray_job.py +4 -2
  24. polyaxon/_compiler/resolver/agent.py +12 -2
  25. polyaxon/_compiler/resolver/runtime.py +2 -2
  26. polyaxon/_contexts/paths.py +4 -7
  27. polyaxon/_deploy/operators/compose.py +1 -27
  28. polyaxon/_deploy/schemas/deployment.py +4 -1
  29. polyaxon/_deploy/schemas/intervals.py +0 -7
  30. polyaxon/_deploy/schemas/proxy.py +1 -0
  31. polyaxon/_deploy/schemas/service.py +11 -1
  32. polyaxon/_docker/converter/base/base.py +8 -0
  33. polyaxon/_docker/executor.py +10 -4
  34. polyaxon/_env_vars/getters/owner_entity.py +4 -2
  35. polyaxon/_env_vars/getters/project.py +4 -2
  36. polyaxon/_env_vars/getters/run.py +5 -2
  37. polyaxon/_env_vars/keys.py +7 -1
  38. polyaxon/_flow/__init__.py +2 -0
  39. polyaxon/_flow/builds/__init__.py +19 -6
  40. polyaxon/_flow/component/base.py +1 -0
  41. polyaxon/_flow/component/component.py +14 -0
  42. polyaxon/_flow/environment/__init__.py +8 -8
  43. polyaxon/_flow/hooks/__init__.py +19 -6
  44. polyaxon/_flow/init/__init__.py +6 -6
  45. polyaxon/_flow/matrix/iterative.py +0 -1
  46. polyaxon/_flow/matrix/tuner.py +18 -6
  47. polyaxon/_flow/operations/operation.py +44 -17
  48. polyaxon/_flow/plugins/__init__.py +6 -0
  49. polyaxon/_flow/run/__init__.py +2 -2
  50. polyaxon/_flow/run/dag.py +2 -2
  51. polyaxon/_flow/run/dask/dask.py +0 -1
  52. polyaxon/_flow/run/dask/replica.py +3 -3
  53. polyaxon/_flow/run/enums.py +5 -0
  54. polyaxon/_flow/run/job.py +4 -4
  55. polyaxon/_flow/run/kubeflow/mpi_job.py +1 -2
  56. polyaxon/_flow/run/kubeflow/mx_job.py +1 -2
  57. polyaxon/_flow/run/kubeflow/paddle_job.py +35 -4
  58. polyaxon/_flow/run/kubeflow/pytorch_job.py +51 -5
  59. polyaxon/_flow/run/kubeflow/replica.py +4 -4
  60. polyaxon/_flow/run/kubeflow/scheduling_policy.py +12 -0
  61. polyaxon/_flow/run/kubeflow/tf_job.py +3 -3
  62. polyaxon/_flow/run/kubeflow/xgboost_job.py +1 -2
  63. polyaxon/_flow/run/ray/ray.py +2 -3
  64. polyaxon/_flow/run/ray/replica.py +3 -3
  65. polyaxon/_flow/run/service.py +4 -4
  66. polyaxon/_fs/fs.py +7 -2
  67. polyaxon/_fs/utils.py +3 -2
  68. polyaxon/_k8s/converter/base/base.py +2 -1
  69. polyaxon/_k8s/converter/base/main.py +1 -0
  70. polyaxon/_k8s/converter/base/sidecar.py +16 -1
  71. polyaxon/_k8s/converter/common/accelerators.py +7 -4
  72. polyaxon/_k8s/converter/converters/job.py +1 -1
  73. polyaxon/_k8s/converter/converters/kubeflow/paddle_job.py +1 -0
  74. polyaxon/_k8s/converter/converters/kubeflow/pytroch_job.py +2 -0
  75. polyaxon/_k8s/converter/converters/kubeflow/tf_job.py +1 -0
  76. polyaxon/_k8s/converter/converters/ray_job.py +4 -2
  77. polyaxon/_k8s/custom_resources/dask_job.py +3 -0
  78. polyaxon/_k8s/custom_resources/kubeflow/common.py +4 -1
  79. polyaxon/_k8s/custom_resources/kubeflow/paddle_job.py +10 -1
  80. polyaxon/_k8s/custom_resources/kubeflow/pytorch_job.py +14 -1
  81. polyaxon/_k8s/custom_resources/kubeflow/tf_job.py +4 -0
  82. polyaxon/_k8s/custom_resources/ray_job.py +3 -0
  83. polyaxon/_k8s/custom_resources/setter.py +1 -1
  84. polyaxon/_k8s/executor/async_executor.py +2 -0
  85. polyaxon/_k8s/executor/base.py +23 -6
  86. polyaxon/_k8s/logging/async_monitor.py +150 -5
  87. polyaxon/_k8s/manager/async_manager.py +96 -23
  88. polyaxon/_k8s/manager/base.py +4 -0
  89. polyaxon/_k8s/manager/manager.py +282 -134
  90. polyaxon/_local_process/__init__.py +0 -0
  91. polyaxon/_local_process/agent.py +6 -0
  92. polyaxon/_local_process/converter/__init__.py +1 -0
  93. polyaxon/_local_process/converter/base/__init__.py +1 -0
  94. polyaxon/_local_process/converter/base/base.py +140 -0
  95. polyaxon/_local_process/converter/base/containers.py +69 -0
  96. polyaxon/_local_process/converter/base/env_vars.py +253 -0
  97. polyaxon/_local_process/converter/base/init.py +414 -0
  98. polyaxon/_local_process/converter/base/main.py +74 -0
  99. polyaxon/_local_process/converter/base/mounts.py +82 -0
  100. polyaxon/_local_process/converter/converters/__init__.py +8 -0
  101. polyaxon/_local_process/converter/converters/job.py +40 -0
  102. polyaxon/_local_process/converter/converters/service.py +41 -0
  103. polyaxon/_local_process/converter/mixins.py +38 -0
  104. polyaxon/_local_process/executor.py +132 -0
  105. polyaxon/_local_process/process_types.py +39 -0
  106. polyaxon/_managers/agent.py +2 -0
  107. polyaxon/_managers/home.py +2 -1
  108. polyaxon/_operations/tuner.py +1 -0
  109. polyaxon/_polyaxonfile/check.py +2 -0
  110. polyaxon/_polyaxonfile/manager/operations.py +3 -0
  111. polyaxon/_polyaxonfile/manager/workflows.py +2 -0
  112. polyaxon/_polyaxonfile/specs/compiled_operation.py +1 -0
  113. polyaxon/_polyaxonfile/specs/operation.py +1 -0
  114. polyaxon/_polyaxonfile/specs/sections.py +3 -0
  115. polyaxon/_pql/manager.py +1 -1
  116. polyaxon/_runner/agent/async_agent.py +97 -21
  117. polyaxon/_runner/agent/base_agent.py +27 -9
  118. polyaxon/_runner/agent/client.py +15 -1
  119. polyaxon/_runner/agent/sync_agent.py +85 -20
  120. polyaxon/_runner/converter/converter.py +6 -2
  121. polyaxon/_runner/executor.py +13 -7
  122. polyaxon/_schemas/agent.py +27 -1
  123. polyaxon/_schemas/client.py +30 -3
  124. polyaxon/_schemas/installation.py +4 -3
  125. polyaxon/_schemas/lifecycle.py +10 -5
  126. polyaxon/_schemas/log_handler.py +2 -3
  127. polyaxon/_schemas/types/artifacts.py +3 -3
  128. polyaxon/_schemas/types/dockerfile.py +3 -3
  129. polyaxon/_schemas/types/file.py +3 -3
  130. polyaxon/_schemas/types/git.py +3 -3
  131. polyaxon/_schemas/types/tensorboard.py +3 -3
  132. polyaxon/_sdk/api/agents_v1_api.py +1076 -73
  133. polyaxon/_sdk/api/organizations_v1_api.py +371 -10
  134. polyaxon/_sdk/api/project_dashboards_v1_api.py +12 -12
  135. polyaxon/_sdk/api/project_searches_v1_api.py +12 -12
  136. polyaxon/_sdk/api/projects_v1_api.py +221 -44
  137. polyaxon/_sdk/api/runs_v1_api.py +917 -445
  138. polyaxon/_sdk/api/service_accounts_v1_api.py +16 -16
  139. polyaxon/_sdk/api/teams_v1_api.py +2827 -375
  140. polyaxon/_sdk/api/users_v1_api.py +231 -55
  141. polyaxon/_sdk/async_client/api_client.py +4 -0
  142. polyaxon/_sdk/schemas/__init__.py +10 -2
  143. polyaxon/_sdk/schemas/v1_agent.py +2 -1
  144. polyaxon/_sdk/schemas/v1_agent_reconcile_body_request.py +14 -0
  145. polyaxon/_sdk/schemas/v1_artifact_tree.py +1 -1
  146. polyaxon/_sdk/schemas/v1_dashboard_spec.py +4 -0
  147. polyaxon/_sdk/schemas/v1_events_response.py +4 -0
  148. polyaxon/_sdk/schemas/v1_organization.py +1 -0
  149. polyaxon/_sdk/schemas/v1_preset.py +8 -0
  150. polyaxon/_sdk/schemas/v1_project.py +1 -0
  151. polyaxon/_sdk/schemas/v1_project_settings.py +4 -2
  152. polyaxon/_sdk/schemas/v1_run.py +2 -2
  153. polyaxon/_sdk/schemas/v1_run_edge_lineage.py +14 -0
  154. polyaxon/_sdk/schemas/v1_run_edges_graph.py +9 -0
  155. polyaxon/_sdk/schemas/v1_section_spec.py +7 -2
  156. polyaxon/_sdk/schemas/v1_settings_catalog.py +1 -0
  157. polyaxon/_sdk/schemas/v1_team.py +3 -0
  158. polyaxon/_sdk/schemas/v1_user.py +1 -2
  159. polyaxon/_sdk/schemas/v1_user_access.py +17 -0
  160. polyaxon/_services/values.py +1 -0
  161. polyaxon/_sidecar/container/__init__.py +39 -18
  162. polyaxon/_sidecar/container/monitors/__init__.py +1 -0
  163. polyaxon/_sidecar/container/monitors/logs.py +10 -13
  164. polyaxon/_sidecar/container/monitors/spec.py +24 -0
  165. polyaxon/_sidecar/ignore.py +0 -1
  166. polyaxon/_utils/fqn_utils.py +25 -2
  167. polyaxon/client.py +1 -1
  168. polyaxon/pkg.py +1 -1
  169. polyaxon/schemas.py +8 -1
  170. polyaxon/settings.py +6 -0
  171. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/METADATA +43 -43
  172. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/RECORD +176 -155
  173. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/WHEEL +1 -1
  174. polyaxon/_sdk/schemas/v1_project_user_access.py +0 -10
  175. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/LICENSE +0 -0
  176. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/entry_points.txt +0 -0
  177. {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,414 @@
1
+ from typing import Any, List, Optional, Tuple, Union
2
+
3
+ from clipped.utils.enums import get_enum_value
4
+ from clipped.utils.lists import to_list
5
+
6
+ from polyaxon._auxiliaries import V1PolyaxonInitContainer
7
+ from polyaxon._connections import V1Connection, V1ConnectionKind
8
+ from polyaxon._constants.globals import DEFAULT
9
+ from polyaxon._containers.names import (
10
+ INIT_ARTIFACTS_CONTAINER_PREFIX,
11
+ INIT_AUTH_CONTAINER,
12
+ INIT_CUSTOM_CONTAINER_PREFIX,
13
+ INIT_DOCKERFILE_CONTAINER_PREFIX,
14
+ INIT_FILE_CONTAINER_PREFIX,
15
+ INIT_GIT_CONTAINER_PREFIX,
16
+ INIT_TENSORBOARD_CONTAINER_PREFIX,
17
+ generate_container_name,
18
+ )
19
+ from polyaxon._contexts import paths as ctx_paths
20
+ from polyaxon._env_vars.keys import ENV_KEYS_SSH_PATH
21
+ from polyaxon._flow import V1Plugins
22
+ from polyaxon._local_process import process_types
23
+ from polyaxon._runner.converter import BaseConverter as _BaseConverter
24
+ from polyaxon._runner.converter.init.artifacts import init_artifact_context_args
25
+ from polyaxon._runner.converter.init.file import FILE_INIT_COMMAND, get_file_init_args
26
+ from polyaxon._runner.converter.init.git import REPO_INIT_COMMAND, get_repo_context_args
27
+ from polyaxon._runner.converter.init.store import get_volume_args
28
+ from polyaxon._runner.converter.init.tensorboard import (
29
+ TENSORBOARD_INIT_COMMAND,
30
+ get_tensorboard_args,
31
+ )
32
+ from polyaxon._schemas.types import (
33
+ V1ArtifactsType,
34
+ V1DockerfileType,
35
+ V1FileType,
36
+ V1TensorboardType,
37
+ )
38
+ from polyaxon.exceptions import PolyaxonConverterError
39
+
40
+
41
+ class InitConverter(_BaseConverter):
42
+ @classmethod
43
+ def _get_base_store_container(
44
+ cls,
45
+ container: Optional[process_types.V1Container],
46
+ container_name: str,
47
+ polyaxon_init: V1PolyaxonInitContainer,
48
+ store: V1Connection,
49
+ env: List[process_types.V1EnvVar],
50
+ env_from: List[Any],
51
+ args: List[str],
52
+ command: Optional[List[str]] = None,
53
+ **kwargs
54
+ ) -> Optional[process_types.V1Container]:
55
+ env = env or []
56
+
57
+ # Artifact store needs to allow init the contexts as well, so the store is not required
58
+ if not store:
59
+ raise PolyaxonConverterError("Init store container requires a store")
60
+
61
+ if store.is_bucket:
62
+ secret = store.secret
63
+ env = env + to_list(
64
+ cls._get_items_from_json_resource(resource=secret), check_none=True
65
+ )
66
+ config_map = store.config_map
67
+ env = env + to_list(
68
+ cls._get_from_json_resource(resource=config_map),
69
+ check_none=True,
70
+ )
71
+ # Add connections catalog env vars information
72
+ connection_env = cls._get_connections_catalog_env_var(connections=[store])
73
+ if connection_env:
74
+ env.append(connection_env)
75
+
76
+ return cls._patch_container(
77
+ container=container,
78
+ name=container_name,
79
+ command=command or ["/bin/sh", "-c"],
80
+ args=args,
81
+ env=env,
82
+ )
83
+
84
+ @classmethod
85
+ def _get_custom_init_container(
86
+ cls,
87
+ connection: V1Connection,
88
+ plugins: V1Plugins,
89
+ container: Optional[process_types.V1Container],
90
+ run_path: str,
91
+ env: List[process_types.V1EnvVar] = None,
92
+ mount_path: Optional[str] = None,
93
+ ) -> process_types.V1Container:
94
+ if not connection:
95
+ raise PolyaxonConverterError(
96
+ "A connection is required to create a repo context."
97
+ )
98
+
99
+ env = to_list(env, check_none=True)
100
+ secret = connection.secret
101
+ if secret:
102
+ env += to_list(
103
+ cls._get_from_json_resource(resource=secret), check_none=True
104
+ )
105
+
106
+ # Add connections catalog env vars information
107
+ connection_env = cls._get_connections_catalog_env_var(connections=[connection])
108
+ if connection_env:
109
+ env.append(connection_env)
110
+ connection_env = cls._get_connection_env_var(connection=connection)
111
+ if connection_env:
112
+ env.append(connection_env)
113
+ config_map = connection.config_map
114
+ if config_map:
115
+ env += to_list(
116
+ cls._get_from_json_resource(resource=config_map),
117
+ check_none=True,
118
+ )
119
+ container_name = container.name or generate_container_name(
120
+ INIT_CUSTOM_CONTAINER_PREFIX, connection.name
121
+ )
122
+ return cls._patch_container(
123
+ container=container,
124
+ name=container_name,
125
+ env=env,
126
+ )
127
+
128
+ @classmethod
129
+ def _get_dockerfile_init_container(
130
+ cls,
131
+ polyaxon_init: V1PolyaxonInitContainer,
132
+ dockerfile_args: V1DockerfileType,
133
+ plugins: V1Plugins,
134
+ run_path: str,
135
+ run_instance: str,
136
+ container: Optional[process_types.V1Container] = None,
137
+ env: List[process_types.V1EnvVar] = None,
138
+ mount_path: Optional[str] = None,
139
+ ) -> process_types.V1Container:
140
+ env = to_list(env, check_none=True)
141
+ env = env + [cls._get_run_instance_env_var(run_instance)]
142
+
143
+ container_name = generate_container_name(INIT_DOCKERFILE_CONTAINER_PREFIX)
144
+ if not container:
145
+ container = cls._new_container(name=container_name)
146
+
147
+ mount_path = mount_path or ctx_paths.CONTEXT_MOUNT_ARTIFACTS
148
+
149
+ return cls._patch_container(
150
+ container=container,
151
+ name=container_name,
152
+ image=polyaxon_init.get_image(),
153
+ image_pull_policy=polyaxon_init.image_pull_policy,
154
+ command=["polyaxon", "docker", "generate"],
155
+ args=[
156
+ "--build-context={}".format(dockerfile_args.to_json()),
157
+ "--destination={}".format(mount_path),
158
+ "--copy-path={}".format(
159
+ ctx_paths.CONTEXT_MOUNT_RUN_OUTPUTS_FORMAT.format(run_path)
160
+ ),
161
+ "--track",
162
+ ],
163
+ env=env,
164
+ )
165
+
166
+ @classmethod
167
+ def _get_file_init_container(
168
+ cls,
169
+ polyaxon_init: V1PolyaxonInitContainer,
170
+ file_args: V1FileType,
171
+ plugins: V1Plugins,
172
+ run_path: str,
173
+ run_instance: str,
174
+ container: Optional[process_types.V1Container] = None,
175
+ env: List[process_types.V1EnvVar] = None,
176
+ mount_path: Optional[str] = None,
177
+ ) -> process_types.V1Container:
178
+ env = to_list(env, check_none=True)
179
+ env = env + [cls._get_run_instance_env_var(run_instance)]
180
+
181
+ container_name = generate_container_name(INIT_FILE_CONTAINER_PREFIX)
182
+ if not container:
183
+ container = cls._new_container(name=container_name)
184
+
185
+ mount_path = mount_path or ctx_paths.CONTEXT_MOUNT_ARTIFACTS
186
+
187
+ file_args.filename = file_args.filename or "file"
188
+ return cls._patch_container(
189
+ container=container,
190
+ name=container_name,
191
+ image=polyaxon_init.get_image(),
192
+ image_pull_policy=polyaxon_init.image_pull_policy,
193
+ command=FILE_INIT_COMMAND,
194
+ args=get_file_init_args(
195
+ file_args=file_args, run_path=run_path, mount_path=mount_path
196
+ ),
197
+ env=env,
198
+ )
199
+
200
+ @classmethod
201
+ def _get_git_init_container(
202
+ cls,
203
+ polyaxon_init: V1PolyaxonInitContainer,
204
+ connection: V1Connection,
205
+ plugins: V1Plugins,
206
+ run_path: str,
207
+ container: Optional[process_types.V1Container] = None,
208
+ env: List[process_types.V1EnvVar] = None,
209
+ mount_path: Optional[str] = None,
210
+ track: bool = False,
211
+ ) -> process_types.V1Container:
212
+ if not connection:
213
+ raise PolyaxonConverterError(
214
+ "A connection is required to create a repo context."
215
+ )
216
+ container_name = generate_container_name(
217
+ INIT_GIT_CONTAINER_PREFIX, connection.name
218
+ )
219
+ if not container:
220
+ container = cls._new_container(name=container_name)
221
+
222
+ mount_path = mount_path or ctx_paths.CONTEXT_MOUNT_ARTIFACTS
223
+
224
+ env = to_list(env, check_none=True)
225
+ env_from = []
226
+ secret = connection.secret
227
+ if secret:
228
+ env += to_list(
229
+ cls._get_from_json_resource(resource=secret), check_none=True
230
+ )
231
+ env_from += to_list(
232
+ cls._get_env_from_secret(secret=secret), check_none=True
233
+ )
234
+
235
+ # Add connections catalog env vars information
236
+ env += to_list(
237
+ cls._get_connections_catalog_env_var(connections=[connection]),
238
+ check_none=True,
239
+ )
240
+ env += to_list(
241
+ cls._get_connection_env_var(connection=connection), check_none=True
242
+ )
243
+ # Add special handling to auto-inject ssh mount path
244
+ if connection.kind == V1ConnectionKind.SSH and secret.mount_path:
245
+ env += [cls._get_env_var(ENV_KEYS_SSH_PATH, secret.mount_path)]
246
+ config_map = connection.config_map
247
+ if config_map:
248
+ env += to_list(
249
+ cls._get_from_json_resource(resource=config_map),
250
+ check_none=True,
251
+ )
252
+ env_from += to_list(
253
+ cls._get_env_from_config_map(config_map=config_map),
254
+ check_none=True,
255
+ )
256
+ args = get_repo_context_args(
257
+ name=connection.name,
258
+ # Handle the case of custom connection
259
+ url=getattr(connection.schema_, "url", None),
260
+ revision=getattr(connection.schema_, "revision", None),
261
+ flags=getattr(connection.schema_, "flags", None),
262
+ mount_path=mount_path,
263
+ connection=connection.name if track else None,
264
+ )
265
+ return cls._patch_container(
266
+ container=container,
267
+ name=container_name,
268
+ image=polyaxon_init.get_image(),
269
+ image_pull_policy=polyaxon_init.image_pull_policy,
270
+ command=REPO_INIT_COMMAND,
271
+ args=args,
272
+ env=env,
273
+ env_from=env_from,
274
+ )
275
+
276
+ @classmethod
277
+ def _get_store_init_container(
278
+ cls,
279
+ polyaxon_init: V1PolyaxonInitContainer,
280
+ connection: V1Connection,
281
+ artifacts: V1ArtifactsType,
282
+ paths: Union[List[str], List[Tuple[str, str]]],
283
+ run_path: str,
284
+ container: Optional[process_types.V1Container] = None,
285
+ env: List[process_types.V1EnvVar] = None,
286
+ mount_path: Optional[str] = None,
287
+ is_default_artifacts_store: bool = False,
288
+ ) -> process_types.V1Container:
289
+ container_name = generate_container_name(
290
+ INIT_ARTIFACTS_CONTAINER_PREFIX, connection.name
291
+ )
292
+ if not container:
293
+ container = cls._new_container(name=container_name)
294
+
295
+ mount_path = mount_path or (
296
+ ctx_paths.CONTEXT_MOUNT_ARTIFACTS
297
+ if is_default_artifacts_store
298
+ else ctx_paths.CONTEXT_MOUNT_ARTIFACTS_FORMAT.format(connection.name)
299
+ )
300
+
301
+ return cls._get_base_store_container(
302
+ container=container,
303
+ container_name=container_name,
304
+ polyaxon_init=polyaxon_init,
305
+ store=connection,
306
+ env=env,
307
+ env_from=[],
308
+ args=[
309
+ get_volume_args(
310
+ store=connection,
311
+ mount_path=mount_path,
312
+ artifacts=artifacts,
313
+ paths=paths,
314
+ )
315
+ ],
316
+ )
317
+
318
+ @classmethod
319
+ def _get_tensorboard_init_container(
320
+ cls,
321
+ polyaxon_init: V1PolyaxonInitContainer,
322
+ artifacts_store: V1Connection,
323
+ tb_args: V1TensorboardType,
324
+ plugins: V1Plugins,
325
+ run_path: str,
326
+ run_instance: str,
327
+ container: Optional[process_types.V1Container] = None,
328
+ env: List[process_types.V1EnvVar] = None,
329
+ mount_path: Optional[str] = None,
330
+ ) -> process_types.V1Container:
331
+ env = to_list(env, check_none=True)
332
+ env = env + [cls._get_run_instance_env_var(run_instance)]
333
+
334
+ container_name = generate_container_name(INIT_TENSORBOARD_CONTAINER_PREFIX)
335
+ if not container:
336
+ container = cls._new_container(name=container_name)
337
+
338
+ mount_path = mount_path or ctx_paths.CONTEXT_MOUNT_ARTIFACTS
339
+
340
+ args = get_tensorboard_args(
341
+ tb_args=tb_args,
342
+ context_from=artifacts_store.store_path,
343
+ context_to=mount_path,
344
+ connection_kind=get_enum_value(artifacts_store.kind),
345
+ )
346
+
347
+ return cls._get_base_store_container(
348
+ container=container,
349
+ container_name=container_name,
350
+ polyaxon_init=polyaxon_init,
351
+ store=artifacts_store,
352
+ command=TENSORBOARD_INIT_COMMAND,
353
+ args=args,
354
+ env=env,
355
+ env_from=[],
356
+ )
357
+
358
+ @classmethod
359
+ def _get_auth_context_init_container(
360
+ cls,
361
+ polyaxon_init: V1PolyaxonInitContainer,
362
+ run_path: str,
363
+ env: Optional[List[process_types.V1EnvVar]] = None,
364
+ ) -> process_types.V1Container:
365
+ env = to_list(env, check_none=True)
366
+ container = process_types.V1Container(
367
+ name=INIT_AUTH_CONTAINER,
368
+ image=polyaxon_init.get_image(),
369
+ command=["polyaxon", "initializer", "auth"],
370
+ env=env,
371
+ )
372
+ return cls._patch_container(container)
373
+
374
+ @classmethod
375
+ def _get_artifacts_path_init_container(
376
+ cls,
377
+ polyaxon_init: V1PolyaxonInitContainer,
378
+ artifacts_store: V1Connection,
379
+ run_path: str,
380
+ auto_resume: bool,
381
+ env: Optional[List[process_types.V1EnvVar]] = None,
382
+ ) -> process_types.V1Container:
383
+ if not artifacts_store:
384
+ raise PolyaxonConverterError("Init artifacts container requires a store.")
385
+
386
+ env = to_list(env, check_none=True)
387
+ init_args = init_artifact_context_args(run_path=run_path)
388
+ if auto_resume:
389
+ init_args.append(
390
+ get_volume_args(
391
+ store=artifacts_store,
392
+ mount_path=ctx_paths.CONTEXT_MOUNT_ARTIFACTS,
393
+ artifacts=V1ArtifactsType(dirs=[run_path]),
394
+ paths=None,
395
+ sync_fw=True,
396
+ )
397
+ )
398
+
399
+ container_name = generate_container_name(
400
+ INIT_ARTIFACTS_CONTAINER_PREFIX, DEFAULT, False
401
+ )
402
+ container = cls._new_container(name=container_name)
403
+
404
+ return cls._get_base_store_container(
405
+ container_name=container_name,
406
+ container=container,
407
+ polyaxon_init=polyaxon_init,
408
+ store=artifacts_store,
409
+ env=env,
410
+ env_from=[],
411
+ # If we are dealing with a volume we need to make sure the path exists for the user
412
+ # We also clean the path if this is not a resume run
413
+ args=[" ".join(init_args)],
414
+ )
@@ -0,0 +1,74 @@
1
+ from typing import Dict, Iterable, List, Optional
2
+
3
+ from clipped.utils.lists import to_list
4
+
5
+ from polyaxon._connections import V1Connection, V1ConnectionResource
6
+ from polyaxon._flow import V1Init, V1Plugins
7
+ from polyaxon._local_process import process_types
8
+ from polyaxon._runner.converter import BaseConverter as _BaseConverter
9
+ from polyaxon.exceptions import PolyaxonConverterError
10
+
11
+
12
+ class MainConverter(_BaseConverter):
13
+ def _get_main_container(
14
+ self,
15
+ container_id: str,
16
+ main_container: process_types.V1Container,
17
+ plugins: V1Plugins,
18
+ artifacts_store: Optional[V1Connection],
19
+ init: Optional[List[V1Init]],
20
+ connections: Optional[List[str]],
21
+ connection_by_names: Dict[str, V1Connection],
22
+ secrets: Optional[Iterable[V1ConnectionResource]],
23
+ config_maps: Optional[Iterable[V1ConnectionResource]],
24
+ run_path: Optional[str],
25
+ kv_env_vars: List[List] = None,
26
+ ports: List[int] = None,
27
+ ) -> process_types.V1Container:
28
+ connections = connections or []
29
+ connection_by_names = connection_by_names or {}
30
+ secrets = secrets or []
31
+ config_maps = config_maps or []
32
+
33
+ if artifacts_store and not run_path:
34
+ raise PolyaxonConverterError("Run path is required for main container.")
35
+
36
+ if artifacts_store and (
37
+ not plugins.collect_artifacts or plugins.mount_artifacts_store
38
+ ):
39
+ if artifacts_store.name not in connection_by_names:
40
+ connection_by_names[artifacts_store.name] = artifacts_store
41
+ if artifacts_store.name not in connections:
42
+ connections.append(artifacts_store.name)
43
+
44
+ requested_connections = [connection_by_names[c] for c in connections]
45
+ requested_config_maps = V1Connection.get_requested_resources(
46
+ resources=config_maps,
47
+ connections=requested_connections,
48
+ resource_key="config_map",
49
+ )
50
+ requested_secrets = V1Connection.get_requested_resources(
51
+ resources=secrets, connections=requested_connections, resource_key="secret"
52
+ )
53
+
54
+ # Env vars
55
+ env = self._get_main_env_vars(
56
+ plugins=plugins,
57
+ kv_env_vars=kv_env_vars,
58
+ artifacts_store_name=artifacts_store.name if artifacts_store else None,
59
+ connections=requested_connections,
60
+ secrets=requested_secrets,
61
+ config_maps=requested_config_maps,
62
+ )
63
+
64
+ # Env from
65
+ resources = to_list(requested_secrets, check_none=True) + to_list(
66
+ requested_config_maps, check_none=True
67
+ )
68
+ env += self._get_env_from_json_resources(resources=resources)
69
+
70
+ return self._patch_container(
71
+ container=main_container,
72
+ name=container_id,
73
+ env=env,
74
+ )
@@ -0,0 +1,82 @@
1
+ from typing import List, Optional
2
+
3
+ from polyaxon._connections import V1Connection, V1ConnectionResource
4
+ from polyaxon._contexts import paths as ctx_paths
5
+ from polyaxon._local_process import process_types
6
+ from polyaxon._runner.converter import BaseConverter
7
+
8
+
9
+ class MountsMixin(BaseConverter):
10
+ @classmethod
11
+ def _get_mount_from_store(
12
+ cls,
13
+ store: V1Connection,
14
+ ):
15
+ pass
16
+
17
+ @classmethod
18
+ def _get_mount_from_resource(
19
+ cls,
20
+ resource: V1ConnectionResource,
21
+ ):
22
+ pass
23
+
24
+ @classmethod
25
+ def _get_volume(
26
+ cls,
27
+ mount_path: str,
28
+ host_path: Optional[str] = None,
29
+ read_only: Optional[bool] = None,
30
+ ):
31
+ pass
32
+
33
+ @classmethod
34
+ def _get_docker_context_mount(cls):
35
+ pass
36
+
37
+ @classmethod
38
+ def _get_auth_context_mount(
39
+ cls,
40
+ read_only: Optional[bool] = None,
41
+ run_path: Optional[str] = None,
42
+ ):
43
+ pass
44
+
45
+ @classmethod
46
+ def _get_artifacts_context_mount(
47
+ cls,
48
+ read_only: bool = False,
49
+ run_path: Optional[str] = None,
50
+ ):
51
+ pass
52
+
53
+ @classmethod
54
+ def _get_connections_context_mount(
55
+ cls,
56
+ name: str,
57
+ mount_path: str,
58
+ run_path: str,
59
+ ):
60
+ pass
61
+
62
+ @classmethod
63
+ def _get_shm_context_mount(cls):
64
+ """
65
+ Mount a tmpfs volume to /dev/shm.
66
+ This will set /dev/shm size to half of the RAM of node.
67
+ By default, /dev/shm is very small, only 64MB.
68
+ Some experiments will fail due to lack of share memory,
69
+ such as some experiments running on Pytorch.
70
+ """
71
+ pass
72
+
73
+ @classmethod
74
+ def _get_mounts(
75
+ cls,
76
+ use_auth_context: bool,
77
+ use_docker_context: bool,
78
+ use_shm_context: bool,
79
+ use_artifacts_context: bool,
80
+ run_path: Optional[str] = None,
81
+ ) -> List:
82
+ return []
@@ -0,0 +1,8 @@
1
+ from polyaxon._flow import V1RunKind
2
+ from polyaxon._local_process.converter.converters.job import JobConverter
3
+ from polyaxon._local_process.converter.converters.service import ServiceConverter
4
+
5
+ CONVERTERS = {
6
+ V1RunKind.JOB: JobConverter,
7
+ V1RunKind.SERVICE: ServiceConverter,
8
+ }
@@ -0,0 +1,40 @@
1
+ from typing import Dict, Iterable, List, Optional
2
+
3
+ from polyaxon._connections import V1Connection, V1ConnectionResource
4
+ from polyaxon._flow import V1CompiledOperation, V1Job, V1Plugins
5
+ from polyaxon._k8s.converter.mixins import JobMixin
6
+ from polyaxon._local_process import process_types
7
+ from polyaxon._local_process.converter.base import BaseConverter
8
+
9
+
10
+ class JobConverter(JobMixin, BaseConverter):
11
+ def get_resource(
12
+ self,
13
+ compiled_operation: V1CompiledOperation,
14
+ artifacts_store: V1Connection,
15
+ connection_by_names: Dict[str, V1Connection],
16
+ secrets: Optional[Iterable[V1ConnectionResource]],
17
+ config_maps: Optional[Iterable[V1ConnectionResource]],
18
+ default_sa: Optional[str] = None,
19
+ default_auth: bool = False,
20
+ ) -> List[process_types.V1Container]:
21
+ job = compiled_operation.run # type: V1Job
22
+ plugins = V1Plugins.get_or_create(
23
+ config=compiled_operation.plugins, auth=default_auth
24
+ )
25
+ kv_env_vars = compiled_operation.get_env_io()
26
+ return self.get_replica_resource(
27
+ environment=job.environment,
28
+ plugins=plugins,
29
+ volumes=job.volumes,
30
+ init=job.init,
31
+ sidecars=job.sidecars,
32
+ container=job.container,
33
+ artifacts_store=artifacts_store,
34
+ connections=job.connections,
35
+ connection_by_names=connection_by_names,
36
+ secrets=secrets,
37
+ config_maps=config_maps,
38
+ kv_env_vars=kv_env_vars,
39
+ default_sa=default_sa,
40
+ )
@@ -0,0 +1,41 @@
1
+ from typing import Dict, Iterable, List, Optional
2
+
3
+ from polyaxon._connections import V1Connection, V1ConnectionResource
4
+ from polyaxon._flow import V1CompiledOperation, V1Plugins, V1Service
5
+ from polyaxon._local_process import process_types
6
+ from polyaxon._local_process.converter.base import BaseConverter
7
+ from polyaxon._local_process.converter.mixins import ServiceMixin
8
+
9
+
10
+ class ServiceConverter(ServiceMixin, BaseConverter):
11
+ def get_resource(
12
+ self,
13
+ compiled_operation: V1CompiledOperation,
14
+ artifacts_store: V1Connection,
15
+ connection_by_names: Dict[str, V1Connection],
16
+ secrets: Optional[Iterable[V1ConnectionResource]],
17
+ config_maps: Optional[Iterable[V1ConnectionResource]],
18
+ default_sa: Optional[str] = None,
19
+ default_auth: bool = False,
20
+ ) -> List[process_types.V1Container]:
21
+ service = compiled_operation.run # type: V1Service
22
+ plugins = V1Plugins.get_or_create(
23
+ config=compiled_operation.plugins, auth=default_auth
24
+ )
25
+ kv_env_vars = compiled_operation.get_env_io()
26
+ return self.get_replica_resource(
27
+ plugins=plugins,
28
+ environment=service.environment,
29
+ volumes=service.volumes,
30
+ init=service.init,
31
+ sidecars=service.sidecars,
32
+ container=service.container,
33
+ artifacts_store=artifacts_store,
34
+ connections=service.connections,
35
+ connection_by_names=connection_by_names,
36
+ secrets=secrets,
37
+ config_maps=config_maps,
38
+ kv_env_vars=kv_env_vars,
39
+ default_sa=default_sa,
40
+ ports=service.ports,
41
+ )
@@ -0,0 +1,38 @@
1
+ from typing import Dict
2
+
3
+ from polyaxon._containers.names import MAIN_JOB_CONTAINER
4
+ from polyaxon._flow import V1RunKind
5
+
6
+
7
+ class JobMixin:
8
+ K8S_ANNOTATIONS_KIND = V1RunKind.JOB
9
+ MAIN_CONTAINER_ID = MAIN_JOB_CONTAINER
10
+
11
+
12
+ class NotifierMixin:
13
+ K8S_ANNOTATIONS_KIND = V1RunKind.NOTIFIER
14
+ MAIN_CONTAINER_ID = MAIN_JOB_CONTAINER
15
+
16
+
17
+ class CleanerMixin:
18
+ K8S_ANNOTATIONS_KIND = V1RunKind.CLEANER
19
+ MAIN_CONTAINER_ID = MAIN_JOB_CONTAINER
20
+
21
+
22
+ class TunerMixin:
23
+ K8S_ANNOTATIONS_KIND = V1RunKind.TUNER
24
+ MAIN_CONTAINER_ID = MAIN_JOB_CONTAINER
25
+
26
+
27
+ class ServiceMixin:
28
+ K8S_ANNOTATIONS_KIND = V1RunKind.SERVICE
29
+ MAIN_CONTAINER_ID = MAIN_JOB_CONTAINER
30
+
31
+
32
+ MIXIN_MAPPING: Dict = {
33
+ V1RunKind.JOB: JobMixin,
34
+ V1RunKind.NOTIFIER: NotifierMixin,
35
+ V1RunKind.CLEANER: CleanerMixin,
36
+ V1RunKind.TUNER: TunerMixin,
37
+ V1RunKind.SERVICE: ServiceMixin,
38
+ }