# The spawner is based on PRP's https://gitlab.nrp-nautilus.io/vpeddu/jupyterlab-west.git # This file is managed by [youngsu.kim|dung.vu]@csusb.edu from kubespawner import KubeSpawner class MySpawner(KubeSpawner): with open('/etc/jupyterhub/custom/my_spawner.html', 'r') as f: profile_form_template = f.readlines() profile_form_template = "".join(profile_form_template) def options_from_form(self, formdata): # cephfs_pvc_users = {"dvu@csusb.edu":"dvu", "youngsu.kim@csusb.edu":"ykim", "x5he@eng.ucsd.edu":"x5he" } cephfs_pvc_users = {"youngsu.kim@csusb.edu":"ykim", "x5he@eng.ucsd.edu":"x5he" } if not self.profile_list or not hasattr(self, '_profile_list'): return formdata selected_profile = int(formdata.get('profile', [0])[0]) options = self._profile_list[selected_profile] self.log.debug("Applying KubeSpawner override for profile '%s'", options['display_name']) kubespawner_override = options.get('kubespawner_override', {}) for k, v in kubespawner_override.items(): if callable(v): v = v(self) self.log.debug(".. overriding KubeSpawner value %s=%s (callable result)", k, v) else: self.log.debug(".. overriding KubeSpawner value %s=%s", k, v) setattr(self, k, v) gpus = int(formdata.get('gpus', [0])[0]) setattr(self, "extra_resource_limits", {"nvidia.com/gpu": gpus}) setattr(self, "mem_guarantee", formdata.get('ram', [0])[0]+"G") setattr(self, "cpu_guarantee", float(formdata.get('cores', [0])[0])) setattr(self, "mem_limit", formdata.get('ram', [0])[0]+"G") setattr(self, "cpu_limit", float(formdata.get('cores', [0])[0])) nodeSelectorTermsExpressions = [{ 'key': 'topology.kubernetes.io/region', 'operator': 'In', 'values': ["us-west","us-central"] }, { 'key': 'kubernetes.io/arch', 'operator': 'In', 'values': ["amd64"] }, # { # 'key': 'kubernetes.io/hostname', # 'operator': 'In', # 'values': ["node-2-1.sdsc.optiputer.net", "node-2-7.sdsc.optiputer.net","node-2-8.sdsc.optiputer.net"] # } ] if formdata.get('gputype', [0])[0]: nodeSelectorTermsExpressions.append({ 'key': 'nvidia.com/gpu.product', 'operator': 'In', 'values': formdata.get('gputype', [0]) }) tolerationsExpression = [{ 'key': 'nautilus.io/nrp-testing', 'operator': 'Exists', 'effect': 'NoSchedule', }, { 'key': 'nautilus.io/csusb', 'operator': 'Exists', 'effect': 'NoSchedule', } ] setattr(self, 'extra_pod_config', { 'affinity': { 'nodeAffinity': { 'requiredDuringSchedulingIgnoredDuringExecution': { 'nodeSelectorTerms': [{ 'matchExpressions': nodeSelectorTermsExpressions, }], }, }, }, 'tolerations': tolerationsExpression, 'priorityClassName': 'owner', # 'imagePullPolicy': 'IfNotPresent', }) if self.user.name in cephfs_pvc_users: self.volume_mounts.append({ 'name': 'vasp', 'mountPath': '/home/jovyan/.vasp', }) self.volumes.append({ 'name': 'vasp', 'persistentVolumeClaim': { 'claimName': 'csusb-hub-dev-vasp-south-east', } }) if formdata.get('shared', [0])[0]: self.volume_mounts.append({ 'name': 'csusb-hpc-share', 'mountPath': '/home/jovyan/shared', }) self.volumes.append({ 'name': 'csusb-hpc-share', 'persistentVolumeClaim': { 'claimName': 'csusb-hub-dev-share-south-east', } }) setattr(self, 'startTimeout', 1200) return options profile_list = [ { 'display_name': 'Nrp-Stack Minimal', }, { 'display_name': 'Nrp-Stack Desktop v1.1', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/5g-desktop:ab90e952', # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/prism-desktop:0addcd15', 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/desktop:v1.1', # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/relion-desktop', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack Desktop - Visual Code, mutiple Apps', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/5g-desktop:v1.1', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack Datascience', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/datascience:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'Nrp-Stack Tensorflow + PRP Packages', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/prp:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'Nrp-Stack R-Studio', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'Nrp-Stack PySpark', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/pyspark:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': "Nrp-Stack Matlab", 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/matlab:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': "Nrp-Stack OSGEO", 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/osgeo-notebook:v1.0', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack Desktop - Visual Studio', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/5g-desktop', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack wcsng-desktop', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/wcsng-desktop:v1.0', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack Prism Desktop', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/prism-desktop:v1.0', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Stack u55c-desktop', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/u55c-desktop:v1.0', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'Nrp-Scipy', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/scipy:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'Nrp-PyTorch2', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/prp-pytorch2:v1.0', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'YoungSu- becerra-class', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/youngsu_kim/csusb-jupyter-stack/stack-rstudio-becerra-class', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'YoungSu-Stack SageMath', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/youngsu_kim/csusb-jupyter-stack/stack-sagemath', 'imagePullPolicy': 'IfNotPresent', } } , { 'display_name': 'NRP Desktop- Pgadmin4', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/desktop:11-add-pgadmin4', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } } , { 'display_name': 'CSUSB Desktop- Pgadmin4', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop-plus:d5292f66', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop-plus:a0544c38', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop-plus:latest', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'CSUSB Desktop', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio', 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop:latest', 'imagePullPolicy': 'IfNotPresent', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio:latest', } }, { 'display_name': 'CSUSB Minimal', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio', 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/minimal:latest', 'imagePullPolicy': 'IfNotPresent', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio:latest', } }, { 'display_name': 'CSUSB Desktop - 5g', 'kubespawner_override': { 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/5g-desktop', 'imagePullPolicy': 'IfNotPresent', 'lifecycle_hooks': { 'postStart': { 'exec': { 'command': [ 'sh', '-c', 'mkdir -p /home/jovyan/Desktop && cp /home/jovyan/shared/.software/desktopInit.desktop /home/jovyan/Desktop/ || true' ] } } } } }, { 'display_name': 'CSUSB-Stack R-Studio', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio', 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio', 'imagePullPolicy': 'IfNotPresent', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio:latest', } }, { 'display_name': 'CSUSB-Stack Tensorflow 2.85', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio', 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/prp:10-rebuild-stack-tf-image-with-tf-cudnn-8-5', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/tensorflow:d525d538', 'imagePullPolicy': 'IfNotPresent', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio:latest', } } , { 'display_name': 'CSUSB-Stack Blender', 'kubespawner_override': { # 'image': 'gitlab-registry.nrp-nautilus.io/prp/jupyter-stack/r-studio', # without metashape & 22.04 OS 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop-blender:ee8ef8ee', # with metashape # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/desktop-blender:5b5f0289', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/tensorflow:d525d538', 'imagePullPolicy': 'IfNotPresent', # 'image': 'gitlab-registry.nrp-nautilus.io/csusb-prp/csusb-jupyter-stacks/r-studio:latest', } }, { 'display_name': 'jupyter/minimal-notebook', 'kubespawner_override': { 'image': 'jupyter/minimal-notebook', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'jupyter/scipy-notebook', 'kubespawner_override': { 'image': 'jupyter/scipy-notebook', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'jupyter/tensorflow-notebook', 'kubespawner_override': { 'image': 'jupyter/tensorflow-notebook', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'jupyter/pyspark-notebook', 'kubespawner_override': { 'image': 'jupyter/pyspark-notebook', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'jupyter/datascience-notebook', 'kubespawner_override': { 'image': 'jupyter/datascience-notebook', 'imagePullPolicy': 'IfNotPresent', } }, { 'display_name': 'jupyter/all-spark-notebook', 'kubespawner_override': { 'image': 'jupyter/all-spark-notebook', 'imagePullPolicy': 'IfNotPresent', } }, ] c.JupyterHub.spawner_class = MySpawner