runnable 0.28.3__py3-none-any.whl → 0.28.5__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.
- 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
|