11"""Utilities for notebooks."""
22
33import renku_data_services .crc .models as crc_models
4- from renku_data_services .base_models .core import RESET
4+ from renku_data_services .base_models .core import RESET , ResetType
5+ from renku_data_services .errors import errors
56from renku_data_services .notebooks .crs import (
67 Affinity ,
78 AffinityPatch ,
89 MatchExpression ,
910 NodeAffinity ,
11+ NodeAffinityPatch ,
1012 NodeSelectorTerm ,
13+ PodAffinityPatch ,
14+ PodAntiAffinityPatch ,
1115 Preference ,
1216 PreferredDuringSchedulingIgnoredDuringExecutionItem ,
1317 RequiredDuringSchedulingIgnoredDuringExecution ,
@@ -85,10 +89,10 @@ def intersect_node_affinities(
8589
8690def node_affinity_from_resource_class (
8791 resource_class : crc_models .ResourceClass ,
88- default_affinity : Affinity ,
89- ) -> Affinity :
92+ default_affinity : Affinity | None ,
93+ ) -> Affinity | None :
9094 """Generate an affinity from the affinities stored in a resource class."""
91- rc_node_affinity = NodeAffinity ()
95+ rc_node_affinity : NodeAffinity | None = None
9296 required_expr = [
9397 MatchExpression (key = affinity .key , operator = "Exists" )
9498 for affinity in resource_class .node_affinities
@@ -100,6 +104,7 @@ def node_affinity_from_resource_class(
100104 if not affinity .required_during_scheduling
101105 ]
102106 if required_expr :
107+ rc_node_affinity = NodeAffinity ()
103108 rc_node_affinity .requiredDuringSchedulingIgnoredDuringExecution = (
104109 RequiredDuringSchedulingIgnoredDuringExecution (
105110 nodeSelectorTerms = [
@@ -112,6 +117,8 @@ def node_affinity_from_resource_class(
112117 )
113118 )
114119 if preferred_expr :
120+ if not rc_node_affinity :
121+ rc_node_affinity = NodeAffinity ()
115122 rc_node_affinity .preferredDuringSchedulingIgnoredDuringExecution = [
116123 PreferredDuringSchedulingIgnoredDuringExecutionItem (
117124 weight = 1 ,
@@ -122,24 +129,60 @@ def node_affinity_from_resource_class(
122129 )
123130 ]
124131
125- affinity = default_affinity .model_copy (deep = True )
126- if affinity .nodeAffinity :
127- affinity .nodeAffinity = intersect_node_affinities (affinity .nodeAffinity , rc_node_affinity )
128- else :
129- affinity .nodeAffinity = rc_node_affinity
130- return affinity
132+ match (default_affinity , rc_node_affinity ):
133+ case (None , None ):
134+ return None
135+ case (None , NodeAffinity ()):
136+ return Affinity (nodeAffinity = rc_node_affinity )
137+ case (Affinity (), None ):
138+ return default_affinity
139+ case (Affinity (), NodeAffinity ()):
140+ affinity = default_affinity .model_copy (deep = True )
141+ if affinity .nodeAffinity :
142+ affinity .nodeAffinity = intersect_node_affinities (affinity .nodeAffinity , rc_node_affinity )
143+ else :
144+ affinity .nodeAffinity = rc_node_affinity
145+ return affinity
146+ case _:
147+ raise errors .ProgrammingError (message = "Cannot derive node affinity from resource class and defaults." )
131148
132149
133150def node_affinity_patch_from_resource_class (
134- resource_class : crc_models .ResourceClass , default_affinity : Affinity
135- ) -> AffinityPatch :
151+ resource_class : crc_models .ResourceClass , default_affinity : Affinity | None
152+ ) -> AffinityPatch | ResetType :
136153 """Create a patch for the session affinity."""
137154 affinity = node_affinity_from_resource_class (resource_class , default_affinity )
138- return AffinityPatch (
139- nodeAffinity = affinity .nodeAffinity or RESET ,
140- podAffinity = affinity .podAffinity or RESET ,
141- podAntiAffinity = affinity .podAntiAffinity or RESET ,
142- )
155+ if not affinity :
156+ return RESET
157+ patch = AffinityPatch (nodeAffinity = RESET , podAffinity = RESET , podAntiAffinity = RESET )
158+ if affinity .nodeAffinity :
159+ patch .nodeAffinity = NodeAffinityPatch (
160+ preferredDuringSchedulingIgnoredDuringExecution = (
161+ affinity .nodeAffinity .preferredDuringSchedulingIgnoredDuringExecution or RESET
162+ ),
163+ requiredDuringSchedulingIgnoredDuringExecution = (
164+ affinity .nodeAffinity .requiredDuringSchedulingIgnoredDuringExecution or RESET
165+ ),
166+ )
167+ if affinity .podAffinity :
168+ patch .podAffinity = PodAffinityPatch (
169+ preferredDuringSchedulingIgnoredDuringExecution = (
170+ affinity .podAffinity .preferredDuringSchedulingIgnoredDuringExecution or RESET
171+ ),
172+ requiredDuringSchedulingIgnoredDuringExecution = (
173+ affinity .podAffinity .requiredDuringSchedulingIgnoredDuringExecution or RESET
174+ ),
175+ )
176+ if affinity .podAntiAffinity :
177+ patch .podAntiAffinity = PodAntiAffinityPatch (
178+ preferredDuringSchedulingIgnoredDuringExecution = (
179+ affinity .podAntiAffinity .preferredDuringSchedulingIgnoredDuringExecution or RESET
180+ ),
181+ requiredDuringSchedulingIgnoredDuringExecution = (
182+ affinity .podAntiAffinity .requiredDuringSchedulingIgnoredDuringExecution or RESET
183+ ),
184+ )
185+ return patch
143186
144187
145188def tolerations_from_resource_class (
0 commit comments