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.
- polyaxon/_auxiliaries/cleaner.py +8 -3
- polyaxon/_auxiliaries/init.py +7 -2
- polyaxon/_auxiliaries/notifier.py +8 -2
- polyaxon/_auxiliaries/sidecar.py +30 -2
- polyaxon/_cli/artifacts.py +96 -11
- polyaxon/_cli/components.py +96 -11
- polyaxon/_cli/config.py +118 -22
- polyaxon/_cli/dashboard.py +15 -2
- polyaxon/_cli/init.py +1 -1
- polyaxon/_cli/models.py +96 -11
- polyaxon/_cli/operations.py +267 -90
- polyaxon/_cli/project_versions.py +139 -6
- polyaxon/_cli/projects.py +23 -9
- polyaxon/_cli/run.py +37 -9
- polyaxon/_cli/services/agent.py +2 -2
- polyaxon/_cli/services/clean_artifacts.py +1 -1
- polyaxon/_cli/services/sidecar.py +8 -1
- polyaxon/_client/client.py +17 -0
- polyaxon/_client/mixin.py +39 -0
- polyaxon/_client/project.py +218 -23
- polyaxon/_client/run.py +131 -33
- polyaxon/_compiler/contexts/contexts.py +2 -2
- polyaxon/_compiler/contexts/ray_job.py +4 -2
- polyaxon/_compiler/resolver/agent.py +12 -2
- polyaxon/_compiler/resolver/runtime.py +2 -2
- polyaxon/_contexts/paths.py +4 -7
- polyaxon/_deploy/operators/compose.py +1 -27
- polyaxon/_deploy/schemas/deployment.py +4 -1
- polyaxon/_deploy/schemas/intervals.py +0 -7
- polyaxon/_deploy/schemas/proxy.py +1 -0
- polyaxon/_deploy/schemas/service.py +11 -1
- polyaxon/_docker/converter/base/base.py +8 -0
- polyaxon/_docker/executor.py +10 -4
- polyaxon/_env_vars/getters/owner_entity.py +4 -2
- polyaxon/_env_vars/getters/project.py +4 -2
- polyaxon/_env_vars/getters/run.py +5 -2
- polyaxon/_env_vars/keys.py +7 -1
- polyaxon/_flow/__init__.py +2 -0
- polyaxon/_flow/builds/__init__.py +19 -6
- polyaxon/_flow/component/base.py +1 -0
- polyaxon/_flow/component/component.py +14 -0
- polyaxon/_flow/environment/__init__.py +8 -8
- polyaxon/_flow/hooks/__init__.py +19 -6
- polyaxon/_flow/init/__init__.py +6 -6
- polyaxon/_flow/matrix/iterative.py +0 -1
- polyaxon/_flow/matrix/tuner.py +18 -6
- polyaxon/_flow/operations/operation.py +44 -17
- polyaxon/_flow/plugins/__init__.py +6 -0
- polyaxon/_flow/run/__init__.py +2 -2
- polyaxon/_flow/run/dag.py +2 -2
- polyaxon/_flow/run/dask/dask.py +0 -1
- polyaxon/_flow/run/dask/replica.py +3 -3
- polyaxon/_flow/run/enums.py +5 -0
- polyaxon/_flow/run/job.py +4 -4
- polyaxon/_flow/run/kubeflow/mpi_job.py +1 -2
- polyaxon/_flow/run/kubeflow/mx_job.py +1 -2
- polyaxon/_flow/run/kubeflow/paddle_job.py +35 -4
- polyaxon/_flow/run/kubeflow/pytorch_job.py +51 -5
- polyaxon/_flow/run/kubeflow/replica.py +4 -4
- polyaxon/_flow/run/kubeflow/scheduling_policy.py +12 -0
- polyaxon/_flow/run/kubeflow/tf_job.py +3 -3
- polyaxon/_flow/run/kubeflow/xgboost_job.py +1 -2
- polyaxon/_flow/run/ray/ray.py +2 -3
- polyaxon/_flow/run/ray/replica.py +3 -3
- polyaxon/_flow/run/service.py +4 -4
- polyaxon/_fs/fs.py +7 -2
- polyaxon/_fs/utils.py +3 -2
- polyaxon/_k8s/converter/base/base.py +2 -1
- polyaxon/_k8s/converter/base/main.py +1 -0
- polyaxon/_k8s/converter/base/sidecar.py +16 -1
- polyaxon/_k8s/converter/common/accelerators.py +7 -4
- polyaxon/_k8s/converter/converters/job.py +1 -1
- polyaxon/_k8s/converter/converters/kubeflow/paddle_job.py +1 -0
- polyaxon/_k8s/converter/converters/kubeflow/pytroch_job.py +2 -0
- polyaxon/_k8s/converter/converters/kubeflow/tf_job.py +1 -0
- polyaxon/_k8s/converter/converters/ray_job.py +4 -2
- polyaxon/_k8s/custom_resources/dask_job.py +3 -0
- polyaxon/_k8s/custom_resources/kubeflow/common.py +4 -1
- polyaxon/_k8s/custom_resources/kubeflow/paddle_job.py +10 -1
- polyaxon/_k8s/custom_resources/kubeflow/pytorch_job.py +14 -1
- polyaxon/_k8s/custom_resources/kubeflow/tf_job.py +4 -0
- polyaxon/_k8s/custom_resources/ray_job.py +3 -0
- polyaxon/_k8s/custom_resources/setter.py +1 -1
- polyaxon/_k8s/executor/async_executor.py +2 -0
- polyaxon/_k8s/executor/base.py +23 -6
- polyaxon/_k8s/logging/async_monitor.py +150 -5
- polyaxon/_k8s/manager/async_manager.py +96 -23
- polyaxon/_k8s/manager/base.py +4 -0
- polyaxon/_k8s/manager/manager.py +282 -134
- polyaxon/_local_process/__init__.py +0 -0
- polyaxon/_local_process/agent.py +6 -0
- polyaxon/_local_process/converter/__init__.py +1 -0
- polyaxon/_local_process/converter/base/__init__.py +1 -0
- polyaxon/_local_process/converter/base/base.py +140 -0
- polyaxon/_local_process/converter/base/containers.py +69 -0
- polyaxon/_local_process/converter/base/env_vars.py +253 -0
- polyaxon/_local_process/converter/base/init.py +414 -0
- polyaxon/_local_process/converter/base/main.py +74 -0
- polyaxon/_local_process/converter/base/mounts.py +82 -0
- polyaxon/_local_process/converter/converters/__init__.py +8 -0
- polyaxon/_local_process/converter/converters/job.py +40 -0
- polyaxon/_local_process/converter/converters/service.py +41 -0
- polyaxon/_local_process/converter/mixins.py +38 -0
- polyaxon/_local_process/executor.py +132 -0
- polyaxon/_local_process/process_types.py +39 -0
- polyaxon/_managers/agent.py +2 -0
- polyaxon/_managers/home.py +2 -1
- polyaxon/_operations/tuner.py +1 -0
- polyaxon/_polyaxonfile/check.py +2 -0
- polyaxon/_polyaxonfile/manager/operations.py +3 -0
- polyaxon/_polyaxonfile/manager/workflows.py +2 -0
- polyaxon/_polyaxonfile/specs/compiled_operation.py +1 -0
- polyaxon/_polyaxonfile/specs/operation.py +1 -0
- polyaxon/_polyaxonfile/specs/sections.py +3 -0
- polyaxon/_pql/manager.py +1 -1
- polyaxon/_runner/agent/async_agent.py +97 -21
- polyaxon/_runner/agent/base_agent.py +27 -9
- polyaxon/_runner/agent/client.py +15 -1
- polyaxon/_runner/agent/sync_agent.py +85 -20
- polyaxon/_runner/converter/converter.py +6 -2
- polyaxon/_runner/executor.py +13 -7
- polyaxon/_schemas/agent.py +27 -1
- polyaxon/_schemas/client.py +30 -3
- polyaxon/_schemas/installation.py +4 -3
- polyaxon/_schemas/lifecycle.py +10 -5
- polyaxon/_schemas/log_handler.py +2 -3
- polyaxon/_schemas/types/artifacts.py +3 -3
- polyaxon/_schemas/types/dockerfile.py +3 -3
- polyaxon/_schemas/types/file.py +3 -3
- polyaxon/_schemas/types/git.py +3 -3
- polyaxon/_schemas/types/tensorboard.py +3 -3
- polyaxon/_sdk/api/agents_v1_api.py +1076 -73
- polyaxon/_sdk/api/organizations_v1_api.py +371 -10
- polyaxon/_sdk/api/project_dashboards_v1_api.py +12 -12
- polyaxon/_sdk/api/project_searches_v1_api.py +12 -12
- polyaxon/_sdk/api/projects_v1_api.py +221 -44
- polyaxon/_sdk/api/runs_v1_api.py +917 -445
- polyaxon/_sdk/api/service_accounts_v1_api.py +16 -16
- polyaxon/_sdk/api/teams_v1_api.py +2827 -375
- polyaxon/_sdk/api/users_v1_api.py +231 -55
- polyaxon/_sdk/async_client/api_client.py +4 -0
- polyaxon/_sdk/schemas/__init__.py +10 -2
- polyaxon/_sdk/schemas/v1_agent.py +2 -1
- polyaxon/_sdk/schemas/v1_agent_reconcile_body_request.py +14 -0
- polyaxon/_sdk/schemas/v1_artifact_tree.py +1 -1
- polyaxon/_sdk/schemas/v1_dashboard_spec.py +4 -0
- polyaxon/_sdk/schemas/v1_events_response.py +4 -0
- polyaxon/_sdk/schemas/v1_organization.py +1 -0
- polyaxon/_sdk/schemas/v1_preset.py +8 -0
- polyaxon/_sdk/schemas/v1_project.py +1 -0
- polyaxon/_sdk/schemas/v1_project_settings.py +4 -2
- polyaxon/_sdk/schemas/v1_run.py +2 -2
- polyaxon/_sdk/schemas/v1_run_edge_lineage.py +14 -0
- polyaxon/_sdk/schemas/v1_run_edges_graph.py +9 -0
- polyaxon/_sdk/schemas/v1_section_spec.py +7 -2
- polyaxon/_sdk/schemas/v1_settings_catalog.py +1 -0
- polyaxon/_sdk/schemas/v1_team.py +3 -0
- polyaxon/_sdk/schemas/v1_user.py +1 -2
- polyaxon/_sdk/schemas/v1_user_access.py +17 -0
- polyaxon/_services/values.py +1 -0
- polyaxon/_sidecar/container/__init__.py +39 -18
- polyaxon/_sidecar/container/monitors/__init__.py +1 -0
- polyaxon/_sidecar/container/monitors/logs.py +10 -13
- polyaxon/_sidecar/container/monitors/spec.py +24 -0
- polyaxon/_sidecar/ignore.py +0 -1
- polyaxon/_utils/fqn_utils.py +25 -2
- polyaxon/client.py +1 -1
- polyaxon/pkg.py +1 -1
- polyaxon/schemas.py +8 -1
- polyaxon/settings.py +6 -0
- {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/METADATA +43 -43
- {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/RECORD +176 -155
- {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/WHEEL +1 -1
- polyaxon/_sdk/schemas/v1_project_user_access.py +0 -10
- {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/LICENSE +0 -0
- {polyaxon-2.0.0rc49.dist-info → polyaxon-2.4.0rc1.dist-info}/entry_points.txt +0 -0
- {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
|
+
}
|