@@ -37,6 +37,12 @@ class KubernetesProcessProxy(ContainerProcessProxy):
3737 Kernel lifecycle management for Kubernetes kernels.
3838 """
3939
40+ # Identifies the kind of object being managed by this process proxy.
41+ # For these values we will prefer the values found in the 'kind' field
42+ # of the object's metadata. This attribute is strictly used to provide
43+ # context to log messages.
44+ object_kind = "Pod"
45+
4046 def __init__ (self , kernel_manager : RemoteKernelManager , proxy_config : dict ):
4147 """Initialize the proxy."""
4248 super ().__init__ (kernel_manager , proxy_config )
@@ -91,19 +97,37 @@ def get_container_status(self, iteration: int | None) -> str | None:
9197
9298 if iteration : # only log if iteration is not None (otherwise poll() is too noisy)
9399 self .log .debug (
94- "{}: Waiting to connect to k8s pod in namespace '{}'. "
95- "Name: '{}', Status: '{}', Pod IP: '{}', KernelID: '{}'" .format (
96- iteration ,
97- self .kernel_namespace ,
98- self .container_name ,
99- pod_status ,
100- self .assigned_ip ,
101- self .kernel_id ,
102- )
100+ f"{ iteration } : Waiting to connect to k8s { self .object_kind .lower ()} in "
101+ f"namespace '{ self .kernel_namespace } '. Name: '{ self .container_name } ', "
102+ f"Status: '{ pod_status } ', Pod IP: '{ self .assigned_ip } ', KernelID: '{ self .kernel_id } '"
103103 )
104104
105105 return pod_status
106106
107+ def delete_managed_object (self , termination_stati : list [str ]) -> bool :
108+ """Deletes the object managed by this process-proxy
109+
110+ A return value of True indicates the object is considered deleted,
111+ otherwise a False or None value is returned.
112+
113+ Note: the caller is responsible for handling exceptions.
114+ """
115+ body = client .V1DeleteOptions (grace_period_seconds = 0 , propagation_policy = "Background" )
116+
117+ # Deleting a Pod will return a v1.Pod if found and its status will be a PodStatus containing
118+ # a phase string property
119+ # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#podstatus-v1-core
120+ v1_pod = client .CoreV1Api ().delete_namespaced_pod (
121+ namespace = self .kernel_namespace , body = body , name = self .container_name
122+ )
123+ status = None
124+ if v1_pod and v1_pod .status :
125+ status = v1_pod .status .phase
126+
127+ result = status in termination_stati
128+
129+ return result
130+
107131 def terminate_container_resources (self ) -> bool | None :
108132 """Terminate any artifacts created on behalf of the container's lifetime."""
109133 # Kubernetes objects don't go away on their own - so we need to tear down the namespace
@@ -114,46 +138,36 @@ def terminate_container_resources(self) -> bool | None:
114138 # from the pod deletion API, since it's not necessarily reflective of the actual status.
115139
116140 result = False
117- body = client . V1DeleteOptions ( grace_period_seconds = 0 , propagation_policy = "Background" )
141+ termination_stati = [ "Succeeded" , "Failed" , "Terminating" , "Success" ]
118142
119- # Delete the pod then, if applicable, the namespace
143+ # Delete the managed object then, if applicable, the namespace
144+ object_type = self .object_kind
120145 try :
121- object_name = "pod"
122- status = None
123- termination_stati = ["Succeeded" , "Failed" , "Terminating" ]
124-
125- # Deleting a Pod will return a v1.Pod if found and its status will be a PodStatus containing
126- # a phase string property
127- # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#podstatus-v1-core
128- v1_pod = client .CoreV1Api ().delete_namespaced_pod (
129- namespace = self .kernel_namespace , body = body , name = self .container_name
130- )
131- if v1_pod and v1_pod .status :
132- status = v1_pod .status .phase
133-
134- if status in termination_stati :
135- result = True
136-
146+ result = self .delete_managed_object (termination_stati )
137147 if not result :
138- # If the status indicates the pod is not terminated, capture its current status.
148+ # If the status indicates the object is not terminated, capture its current status.
139149 # If None, update the result to True, else issue warning that it is not YET deleted
140150 # since we still have the hard termination sequence to occur.
141151 cur_status = self .get_container_status (None )
142152 if cur_status is None :
143153 result = True
144154 else :
145155 self .log .warning (
146- f"Pod { self .kernel_namespace } .{ self .container_name } is not yet deleted. "
147- f"Current status is '{ cur_status } '."
156+ f"{ object_type } ' { self .kernel_namespace } .{ self .container_name } ' "
157+ f" is not yet deleted. Current status is '{ cur_status } '."
148158 )
149159
150160 if self .delete_kernel_namespace and not self .kernel_manager .restarting :
151- object_name = "namespace "
161+ object_type = "Namespace "
152162 # Status is a return value for calls that don't return other objects.
153163 # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#status-v1-meta
164+ body = client .V1DeleteOptions (
165+ grace_period_seconds = 0 , propagation_policy = "Background"
166+ )
154167 v1_status = client .CoreV1Api ().delete_namespace (
155168 name = self .kernel_namespace , body = body
156169 )
170+ status = None
157171 if v1_status :
158172 status = v1_status .status
159173
@@ -169,25 +183,23 @@ def terminate_container_resources(self) -> bool | None:
169183
170184 except Exception as err :
171185 if isinstance (err , client .rest .ApiException ) and err .status == 404 :
172- result = True # okay if its not found
186+ result = True # okay if it's not found
173187 else :
174- self .log .warning (f"Error occurred deleting { object_name } : { err } " )
188+ self .log .warning (f"Error occurred deleting { object_type . lower () } : { err } " )
175189
176190 if result :
177191 self .log .debug (
178- "KubernetesProcessProxy.terminate_container_resources, pod: {}.{}, kernel ID: {} has "
179- "been terminated." .format (
180- self .kernel_namespace , self .container_name , self .kernel_id
181- )
192+ f"KubernetesProcessProxy.terminate_container_resources, "
193+ f"{ self .object_kind } : { self .kernel_namespace } .{ self .container_name } , "
194+ f"kernel ID: { self .kernel_id } has been terminated."
182195 )
183196 self .container_name = None
184197 result = None # maintain jupyter contract
185198 else :
186199 self .log .warning (
187- "KubernetesProcessProxy.terminate_container_resources, pod: {}.{}, kernel ID: {} has "
188- "not been terminated." .format (
189- self .kernel_namespace , self .container_name , self .kernel_id
190- )
200+ "KubernetesProcessProxy.terminate_container_resources, "
201+ f"{ self .object_kind } : { self .kernel_namespace } .{ self .container_name } , "
202+ f"kernel ID: { self .kernel_id } has not been terminated."
191203 )
192204
193205 # Check if there's a kernel pod template file for this kernel and silently delete it.
0 commit comments