6
6
from typing import NamedTuple
7
7
8
8
import kr8s
9
+ import pyhelm3
9
10
import yaml
10
11
from kr8s .objects import (
11
12
ConfigMap ,
@@ -39,20 +40,21 @@ def __init__(self, config: UserCodeDeploymentsConfig, kr8s_api: kr8s.Api) -> Non
39
40
40
41
def maybe_create_user_deployments_configmap (self ) -> None :
41
42
"""Creates a user deployments_configmap if it doesn't exist yet."""
42
- from copy import deepcopy
43
-
44
- dagster_user_deployments_values_yaml_configmap = deepcopy (BASE_CONFIGMAP )
45
- dagster_user_deployments_values_yaml_configmap ["metadata" ]["name" ] = (
46
- self .config .user_code_deployments_configmap_name
47
- )
48
- dagster_user_deployments_values_yaml_configmap ["data" ]["yaml" ] = yaml .dump (
49
- BASE_CONFIGMAP_DATA ,
50
- )
51
43
try :
52
44
self ._read_namespaced_config_map (
53
45
self .config .user_code_deployments_configmap_name ,
54
46
)
55
47
except kr8s .NotFoundError :
48
+ from copy import deepcopy
49
+
50
+ dagster_user_deployments_values_yaml_configmap = deepcopy (BASE_CONFIGMAP )
51
+ dagster_user_deployments_values_yaml_configmap ["metadata" ]["name" ] = (
52
+ self .config .user_code_deployments_configmap_name
53
+ )
54
+ dagster_user_deployments_values_yaml_configmap ["data" ]["yaml" ] = yaml .dump (
55
+ BASE_CONFIGMAP_DATA ,
56
+ )
57
+
56
58
ConfigMap (
57
59
resource = dagster_user_deployments_values_yaml_configmap ,
58
60
namespace = self .config .namespace ,
@@ -180,36 +182,43 @@ def deploy_to_k8s(
180
182
self .update_dagster_workspace_yaml ()
181
183
182
184
loop = asyncio .new_event_loop ()
183
- helm_client = Client ()
185
+ RELEASE_NAME = "dagster-user-code" # noqa
186
+ helm_client = Client (kubecontext = self .config .kubernetes_context )
187
+
184
188
chart = loop .run_until_complete (
185
189
helm_client .get_chart (
186
190
chart_ref = "dagster-user-deployments" ,
187
191
repo = "https://dagster-io.github.io/helm" ,
188
192
version = self .config .dagster_version ,
189
193
),
190
194
)
191
- helm_templates = [
192
- * loop .run_until_complete (
193
- helm_client .template_resources (
194
- chart ,
195
- "dagster" ,
196
- values_dict ,
197
- namespace = self .config .namespace ,
198
- ),
195
+ logger .info (
196
+ "Upgrading helm release '%s'..." ,
197
+ RELEASE_NAME ,
198
+ )
199
+ installed = loop .run_until_complete (
200
+ helm_client .install_or_upgrade_release (
201
+ RELEASE_NAME ,
202
+ chart ,
203
+ values_dict ,
204
+ namespace = self .config .namespace ,
205
+ wait = True ,
199
206
),
200
- ]
207
+ )
208
+ if installed .status == pyhelm3 .ReleaseRevisionStatus .FAILED :
209
+ logger .error (
210
+ "Dagster-usercode helm release install or upgrade failed, rolling back now.." ,
211
+ )
212
+ from pyhelm3 import Release
201
213
202
- # Update user code deployments in k8s (akin to kubectl apply -f)
203
- for obj in helm_templates :
204
- k8s_obj = eval (obj ["kind" ])(obj , api = self .api )
205
- try :
206
- k8s_obj .patch (obj )
207
- except kr8s .NotFoundError :
208
- k8s_obj .create ()
214
+ release = Release (name = RELEASE_NAME , namespace = self .config .namespace )
215
+ loop .run_until_complete (release .rollback ())
216
+ raise Exception ("Helm user-code deployment failed, had to rollback." )
209
217
210
218
if reload_dagster :
211
219
for deployment_name in ["dagster-daemon" , "dagster-dagster-webserver" ]:
212
220
deployment = Deployment .get (deployment_name , namespace = self .config .namespace )
221
+
213
222
reload_patch = {
214
223
"spec" : {
215
224
"template" : {
@@ -225,38 +234,6 @@ def deploy_to_k8s(
225
234
}
226
235
deployment .patch (reload_patch )
227
236
228
- def delete_k8s_resources_for_user_deployment (
229
- self ,
230
- label : str ,
231
- delete_deployments : bool = True ,
232
- ) -> None :
233
- """Deletes all k8s resources related to a specific user code deployment.
234
- Returns a boolean letting you know if pod was found
235
- """
236
- for pod in self .api .get (
237
- Pod ,
238
- label_selector = f"dagster/code-location={ label } " ,
239
- field_selector = "status.phase=Succeeded" ,
240
- namespace = self .config .namespace ,
241
- ):
242
- logger .info (f"Deleting pod { pod .name } " )
243
- pod .delete ()
244
-
245
- if delete_deployments :
246
- import contextlib
247
-
248
- with contextlib .suppress (kr8s .NotFoundError ):
249
- Deployment .get (
250
- namespace = self .config .namespace ,
251
- label_selector = f"deployment={ label } " ,
252
- api = self .api ,
253
- ).delete ()
254
- Deployment .get (
255
- namespace = self .config .namespace ,
256
- label_selector = f"dagster/code-location={ label } " ,
257
- api = self .api ,
258
- ).delete ()
259
-
260
237
def gen_new_deployment_yaml (
261
238
self ,
262
239
name : str ,
@@ -480,27 +457,6 @@ def check_if_code_pod_exists(self, label: str) -> bool:
480
457
)
481
458
return len (running_pods ) > 0
482
459
483
- def delete_k8s_resources (self , label_selector : str ):
484
- """Delete all k8s resources with a specified label_selector"""
485
- for resource in [
486
- "Pod" ,
487
- "ReplicationController" ,
488
- "Service" ,
489
- "DaemonSet" ,
490
- "Deployment" ,
491
- "ReplicaSet" ,
492
- "StatefulSet" ,
493
- "HorizontalPodAutoscaler" ,
494
- "CronJob" ,
495
- "Job" ,
496
- ]:
497
- for item in self .api .get (
498
- resource ,
499
- namespace = self .config .namespace ,
500
- label_selector = label_selector ,
501
- ):
502
- item .delete ()
503
-
504
460
def acquire_semaphore (self , reset_lock : bool = False ) -> bool :
505
461
"""Acquires a semaphore by creating a configmap"""
506
462
if reset_lock :
0 commit comments