runnable 0.28.3__py3-none-any.whl → 0.28.5__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- extensions/job_executor/k8s.py +41 -33
- {runnable-0.28.3.dist-info → runnable-0.28.5.dist-info}/METADATA +1 -1
- {runnable-0.28.3.dist-info → runnable-0.28.5.dist-info}/RECORD +6 -6
- {runnable-0.28.3.dist-info → runnable-0.28.5.dist-info}/WHEEL +0 -0
- {runnable-0.28.3.dist-info → runnable-0.28.5.dist-info}/entry_points.txt +0 -0
- {runnable-0.28.3.dist-info → runnable-0.28.5.dist-info}/licenses/LICENSE +0 -0
extensions/job_executor/k8s.py
CHANGED
@@ -7,6 +7,7 @@ from kubernetes import client
|
|
7
7
|
from kubernetes import config as k8s_config
|
8
8
|
from pydantic import BaseModel, ConfigDict, Field, PlainSerializer, PrivateAttr
|
9
9
|
from pydantic.alias_generators import to_camel
|
10
|
+
from rich import print
|
10
11
|
|
11
12
|
from extensions.job_executor import GenericJobExecutor
|
12
13
|
from runnable import console, defaults, utils
|
@@ -39,7 +40,17 @@ class TolerationOperator(str, Enum):
|
|
39
40
|
EQUAL = "Equal"
|
40
41
|
|
41
42
|
|
42
|
-
class
|
43
|
+
class BaseModelWIthConfig(BaseModel, use_enum_values=True):
|
44
|
+
model_config = ConfigDict(
|
45
|
+
extra="forbid",
|
46
|
+
alias_generator=to_camel,
|
47
|
+
populate_by_name=True,
|
48
|
+
from_attributes=True,
|
49
|
+
validate_default=True,
|
50
|
+
)
|
51
|
+
|
52
|
+
|
53
|
+
class Toleration(BaseModelWIthConfig):
|
43
54
|
key: str
|
44
55
|
operator: TolerationOperator = TolerationOperator.EQUAL
|
45
56
|
value: Optional[str]
|
@@ -47,24 +58,24 @@ class Toleration(BaseModel):
|
|
47
58
|
toleration_seconds: Optional[int] = Field(default=None)
|
48
59
|
|
49
60
|
|
50
|
-
class LabelSelectorRequirement(
|
61
|
+
class LabelSelectorRequirement(BaseModelWIthConfig):
|
51
62
|
key: str
|
52
63
|
operator: Operator
|
53
64
|
values: list[str]
|
54
65
|
|
55
66
|
|
56
|
-
class LabelSelector(
|
67
|
+
class LabelSelector(BaseModelWIthConfig):
|
57
68
|
match_expressions: list[LabelSelectorRequirement]
|
58
69
|
match_labels: dict[str, str]
|
59
70
|
|
60
71
|
|
61
|
-
class ObjectMetaData(
|
72
|
+
class ObjectMetaData(BaseModelWIthConfig):
|
62
73
|
generate_name: Optional[str]
|
63
74
|
annotations: Optional[dict[str, str]]
|
64
75
|
namespace: Optional[str] = "default"
|
65
76
|
|
66
77
|
|
67
|
-
class EnvVar(
|
78
|
+
class EnvVar(BaseModelWIthConfig):
|
68
79
|
name: str
|
69
80
|
value: str
|
70
81
|
|
@@ -75,7 +86,7 @@ VendorGPU = Annotated[
|
|
75
86
|
]
|
76
87
|
|
77
88
|
|
78
|
-
class Request(
|
89
|
+
class Request(BaseModelWIthConfig):
|
79
90
|
"""
|
80
91
|
The default requests
|
81
92
|
"""
|
@@ -85,7 +96,7 @@ class Request(BaseModel):
|
|
85
96
|
gpu: VendorGPU = Field(default=None, serialization_alias="nvidia.com/gpu")
|
86
97
|
|
87
98
|
|
88
|
-
class Limit(
|
99
|
+
class Limit(BaseModelWIthConfig):
|
89
100
|
"""
|
90
101
|
The default limits
|
91
102
|
"""
|
@@ -95,49 +106,43 @@ class Limit(BaseModel):
|
|
95
106
|
gpu: VendorGPU = Field(default=None, serialization_alias="nvidia.com/gpu")
|
96
107
|
|
97
108
|
|
98
|
-
class Resources(
|
109
|
+
class Resources(BaseModelWIthConfig):
|
99
110
|
limits: Limit = Limit()
|
100
|
-
requests: Request =
|
111
|
+
requests: Optional[Request] = Field(default=None)
|
101
112
|
|
102
113
|
|
103
|
-
class VolumeMount(
|
114
|
+
class VolumeMount(BaseModelWIthConfig):
|
104
115
|
name: str
|
105
116
|
mount_path: str
|
106
117
|
|
107
118
|
|
108
|
-
class Container(
|
119
|
+
class Container(BaseModelWIthConfig):
|
109
120
|
image: str
|
110
121
|
env: list[EnvVar] = Field(default_factory=list)
|
111
|
-
image_pull_policy: ImagePullPolicy = ImagePullPolicy.NEVER
|
122
|
+
image_pull_policy: ImagePullPolicy = Field(default=ImagePullPolicy.NEVER)
|
112
123
|
resources: Resources = Resources()
|
113
124
|
volume_mounts: Optional[list[VolumeMount]] = Field(default_factory=lambda: [])
|
114
125
|
|
115
126
|
|
116
|
-
class HostPath(
|
127
|
+
class HostPath(BaseModelWIthConfig):
|
117
128
|
path: str
|
118
129
|
|
119
130
|
|
120
|
-
class HostPathVolume(
|
131
|
+
class HostPathVolume(BaseModelWIthConfig):
|
121
132
|
name: str
|
122
133
|
host_path: HostPath
|
123
134
|
|
124
135
|
|
125
|
-
class PVCClaim(
|
126
|
-
|
127
|
-
|
128
|
-
model_config = ConfigDict(
|
129
|
-
alias_generator=to_camel,
|
130
|
-
populate_by_name=True,
|
131
|
-
from_attributes=True,
|
132
|
-
)
|
136
|
+
class PVCClaim(BaseModelWIthConfig):
|
137
|
+
claimName: str
|
133
138
|
|
134
139
|
|
135
|
-
class PVCVolume(
|
140
|
+
class PVCVolume(BaseModelWIthConfig):
|
136
141
|
name: str
|
137
142
|
persistent_volume_claim: PVCClaim
|
138
143
|
|
139
144
|
|
140
|
-
class K8sTemplateSpec(
|
145
|
+
class K8sTemplateSpec(BaseModelWIthConfig):
|
141
146
|
active_deadline_seconds: int = Field(default=60 * 60 * 2) # 2 hours
|
142
147
|
node_selector: Optional[dict[str, str]] = None
|
143
148
|
tolerations: Optional[list[Toleration]] = None
|
@@ -149,12 +154,12 @@ class K8sTemplateSpec(BaseModel):
|
|
149
154
|
container: Container
|
150
155
|
|
151
156
|
|
152
|
-
class K8sTemplate(
|
157
|
+
class K8sTemplate(BaseModelWIthConfig):
|
153
158
|
spec: K8sTemplateSpec
|
154
159
|
metadata: Optional[ObjectMetaData] = None
|
155
160
|
|
156
161
|
|
157
|
-
class Spec(
|
162
|
+
class Spec(BaseModelWIthConfig):
|
158
163
|
active_deadline_seconds: Optional[int] = Field(default=60 * 60 * 2) # 2 hours
|
159
164
|
backoff_limit: int = 6
|
160
165
|
selector: Optional[LabelSelector] = None
|
@@ -251,7 +256,7 @@ class GenericK8sJobExecutor(GenericJobExecutor):
|
|
251
256
|
command = utils.get_job_execution_command()
|
252
257
|
|
253
258
|
container_env = [
|
254
|
-
self._client.V1EnvVar(**env.model_dump(
|
259
|
+
self._client.V1EnvVar(**env.model_dump())
|
255
260
|
for env in self.job_spec.template.spec.container.env
|
256
261
|
]
|
257
262
|
|
@@ -260,8 +265,12 @@ class GenericK8sJobExecutor(GenericJobExecutor):
|
|
260
265
|
env=container_env,
|
261
266
|
name="default",
|
262
267
|
volume_mounts=container_volume_mounts,
|
268
|
+
resources=self.job_spec.template.spec.container.resources.model_dump(
|
269
|
+
by_alias=True, exclude_none=True
|
270
|
+
),
|
263
271
|
**self.job_spec.template.spec.container.model_dump(
|
264
|
-
exclude_none=True,
|
272
|
+
exclude_none=True,
|
273
|
+
exclude={"volume_mounts", "command", "env", "resources"},
|
265
274
|
),
|
266
275
|
)
|
267
276
|
|
@@ -269,20 +278,19 @@ class GenericK8sJobExecutor(GenericJobExecutor):
|
|
269
278
|
self._volumes += self.job_spec.template.spec.volumes
|
270
279
|
|
271
280
|
spec_volumes = [
|
272
|
-
self._client.V1Volume(**vol.model_dump(
|
273
|
-
for vol in self._volumes
|
281
|
+
self._client.V1Volume(**vol.model_dump()) for vol in self._volumes
|
274
282
|
]
|
275
283
|
|
276
284
|
tolerations = None
|
277
285
|
if self.job_spec.template.spec.tolerations:
|
278
286
|
tolerations = [
|
279
|
-
self._client.V1Toleration(**toleration.model_dump(
|
287
|
+
self._client.V1Toleration(**toleration.model_dump())
|
280
288
|
for toleration in self.job_spec.template.spec.tolerations
|
281
289
|
]
|
282
290
|
|
283
291
|
pod_spec = self._client.V1PodSpec(
|
284
292
|
containers=[base_container],
|
285
|
-
# volumes=[vol.model_dump(by_alias=True) for vol in
|
293
|
+
# volumes=[vol.model_dump(by_alias=True) for vol in spec_volumes],
|
286
294
|
volumes=spec_volumes,
|
287
295
|
tolerations=tolerations,
|
288
296
|
**self.job_spec.template.spec.model_dump(
|
@@ -473,7 +481,7 @@ class K8sJobExecutor(GenericK8sJobExecutor):
|
|
473
481
|
self._volumes.append(
|
474
482
|
PVCVolume(
|
475
483
|
name=self.pvc_claim_name,
|
476
|
-
persistent_volume_claim=PVCClaim(
|
484
|
+
persistent_volume_claim=PVCClaim(claimName=self.pvc_claim_name),
|
477
485
|
)
|
478
486
|
)
|
479
487
|
match self._context.run_log_store.service_name:
|
@@ -8,7 +8,7 @@ extensions/catalog/pyproject.toml,sha256=lLNxY6v04c8I5QK_zKw_E6sJTArSJRA_V-79kta
|
|
8
8
|
extensions/catalog/s3.py,sha256=Sw5t8_kVRprn3uGGJCiHn7M9zw1CLaCOFj6YErtfG0o,287
|
9
9
|
extensions/job_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
extensions/job_executor/__init__.py,sha256=E2R6GV5cZTlZdqA5SVJ6ajZFh4oruM0k8AKHkpOZ3W8,5772
|
11
|
-
extensions/job_executor/k8s.py,sha256=
|
11
|
+
extensions/job_executor/k8s.py,sha256=Mlmuqm1D70gfj471KKZrQF1PeDSCpOiW1bd4vD0pQ-w,16243
|
12
12
|
extensions/job_executor/k8s_job_spec.yaml,sha256=7aFpxHdO_p6Hkc3YxusUOuAQTD1Myu0yTPX9DrhxbOg,1158
|
13
13
|
extensions/job_executor/local.py,sha256=FvxTk0vyxdrbLOAyNkLyjvmmowypabWOSITQBK_ffVE,1907
|
14
14
|
extensions/job_executor/local_container.py,sha256=hyFnpicCp3_87mZsW64P6KSVbz7XMLjwJUWVjeCJ0_I,6627
|
@@ -56,8 +56,8 @@ runnable/sdk.py,sha256=T1nqDpLN9fULvvU9L-oY0EHqYdKUI9qk7oekLynm02Y,33568
|
|
56
56
|
runnable/secrets.py,sha256=PXcEJw-4WPzeWRLfsatcPPyr1zkqgHzdRWRcS9vvpvM,2354
|
57
57
|
runnable/tasks.py,sha256=X6xijut7ffwpfYDcXoN6y0AcRVd7fWHs676DJ00Kma4,29134
|
58
58
|
runnable/utils.py,sha256=hBr7oGwGL2VgfITlQCTz-a1iwvvf7Mfl-HY8UdENZac,19929
|
59
|
-
runnable-0.28.
|
60
|
-
runnable-0.28.
|
61
|
-
runnable-0.28.
|
62
|
-
runnable-0.28.
|
63
|
-
runnable-0.28.
|
59
|
+
runnable-0.28.5.dist-info/METADATA,sha256=coPYv1TmJ8bJaBaXNnnvax7cdKWS9hGBYSJWKtuEpZU,10047
|
60
|
+
runnable-0.28.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
61
|
+
runnable-0.28.5.dist-info/entry_points.txt,sha256=ioMbWojILtdibYVgh1jXJ00SpK-tX3gy7oVGDq61cSk,1839
|
62
|
+
runnable-0.28.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
63
|
+
runnable-0.28.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|