LabConfig

pydantic model controller.config.LabConfig

Configuration for spawning user labs.

Parameters:

data (Any)

Show JSON schema
{
   "title": "LabConfig",
   "description": "Configuration for spawning user labs.",
   "type": "object",
   "properties": {
      "application": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "An Argo CD application under which lab objects should be shown",
         "title": "Argo CD application"
      },
      "affinity": {
         "anyOf": [
            {
               "$ref": "#/$defs/Affinity"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "Node and pod affinity rules for lab pods",
         "title": "Affinity rules"
      },
      "deleteTimeout": {
         "default": "PT1M",
         "description": "How long to wait in total for deletion of Kubernetes resources for a user lab",
         "examples": [
            60
         ],
         "format": "duration",
         "title": "Timeout for lab deletion",
         "type": "string"
      },
      "env": {
         "additionalProperties": {
            "type": "string"
         },
         "default": {},
         "description": "Additional environment variables to set in all spawned user labs",
         "title": "Additional lab environment variables",
         "type": "object"
      },
      "extraAnnotations": {
         "additionalProperties": {
            "type": "string"
         },
         "default": {},
         "description": "These annotations will be added to the Kubernetes ``Pod`` resource in addition to annotations used by Nublado itself to track metadata about the pod",
         "title": "Extra annotations",
         "type": "object"
      },
      "files": {
         "additionalProperties": {
            "type": "string"
         },
         "default": {},
         "description": "The key is the path inside the lab at which to mount the file, and the value describes the contents of the file.",
         "title": "Files to create inside the lab",
         "type": "object"
      },
      "jupyterlabConfigDir": {
         "default": "/opt/lsst/software/jupyterlab",
         "description": "Path inside the lab container where custom configuration is stored.  Things like kernel definitions, custom logger definitions, service tokens, and Lab-instance-specific secrets are stored under this path.",
         "title": "Root of Lab custom Jupyterlab configuration",
         "type": "string"
      },
      "homedirPrefix": {
         "default": "/home",
         "description": "Portion of home directory path added before the username. This is the path *inside* the container, not the path of the volume mounted in the container, so it need not reflect the structure of the home directory volume source. The primary reason to set this is to make paths inside the container match a pattern that users are familiar with outside of Nublado.",
         "examples": [
            "/home",
            "/u"
         ],
         "title": "Prefix for home directory path",
         "type": "string"
      },
      "homedirSchema": {
         "$ref": "#/$defs/UserHomeDirectorySchema",
         "default": "username",
         "description": "Determines how the username portion of the home directory path is constructed.",
         "title": "Schema for user homedir construction"
      },
      "homedirSuffix": {
         "default": "",
         "description": "Portion of home directory path added after the username. This is primarily used for environments that want the user's Nublado home directory to be a subdirectory of their regular home directory outside of Nublado. This configuration is strongly recommended in environments that change home directories, since Nublado often has different needs for dot files and other configuration.",
         "examples": [
            "nublado",
            "jhome"
         ],
         "title": "Suffix for home directory path",
         "type": "string"
      },
      "initContainers": {
         "default": [],
         "description": "Kubernetes init containers to run before user's lab starts. Use these containers to do any required setup, particularly any actions that require privileges, since init containers can be run as privileged and the lab container is always run as the user.",
         "items": {
            "$ref": "#/$defs/LabInitContainer"
         },
         "title": "Lab init containers",
         "type": "array"
      },
      "labStartCommand": {
         "default": [
            "/opt/lsst/software/jupyterlab/runlab.sh"
         ],
         "description": "This is the executable in the container that will be run to start the lab, and its arguments, supplied as a list of strings.",
         "items": {
            "type": "string"
         },
         "title": "Lab command",
         "type": "array"
      },
      "namespacePrefix": {
         "description": "The namespace for the user's lab will start with this string, a hyphen (``-``), and the user's username",
         "title": "Namespace prefix for lab environments",
         "type": "string"
      },
      "nodeSelector": {
         "additionalProperties": {
            "type": "string"
         },
         "default": {},
         "description": "Labels that must be present on Kubernetes nodes for any lab pod to be scheduled there",
         "examples": [
            {
               "disktype": "ssd"
            }
         ],
         "title": "Lab pod node selector",
         "type": "object"
      },
      "nss": {
         "$ref": "#/$defs/LabNSSFiles",
         "description": "Configuration for the ``/etc/passwd`` and ``/etc/group`` files inside the lab",
         "title": "passwd and group contents for lab"
      },
      "pullSecret": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "If set, must be the name of a secret in the same namespace as the lab controller. This secret is copied to the user's lab namespace and referenced as a pull secret in the pod object.",
         "title": "Pull secret to use for lab pods"
      },
      "runtimeMountsDir": {
         "default": "/opt/lsst/software/jupyterlab",
         "description": "Directory under which runtime information (e.g. tokens, environment variables, and container resource information will be mounted.",
         "title": "Runtime-info mounts",
         "type": "string"
      },
      "secrets": {
         "default": [],
         "description": "Secrets to make available inside lab",
         "items": {
            "$ref": "#/$defs/LabSecret"
         },
         "title": "Lab secrets",
         "type": "array"
      },
      "sizes": {
         "default": [],
         "description": "Only these sizes will be present in the menu, in the order in which they're defined in the configuration file. The first size defined will be the default.",
         "items": {
            "$ref": "#/$defs/LabSizeDefinition"
         },
         "title": "Possible lab sizes",
         "type": "array"
      },
      "spawnTimeout": {
         "default": "PT10M",
         "description": "Creation of the lab will fail if it takes longer than this for the lab pod to be created and start running. This does not include the time spent by JupyterHub waiting for the lab to start listening to the network. It should generally be shorter than the spawn timeout set in JupyterHub.",
         "examples": [
            300
         ],
         "format": "duration",
         "title": "Timeout for lab spawning",
         "type": "string"
      },
      "tmpSource": {
         "$ref": "#/$defs/TmpSource",
         "default": "memory",
         "description": "Use this to select whether the pod's :file:`/tmp` will come from memory or node-local disk.  Both are scarce resources, and the appropriate choice is environment-dependent.",
         "title": "Source (memory or disk) for lab :file:`/tmp`"
      },
      "tolerations": {
         "default": [],
         "description": "Kubernetes tolerations for file server pods",
         "items": {
            "$ref": "#/$defs/Toleration"
         },
         "title": "File server pod tolerations",
         "type": "array"
      },
      "volumes": {
         "default": [],
         "description": "Volumes available to mount inside either the lab container or an init container. Inclusion in this list does not mean that they will be mounted. They must separately be listed under ``volumeMounts`` for either an init container or the main lab configuration.",
         "items": {
            "$ref": "#/$defs/VolumeConfig"
         },
         "title": "Available volumes",
         "type": "array"
      },
      "volumeMounts": {
         "default": [],
         "description": "Volumes to mount inside the lab container",
         "items": {
            "$ref": "#/$defs/VolumeMountConfig"
         },
         "title": "Mounted volumes",
         "type": "array"
      }
   },
   "$defs": {
      "Affinity": {
         "additionalProperties": false,
         "description": "Pod affinity rules.",
         "properties": {
            "nodeAffinity": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/NodeAffinity"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Node affinity rules"
            },
            "podAffinity": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/PodAffinity"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Pod affinity rules"
            },
            "podAntiAffinity": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/PodAntiAffinity"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Pod anti-affinity rules"
            }
         },
         "title": "Affinity",
         "type": "object"
      },
      "ContainerImage": {
         "additionalProperties": false,
         "description": "Docker image that may be run as a container.\n\nThe structure of this model should follow the normal Helm chart\nconventions so that `Mend Renovate`_ can detect that this is a Docker\nimage reference and create pull requests to update it automatically.",
         "properties": {
            "repository": {
               "description": "Docker repository from which to pull the image",
               "examples": [
                  "docker.io/lsstit/ddsnet4u"
               ],
               "title": "Repository",
               "type": "string"
            },
            "pullPolicy": {
               "$ref": "#/$defs/PullPolicy",
               "default": "IfNotPresent",
               "description": "Kubernetes image pull policy. Set to ``Always`` when testing images that reuse the same tag.",
               "examples": [
                  "Always"
               ],
               "title": "Pull policy"
            },
            "tag": {
               "description": "Tag of image to use (conventionally the version)",
               "examples": [
                  "1.4.2"
               ],
               "title": "Image tag",
               "type": "string"
            }
         },
         "required": [
            "repository",
            "tag"
         ],
         "title": "ContainerImage",
         "type": "object"
      },
      "HostPathVolumeSource": {
         "additionalProperties": false,
         "description": "Path on Kubernetes node to mount in the container.",
         "properties": {
            "type": {
               "const": "hostPath",
               "enum": [
                  "hostPath"
               ],
               "title": "Type of volume to mount",
               "type": "string"
            },
            "path": {
               "description": "Absolute host path to mount in the container",
               "examples": [
                  "/home"
               ],
               "pattern": "^/.*",
               "title": "Host path",
               "type": "string"
            }
         },
         "required": [
            "type",
            "path"
         ],
         "title": "HostPathVolumeSource",
         "type": "object"
      },
      "LabInitContainer": {
         "additionalProperties": false,
         "description": "A container to run as an init container before the user's lab.",
         "properties": {
            "name": {
               "description": "Name of the init container run before the user lab starts. Must be unique across all init containers.",
               "examples": [
                  "multus-init"
               ],
               "title": "Name of container",
               "type": "string"
            },
            "image": {
               "$ref": "#/$defs/ContainerImage",
               "title": "Image to run"
            },
            "privileged": {
               "default": false,
               "description": "Whether the init container needs to run privileged to do its job. Set to true if, for example, it has to configure networking or change ownership of files or directories.",
               "examples": [
                  false
               ],
               "title": "Run container privileged",
               "type": "boolean"
            },
            "volumeMounts": {
               "default": [],
               "description": "Volumes mounted inside this init container",
               "items": {
                  "$ref": "#/$defs/VolumeMountConfig"
               },
               "title": "Volume mounts",
               "type": "array"
            }
         },
         "required": [
            "name",
            "image"
         ],
         "title": "LabInitContainer",
         "type": "object"
      },
      "LabNSSFiles": {
         "additionalProperties": false,
         "description": "Rules for :file:`/etc/passwd` and :file:`/etc/group` inside the lab.",
         "properties": {
            "basePasswd": {
               "default": "root:x:0:0:root:/root:/bin/bash\n",
               "description": "These contents will be copied verbatim to ``/etc/passwd`` inside the lab, and then an entry for the user will be appended",
               "examples": [
                  "root:x:0:0:root:/root:/bin/bash\n"
               ],
               "title": "Base contents of ``/etc/passwd``",
               "type": "string"
            },
            "baseGroup": {
               "default": "root:x:0\n",
               "description": "These contents will be copied verbatim to ``/etc/group`` inside the lab, and then entries for the user's groups will be appended",
               "examples": [
                  "root:x:0\n"
               ],
               "title": "Base contents of ``/etc/group``",
               "type": "string"
            }
         },
         "title": "LabNSSFiles",
         "type": "object"
      },
      "LabSecret": {
         "additionalProperties": false,
         "description": "A secret to make available to lab containers.",
         "properties": {
            "secretName": {
               "description": "Must name a ``Secret`` resource in the same namespace as the Nublado controller pod",
               "examples": [
                  "credentials"
               ],
               "title": "Source secret name",
               "type": "string"
            },
            "secretKey": {
               "description": "Name of field inside the ``Secret`` named ``secretName`` containing the secret. Each secret key must be unique across all secrets in the list of source secrets, since it is also used as the key for the entry in the secret created in the user's lab environment.",
               "examples": [
                  "butler-credentials"
               ],
               "title": "Key of secret",
               "type": "string"
            },
            "env": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "If set, also inject the value of this secret into the lab environment variable of this name",
               "examples": [
                  "BUTLER_CREDENTIALS"
               ],
               "title": "Environment variable to set"
            },
            "path": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "If set, also mount the secret at this path inside the lab container",
               "examples": [
                  "/opt/lsst/software/jupyterlab/butler-secret"
               ],
               "title": "Path at which to mount secret"
            }
         },
         "required": [
            "secretName",
            "secretKey"
         ],
         "title": "LabSecret",
         "type": "object"
      },
      "LabSize": {
         "description": "Allowable names for pod sizes.\n\nTaken from `d20 creature sizes`_.",
         "enum": [
            "fine",
            "diminutive",
            "tiny",
            "small",
            "medium",
            "large",
            "huge",
            "gargantuan",
            "colossal",
            "custom"
         ],
         "title": "LabSize",
         "type": "string"
      },
      "LabSizeDefinition": {
         "additionalProperties": false,
         "description": "Possible size of lab.\n\nThis will be used as the resource limits in Kubernetes, meaning that using\nmore than this amount of CPU will result in throttling and more than this\namount of memory may result in the lab being killed with an out-of-memory\nerror. Requests will be less than this, adjusted by\n``LIMIT_TO_REQUEST_RATIO``.",
         "properties": {
            "size": {
               "$ref": "#/$defs/LabSize",
               "description": "Human-readable name for this lab size",
               "examples": [
                  "small",
                  "huge"
               ],
               "title": "Lab size"
            },
            "cpu": {
               "description": "Number of CPU cores",
               "examples": [
                  0.5
               ],
               "title": "CPU",
               "type": "number"
            },
            "memory": {
               "description": "Amount of memory in bytes (SI suffixes allowed)",
               "examples": [
                  "1536MiB"
               ],
               "title": "Memory",
               "type": "string"
            }
         },
         "required": [
            "size",
            "cpu",
            "memory"
         ],
         "title": "LabSizeDefinition",
         "type": "object"
      },
      "LabelSelector": {
         "additionalProperties": false,
         "description": "Rule for matching labels of pods or namespaces.\n\nAll provided expressions must match. (In other words, they are combined\nwith and.)",
         "properties": {
            "matchExpressions": {
               "default": [],
               "description": "Rules for matching labels",
               "items": {
                  "$ref": "#/$defs/LabelSelectorRequirement"
               },
               "title": "Label match expressions",
               "type": "array"
            },
            "matchLabels": {
               "additionalProperties": {
                  "type": "string"
               },
               "default": {},
               "description": "Label keys and values that must be set",
               "title": "Exact label matches",
               "type": "object"
            }
         },
         "title": "LabelSelector",
         "type": "object"
      },
      "LabelSelectorOperator": {
         "description": "Match operations for label selectors.",
         "enum": [
            "In",
            "NotIn",
            "Exists",
            "DoesNotExist"
         ],
         "title": "LabelSelectorOperator",
         "type": "string"
      },
      "LabelSelectorRequirement": {
         "additionalProperties": false,
         "description": "Single rule for label matching.",
         "properties": {
            "key": {
               "description": "Label key to match",
               "title": "Key",
               "type": "string"
            },
            "operator": {
               "$ref": "#/$defs/LabelSelectorOperator",
               "description": "Label match operator",
               "title": "Operator"
            },
            "values": {
               "default": [],
               "description": "For ``In`` and ``NotIn``, matches any value in this list. For ``Exists`` or ``DoesNotExist``, must be empty.",
               "items": {
                  "type": "string"
               },
               "title": "Matching values",
               "type": "array"
            }
         },
         "required": [
            "key",
            "operator"
         ],
         "title": "LabelSelectorRequirement",
         "type": "object"
      },
      "NFSVolumeSource": {
         "additionalProperties": false,
         "description": "NFS volume to mount in the container.",
         "properties": {
            "type": {
               "const": "nfs",
               "enum": [
                  "nfs"
               ],
               "title": "Type of volume to mount",
               "type": "string"
            },
            "server": {
               "description": "Name or IP address of the server providing the volume",
               "examples": [
                  "10.13.105.122"
               ],
               "title": "NFS server",
               "type": "string"
            },
            "serverPath": {
               "description": "Absolute path of NFS server export of the volume",
               "examples": [
                  "/share1/home"
               ],
               "pattern": "^/.*",
               "title": "Export path",
               "type": "string"
            },
            "readOnly": {
               "default": false,
               "description": "Whether to mount the NFS volume read-only. If this is true, any mount of this volume will be read-only even if the mount is not marked as such.",
               "title": "Is read-only",
               "type": "boolean"
            }
         },
         "required": [
            "type",
            "server",
            "serverPath"
         ],
         "title": "NFSVolumeSource",
         "type": "object"
      },
      "NodeAffinity": {
         "additionalProperties": false,
         "description": "Node affinity rules.",
         "properties": {
            "preferredDuringSchedulingIgnoredDuringExecution": {
               "default": [],
               "description": "Preference rules used for scheduling and ignored afterwards",
               "items": {
                  "$ref": "#/$defs/PreferredSchedulingTerm"
               },
               "title": "Scheduling terms",
               "type": "array"
            },
            "requiredDuringSchedulingIgnoredDuringExecution": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/NodeSelector"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Required node selection rules",
               "title": "Node selectors"
            }
         },
         "title": "NodeAffinity",
         "type": "object"
      },
      "NodeSelector": {
         "additionalProperties": false,
         "description": "Matching terms for nodes.",
         "properties": {
            "nodeSelectorTerms": {
               "default": [],
               "description": "Matching terms for nodes",
               "items": {
                  "$ref": "#/$defs/NodeSelectorTerm"
               },
               "title": "Terms",
               "type": "array"
            }
         },
         "title": "NodeSelector",
         "type": "object"
      },
      "NodeSelectorOperator": {
         "description": "Match operations for node selectors.",
         "enum": [
            "In",
            "NotIn",
            "Exists",
            "DoesNotExist",
            "Gt",
            "Lt"
         ],
         "title": "NodeSelectorOperator",
         "type": "string"
      },
      "NodeSelectorRequirement": {
         "additionalProperties": false,
         "description": "Individual match rule for nodes.",
         "properties": {
            "key": {
               "description": "Label key to match",
               "title": "Key",
               "type": "string"
            },
            "operator": {
               "$ref": "#/$defs/NodeSelectorOperator",
               "description": "Match operation to use",
               "title": "Operator"
            },
            "values": {
               "default": [],
               "description": "For ``In`` and ``NotIn``, matches any value in this list. For ``Gt`` or ``Lt``, must contain a single member interpreted as an integer. For ``Exists`` or ``DoesNotExist``, must be empty.",
               "items": {
                  "type": "string"
               },
               "title": "Matching values",
               "type": "array"
            }
         },
         "required": [
            "key",
            "operator"
         ],
         "title": "NodeSelectorRequirement",
         "type": "object"
      },
      "NodeSelectorTerm": {
         "additionalProperties": false,
         "description": "Term to match nodes.",
         "properties": {
            "matchExpressions": {
               "default": [],
               "description": "Matching rules applied to node labels",
               "items": {
                  "$ref": "#/$defs/NodeSelectorRequirement"
               },
               "title": "Rules for node labels",
               "type": "array"
            },
            "matchFields": {
               "default": [],
               "description": "Matching rules applied to node fields",
               "items": {
                  "$ref": "#/$defs/NodeSelectorRequirement"
               },
               "title": "Rules for node fields",
               "type": "array"
            }
         },
         "title": "NodeSelectorTerm",
         "type": "object"
      },
      "PVCVolumeResources": {
         "additionalProperties": false,
         "description": "Resources for a persistent volume claim.",
         "properties": {
            "requests": {
               "additionalProperties": {
                  "type": "string"
               },
               "title": "Resource requests",
               "type": "object"
            }
         },
         "required": [
            "requests"
         ],
         "title": "PVCVolumeResources",
         "type": "object"
      },
      "PVCVolumeSource": {
         "additionalProperties": false,
         "description": "A PVC to create to materialize the volume to mount in the container.",
         "properties": {
            "type": {
               "const": "persistentVolumeClaim",
               "enum": [
                  "persistentVolumeClaim"
               ],
               "title": "Type of volume to mount",
               "type": "string"
            },
            "accessModes": {
               "items": {
                  "$ref": "#/$defs/VolumeAccessMode"
               },
               "title": "Access mode",
               "type": "array"
            },
            "storageClassName": {
               "title": "Storage class",
               "type": "string"
            },
            "resources": {
               "$ref": "#/$defs/PVCVolumeResources",
               "title": "Resources for volume"
            },
            "readOnly": {
               "default": false,
               "description": "If set to true, forces all mounts of this volume to read-only",
               "title": "Is read-only",
               "type": "boolean"
            }
         },
         "required": [
            "type",
            "accessModes",
            "storageClassName",
            "resources"
         ],
         "title": "PVCVolumeSource",
         "type": "object"
      },
      "PodAffinity": {
         "additionalProperties": false,
         "description": "Pod affinity rules.",
         "properties": {
            "preferredDuringSchedulingIgnoredDuringExecution": {
               "default": [],
               "description": "Preference rules used for scheduling and ignored afterwards",
               "items": {
                  "$ref": "#/$defs/WeightedPodAffinityTerm"
               },
               "title": "Scheduling terms",
               "type": "array"
            },
            "requiredDuringSchedulingIgnoredDuringExecution": {
               "default": [],
               "description": "Required node selection rules",
               "items": {
                  "$ref": "#/$defs/PodAffinityTerm"
               },
               "title": "Node selectors",
               "type": "array"
            }
         },
         "title": "PodAffinity",
         "type": "object"
      },
      "PodAffinityTerm": {
         "additionalProperties": false,
         "description": "Pod matching term for pod affinity.",
         "properties": {
            "labelSelector": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/LabelSelector"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Match rules for pod labels",
               "title": "Pod label match"
            },
            "namespaceSelector": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/LabelSelector"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Match rules for namespace labels",
               "title": "Namespace label match"
            },
            "namespaces": {
               "default": [],
               "description": "List of namespaces to which this term applies. The term will apply to the union of this list of namespaces and any namespaces that match ``namespaceSelector``, if given. If both are empty, only the pod's namespace is matched.",
               "items": {
                  "type": "string"
               },
               "title": "Matching namespaces",
               "type": "array"
            },
            "topologyKey": {
               "description": "Name of the node label that should match between nodes to consider two pods to be scheduled on adjacent nodes, which in turn is the definition of an affinity (and the opposite of an anti-affinity).",
               "title": "Node topology label",
               "type": "string"
            }
         },
         "required": [
            "topologyKey"
         ],
         "title": "PodAffinityTerm",
         "type": "object"
      },
      "PodAntiAffinity": {
         "additionalProperties": false,
         "description": "Pod anti-affinity rules.\n\nNotes\n-----\nThis model is structurally identical to `PodAffinity`, but it has to\nconvert to a different Kubernetes model.",
         "properties": {
            "preferredDuringSchedulingIgnoredDuringExecution": {
               "default": [],
               "description": "Preference rules used for scheduling and ignored afterwards",
               "items": {
                  "$ref": "#/$defs/WeightedPodAffinityTerm"
               },
               "title": "Scheduling terms",
               "type": "array"
            },
            "requiredDuringSchedulingIgnoredDuringExecution": {
               "default": [],
               "description": "Required node selection rules",
               "items": {
                  "$ref": "#/$defs/PodAffinityTerm"
               },
               "title": "Node selectors",
               "type": "array"
            }
         },
         "title": "PodAntiAffinity",
         "type": "object"
      },
      "PreferredSchedulingTerm": {
         "additionalProperties": false,
         "description": "Scheduling term with a weight, used to find preferred nodes.",
         "properties": {
            "preference": {
               "$ref": "#/$defs/NodeSelectorTerm",
               "description": "Selector term for a node",
               "title": "Node selector"
            },
            "weight": {
               "description": "Weight to assign to nodes matching this term",
               "title": "Weight",
               "type": "integer"
            }
         },
         "required": [
            "preference",
            "weight"
         ],
         "title": "PreferredSchedulingTerm",
         "type": "object"
      },
      "PullPolicy": {
         "description": "Pull policy for Docker images in Kubernetes.",
         "enum": [
            "Always",
            "IfNotPresent",
            "Never"
         ],
         "title": "PullPolicy",
         "type": "string"
      },
      "TaintEffect": {
         "description": "Possible effects of a pod toleration.",
         "enum": [
            "NoSchedule",
            "PreferNoSchedule",
            "NoExecute"
         ],
         "title": "TaintEffect",
         "type": "string"
      },
      "TmpSource": {
         "description": "Whether :file:`/tmp` should come from disk (and thus ephemeralStorage)\nor memory-as-tmpfs (and thus pod memory).",
         "enum": [
            "disk",
            "memory"
         ],
         "title": "TmpSource",
         "type": "string"
      },
      "Toleration": {
         "additionalProperties": false,
         "description": "Represents a single pod toleration rule.\n\nToleration rules describe what Kubernetes node taints a pod will tolerate,\nmeaning that the pod can still be scheduled on that node even though the\nnode is marked as tained.",
         "properties": {
            "effect": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/TaintEffect"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Taint effect to match. If ``None``, match all taint effects.",
               "title": "Taint effect"
            },
            "key": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Taint key to match. If ``None``, ``operator`` must be ``Exists``, and this combination is used to match all taints.",
               "title": "Taint key"
            },
            "operator": {
               "$ref": "#/$defs/TolerationOperator",
               "default": "Equal",
               "description": "``Exists`` is equivalent to a wildcard for value and matches all possible taints of a given catgory.",
               "title": "Match operator"
            },
            "tolerationSeconds": {
               "anyOf": [
                  {
                     "type": "integer"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Defines the length of time a ``NoExecute`` taint is tolerated and is ignored for other taint effects. The pod will be evicted this number of seconds after the taint is added, rather than immediately (the default with no toleration). ``None`` says to tolerate the taint forever.",
               "title": "Duration of toleration"
            },
            "value": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Taint value to match. Must be ``None`` if the operator is ``Exists``.",
               "title": "Taint value"
            }
         },
         "title": "Toleration",
         "type": "object"
      },
      "TolerationOperator": {
         "description": "Possible operators for a toleration.",
         "enum": [
            "Equal",
            "Exists"
         ],
         "title": "TolerationOperator",
         "type": "string"
      },
      "UserHomeDirectorySchema": {
         "description": "Algorithm for building a user's home directory path.",
         "enum": [
            "username",
            "initialThenUsername"
         ],
         "title": "UserHomeDirectorySchema",
         "type": "string"
      },
      "VolumeAccessMode": {
         "description": "Access mode for a persistent volume.\n\nThe access modes ``ReadWriteOnce`` and ``ReadWriteOncePod`` are valid\naccess modes in Kubernetes but are intentionally not listed here because\nthey cannot work with user labs or file servers and therefore should be\nrejected by configuration parsing. This should change in the future if\naccess modes are used in other contexts where those access modes may make\nsense.",
         "enum": [
            "ReadOnlyMany",
            "ReadWriteMany"
         ],
         "title": "VolumeAccessMode",
         "type": "string"
      },
      "VolumeConfig": {
         "additionalProperties": false,
         "description": "A volume that may be mounted inside a container.",
         "properties": {
            "name": {
               "description": "Used as the Kubernetes volume name and therefore must be a valid Kubernetes name",
               "pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
               "title": "Name of volume",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "$ref": "#/$defs/HostPathVolumeSource"
                  },
                  {
                     "$ref": "#/$defs/NFSVolumeSource"
                  },
                  {
                     "$ref": "#/$defs/PVCVolumeSource"
                  }
               ],
               "title": "Source of volume"
            }
         },
         "required": [
            "name",
            "source"
         ],
         "title": "VolumeConfig",
         "type": "object"
      },
      "VolumeMountConfig": {
         "additionalProperties": false,
         "description": "The mount of a volume inside a container.",
         "properties": {
            "containerPath": {
               "description": "Absolute path at which to mount the volume in the lab container",
               "examples": [
                  "/home"
               ],
               "pattern": "^/.*",
               "title": "Path inside container",
               "type": "string"
            },
            "subPath": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "description": "Mount only this sub-path of the volume source",
               "examples": [
                  "groups"
               ],
               "title": "Sub-path of source to mount"
            },
            "readOnly": {
               "default": false,
               "description": "Whether the volume should be mounted read-only in the container",
               "examples": [
                  true
               ],
               "title": "Is read-only",
               "type": "boolean"
            },
            "volumeName": {
               "description": "Name of the volume to mount",
               "title": "Volume name",
               "type": "string"
            }
         },
         "required": [
            "containerPath",
            "volumeName"
         ],
         "title": "VolumeMountConfig",
         "type": "object"
      },
      "WeightedPodAffinityTerm": {
         "additionalProperties": false,
         "description": "Pod matching term for pod affinity with an associated weight.",
         "properties": {
            "podAffinityTerm": {
               "$ref": "#/$defs/PodAffinityTerm",
               "description": "Pod affinity matching term",
               "title": "Matching term"
            },
            "weight": {
               "description": "Weight to associate with pods matching this term",
               "maximum": 100,
               "minimum": 1,
               "title": "Associated weight",
               "type": "integer"
            }
         },
         "required": [
            "podAffinityTerm",
            "weight"
         ],
         "title": "WeightedPodAffinityTerm",
         "type": "object"
      }
   },
   "additionalProperties": false,
   "required": [
      "namespacePrefix"
   ]
}

Fields:
Validators:
field affinity: Affinity | None = None

Node and pod affinity rules for lab pods

Validated by:
  • _validate_volumes

field application: str | None = None

An Argo CD application under which lab objects should be shown

Validated by:
  • _validate_volumes

field deleteTimeout: HumanTimedelta = datetime.timedelta(seconds=60) (name 'delete_timeout')

How long to wait in total for deletion of Kubernetes resources for a user lab

Constraints:
  • func = <function _validate_human_timedelta at 0x7f6023c9d120>

  • json_schema_input_type = PydanticUndefined

Validated by:
  • _validate_volumes

field env: dict[str, str] = {}

Additional environment variables to set in all spawned user labs

Validated by:
  • _validate_env

  • _validate_volumes

field extraAnnotations: dict[str, str] = {} (name 'extra_annotations')

These annotations will be added to the Kubernetes Pod resource in addition to annotations used by Nublado itself to track metadata about the pod

Validated by:
  • _validate_volumes

field files: dict[str, str] = {}

The key is the path inside the lab at which to mount the file, and the value describes the contents of the file.

Validated by:
  • _validate_files

  • _validate_volumes

field homedirPrefix: str = '/home' (name 'homedir_prefix')

Portion of home directory path added before the username. This is the path inside the container, not the path of the volume mounted in the container, so it need not reflect the structure of the home directory volume source. The primary reason to set this is to make paths inside the container match a pattern that users are familiar with outside of Nublado.

Validated by:
  • _validate_homedir_prefix

  • _validate_volumes

field homedirSchema: UserHomeDirectorySchema = UserHomeDirectorySchema.USERNAME (name 'homedir_schema')

Determines how the username portion of the home directory path is constructed.

Validated by:
  • _validate_volumes

field homedirSuffix: str = '' (name 'homedir_suffix')

Portion of home directory path added after the username. This is primarily used for environments that want the user’s Nublado home directory to be a subdirectory of their regular home directory outside of Nublado. This configuration is strongly recommended in environments that change home directories, since Nublado often has different needs for dot files and other configuration.

Validated by:
  • _validate_homedir_suffix

  • _validate_volumes

field initContainers: list[LabInitContainer] = [] (name 'init_containers')

Kubernetes init containers to run before user’s lab starts. Use these containers to do any required setup, particularly any actions that require privileges, since init containers can be run as privileged and the lab container is always run as the user.

Validated by:
  • _validate_volumes

field jupyterlabConfigDir: str = '/opt/lsst/software/jupyterlab' (name 'jupyterlab_config_dir')

Path inside the lab container where custom configuration is stored. Things like kernel definitions, custom logger definitions, service tokens, and Lab-instance-specific secrets are stored under this path.

Validated by:
  • _validate_volumes

field labStartCommand: list[str] = ['/opt/lsst/software/jupyterlab/runlab.sh'] (name 'lab_start_command')

This is the executable in the container that will be run to start the lab, and its arguments, supplied as a list of strings.

Validated by:
  • _validate_volumes

field namespacePrefix: str [Required] (name 'namespace_prefix')

The namespace for the user’s lab will start with this string, a hyphen (-), and the user’s username

Validated by:
  • _validate_volumes

field nodeSelector: dict[str, str] = {} (name 'node_selector')

Labels that must be present on Kubernetes nodes for any lab pod to be scheduled there

Validated by:
  • _validate_volumes

field nss: LabNSSFiles [Optional]

Configuration for the /etc/passwd and /etc/group files inside the lab

Validated by:
  • _validate_volumes

field pullSecret: str | None = None (name 'pull_secret')

If set, must be the name of a secret in the same namespace as the lab controller. This secret is copied to the user’s lab namespace and referenced as a pull secret in the pod object.

Validated by:
  • _validate_volumes

field runtimeMountsDir: str = '/opt/lsst/software/jupyterlab' (name 'runtime_mounts_dir')

Directory under which runtime information (e.g. tokens, environment variables, and container resource information will be mounted.

Validated by:
  • _validate_volumes

field secrets: list[LabSecret] = []

Secrets to make available inside lab

Validated by:
  • _validate_secrets

  • _validate_volumes

field sizes: list[LabSizeDefinition] = []

Only these sizes will be present in the menu, in the order in which they’re defined in the configuration file. The first size defined will be the default.

Validated by:
  • _validate_sizes

  • _validate_volumes

field spawnTimeout: HumanTimedelta = datetime.timedelta(seconds=600) (name 'spawn_timeout')

Creation of the lab will fail if it takes longer than this for the lab pod to be created and start running. This does not include the time spent by JupyterHub waiting for the lab to start listening to the network. It should generally be shorter than the spawn timeout set in JupyterHub.

Constraints:
  • func = <function _validate_human_timedelta at 0x7f6023c9d120>

  • json_schema_input_type = PydanticUndefined

Validated by:
  • _validate_volumes

field tmpSource: TmpSource = TmpSource.MEMORY (name 'tmp_source')

Use this to select whether the pod’s /tmp will come from memory or node-local disk. Both are scarce resources, and the appropriate choice is environment-dependent.

Validated by:
  • _validate_volumes

field tolerations: list[Toleration] = []

Kubernetes tolerations for file server pods

Validated by:
  • _validate_volumes

field volumeMounts: list[VolumeMountConfig] = [] (name 'volume_mounts')

Volumes to mount inside the lab container

Validated by:
  • _validate_volumes

field volumes: list[VolumeConfig] = []

Volumes available to mount inside either the lab container or an init container. Inclusion in this list does not mean that they will be mounted. They must separately be listed under volumeMounts for either an init container or the main lab configuration.

Validated by:
  • _validate_volumes

get_size_definition(size)

Return the definition for a given lab size.

Parameters:

size (LabSize) – Size of lab.

Returns:

Corresponding definition.

Return type:

LabSizeDefinition

Raises:

KeyError – Raised if that lab size is not defined.