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
@@ -13,6 +13,7 @@ from urllib3.exceptions import HTTPError
|
|
13
13
|
from polyaxon import pkg, settings
|
14
14
|
from polyaxon._env_vars.getters import get_run_info
|
15
15
|
from polyaxon._runner.agent.base_agent import BaseAgent
|
16
|
+
from polyaxon._utils.fqn_utils import get_run_instance
|
16
17
|
from polyaxon.client import V1Agent, V1AgentStateResponse
|
17
18
|
from polyaxon.exceptions import ApiException as SDKApiException
|
18
19
|
from polyaxon.exceptions import PolyaxonAgentError, PolyaxonConverterError
|
@@ -25,13 +26,13 @@ class BaseSyncAgent(BaseAgent):
|
|
25
26
|
def _enter(self):
|
26
27
|
if not self.client._is_managed:
|
27
28
|
return self
|
28
|
-
|
29
|
+
logger.warning("Agent is starting.")
|
29
30
|
try:
|
30
31
|
agent = self.client.get_info()
|
31
32
|
self._check_status(agent)
|
32
33
|
self.sync()
|
33
34
|
self.client.log_agent_running()
|
34
|
-
|
35
|
+
logger.warning("Agent is running.")
|
35
36
|
return self
|
36
37
|
except (ApiException, SDKApiException, HTTPError) as e:
|
37
38
|
message = "Could not start the agent."
|
@@ -76,6 +77,49 @@ class BaseSyncAgent(BaseAgent):
|
|
76
77
|
),
|
77
78
|
)
|
78
79
|
|
80
|
+
def reconcile(self):
|
81
|
+
if (
|
82
|
+
now() - self._last_reconciled_at
|
83
|
+
).total_seconds() > self.SLEEP_AGENT_DATA_COLLECT_TIME:
|
84
|
+
return
|
85
|
+
|
86
|
+
# Collect data
|
87
|
+
self.collect_agent_data()
|
88
|
+
|
89
|
+
# Update reconcile
|
90
|
+
namespaces = [settings.AGENT_CONFIG.namespace]
|
91
|
+
namespaces += settings.AGENT_CONFIG.additional_namespaces or []
|
92
|
+
ops = []
|
93
|
+
for namespace in namespaces:
|
94
|
+
_ops = self.executor.list_ops(namespace=namespace)
|
95
|
+
if _ops:
|
96
|
+
ops += [
|
97
|
+
(
|
98
|
+
get_run_instance(
|
99
|
+
owner=op["metadata"]["annotations"][
|
100
|
+
"operation.polyaxon.com/owner"
|
101
|
+
],
|
102
|
+
project=op["metadata"]["annotations"][
|
103
|
+
"operation.polyaxon.com/project"
|
104
|
+
],
|
105
|
+
run_uuid=op["metadata"]["labels"][
|
106
|
+
"app.kubernetes.io/instance"
|
107
|
+
],
|
108
|
+
),
|
109
|
+
op["metadata"]["annotations"]["operation.polyaxon.com/kind"],
|
110
|
+
op["metadata"]["annotations"]["operation.polyaxon.com/name"],
|
111
|
+
namespace,
|
112
|
+
)
|
113
|
+
for op in _ops
|
114
|
+
]
|
115
|
+
if not ops:
|
116
|
+
return None
|
117
|
+
|
118
|
+
logger.info("Reconcile agent.")
|
119
|
+
return self.client.reconcile_agent(
|
120
|
+
reconcile={"ops": ops},
|
121
|
+
)
|
122
|
+
|
79
123
|
def start(self):
|
80
124
|
try:
|
81
125
|
with sync_exit_context() as exit_event:
|
@@ -88,7 +132,9 @@ class BaseSyncAgent(BaseAgent):
|
|
88
132
|
while not exit_event.wait(timeout=timeout):
|
89
133
|
index += 1
|
90
134
|
self.refresh_executor()
|
91
|
-
if
|
135
|
+
if self._default_auth:
|
136
|
+
self.reconcile()
|
137
|
+
else:
|
92
138
|
self.cron()
|
93
139
|
agent_state = self.process(pool)
|
94
140
|
if not agent_state:
|
@@ -113,7 +159,7 @@ class BaseSyncAgent(BaseAgent):
|
|
113
159
|
self.sync_compatible_updates(agent_state.compatible_updates)
|
114
160
|
|
115
161
|
if agent_state:
|
116
|
-
logger.info("
|
162
|
+
logger.info("Checking agent state.")
|
117
163
|
else:
|
118
164
|
logger.info("No state was found.")
|
119
165
|
return V1AgentStateResponse.construct()
|
@@ -180,7 +226,7 @@ class BaseSyncAgent(BaseAgent):
|
|
180
226
|
)
|
181
227
|
return None
|
182
228
|
|
183
|
-
def submit_run(self, run_data: Tuple[str, str, str, str]):
|
229
|
+
def submit_run(self, run_data: Tuple[str, str, str, str, str]):
|
184
230
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
185
231
|
resource = self.prepare_run_resource(
|
186
232
|
owner_name=run_owner,
|
@@ -194,7 +240,10 @@ class BaseSyncAgent(BaseAgent):
|
|
194
240
|
|
195
241
|
try:
|
196
242
|
self.executor.create(
|
197
|
-
run_uuid=run_uuid,
|
243
|
+
run_uuid=run_uuid,
|
244
|
+
run_kind=run_data[1],
|
245
|
+
resource=resource,
|
246
|
+
namespace=run_data[4],
|
198
247
|
)
|
199
248
|
except ApiException as e:
|
200
249
|
if e.status == 409:
|
@@ -217,7 +266,7 @@ class BaseSyncAgent(BaseAgent):
|
|
217
266
|
)
|
218
267
|
|
219
268
|
def make_and_create_run(
|
220
|
-
self, run_data: Tuple[str, str, str, str], default_auth: bool = False
|
269
|
+
self, run_data: Tuple[str, str, str, str, str], default_auth: bool = False
|
221
270
|
):
|
222
271
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
223
272
|
resource = self.make_run_resource(
|
@@ -233,7 +282,10 @@ class BaseSyncAgent(BaseAgent):
|
|
233
282
|
|
234
283
|
try:
|
235
284
|
self.executor.create(
|
236
|
-
run_uuid=run_uuid,
|
285
|
+
run_uuid=run_uuid,
|
286
|
+
run_kind=run_data[1],
|
287
|
+
resource=resource,
|
288
|
+
namespace=run_data[4],
|
237
289
|
)
|
238
290
|
except ApiException as e:
|
239
291
|
if e.status == 409:
|
@@ -247,7 +299,7 @@ class BaseSyncAgent(BaseAgent):
|
|
247
299
|
)
|
248
300
|
)
|
249
301
|
|
250
|
-
def apply_run(self, run_data: Tuple[str, str, str, str]):
|
302
|
+
def apply_run(self, run_data: Tuple[str, str, str, str, str]):
|
251
303
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
252
304
|
resource = self.prepare_run_resource(
|
253
305
|
owner_name=run_owner,
|
@@ -261,7 +313,10 @@ class BaseSyncAgent(BaseAgent):
|
|
261
313
|
|
262
314
|
try:
|
263
315
|
self.executor.apply(
|
264
|
-
run_uuid=run_uuid,
|
316
|
+
run_uuid=run_uuid,
|
317
|
+
run_kind=run_data[1],
|
318
|
+
resource=resource,
|
319
|
+
namespace=run_data[4],
|
265
320
|
)
|
266
321
|
self.client.log_run_running(
|
267
322
|
run_owner=run_owner, run_project=run_project, run_uuid=run_uuid
|
@@ -270,12 +325,16 @@ class BaseSyncAgent(BaseAgent):
|
|
270
325
|
self.client.log_run_failed(
|
271
326
|
run_owner=run_owner, run_project=run_project, run_uuid=run_uuid, exc=e
|
272
327
|
)
|
273
|
-
self.clean_run(
|
328
|
+
self.clean_run(
|
329
|
+
run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[4]
|
330
|
+
)
|
274
331
|
|
275
|
-
def check_run(self, run_data: Tuple[str, str]):
|
332
|
+
def check_run(self, run_data: Tuple[str, str, str]):
|
276
333
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
277
334
|
try:
|
278
|
-
self.executor.get(
|
335
|
+
self.executor.get(
|
336
|
+
run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[2]
|
337
|
+
)
|
279
338
|
except ApiException as e:
|
280
339
|
if e.status == 404:
|
281
340
|
logger.info(
|
@@ -285,10 +344,12 @@ class BaseSyncAgent(BaseAgent):
|
|
285
344
|
run_owner=run_owner, run_project=run_project, run_uuid=run_uuid
|
286
345
|
)
|
287
346
|
|
288
|
-
def stop_run(self, run_data: Tuple[str, str]):
|
347
|
+
def stop_run(self, run_data: Tuple[str, str, str]):
|
289
348
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
290
349
|
try:
|
291
|
-
self.executor.stop(
|
350
|
+
self.executor.stop(
|
351
|
+
run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[2]
|
352
|
+
)
|
292
353
|
except ApiException as e:
|
293
354
|
if e.status == 404:
|
294
355
|
logger.info("Run does not exist anymore, it could have been stopped.")
|
@@ -304,16 +365,20 @@ class BaseSyncAgent(BaseAgent):
|
|
304
365
|
message="Agent failed stopping run.\n",
|
305
366
|
)
|
306
367
|
|
307
|
-
def delete_run(self, run_data: Tuple[str, str, str, str]):
|
368
|
+
def delete_run(self, run_data: Tuple[str, str, str, str, str]):
|
308
369
|
run_owner, run_project, run_uuid = get_run_info(run_instance=run_data[0])
|
309
|
-
self.clean_run(run_uuid=run_uuid, run_kind=run_data[1])
|
370
|
+
self.clean_run(run_uuid=run_uuid, run_kind=run_data[1], namespace=run_data[4])
|
310
371
|
if run_data[3]:
|
311
372
|
self.make_and_create_run(run_data)
|
312
373
|
|
313
|
-
def clean_run(self, run_uuid: str, run_kind: str):
|
374
|
+
def clean_run(self, run_uuid: str, run_kind: str, namespace: str = None):
|
314
375
|
try:
|
315
|
-
self.executor.clean(
|
316
|
-
|
376
|
+
self.executor.clean(
|
377
|
+
run_uuid=run_uuid, run_kind=run_kind, namespace=namespace
|
378
|
+
)
|
379
|
+
self.executor.stop(
|
380
|
+
run_uuid=run_uuid, run_kind=run_kind, namespace=namespace
|
381
|
+
)
|
317
382
|
except ApiException as e:
|
318
383
|
if e.status == 404:
|
319
384
|
logger.info("Run does not exist.")
|
@@ -711,7 +711,9 @@ class BaseConverter:
|
|
711
711
|
V1ConnectionKind.is_ssh(connection_spec.kind)
|
712
712
|
and init_connection.git
|
713
713
|
):
|
714
|
-
|
714
|
+
connection_spec.schema_ = patch_git(
|
715
|
+
connection_spec.schema_, init_connection.git
|
716
|
+
)
|
715
717
|
containers.append(
|
716
718
|
self._get_git_init_container(
|
717
719
|
run_path=self.run_path,
|
@@ -731,7 +733,9 @@ class BaseConverter:
|
|
731
733
|
)
|
732
734
|
elif V1ConnectionKind.is_git(connection_spec.kind):
|
733
735
|
if init_connection.git: # Update the default schema
|
734
|
-
connection_spec.schema_
|
736
|
+
connection_spec.schema_ = patch_git(
|
737
|
+
connection_spec.schema_, init_connection.git
|
738
|
+
)
|
735
739
|
containers.append(
|
736
740
|
self._get_git_init_container(
|
737
741
|
run_path=self.run_path,
|
polyaxon/_runner/executor.py
CHANGED
@@ -50,19 +50,21 @@ class BaseExecutor:
|
|
50
50
|
self._manager = None
|
51
51
|
return self.manager
|
52
52
|
|
53
|
-
def get(self, run_uuid: str, run_kind: str):
|
53
|
+
def get(self, run_uuid: str, run_kind: str, namespace: str = None):
|
54
54
|
raise NotImplementedError
|
55
55
|
|
56
|
-
def create(
|
56
|
+
def create(
|
57
|
+
self, run_uuid: str, run_kind: str, resource: Any, namespace: str = None
|
58
|
+
):
|
57
59
|
raise NotImplementedError
|
58
60
|
|
59
|
-
def apply(self, run_uuid: str, run_kind: str, resource: Any):
|
61
|
+
def apply(self, run_uuid: str, run_kind: str, resource: Any, namespace: str = None):
|
60
62
|
raise NotImplementedError
|
61
63
|
|
62
|
-
def stop(self, run_uuid: str, run_kind: str):
|
64
|
+
def stop(self, run_uuid: str, run_kind: str, namespace: str = None):
|
63
65
|
raise NotImplementedError
|
64
66
|
|
65
|
-
def clean(self, run_uuid: str, run_kind: str):
|
67
|
+
def clean(self, run_uuid: str, run_kind: str, namespace: str = None):
|
66
68
|
raise NotImplementedError
|
67
69
|
|
68
70
|
def _clean_temp_execution_path(self, run_uuid: str):
|
@@ -154,7 +156,7 @@ class BaseExecutor:
|
|
154
156
|
run_name=run_name,
|
155
157
|
run_uuid=run_uuid,
|
156
158
|
run_path=run_uuid,
|
157
|
-
namespace=agent_env.namespace,
|
159
|
+
namespace=compiled_operation.namespace or agent_env.namespace,
|
158
160
|
compiled_operation=compiled_operation,
|
159
161
|
polyaxon_init=agent_env.polyaxon_init,
|
160
162
|
polyaxon_sidecar=agent_env.polyaxon_sidecar,
|
@@ -191,7 +193,7 @@ class BaseExecutor:
|
|
191
193
|
params=operation.params,
|
192
194
|
)
|
193
195
|
return cls.get_resource(
|
194
|
-
namespace=resolver_obj.namespace,
|
196
|
+
namespace=compiled_operation.namespace or resolver_obj.namespace,
|
195
197
|
owner_name=resolver_obj.owner_name,
|
196
198
|
project_name=resolver_obj.project_name,
|
197
199
|
run_name=resolver_obj.run_name,
|
@@ -223,4 +225,8 @@ class BaseExecutor:
|
|
223
225
|
run_uuid=response.uuid,
|
224
226
|
run_kind=response.kind,
|
225
227
|
resource=resource,
|
228
|
+
namespace=response.settings.namespace if response.settings else None,
|
226
229
|
)
|
230
|
+
|
231
|
+
def list_ops(self, namespace: str = None):
|
232
|
+
raise NotImplementedError
|
polyaxon/_schemas/agent.py
CHANGED
@@ -18,6 +18,7 @@ from polyaxon._connections import V1Connection, V1ConnectionKind, V1HostPathConn
|
|
18
18
|
from polyaxon._contexts import paths as ctx_paths
|
19
19
|
from polyaxon._env_vars.getters import get_artifacts_store_name
|
20
20
|
from polyaxon._env_vars.keys import (
|
21
|
+
ENV_KEYS_ADDITIONAL_NAMESPACES,
|
21
22
|
ENV_KEYS_AGENT_ARTIFACTS_STORE,
|
22
23
|
ENV_KEYS_AGENT_CLEANER,
|
23
24
|
ENV_KEYS_AGENT_CONNECTIONS,
|
@@ -35,6 +36,8 @@ from polyaxon._env_vars.keys import (
|
|
35
36
|
ENV_KEYS_ARTIFACTS_STORE_NAME,
|
36
37
|
ENV_KEYS_K8S_APP_SECRET_NAME,
|
37
38
|
ENV_KEYS_K8S_NAMESPACE,
|
39
|
+
ENV_KEYS_SINGLE_NAMESPACE,
|
40
|
+
ENV_KEYS_WATCH_CLUSTER,
|
38
41
|
)
|
39
42
|
from polyaxon._fs.utils import get_store_path
|
40
43
|
from polyaxon._schemas.base import BaseSchemaModel
|
@@ -185,6 +188,11 @@ class AgentConfig(BaseAgentConfig):
|
|
185
188
|
_IDENTIFIER = "agent"
|
186
189
|
|
187
190
|
is_replica: Optional[bool] = Field(alias=ENV_KEYS_AGENT_IS_REPLICA)
|
191
|
+
watch_cluster: Optional[bool] = Field(alias=ENV_KEYS_WATCH_CLUSTER)
|
192
|
+
single_namespace: Optional[bool] = Field(alias=ENV_KEYS_SINGLE_NAMESPACE)
|
193
|
+
additional_namespaces: Optional[List[StrictStr]] = Field(
|
194
|
+
alias=ENV_KEYS_ADDITIONAL_NAMESPACES
|
195
|
+
)
|
188
196
|
sidecar: Optional[V1PolyaxonSidecarContainer] = Field(alias=ENV_KEYS_AGENT_SIDECAR)
|
189
197
|
init: Optional[V1PolyaxonInitContainer] = Field(alias=ENV_KEYS_AGENT_INIT)
|
190
198
|
notifier: Optional[V1PolyaxonNotifier] = Field(alias=ENV_KEYS_AGENT_NOTIFIER)
|
@@ -217,6 +225,24 @@ class AgentConfig(BaseAgentConfig):
|
|
217
225
|
and "isReplica" in values
|
218
226
|
):
|
219
227
|
values[ENV_KEYS_AGENT_IS_REPLICA] = values["isReplica"]
|
228
|
+
if (
|
229
|
+
not values.get("watch_cluster")
|
230
|
+
and not values.get(ENV_KEYS_WATCH_CLUSTER)
|
231
|
+
and "watchCluster" in values
|
232
|
+
):
|
233
|
+
values[ENV_KEYS_WATCH_CLUSTER] = values["watchCluster"]
|
234
|
+
if (
|
235
|
+
not values.get("single_namespace")
|
236
|
+
and not values.get(ENV_KEYS_SINGLE_NAMESPACE)
|
237
|
+
and "singleNamespace" in values
|
238
|
+
):
|
239
|
+
values[ENV_KEYS_SINGLE_NAMESPACE] = values["singleNamespace"]
|
240
|
+
if (
|
241
|
+
not values.get("additional_namespace")
|
242
|
+
and not values.get(ENV_KEYS_ADDITIONAL_NAMESPACES)
|
243
|
+
and "additionalNamespaces" in values
|
244
|
+
):
|
245
|
+
values[ENV_KEYS_ADDITIONAL_NAMESPACES] = values["additionalNamespaces"]
|
220
246
|
if (
|
221
247
|
not values.get("use_proxy_env_vars_use_in_ops")
|
222
248
|
and not values.get(ENV_KEYS_AGENT_USE_PROXY_ENV_VARS_IN_OPS)
|
@@ -312,7 +338,7 @@ class AgentConfig(BaseAgentConfig):
|
|
312
338
|
"Received an invalid {} `{}`".format(field.alias, v)
|
313
339
|
) from e
|
314
340
|
|
315
|
-
@validator("default_image_pull_secrets", pre=True)
|
341
|
+
@validator("additional_namespaces", "default_image_pull_secrets", pre=True)
|
316
342
|
def validate_str_list(cls, v, field):
|
317
343
|
try:
|
318
344
|
return ConfigParser.parse(str)(
|
polyaxon/_schemas/client.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import os
|
2
|
+
|
1
3
|
from typing import Dict, Optional, Union
|
2
4
|
|
3
5
|
import urllib3
|
@@ -29,6 +31,7 @@ from polyaxon._env_vars.keys import (
|
|
29
31
|
ENV_KEYS_NO_API,
|
30
32
|
ENV_KEYS_NO_OP,
|
31
33
|
ENV_KEYS_RETRIES,
|
34
|
+
ENV_KEYS_SECRET_INTERNAL_TOKEN,
|
32
35
|
ENV_KEYS_SSL_CA_CERT,
|
33
36
|
ENV_KEYS_TIME_ZONE,
|
34
37
|
ENV_KEYS_TIMEOUT,
|
@@ -137,6 +140,10 @@ class ClientConfig(BaseSchemaModel):
|
|
137
140
|
self.client_header["header_name"] = self.header
|
138
141
|
self.client_header["header_value"] = self.header_service
|
139
142
|
|
143
|
+
def get_internal_header(self) -> Dict:
|
144
|
+
header = PolyaxonServiceHeaders.get_header(PolyaxonServiceHeaders.INTERNAL)
|
145
|
+
return {"header_name": header, "header_value": self.header_service}
|
146
|
+
|
140
147
|
def get_full_headers(self, headers=None, auth_key="Authorization") -> Dict:
|
141
148
|
request_headers = {}
|
142
149
|
request_headers.update(headers or {})
|
@@ -151,7 +158,19 @@ class ClientConfig(BaseSchemaModel):
|
|
151
158
|
return request_headers
|
152
159
|
|
153
160
|
@property
|
154
|
-
def sdk_config(self)
|
161
|
+
def sdk_config(self):
|
162
|
+
return self.get_sdk_config()
|
163
|
+
|
164
|
+
@property
|
165
|
+
def internal_sdk_config(self):
|
166
|
+
return self.get_sdk_config(
|
167
|
+
token=os.environ.get(ENV_KEYS_SECRET_INTERNAL_TOKEN),
|
168
|
+
authentication_type=AuthenticationTypes.INTERNAL_TOKEN,
|
169
|
+
)
|
170
|
+
|
171
|
+
def get_sdk_config(
|
172
|
+
self, token: str = None, authentication_type: AuthenticationTypes = None
|
173
|
+
) -> Configuration:
|
155
174
|
if not self.host and not self.in_cluster:
|
156
175
|
raise PolyaxonClientException(
|
157
176
|
"Api config requires at least a host if not running in-cluster."
|
@@ -171,8 +190,10 @@ class ClientConfig(BaseSchemaModel):
|
|
171
190
|
if self.connection_pool_maxsize:
|
172
191
|
config.connection_pool_maxsize = self.connection_pool_maxsize
|
173
192
|
if self.token:
|
174
|
-
config.api_key["ApiKey"] = self.token
|
175
|
-
config.api_key_prefix["ApiKey"] =
|
193
|
+
config.api_key["ApiKey"] = token or self.token
|
194
|
+
config.api_key_prefix["ApiKey"] = (
|
195
|
+
authentication_type or self.authentication_type
|
196
|
+
)
|
176
197
|
return config
|
177
198
|
|
178
199
|
@property
|
@@ -181,6 +202,12 @@ class ClientConfig(BaseSchemaModel):
|
|
181
202
|
config.connection_pool_maxsize = 100
|
182
203
|
return config
|
183
204
|
|
205
|
+
@property
|
206
|
+
def async_internal_sdk_config(self) -> Configuration:
|
207
|
+
config = self.internal_sdk_config
|
208
|
+
config.connection_pool_maxsize = 100
|
209
|
+
return config
|
210
|
+
|
184
211
|
@classmethod
|
185
212
|
def patch_from(cls, config: "ClientConfig", **kwargs) -> "ClientConfig":
|
186
213
|
data = {**config.to_dict(), **kwargs}
|
@@ -1,14 +1,15 @@
|
|
1
1
|
from typing import List, Optional
|
2
2
|
|
3
3
|
from clipped.compact.pydantic import StrictStr
|
4
|
+
from clipped.config.schema import BaseAllowSchemaModel
|
4
5
|
|
5
|
-
from polyaxon._schemas.base import BaseSchemaModel
|
6
6
|
|
7
|
-
|
8
|
-
class V1Installation(BaseSchemaModel):
|
7
|
+
class V1Installation(BaseAllowSchemaModel):
|
9
8
|
key: Optional[StrictStr]
|
10
9
|
version: Optional[StrictStr]
|
11
10
|
dist: Optional[StrictStr]
|
12
11
|
host: Optional[StrictStr]
|
13
12
|
hmac: Optional[StrictStr]
|
13
|
+
mode: Optional[StrictStr]
|
14
|
+
org: Optional[bool]
|
14
15
|
auth: Optional[List[StrictStr]]
|
polyaxon/_schemas/lifecycle.py
CHANGED
@@ -3,6 +3,7 @@ import datetime
|
|
3
3
|
from typing import Any, Dict, List, Optional, Union
|
4
4
|
|
5
5
|
from clipped.compact.pydantic import StrictStr
|
6
|
+
from clipped.config.schema import BaseAllowSchemaModel
|
6
7
|
from clipped.utils.dates import parse_datetime
|
7
8
|
from clipped.utils.enums import PEnum
|
8
9
|
from clipped.utils.tz import now
|
@@ -275,8 +276,8 @@ class LifeCycle:
|
|
275
276
|
entity.started_at = now()
|
276
277
|
# Update wait_time
|
277
278
|
if entity.wait_time is None:
|
278
|
-
entity.wait_time =
|
279
|
-
(entity.started_at - entity.created_at).total_seconds()
|
279
|
+
entity.wait_time = round(
|
280
|
+
(entity.started_at - entity.created_at).total_seconds(), 2
|
280
281
|
)
|
281
282
|
return True
|
282
283
|
|
@@ -290,14 +291,14 @@ class LifeCycle:
|
|
290
291
|
entity.started_at = entity.created_at
|
291
292
|
# Update duration
|
292
293
|
if entity.duration is None:
|
293
|
-
entity.duration =
|
294
|
-
(entity.finished_at - entity.started_at).total_seconds()
|
294
|
+
entity.duration = round(
|
295
|
+
(entity.finished_at - entity.started_at).total_seconds(), 2
|
295
296
|
)
|
296
297
|
return True
|
297
298
|
return False
|
298
299
|
|
299
300
|
|
300
|
-
class BaseCondition(
|
301
|
+
class BaseCondition(BaseAllowSchemaModel):
|
301
302
|
@classmethod
|
302
303
|
def get_condition(
|
303
304
|
cls,
|
@@ -307,6 +308,7 @@ class BaseCondition(BaseSchemaModel):
|
|
307
308
|
last_transition_time=None,
|
308
309
|
reason=None,
|
309
310
|
message=None,
|
311
|
+
meta_info=None,
|
310
312
|
):
|
311
313
|
current_time = now()
|
312
314
|
last_update_time = last_update_time or current_time
|
@@ -318,6 +320,7 @@ class BaseCondition(BaseSchemaModel):
|
|
318
320
|
last_transition_time=last_transition_time,
|
319
321
|
reason=reason,
|
320
322
|
message=message,
|
323
|
+
meta_info=meta_info,
|
321
324
|
)
|
322
325
|
|
323
326
|
def __eq__(self, other):
|
@@ -335,6 +338,7 @@ class V1StatusCondition(BaseCondition):
|
|
335
338
|
message: Optional[StrictStr]
|
336
339
|
last_update_time: Optional[datetime.datetime]
|
337
340
|
last_transition_time: Optional[datetime.datetime]
|
341
|
+
meta_info: Optional[Dict[str, Any]]
|
338
342
|
|
339
343
|
|
340
344
|
class V1Status(BaseSchemaModel):
|
@@ -351,6 +355,7 @@ class V1StageCondition(BaseCondition):
|
|
351
355
|
message: Optional[StrictStr]
|
352
356
|
last_update_time: Optional[datetime.datetime]
|
353
357
|
last_transition_time: Optional[datetime.datetime]
|
358
|
+
meta_info: Optional[Dict[str, Any]]
|
354
359
|
|
355
360
|
|
356
361
|
class V1Stage(BaseSchemaModel):
|
polyaxon/_schemas/log_handler.py
CHANGED
@@ -3,11 +3,10 @@ import base64
|
|
3
3
|
from typing import Optional
|
4
4
|
|
5
5
|
from clipped.compact.pydantic import StrictStr
|
6
|
+
from clipped.config.schema import BaseAllowSchemaModel
|
6
7
|
|
7
|
-
from polyaxon._schemas.base import BaseSchemaModel
|
8
8
|
|
9
|
-
|
10
|
-
class V1LogHandler(BaseSchemaModel):
|
9
|
+
class V1LogHandler(BaseAllowSchemaModel):
|
11
10
|
_IDENTIFIER = "log_handler"
|
12
11
|
|
13
12
|
dsn: Optional[StrictStr]
|
@@ -129,8 +129,8 @@ class V1ArtifactsType(BaseTypeConfig):
|
|
129
129
|
|
130
130
|
```python
|
131
131
|
>>> from polyaxon.schemas import V1Component, V1Init, V1Job
|
132
|
-
>>> from polyaxon.
|
133
|
-
>>> from polyaxon
|
132
|
+
>>> from polyaxon.types import V1ArtifactsType
|
133
|
+
>>> from polyaxon import k8s
|
134
134
|
>>> component = V1Component(
|
135
135
|
>>> run=V1Job(
|
136
136
|
>>> init=[
|
@@ -146,7 +146,7 @@ class V1ArtifactsType(BaseTypeConfig):
|
|
146
146
|
>>> connection="s3-dataset"
|
147
147
|
>>> ),
|
148
148
|
>>> ],
|
149
|
-
>>> container=
|
149
|
+
>>> container=k8s.V1Container(...)
|
150
150
|
>>> )
|
151
151
|
>>> )
|
152
152
|
```
|
@@ -111,8 +111,8 @@ class V1DockerfileType(BaseTypeConfig):
|
|
111
111
|
|
112
112
|
```python
|
113
113
|
>>> from polyaxon.schemas import V1Component, V1Init, V1Job
|
114
|
-
>>> from polyaxon.
|
115
|
-
>>> from polyaxon
|
114
|
+
>>> from polyaxon.types import V1DockerfileType
|
115
|
+
>>> from polyaxon import k8s
|
116
116
|
>>> component = V1Component(
|
117
117
|
>>> run=V1Job(
|
118
118
|
>>> init=[
|
@@ -124,7 +124,7 @@ class V1DockerfileType(BaseTypeConfig):
|
|
124
124
|
>>> )
|
125
125
|
>>> ),
|
126
126
|
>>> ],
|
127
|
-
>>> container=
|
127
|
+
>>> container=k8s.V1Container(...)
|
128
128
|
>>> )
|
129
129
|
>>> )
|
130
130
|
```
|
polyaxon/_schemas/types/file.py
CHANGED
@@ -116,8 +116,8 @@ class V1FileType(BaseTypeConfig):
|
|
116
116
|
|
117
117
|
```python
|
118
118
|
>>> from polyaxon.schemas import V1Component, V1Init, V1Job
|
119
|
-
>>> from polyaxon.
|
120
|
-
>>> from polyaxon
|
119
|
+
>>> from polyaxon.types import V1FileType
|
120
|
+
>>> from polyaxon import k8s
|
121
121
|
>>> component = V1Component(
|
122
122
|
>>> run=V1Job(
|
123
123
|
>>> init=[
|
@@ -129,7 +129,7 @@ class V1FileType(BaseTypeConfig):
|
|
129
129
|
>>> )
|
130
130
|
>>> ),
|
131
131
|
>>> ],
|
132
|
-
>>> container=
|
132
|
+
>>> container=k8s.V1Container(...)
|
133
133
|
>>> )
|
134
134
|
>>> )
|
135
135
|
```
|
polyaxon/_schemas/types/git.py
CHANGED
@@ -103,8 +103,8 @@ class V1GitType(BaseTypeConfig):
|
|
103
103
|
### Usage in initializers
|
104
104
|
```python
|
105
105
|
>>> from polyaxon.schemas import V1Component, V1Init, V1Job
|
106
|
-
>>> from polyaxon.
|
107
|
-
>>> from polyaxon
|
106
|
+
>>> from polyaxon.types import V1GitType
|
107
|
+
>>> from polyaxon import k8s
|
108
108
|
>>> component = V1Component(
|
109
109
|
>>> run=V1Job(
|
110
110
|
>>> init=[
|
@@ -116,7 +116,7 @@ class V1GitType(BaseTypeConfig):
|
|
116
116
|
>>> connection="my-git-connection",
|
117
117
|
>>> ),
|
118
118
|
>>> ],
|
119
|
-
>>> container=
|
119
|
+
>>> container=k8s.V1Container(...)
|
120
120
|
>>> )
|
121
121
|
>>> )
|
122
122
|
```
|
@@ -99,8 +99,8 @@ class V1TensorboardType(BaseTypeConfig):
|
|
99
99
|
|
100
100
|
```python
|
101
101
|
>>> from polyaxon.schemas import V1Component, V1Init, V1Job
|
102
|
-
>>> from polyaxon.
|
103
|
-
>>> from polyaxon
|
102
|
+
>>> from polyaxon.types import V1FileType
|
103
|
+
>>> from polyaxon import k8s
|
104
104
|
>>> component = V1Component(
|
105
105
|
>>> run=V1Job(
|
106
106
|
>>> init=[
|
@@ -114,7 +114,7 @@ class V1TensorboardType(BaseTypeConfig):
|
|
114
114
|
>>> )
|
115
115
|
>>> ),
|
116
116
|
>>> ],
|
117
|
-
>>> container=
|
117
|
+
>>> container=k8s.V1Container(...)
|
118
118
|
>>> )
|
119
119
|
>>> )
|
120
120
|
```
|