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