@@ -252,6 +252,9 @@ def camelCaseify(s):
252252if tolerations :
253253 c .KubeSpawner .tolerations = tolerations
254254
255+ volumes = {}
256+ volume_mounts = {}
257+
255258# Configure dynamically provisioning pvc
256259storage_type = get_config ("singleuser.storage.type" )
257260if storage_type == "dynamic" :
@@ -273,32 +276,35 @@ def camelCaseify(s):
273276 )
274277
275278 # Add volumes to singleuser pods
276- c . KubeSpawner . volumes = [
277- {
279+ volumes = {
280+ volume_name_template : {
278281 "name" : volume_name_template ,
279282 "persistentVolumeClaim" : {"claimName" : "{pvc_name}" },
280283 }
281- ]
282- c . KubeSpawner . volume_mounts = [
283- {
284+ }
285+ volume_mounts = {
286+ volume_name_template : {
284287 "mountPath" : get_config ("singleuser.storage.homeMountPath" ),
285288 "name" : volume_name_template ,
286289 "subPath" : get_config ("singleuser.storage.dynamic.subPath" ),
287290 }
288- ]
291+ }
289292elif storage_type == "static" :
290293 pvc_claim_name = get_config ("singleuser.storage.static.pvcName" )
291- c .KubeSpawner .volumes = [
292- {"name" : "home" , "persistentVolumeClaim" : {"claimName" : pvc_claim_name }}
293- ]
294+ volumes = {
295+ "home" : {
296+ "name" : "home" ,
297+ "persistentVolumeClaim" : {"claimName" : pvc_claim_name },
298+ }
299+ }
294300
295- c . KubeSpawner . volume_mounts = [
296- {
301+ volume_mounts = {
302+ "home" : {
297303 "mountPath" : get_config ("singleuser.storage.homeMountPath" ),
298304 "name" : "home" ,
299305 "subPath" : get_config ("singleuser.storage.static.subPath" ),
300306 }
301- ]
307+ }
302308
303309# Inject singleuser.extraFiles as volumes and volumeMounts with data loaded from
304310# the dedicated k8s Secret prepared to hold the extraFiles actual content.
@@ -323,24 +329,37 @@ def camelCaseify(s):
323329 "secretName" : get_name ("singleuser" ),
324330 "items" : items ,
325331 }
326- c . KubeSpawner . volumes . append ( volume )
332+ volumes [ volume [ "name" ]] = volume
327333
328- volume_mounts = []
329- for file_key , file_details in extra_files .items ():
330- volume_mounts .append (
331- {
332- "mountPath" : file_details ["mountPath" ],
333- "subPath" : file_key ,
334- "name" : "files" ,
335- }
336- )
337- c .KubeSpawner .volume_mounts .extend (volume_mounts )
334+ for idx , (file_key , file_details ) in enumerate (extra_files .items ()):
335+ volume_mount = {
336+ "mountPath" : file_details ["mountPath" ],
337+ "subPath" : file_key ,
338+ "name" : "files" ,
339+ }
340+ volume_mounts [f"{ idx } -files" ] = volume_mount
338341
339342# Inject extraVolumes / extraVolumeMounts
340- c .KubeSpawner .volumes .extend (get_config ("singleuser.storage.extraVolumes" , []))
341- c .KubeSpawner .volume_mounts .extend (
342- get_config ("singleuser.storage.extraVolumeMounts" , [])
343- )
343+ extra_volumes = get_config ("singleuser.storage.extraVolumes" , default = {})
344+ if isinstance (extra_volumes , dict ):
345+ volumes .update (extra_volumes )
346+ elif isinstance (extra_volumes , list ):
347+ for volume in extra_volumes :
348+ volumes [volume ["name" ]] = volume
349+
350+ extra_volume_mounts = get_config ("singleuser.storage.extraVolumeMounts" , default = {})
351+ if isinstance (extra_volume_mounts , dict ):
352+ volume_mounts .update (extra_volume_mounts )
353+ elif isinstance (extra_volume_mounts , list ):
354+ # If extraVolumeMounts is a list, we need to add them to the volume_mounts
355+ # dictionary with a unique key.
356+ # Since volume mount's name is not guaranteed to be unique, we use the index
357+ # as part of the key.
358+ for idx , volume_mount in enumerate (extra_volume_mounts ):
359+ volume_mounts [f"{ idx } -{ volume_mount ['name' ]} " ] = volume_mount
360+
361+ c .KubeSpawner .volumes = volumes
362+ c .KubeSpawner .volume_mounts = volume_mounts
344363
345364c .JupyterHub .services = []
346365c .JupyterHub .load_roles = []
0 commit comments