diff --git a/jupyter/base/charts/jupyterhub/Chart.yaml b/jupyter/base/charts/jupyterhub/Chart.yaml index 8cee39a..eaa3033 100644 --- a/jupyter/base/charts/jupyterhub/Chart.yaml +++ b/jupyter/base/charts/jupyterhub/Chart.yaml @@ -1,27 +1,27 @@ annotations: artifacthub.io/images: | - - image: quay.io/jupyterhub/configurable-http-proxy:4.6.2 + - image: quay.io/jupyterhub/configurable-http-proxy:4.6.1 name: configurable-http-proxy - - image: quay.io/jupyterhub/k8s-hub:4.0.0 + - image: quay.io/jupyterhub/k8s-hub:3.2.1 name: k8s-hub - - image: quay.io/jupyterhub/k8s-image-awaiter:4.0.0 + - image: quay.io/jupyterhub/k8s-image-awaiter:3.2.1 name: k8s-image-awaiter - - image: quay.io/jupyterhub/k8s-network-tools:4.0.0 + - image: quay.io/jupyterhub/k8s-network-tools:3.2.1 name: k8s-network-tools - - image: quay.io/jupyterhub/k8s-secret-sync:4.0.0 + - image: quay.io/jupyterhub/k8s-secret-sync:3.2.1 name: k8s-secret-sync - - image: quay.io/jupyterhub/k8s-singleuser-sample:4.0.0 + - image: quay.io/jupyterhub/k8s-singleuser-sample:3.2.1 name: k8s-singleuser-sample - - image: registry.k8s.io/kube-scheduler:v1.30.6 + - image: registry.k8s.io/kube-scheduler:v1.26.11 name: kube-scheduler - - image: registry.k8s.io/pause:3.10 + - image: registry.k8s.io/pause:3.9 name: pause - - image: registry.k8s.io/pause:3.10 + - image: registry.k8s.io/pause:3.9 name: pause - - image: traefik:v3.2.0 + - image: traefik:v2.10.5 name: traefik apiVersion: v2 -appVersion: 5.2.1 +appVersion: 4.0.2 description: Multi-user Jupyter installation home: https://z2jh.jupyter.org icon: https://hub.jupyter.org/helm-chart/images/hublogo.svg @@ -29,7 +29,7 @@ keywords: - jupyter - jupyterhub - z2jh -kubeVersion: '>=1.28.0-0' +kubeVersion: '>=1.23.0-0' maintainers: - email: erik@sundellopensource.se name: Erik Sundell @@ -38,4 +38,4 @@ maintainers: name: jupyterhub sources: - https://github.com/jupyterhub/zero-to-jupyterhub-k8s -version: 4.0.0 +version: 3.2.1 diff --git a/jupyter/base/charts/jupyterhub/files/hub/jupyterhub_config.py b/jupyter/base/charts/jupyterhub/files/hub/jupyterhub_config.py index ad742ed..7047173 100644 --- a/jupyter/base/charts/jupyterhub/files/hub/jupyterhub_config.py +++ b/jupyter/base/charts/jupyterhub/files/hub/jupyterhub_config.py @@ -107,35 +107,28 @@ c.JupyterHub.hub_connect_url = ( ) # implement common labels -# This mimics the jupyterhub.commonLabels helper, but declares managed-by to -# kubespawner instead of helm. -# -# The labels app and release are old labels enabled to be deleted in z2jh 5, but -# for now retained to avoid a breaking change in z2jh 4 that would force user -# server restarts. Restarts would be required because NetworkPolicy resources -# must select old/new pods with labels that then needs to be seen on both -# old/new pods, and we want these resources to keep functioning for old/new user -# server pods during an upgrade. -# +# this duplicates the jupyterhub.commonLabels helper common_labels = c.KubeSpawner.common_labels = {} -common_labels["app.kubernetes.io/name"] = common_labels["app"] = get_config( +common_labels["app"] = get_config( "nameOverride", default=get_config("Chart.Name", "jupyterhub"), ) -release = get_config("Release.Name") -if release: - common_labels["app.kubernetes.io/instance"] = common_labels["release"] = release +common_labels["heritage"] = "jupyterhub" chart_name = get_config("Chart.Name") chart_version = get_config("Chart.Version") if chart_name and chart_version: - common_labels["helm.sh/chart"] = common_labels["chart"] = ( - f"{chart_name}-{chart_version.replace('+', '_')}" + common_labels["chart"] = "{}-{}".format( + chart_name, + chart_version.replace("+", "_"), ) -common_labels["app.kubernetes.io/managed-by"] = "kubespawner" +release = get_config("Release.Name") +if release: + common_labels["release"] = release c.KubeSpawner.namespace = os.environ.get("POD_NAMESPACE", "default") # Max number of consecutive failures before the Hub restarts itself +# requires jupyterhub 0.9.2 set_config_if_not_none( c.Spawner, "consecutive_failure_limit", @@ -256,8 +249,7 @@ if tolerations: storage_type = get_config("singleuser.storage.type") if storage_type == "dynamic": pvc_name_template = get_config("singleuser.storage.dynamic.pvcNameTemplate") - if pvc_name_template: - c.KubeSpawner.pvc_name_template = pvc_name_template + c.KubeSpawner.pvc_name_template = pvc_name_template volume_name_template = get_config("singleuser.storage.dynamic.volumeNameTemplate") c.KubeSpawner.storage_pvc_ensure = True set_config_if_not_none( @@ -276,14 +268,13 @@ if storage_type == "dynamic": c.KubeSpawner.volumes = [ { "name": volume_name_template, - "persistentVolumeClaim": {"claimName": "{pvc_name}"}, + "persistentVolumeClaim": {"claimName": pvc_name_template}, } ] c.KubeSpawner.volume_mounts = [ { "mountPath": get_config("singleuser.storage.homeMountPath"), "name": volume_name_template, - "subPath": get_config("singleuser.storage.dynamic.subPath"), } ] elif storage_type == "static": diff --git a/jupyter/base/charts/jupyterhub/files/hub/z2jh.py b/jupyter/base/charts/jupyterhub/files/hub/z2jh.py index f4d7be6..3735169 100644 --- a/jupyter/base/charts/jupyterhub/files/hub/z2jh.py +++ b/jupyter/base/charts/jupyterhub/files/hub/z2jh.py @@ -3,7 +3,6 @@ Utility methods for use in jupyterhub_config.py and dynamic subconfigs. Methods here can be imported by extraConfig in values.yaml """ - import os from collections.abc import Mapping from functools import lru_cache diff --git a/jupyter/base/charts/jupyterhub/templates/_helpers.tpl b/jupyter/base/charts/jupyterhub/templates/_helpers.tpl index 693bd65..5cc5e6d 100644 --- a/jupyter/base/charts/jupyterhub/templates/_helpers.tpl +++ b/jupyter/base/charts/jupyterhub/templates/_helpers.tpl @@ -48,6 +48,7 @@ - commonLabels | uses appLabel - labels | uses commonLabels - matchLabels | uses labels + - podCullerSelector | uses matchLabels ## Example usage @@ -111,62 +112,31 @@ {{- /* jupyterhub.commonLabels: Foundation for "jupyterhub.labels". - - Provides old labels: - app - release - chart (omitted for matchLabels) - heritage (omitted for matchLabels) - Provides modern labels (omitted for matchLabels): - app.kubernetes.io/name ("app") - app.kubernetes.io/instance ("release") - helm.sh/chart ("chart") - app.kubernetes.io/managed-by ("heritage") + Provides labels: app, release, (chart and heritage). */}} {{- define "jupyterhub.commonLabels" -}} -app: {{ .appLabel | default (include "jupyterhub.appLabel" .) | quote }} -release: {{ .Release.Name | quote }} +app: {{ .appLabel | default (include "jupyterhub.appLabel" .) }} +release: {{ .Release.Name }} {{- if not .matchLabels }} chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} -heritage: {{ .Release.Service }} -app.kubernetes.io/name: {{ .appLabel | default (include "jupyterhub.appLabel" .) | quote }} -app.kubernetes.io/instance: {{ .Release.Name | quote }} -helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} -app.kubernetes.io/managed-by: {{ .Release.Service }} +heritage: {{ .heritageLabel | default .Release.Service }} {{- end }} {{- end }} {{- /* jupyterhub.labels: - Provides old labels: - component - app - release - chart (omitted for matchLabels) - heritage (omitted for matchLabels) - Provides modern labels (omitted for matchLabels): - app.kubernetes.io/component ("component") - app.kubernetes.io/name ("app") - app.kubernetes.io/instance release ("release") - helm.sh/chart ("chart") - app.kubernetes.io/managed-by ("heritage") + Provides labels: component, app, release, (chart and heritage). */}} {{- define "jupyterhub.labels" -}} component: {{ include "jupyterhub.componentLabel" . }} -{{- if not .matchLabels }} -app.kubernetes.io/component: {{ include "jupyterhub.componentLabel" . }} -{{- end }} {{ include "jupyterhub.commonLabels" . }} {{- end }} {{- /* jupyterhub.matchLabels: - Provides old labels: - component - app - release + Used to provide pod selection labels: component, app, release. */}} {{- define "jupyterhub.matchLabels" -}} {{- $_ := merge (dict "matchLabels" true) . -}} diff --git a/jupyter/base/charts/jupyterhub/templates/hub/deployment.yaml b/jupyter/base/charts/jupyterhub/templates/hub/deployment.yaml index 53eb355..359e981 100644 --- a/jupyter/base/charts/jupyterhub/templates/hub/deployment.yaml +++ b/jupyter/base/charts/jupyterhub/templates/hub/deployment.yaml @@ -5,7 +5,7 @@ metadata: labels: {{- include "jupyterhub.labels" . | nindent 4 }} spec: - {{- if not (typeIs "" .Values.hub.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.hub.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.hub.revisionHistoryLimit }} {{- end }} replicas: 1 @@ -97,6 +97,9 @@ spec: {{- . | toYaml | nindent 8 }} {{- end }} containers: + {{- with .Values.hub.extraContainers }} + {{- . | toYaml | nindent 8 }} + {{- end }} - name: hub image: {{ .Values.hub.image.name }}:{{ .Values.hub.image.tag }} {{- with .Values.hub.command }} @@ -241,9 +244,6 @@ spec: path: {{ .Values.hub.baseUrl | trimSuffix "/" }}/hub/health port: http {{- end }} - {{- with .Values.hub.extraContainers }} - {{- . | toYaml | nindent 8 }} - {{- end }} {{- with .Values.hub.extraPodSpec }} {{- . | toYaml | nindent 6 }} {{- end }} diff --git a/jupyter/base/charts/jupyterhub/templates/hub/secret.yaml b/jupyter/base/charts/jupyterhub/templates/hub/secret.yaml index d1d0c80..851bda0 100644 --- a/jupyter/base/charts/jupyterhub/templates/hub/secret.yaml +++ b/jupyter/base/charts/jupyterhub/templates/hub/secret.yaml @@ -8,7 +8,7 @@ type: Opaque data: {{- $values := merge dict .Values }} {{- /* also passthrough subset of Chart / Release */}} - {{- $_ := set $values "Chart" (dict "Name" .Chart.Name "Version" .Chart.Version "AppVersion" .Chart.AppVersion) }} + {{- $_ := set $values "Chart" (dict "Name" .Chart.Name "Version" .Chart.Version) }} {{- $_ := set $values "Release" (pick .Release "Name" "Namespace" "Service") }} values.yaml: {{ $values | toYaml | b64enc | quote }} diff --git a/jupyter/base/charts/jupyterhub/templates/hub/service.yaml b/jupyter/base/charts/jupyterhub/templates/hub/service.yaml index 5dcc0af..13f80b5 100644 --- a/jupyter/base/charts/jupyterhub/templates/hub/service.yaml +++ b/jupyter/base/charts/jupyterhub/templates/hub/service.yaml @@ -31,9 +31,6 @@ spec: {{- with .Values.hub.service.ports.nodePort }} nodePort: {{ . }} {{- end }} - {{- with .Values.hub.service.ports.appProtocol }} - appProtocol: {{ . }} - {{- end }} {{- with .Values.hub.service.extraPorts }} {{- . | toYaml | nindent 4 }} diff --git a/jupyter/base/charts/jupyterhub/templates/image-puller/_helpers-daemonset.tpl b/jupyter/base/charts/jupyterhub/templates/image-puller/_helpers-daemonset.tpl index 16213b0..610f8bd 100644 --- a/jupyter/base/charts/jupyterhub/templates/image-puller/_helpers-daemonset.tpl +++ b/jupyter/base/charts/jupyterhub/templates/image-puller/_helpers-daemonset.tpl @@ -34,7 +34,7 @@ spec: type: RollingUpdate rollingUpdate: maxUnavailable: 100% - {{- if not (typeIs "" .Values.prePuller.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.prePuller.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.prePuller.revisionHistoryLimit }} {{- end }} template: diff --git a/jupyter/base/charts/jupyterhub/templates/ingress.yaml b/jupyter/base/charts/jupyterhub/templates/ingress.yaml index 090b2ed..91f96f4 100644 --- a/jupyter/base/charts/jupyterhub/templates/ingress.yaml +++ b/jupyter/base/charts/jupyterhub/templates/ingress.yaml @@ -24,9 +24,6 @@ spec: name: {{ include "jupyterhub.proxy-public.fullname" $ }} port: name: http - {{- with $.Values.ingress.extraPaths }} - {{- . | toYaml | nindent 10 }} - {{- end }} {{- if $host }} host: {{ $host | quote }} {{- end }} diff --git a/jupyter/base/charts/jupyterhub/templates/proxy/autohttps/deployment.yaml b/jupyter/base/charts/jupyterhub/templates/proxy/autohttps/deployment.yaml index 53e0736..f76f3ef 100644 --- a/jupyter/base/charts/jupyterhub/templates/proxy/autohttps/deployment.yaml +++ b/jupyter/base/charts/jupyterhub/templates/proxy/autohttps/deployment.yaml @@ -8,7 +8,7 @@ metadata: labels: {{- include "jupyterhub.labels" . | nindent 4 }} spec: - {{- if not (typeIs "" .Values.proxy.traefik.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.proxy.traefik.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.proxy.traefik.revisionHistoryLimit }} {{- end }} replicas: 1 @@ -130,10 +130,10 @@ spec: {{- end }} args: - watch-save - - --label=app.kubernetes.io/name={{ include "jupyterhub.appLabel" . }} - - --label=app.kubernetes.io/instance={{ .Release.Name }} - - --label=helm.sh/chart={{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - - --label=app.kubernetes.io/managed-by=secret-sync + - --label=app={{ include "jupyterhub.appLabel" . }} + - --label=release={{ .Release.Name }} + - --label=chart={{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + - --label=heritage=secret-sync - {{ include "jupyterhub.proxy-public-tls.fullname" . }} - acme.json - /etc/acme/acme.json diff --git a/jupyter/base/charts/jupyterhub/templates/proxy/deployment.yaml b/jupyter/base/charts/jupyterhub/templates/proxy/deployment.yaml index d5a9878..2b35382 100644 --- a/jupyter/base/charts/jupyterhub/templates/proxy/deployment.yaml +++ b/jupyter/base/charts/jupyterhub/templates/proxy/deployment.yaml @@ -7,7 +7,7 @@ metadata: labels: {{- include "jupyterhub.labels" . | nindent 4 }} spec: - {{- if not (typeIs "" .Values.proxy.chp.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.proxy.chp.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.proxy.chp.revisionHistoryLimit }} {{- end }} replicas: 1 @@ -100,9 +100,6 @@ spec: {{- if .Values.debug.enabled }} - --log-level=debug {{- end }} - {{- if .Values.hub.config.JupyterHub.subdomain_host }} - - --host-routing - {{- end }} {{- range .Values.proxy.chp.extraCommandLineFlags }} - {{ tpl . $ }} {{- end }} diff --git a/jupyter/base/charts/jupyterhub/templates/scheduling/user-placeholder/statefulset.yaml b/jupyter/base/charts/jupyterhub/templates/scheduling/user-placeholder/statefulset.yaml index 7f2c785..e0f6f59 100644 --- a/jupyter/base/charts/jupyterhub/templates/scheduling/user-placeholder/statefulset.yaml +++ b/jupyter/base/charts/jupyterhub/templates/scheduling/user-placeholder/statefulset.yaml @@ -16,7 +16,7 @@ metadata: {{- include "jupyterhub.labels" . | nindent 4 }} spec: podManagementPolicy: Parallel - {{- if not (typeIs "" .Values.scheduling.userPlaceholder.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.scheduling.userPlaceholder.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.scheduling.userPlaceholder.revisionHistoryLimit }} {{- end }} replicas: {{ .Values.scheduling.userPlaceholder.replicas }} diff --git a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/configmap.yaml b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/configmap.yaml index a96acb8..0f142b0 100644 --- a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/configmap.yaml +++ b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/configmap.yaml @@ -10,14 +10,26 @@ data: This is configuration of a k8s official kube-scheduler binary running in the user-scheduler. + The config version and kube-scheduler binary version has a fallback for k8s + clusters versioned v1.23 or lower because: + + - v1 / v1beta3 config requires kube-scheduler binary >=1.25 / >=1.23 + - kube-scheduler binary >=1.25 requires storage.k8s.io/v1/CSIStorageCapacity + available first in k8s >=1.24 + ref: https://kubernetes.io/docs/reference/scheduling/config/ ref: https://kubernetes.io/docs/reference/config-api/kube-scheduler-config.v1/ + ref: https://kubernetes.io/docs/reference/config-api/kube-scheduler-config.v1beta3/ */}} config.yaml: | + {{- if semverCompare ">=1.24.0-0" .Capabilities.KubeVersion.Version }} apiVersion: kubescheduler.config.k8s.io/v1 + {{- else }} + apiVersion: kubescheduler.config.k8s.io/v1beta3 + {{- end }} kind: KubeSchedulerConfiguration leaderElection: - resourceLock: leases + resourceLock: endpointsleases resourceName: {{ include "jupyterhub.user-scheduler-lock.fullname" . }} resourceNamespace: "{{ .Release.Namespace }}" profiles: diff --git a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/deployment.yaml b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/deployment.yaml index e73c8ac..5baf4f4 100644 --- a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/deployment.yaml +++ b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/deployment.yaml @@ -6,7 +6,7 @@ metadata: labels: {{- include "jupyterhub.labels" . | nindent 4 }} spec: - {{- if not (typeIs "" .Values.scheduling.userScheduler.revisionHistoryLimit) }} + {{- if typeIs "int" .Values.scheduling.userScheduler.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.scheduling.userScheduler.revisionHistoryLimit }} {{- end }} replicas: {{ .Values.scheduling.userScheduler.replicas }} @@ -50,7 +50,17 @@ spec: {{- end }} containers: - name: kube-scheduler + {{- if semverCompare ">=1.24.0-0" .Capabilities.KubeVersion.Version }} image: {{ .Values.scheduling.userScheduler.image.name }}:{{ .Values.scheduling.userScheduler.image.tag }} + {{- else }} + # WARNING: The tag of this image is hardcoded, and the + # "scheduling.userScheduler.image.tag" configuration of the + # Helm chart that generated this resource manifest isn't + # respected. If you install the Helm chart in a k8s cluster + # versioned 1.24 or higher, your configuration will be + # respected. + image: {{ .Values.scheduling.userScheduler.image.name }}:v1.23.14 + {{- end }} {{- with .Values.scheduling.userScheduler.image.pullPolicy }} imagePullPolicy: {{ . }} {{- end }} diff --git a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/rbac.yaml b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/rbac.yaml index 22a65eb..7e188c7 100644 --- a/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/rbac.yaml +++ b/jupyter/base/charts/jupyterhub/templates/scheduling/user-scheduler/rbac.yaml @@ -20,12 +20,8 @@ rules: # - changed in 1.21: get/list/watch permission for namespace, # csidrivers, csistoragecapacities was added. # - unchanged between 1.22 and 1.27 - # - changed in 1.28: permissions to get/update lock endpoint resource - # removed - # - unchanged between 1.28 and 1.30 - # - (1.31 is known to bring some changes below) # - # ref: https://github.com/kubernetes/kubernetes/blob/v1.30.0/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml#L721-L862 + # ref: https://github.com/kubernetes/kubernetes/blob/v1.27.0/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml#L736-L892 - apiGroups: - "" - events.k8s.io @@ -50,6 +46,21 @@ rules: verbs: - get - update + - apiGroups: + - "" + resources: + - endpoints + verbs: + - create + - apiGroups: + - "" + resourceNames: + - {{ include "jupyterhub.user-scheduler-lock.fullname" . }} + resources: + - endpoints + verbs: + - get + - update - apiGroups: - "" resources: @@ -172,9 +183,9 @@ rules: # Copied from the system:volume-scheduler ClusterRole of the k8s version # matching the kube-scheduler binary we use. # - # NOTE: These rules have not changed between 1.12 and 1.29. + # NOTE: These rules have not changed between 1.12 and 1.27. # - # ref: https://github.com/kubernetes/kubernetes/blob/v1.29.0/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml#L1283-L1310 + # ref: https://github.com/kubernetes/kubernetes/blob/v1.27.0/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml#L1311-L1338 - apiGroups: - "" resources: diff --git a/jupyter/base/charts/jupyterhub/values.schema.json b/jupyter/base/charts/jupyterhub/values.schema.json index b44b2be..044819b 100644 --- a/jupyter/base/charts/jupyterhub/values.schema.json +++ b/jupyter/base/charts/jupyterhub/values.schema.json @@ -1 +1 @@ -{"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "required": ["imagePullSecrets", "hub", "proxy", "singleuser", "ingress", "prePuller", "custom", "cull", "debug", "rbac", "global"], "properties": {"enabled": {"type": ["boolean", "null"]}, "fullnameOverride": {"type": ["string", "null"]}, "nameOverride": {"type": ["string", "null"]}, "imagePullSecret": {"type": "object", "required": ["create"], "if": {"properties": {"create": {"const": true}}}, "then": {"additionalProperties": false, "required": ["registry", "username", "password"], "description": "This is configuration to create a k8s Secret resource of `type:\nkubernetes.io/dockerconfigjson`, with credentials to pull images from a\nprivate image registry. If you opt to do so, it will be available for use\nby all pods in their respective `spec.imagePullSecrets` alongside other\nk8s Secrets defined in `imagePullSecrets` or the pod respective\n`...image.pullSecrets` configuration.\n\nIn other words, using this configuration option can automate both the\notherwise manual creation of a k8s Secret and the otherwise manual\nconfiguration to reference this k8s Secret in all the pods of the Helm\nchart.\n\n```sh\n# you won't need to create a k8s Secret manually...\nkubectl create secret docker-registry image-pull-secret \\\n --docker-server= \\\n --docker-username= \\\n --docker-email= \\\n --docker-password=\n```\n\nIf you just want to let all Pods reference an existing secret, use the\n[`imagePullSecrets`](schema_imagePullSecrets) configuration instead.\n", "properties": {"create": {"type": "boolean", "description": "Toggle the creation of the k8s Secret with provided credentials to\naccess a private image registry.\n"}, "automaticReferenceInjection": {"type": "boolean", "description": "Toggle the automatic reference injection of the created Secret to all\npods' `spec.imagePullSecrets` configuration.\n"}, "registry": {"type": "string", "description": "Name of the private registry you want to create a credential set for.\nIt will default to Docker Hub's image registry.\n\nExamples:\n - https://index.docker.io/v1/\n - quay.io\n - eu.gcr.io\n - alexmorreale.privatereg.net\n"}, "username": {"type": "string", "description": "Name of the user you want to use to connect to your private registry.\n\nFor external gcr.io, you will use the `_json_key`.\n\nExamples:\n - alexmorreale\n - alex@pfc.com\n - _json_key\n"}, "password": {"type": "string", "description": "Password for the private image registry's user.\n\nExamples:\n - plaintextpassword\n - abc123SECRETzyx098\n\nFor gcr.io registries the password will be a big JSON blob for a\nGoogle cloud service account, it should look something like below.\n\n```yaml\npassword: |-\n {\n \"type\": \"service_account\",\n \"project_id\": \"jupyter-se\",\n \"private_key_id\": \"f2ba09118a8d3123b3321bd9a7d6d0d9dc6fdb85\",\n ...\n }\n```\n"}, "email": {"type": ["string", "null"], "description": "Specification of an email is most often not required, but it is\nsupported.\n"}}}}, "imagePullSecrets": {"type": "array"}, "hub": {"type": "object", "additionalProperties": false, "required": ["baseUrl"], "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "config": {"type": "object", "additionalProperties": true, "properties": {"JupyterHub": {"type": "object", "additionalProperties": true, "properties": {"subdomain_host": {"type": "string"}}}}}, "extraFiles": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["mountPath"], "oneOf": [{"required": ["data"]}, {"required": ["stringData"]}, {"required": ["binaryData"]}], "properties": {"mountPath": {"type": "string"}, "data": {"type": "object", "additionalProperties": true}, "stringData": {"type": "string"}, "binaryData": {"type": "string"}, "mode": {"type": "number"}}}}}, "baseUrl": {"type": "string"}, "command": {"type": "array"}, "args": {"type": "array"}, "cookieSecret": {"type": ["string", "null"]}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "db": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["sqlite-pvc", "sqlite-memory", "mysql", "postgres", "other"]}, "pvc": {"type": "object", "additionalProperties": false, "required": ["storage"], "properties": {"annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "selector": {"type": "object", "additionalProperties": true}, "storage": {"type": "string"}, "accessModes": {"type": "array", "items": {"type": ["string", "null"]}}, "storageClassName": {"type": ["string", "null"]}, "subPath": {"type": ["string", "null"]}}}, "upgrade": {"type": ["boolean", "null"]}, "url": {"type": ["string", "null"]}, "password": {"type": ["string", "null"]}}}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "initContainers": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "extraConfig": {"type": "object", "additionalProperties": true}, "fsGid": {"type": ["integer", "null"], "minimum": 0}, "service": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"]}, "ports": {"type": "object", "additionalProperties": false, "properties": {"appProtocol": {"type": ["string", "null"]}, "nodePort": {"type": ["integer", "null"], "minimum": 0}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraPorts": {"type": "array"}, "loadBalancerIP": {"type": ["string", "null"]}}}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "existingSecret": {"type": ["string", "null"]}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "activeServerLimit": {"type": ["integer", "null"]}, "allowNamedServers": {"type": ["boolean", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "authenticatePrometheus": {"type": ["boolean", "null"]}, "concurrentSpawnLimit": {"type": ["integer", "null"]}, "consecutiveFailureLimit": {"type": ["integer", "null"]}, "podSecurityContext": {"additionalProperties": true}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "deploymentStrategy": {"type": "object", "additionalProperties": false, "properties": {"rollingUpdate": {"type": ["string", "null"]}, "type": {"type": ["string", "null"]}}}, "extraContainers": {"type": "array"}, "extraVolumeMounts": {"type": "array"}, "extraVolumes": {"type": "array"}, "livenessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "readinessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "namedServerLimitPerUser": {"type": ["integer", "null"]}, "redirectToServer": {"type": ["boolean", "null"]}, "resources": {"type": "object", "additionalProperties": true}, "lifecycle": {"type": "object", "additionalProperties": false, "properties": {"postStart": {"type": "object", "additionalProperties": true}, "preStop": {"type": "object", "additionalProperties": true}}}, "services": {"type": "object", "additionalProperties": true, "properties": {"name": {"type": "string"}, "admin": {"type": "boolean"}, "command": {"type": ["string", "array"]}, "url": {"type": "string"}, "api_token": {"type": ["string", "null"]}, "apiToken": {"type": ["string", "null"]}}}, "loadRoles": {"type": "object", "additionalProperties": true}, "shutdownOnLogout": {"type": ["boolean", "null"]}, "templatePaths": {"type": "array"}, "templateVars": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "proxy": {"type": "object", "additionalProperties": false, "properties": {"chp": {"type": "object", "additionalProperties": false, "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "extraCommandLineFlags": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "livenessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "readinessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "resources": {"type": "object", "additionalProperties": true}, "defaultTarget": {"type": ["string", "null"]}, "errorTarget": {"type": ["string", "null"]}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "secretToken": {"type": ["string", "null"]}, "service": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"]}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "nodePorts": {"type": "object", "additionalProperties": false, "properties": {"http": {"type": ["integer", "null"]}, "https": {"type": ["integer", "null"]}}}, "disableHttpPort": {"type": "boolean"}, "extraPorts": {"type": "array"}, "loadBalancerIP": {"type": ["string", "null"]}, "loadBalancerSourceRanges": {"type": "array"}}}, "https": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": ["boolean", "null"]}, "type": {"enum": [null, "", "letsencrypt", "manual", "offload", "secret"]}, "letsencrypt": {"type": "object", "additionalProperties": false, "properties": {"contactEmail": {"type": ["string", "null"]}, "acmeServer": {"type": ["string", "null"]}}}, "manual": {"type": "object", "additionalProperties": false, "properties": {"key": {"type": ["string", "null"]}, "cert": {"type": ["string", "null"]}}}, "secret": {"type": "object", "additionalProperties": false, "properties": {"name": {"type": ["string", "null"]}, "key": {"type": ["string", "null"]}, "crt": {"type": ["string", "null"]}}}, "hosts": {"type": "array"}}}, "traefik": {"type": "object", "additionalProperties": false, "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "extraInitContainers": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "extraDynamicConfig": {"type": "object", "additionalProperties": true}, "extraPorts": {"type": "array"}, "extraStaticConfig": {"type": "object", "additionalProperties": true}, "extraVolumes": {"type": "array"}, "extraVolumeMounts": {"type": "array"}, "hsts": {"type": "object", "additionalProperties": false, "required": ["includeSubdomains", "maxAge", "preload"], "properties": {"includeSubdomains": {"type": "boolean"}, "maxAge": {"type": "integer"}, "preload": {"type": "boolean"}}}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "deploymentStrategy": {"type": "object", "additionalProperties": false, "properties": {"rollingUpdate": {"type": ["string", "null"]}, "type": {"type": ["string", "null"]}}}, "secretSync": {"type": "object", "additionalProperties": false, "properties": {"containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}}}}}, "singleuser": {"type": "object", "additionalProperties": false, "properties": {"networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "podNameTemplate": {"type": ["string", "null"]}, "cpu": {"type": "object", "additionalProperties": false, "properties": {"limit": {"type": ["number", "null"]}, "guarantee": {"type": ["number", "null"]}}}, "memory": {"type": "object", "additionalProperties": false, "properties": {"limit": {"type": ["number", "string", "null"]}, "guarantee": {"type": ["number", "string", "null"]}}}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "initContainers": {"type": "array"}, "profileList": {"type": "array"}, "extraFiles": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["mountPath"], "oneOf": [{"required": ["data"]}, {"required": ["stringData"]}, {"required": ["binaryData"]}], "properties": {"mountPath": {"type": "string"}, "data": {"type": "object", "additionalProperties": true}, "stringData": {"type": "string"}, "binaryData": {"type": "string"}, "mode": {"type": "number"}}}}}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "nodeSelector": {"type": "object", "additionalProperties": true}, "extraTolerations": {"type": "array"}, "extraNodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "extraPodAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "extraPodAntiAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "cloudMetadata": {"type": "object", "additionalProperties": false, "required": ["blockWithIptables", "ip"], "properties": {"blockWithIptables": {"type": "boolean"}, "ip": {"type": "string"}}}, "cmd": {"type": ["array", "string", "null"]}, "defaultUrl": {"type": ["string", "null"]}, "events": {"type": ["boolean", "null"]}, "extraAnnotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraContainers": {"type": "array"}, "extraLabels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraPodConfig": {"type": "object", "additionalProperties": true}, "extraResource": {"type": "object", "additionalProperties": false, "properties": {"guarantees": {"type": "object", "additionalProperties": true}, "limits": {"type": "object", "additionalProperties": true}}}, "fsGid": {"type": ["integer", "null"]}, "lifecycleHooks": {"type": "object", "additionalProperties": false, "properties": {"postStart": {"type": "object", "additionalProperties": true}, "preStop": {"type": "object", "additionalProperties": true}}}, "networkTools": {"type": "object", "additionalProperties": false, "properties": {"image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}}}, "serviceAccountName": {"type": ["string", "null"]}, "startTimeout": {"type": ["integer", "null"]}, "storage": {"type": "object", "additionalProperties": false, "required": ["type", "homeMountPath"], "properties": {"capacity": {"type": ["string", "null"]}, "dynamic": {"type": "object", "additionalProperties": false, "properties": {"pvcNameTemplate": {"type": ["string", "null"]}, "storageAccessModes": {"type": "array", "items": {"type": ["string", "null"]}}, "storageClass": {"type": ["string", "null"]}, "subPath": {"type": ["string", "null"]}, "volumeNameTemplate": {"type": ["string", "null"]}}}, "extraLabels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraVolumeMounts": {"type": "array"}, "extraVolumes": {"type": "array"}, "homeMountPath": {"type": "string"}, "static": {"type": "object", "additionalProperties": false, "properties": {"pvcName": {"type": ["string", "null"]}, "subPath": {"type": ["string", "null"]}}}, "type": {"enum": ["dynamic", "static", "none"]}}}, "allowPrivilegeEscalation": {"type": ["boolean", "null"]}, "uid": {"type": ["integer", "null"]}}}, "scheduling": {"type": "object", "additionalProperties": false, "properties": {"userScheduler": {"type": "object", "additionalProperties": false, "required": ["enabled", "plugins", "pluginConfig", "logLevel"], "properties": {"enabled": {"type": "boolean"}, "revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "replicas": {"type": "integer"}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "logLevel": {"type": "integer"}, "plugins": {"type": "object", "additionalProperties": true}, "pluginConfig": {"type": "array"}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "podPriority": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "globalDefault": {"type": "boolean"}, "defaultPriority": {"type": "integer"}, "imagePullerPriority": {"type": "integer"}, "userPlaceholderPriority": {"type": "integer"}}}, "userPlaceholder": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "replicas": {"type": "integer"}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "resources": {"type": "object", "additionalProperties": true}, "containerSecurityContext": {"type": "object", "additionalProperties": true}}}, "corePods": {"type": "object", "additionalProperties": false, "properties": {"tolerations": {"type": "array"}, "nodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"matchNodePurpose": {"enum": ["ignore", "prefer", "require"]}}}}}, "userPods": {"type": "object", "additionalProperties": false, "properties": {"tolerations": {"type": "array"}, "nodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"matchNodePurpose": {"enum": ["ignore", "prefer", "require"]}}}}}}}, "ingress": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "ingressClassName": {"type": ["string", "null"]}, "hosts": {"type": "array"}, "pathSuffix": {"type": ["string", "null"]}, "pathType": {"enum": ["Prefix", "Exact", "ImplementationSpecific"]}, "tls": {"type": "array"}, "extraPaths": {"type": "array"}}}, "prePuller": {"type": "object", "additionalProperties": false, "required": ["hook", "continuous"], "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "resources": {"type": "object", "additionalProperties": true}, "extraTolerations": {"type": "array"}, "hook": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "pullOnlyOnChanges": {"type": "boolean"}, "podSchedulingWaitDuration": {"type": "integer"}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}}}, "continuous": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}}}, "pullProfileListImages": {"type": "boolean"}, "extraImages": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}}}}}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "pause": {"type": "object", "additionalProperties": false, "properties": {"containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}}}}}, "custom": {"type": "object", "additionalProperties": true}, "cull": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "users": {"type": ["boolean", "null"]}, "adminUsers": {"type": ["boolean", "null"]}, "removeNamedServers": {"type": ["boolean", "null"]}, "timeout": {"type": ["integer", "null"]}, "every": {"type": ["integer", "null"]}, "concurrency": {"type": ["integer", "null"]}, "maxAge": {"type": ["integer", "null"]}}}, "debug": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}}}, "rbac": {"type": "object", "additionalProperties": false, "required": ["create"], "properties": {"enabled": {"type": "boolean"}, "create": {"type": "boolean"}}}, "global": {"type": "object", "additionalProperties": true, "properties": {"safeToShowValues": {"type": "boolean"}}}}} \ No newline at end of file +{"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": false, "required": ["imagePullSecrets", "hub", "proxy", "singleuser", "ingress", "prePuller", "custom", "cull", "debug", "rbac", "global"], "properties": {"enabled": {"type": ["boolean", "null"]}, "fullnameOverride": {"type": ["string", "null"]}, "nameOverride": {"type": ["string", "null"]}, "imagePullSecret": {"type": "object", "required": ["create"], "if": {"properties": {"create": {"const": true}}}, "then": {"additionalProperties": false, "required": ["registry", "username", "password"], "description": "This is configuration to create a k8s Secret resource of `type:\nkubernetes.io/dockerconfigjson`, with credentials to pull images from a\nprivate image registry. If you opt to do so, it will be available for use\nby all pods in their respective `spec.imagePullSecrets` alongside other\nk8s Secrets defined in `imagePullSecrets` or the pod respective\n`...image.pullSecrets` configuration.\n\nIn other words, using this configuration option can automate both the\notherwise manual creation of a k8s Secret and the otherwise manual\nconfiguration to reference this k8s Secret in all the pods of the Helm\nchart.\n\n```sh\n# you won't need to create a k8s Secret manually...\nkubectl create secret docker-registry image-pull-secret \\\n --docker-server= \\\n --docker-username= \\\n --docker-email= \\\n --docker-password=\n```\n\nIf you just want to let all Pods reference an existing secret, use the\n[`imagePullSecrets`](schema_imagePullSecrets) configuration instead.\n", "properties": {"create": {"type": "boolean", "description": "Toggle the creation of the k8s Secret with provided credentials to\naccess a private image registry.\n"}, "automaticReferenceInjection": {"type": "boolean", "description": "Toggle the automatic reference injection of the created Secret to all\npods' `spec.imagePullSecrets` configuration.\n"}, "registry": {"type": "string", "description": "Name of the private registry you want to create a credential set for.\nIt will default to Docker Hub's image registry.\n\nExamples:\n - https://index.docker.io/v1/\n - quay.io\n - eu.gcr.io\n - alexmorreale.privatereg.net\n"}, "username": {"type": "string", "description": "Name of the user you want to use to connect to your private registry.\n\nFor external gcr.io, you will use the `_json_key`.\n\nExamples:\n - alexmorreale\n - alex@pfc.com\n - _json_key\n"}, "password": {"type": "string", "description": "Password for the private image registry's user.\n\nExamples:\n - plaintextpassword\n - abc123SECRETzyx098\n\nFor gcr.io registries the password will be a big JSON blob for a\nGoogle cloud service account, it should look something like below.\n\n```yaml\npassword: |-\n {\n \"type\": \"service_account\",\n \"project_id\": \"jupyter-se\",\n \"private_key_id\": \"f2ba09118a8d3123b3321bd9a7d6d0d9dc6fdb85\",\n ...\n }\n```\n"}, "email": {"type": ["string", "null"], "description": "Specification of an email is most often not required, but it is\nsupported.\n"}}}}, "imagePullSecrets": {"type": "array"}, "hub": {"type": "object", "additionalProperties": false, "required": ["baseUrl"], "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "config": {"type": "object", "additionalProperties": true}, "extraFiles": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["mountPath"], "oneOf": [{"required": ["data"]}, {"required": ["stringData"]}, {"required": ["binaryData"]}], "properties": {"mountPath": {"type": "string"}, "data": {"type": "object", "additionalProperties": true}, "stringData": {"type": "string"}, "binaryData": {"type": "string"}, "mode": {"type": "number"}}}}}, "baseUrl": {"type": "string"}, "command": {"type": "array"}, "args": {"type": "array"}, "cookieSecret": {"type": ["string", "null"]}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "db": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["sqlite-pvc", "sqlite-memory", "mysql", "postgres", "other"]}, "pvc": {"type": "object", "additionalProperties": false, "required": ["storage"], "properties": {"annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "selector": {"type": "object", "additionalProperties": true}, "storage": {"type": "string"}, "accessModes": {"type": "array", "items": {"type": ["string", "null"]}}, "storageClassName": {"type": ["string", "null"]}, "subPath": {"type": ["string", "null"]}}}, "upgrade": {"type": ["boolean", "null"]}, "url": {"type": ["string", "null"]}, "password": {"type": ["string", "null"]}}}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "initContainers": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "extraConfig": {"type": "object", "additionalProperties": true}, "fsGid": {"type": ["integer", "null"], "minimum": 0}, "service": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"]}, "ports": {"type": "object", "additionalProperties": false, "properties": {"nodePort": {"type": ["integer", "null"], "minimum": 0}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraPorts": {"type": "array"}, "loadBalancerIP": {"type": ["string", "null"]}}}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "existingSecret": {"type": ["string", "null"]}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "activeServerLimit": {"type": ["integer", "null"]}, "allowNamedServers": {"type": ["boolean", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "authenticatePrometheus": {"type": ["boolean", "null"]}, "concurrentSpawnLimit": {"type": ["integer", "null"]}, "consecutiveFailureLimit": {"type": ["integer", "null"]}, "podSecurityContext": {"additionalProperties": true}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "deploymentStrategy": {"type": "object", "additionalProperties": false, "properties": {"rollingUpdate": {"type": ["string", "null"]}, "type": {"type": ["string", "null"]}}}, "extraContainers": {"type": "array"}, "extraVolumeMounts": {"type": "array"}, "extraVolumes": {"type": "array"}, "livenessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "readinessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "namedServerLimitPerUser": {"type": ["integer", "null"]}, "redirectToServer": {"type": ["boolean", "null"]}, "resources": {"type": "object", "additionalProperties": true}, "lifecycle": {"type": "object", "additionalProperties": false, "properties": {"postStart": {"type": "object", "additionalProperties": true}, "preStop": {"type": "object", "additionalProperties": true}}}, "services": {"type": "object", "additionalProperties": true, "properties": {"name": {"type": "string"}, "admin": {"type": "boolean"}, "command": {"type": ["string", "array"]}, "url": {"type": "string"}, "api_token": {"type": ["string", "null"]}, "apiToken": {"type": ["string", "null"]}}}, "loadRoles": {"type": "object", "additionalProperties": true}, "shutdownOnLogout": {"type": ["boolean", "null"]}, "templatePaths": {"type": "array"}, "templateVars": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "proxy": {"type": "object", "additionalProperties": false, "properties": {"chp": {"type": "object", "additionalProperties": false, "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "extraCommandLineFlags": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "livenessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "readinessProbe": {"type": "object", "additionalProperties": true, "required": ["enabled"], "if": {"properties": {"enabled": {"const": true}}}, "then": {"description": "This config option is like the k8s native specification of a\ncontainer probe, except that it also supports an `enabled` boolean\nflag.\n\nSee [the k8s\ndocumentation](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#probe-v1-core)\nfor more details.\n"}}, "resources": {"type": "object", "additionalProperties": true}, "defaultTarget": {"type": ["string", "null"]}, "errorTarget": {"type": ["string", "null"]}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "secretToken": {"type": ["string", "null"]}, "service": {"type": "object", "additionalProperties": false, "properties": {"type": {"enum": ["ClusterIP", "NodePort", "LoadBalancer", "ExternalName"]}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "nodePorts": {"type": "object", "additionalProperties": false, "properties": {"http": {"type": ["integer", "null"]}, "https": {"type": ["integer", "null"]}}}, "disableHttpPort": {"type": "boolean"}, "extraPorts": {"type": "array"}, "loadBalancerIP": {"type": ["string", "null"]}, "loadBalancerSourceRanges": {"type": "array"}}}, "https": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": ["boolean", "null"]}, "type": {"enum": [null, "", "letsencrypt", "manual", "offload", "secret"]}, "letsencrypt": {"type": "object", "additionalProperties": false, "properties": {"contactEmail": {"type": ["string", "null"]}, "acmeServer": {"type": ["string", "null"]}}}, "manual": {"type": "object", "additionalProperties": false, "properties": {"key": {"type": ["string", "null"]}, "cert": {"type": ["string", "null"]}}}, "secret": {"type": "object", "additionalProperties": false, "properties": {"name": {"type": ["string", "null"]}, "key": {"type": ["string", "null"]}, "crt": {"type": ["string", "null"]}}}, "hosts": {"type": "array"}}}, "traefik": {"type": "object", "additionalProperties": false, "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "extraInitContainers": {"type": "array"}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "extraDynamicConfig": {"type": "object", "additionalProperties": true}, "extraPorts": {"type": "array"}, "extraStaticConfig": {"type": "object", "additionalProperties": true}, "extraVolumes": {"type": "array"}, "extraVolumeMounts": {"type": "array"}, "hsts": {"type": "object", "additionalProperties": false, "required": ["includeSubdomains", "maxAge", "preload"], "properties": {"includeSubdomains": {"type": "boolean"}, "maxAge": {"type": "integer"}, "preload": {"type": "boolean"}}}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "deploymentStrategy": {"type": "object", "additionalProperties": false, "properties": {"rollingUpdate": {"type": ["string", "null"]}, "type": {"type": ["string", "null"]}}}, "secretSync": {"type": "object", "additionalProperties": false, "properties": {"containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}}}}}, "singleuser": {"type": "object", "additionalProperties": false, "properties": {"networkPolicy": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "ingress": {"type": "array"}, "egress": {"type": "array"}, "egressAllowRules": {"type": "object", "additionalProperties": false, "properties": {"cloudMetadataServer": {"type": "boolean"}, "dnsPortsCloudMetadataServer": {"type": "boolean"}, "dnsPortsKubeSystemNamespace": {"type": "boolean"}, "dnsPortsPrivateIPs": {"type": "boolean"}, "nonPrivateIPs": {"type": "boolean"}, "privateIPs": {"type": "boolean"}}}, "interNamespaceAccessLabels": {"enum": ["accept", "ignore"]}, "allowedIngressPorts": {"type": "array"}}}, "podNameTemplate": {"type": ["string", "null"]}, "cpu": {"type": "object", "additionalProperties": false, "properties": {"limit": {"type": ["number", "null"]}, "guarantee": {"type": ["number", "null"]}}}, "memory": {"type": "object", "additionalProperties": false, "properties": {"limit": {"type": ["number", "string", "null"]}, "guarantee": {"type": ["number", "string", "null"]}}}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "initContainers": {"type": "array"}, "profileList": {"type": "array"}, "extraFiles": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["mountPath"], "oneOf": [{"required": ["data"]}, {"required": ["stringData"]}, {"required": ["binaryData"]}], "properties": {"mountPath": {"type": "string"}, "data": {"type": "object", "additionalProperties": true}, "stringData": {"type": "string"}, "binaryData": {"type": "string"}, "mode": {"type": "number"}}}}}, "extraEnv": {"type": ["object", "array"], "additionalProperties": true}, "nodeSelector": {"type": "object", "additionalProperties": true}, "extraTolerations": {"type": "array"}, "extraNodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "extraPodAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "extraPodAntiAffinity": {"type": "object", "additionalProperties": false, "properties": {"required": {"type": "array"}, "preferred": {"type": "array"}}}, "cloudMetadata": {"type": "object", "additionalProperties": false, "required": ["blockWithIptables", "ip"], "properties": {"blockWithIptables": {"type": "boolean"}, "ip": {"type": "string"}}}, "cmd": {"type": ["array", "string", "null"]}, "defaultUrl": {"type": ["string", "null"]}, "events": {"type": ["boolean", "null"]}, "extraAnnotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraContainers": {"type": "array"}, "extraLabels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraPodConfig": {"type": "object", "additionalProperties": true}, "extraResource": {"type": "object", "additionalProperties": false, "properties": {"guarantees": {"type": "object", "additionalProperties": true}, "limits": {"type": "object", "additionalProperties": true}}}, "fsGid": {"type": ["integer", "null"]}, "lifecycleHooks": {"type": "object", "additionalProperties": false, "properties": {"postStart": {"type": "object", "additionalProperties": true}, "preStop": {"type": "object", "additionalProperties": true}}}, "networkTools": {"type": "object", "additionalProperties": false, "properties": {"image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}}}, "serviceAccountName": {"type": ["string", "null"]}, "startTimeout": {"type": ["integer", "null"]}, "storage": {"type": "object", "additionalProperties": false, "required": ["type", "homeMountPath"], "properties": {"capacity": {"type": ["string", "null"]}, "dynamic": {"type": "object", "additionalProperties": false, "properties": {"pvcNameTemplate": {"type": ["string", "null"]}, "storageAccessModes": {"type": "array", "items": {"type": ["string", "null"]}}, "storageClass": {"type": ["string", "null"]}, "volumeNameTemplate": {"type": ["string", "null"]}}}, "extraLabels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "extraVolumeMounts": {"type": "array"}, "extraVolumes": {"type": "array"}, "homeMountPath": {"type": "string"}, "static": {"type": "object", "additionalProperties": false, "properties": {"pvcName": {"type": ["string", "null"]}, "subPath": {"type": ["string", "null"]}}}, "type": {"enum": ["dynamic", "static", "none"]}}}, "allowPrivilegeEscalation": {"type": ["boolean", "null"]}, "uid": {"type": ["integer", "null"]}}}, "scheduling": {"type": "object", "additionalProperties": false, "properties": {"userScheduler": {"type": "object", "additionalProperties": false, "required": ["enabled", "plugins", "pluginConfig", "logLevel"], "properties": {"enabled": {"type": "boolean"}, "revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "replicas": {"type": "integer"}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "pdb": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "maxUnavailable": {"type": ["integer", "null"]}, "minAvailable": {"type": ["integer", "null"]}}}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "logLevel": {"type": "integer"}, "plugins": {"type": "object", "additionalProperties": true}, "pluginConfig": {"type": "array"}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}, "extraPodSpec": {"type": "object", "additionalProperties": true}}}, "podPriority": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "globalDefault": {"type": "boolean"}, "defaultPriority": {"type": "integer"}, "imagePullerPriority": {"type": "integer"}, "userPlaceholderPriority": {"type": "integer"}}}, "userPlaceholder": {"type": "object", "additionalProperties": false, "properties": {"enabled": {"type": "boolean"}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "replicas": {"type": "integer"}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "resources": {"type": "object", "additionalProperties": true}, "containerSecurityContext": {"type": "object", "additionalProperties": true}}}, "corePods": {"type": "object", "additionalProperties": false, "properties": {"tolerations": {"type": "array"}, "nodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"matchNodePurpose": {"enum": ["ignore", "prefer", "require"]}}}}}, "userPods": {"type": "object", "additionalProperties": false, "properties": {"tolerations": {"type": "array"}, "nodeAffinity": {"type": "object", "additionalProperties": false, "properties": {"matchNodePurpose": {"enum": ["ignore", "prefer", "require"]}}}}}}}, "ingress": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "ingressClassName": {"type": ["string", "null"]}, "hosts": {"type": "array"}, "pathSuffix": {"type": ["string", "null"]}, "pathType": {"enum": ["Prefix", "Exact", "ImplementationSpecific"]}, "tls": {"type": "array"}}}, "prePuller": {"type": "object", "additionalProperties": false, "required": ["hook", "continuous"], "properties": {"revisionHistoryLimit": {"type": ["integer", "null"], "minimum": 0}, "labels": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}, "resources": {"type": "object", "additionalProperties": true}, "extraTolerations": {"type": "array"}, "hook": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "pullOnlyOnChanges": {"type": "boolean"}, "podSchedulingWaitDuration": {"type": "integer"}, "nodeSelector": {"type": "object", "additionalProperties": true}, "tolerations": {"type": "array"}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}, "resources": {"type": "object", "additionalProperties": true}, "serviceAccount": {"type": "object", "required": ["create"], "additionalProperties": false, "properties": {"create": {"type": "boolean"}, "name": {"type": ["string", "null"]}, "annotations": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "string"}}}}}}}, "continuous": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}}}, "pullProfileListImages": {"type": "boolean"}, "extraImages": {"type": "object", "additionalProperties": false, "patternProperties": {".*": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}}}}}, "containerSecurityContext": {"type": "object", "additionalProperties": true}, "pause": {"type": "object", "additionalProperties": false, "properties": {"containerSecurityContext": {"type": "object", "additionalProperties": true}, "image": {"type": "object", "additionalProperties": false, "required": ["name", "tag"], "properties": {"name": {"type": "string"}, "tag": {"type": "string"}, "pullPolicy": {"enum": [null, "", "IfNotPresent", "Always", "Never"]}, "pullSecrets": {"type": "array"}}}}}}}, "custom": {"type": "object", "additionalProperties": true}, "cull": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}, "users": {"type": ["boolean", "null"]}, "adminUsers": {"type": ["boolean", "null"]}, "removeNamedServers": {"type": ["boolean", "null"]}, "timeout": {"type": ["integer", "null"]}, "every": {"type": ["integer", "null"]}, "concurrency": {"type": ["integer", "null"]}, "maxAge": {"type": ["integer", "null"]}}}, "debug": {"type": "object", "additionalProperties": false, "required": ["enabled"], "properties": {"enabled": {"type": "boolean"}}}, "rbac": {"type": "object", "additionalProperties": false, "required": ["create"], "properties": {"enabled": {"type": "boolean"}, "create": {"type": "boolean"}}}, "global": {"type": "object", "additionalProperties": true, "properties": {"safeToShowValues": {"type": "boolean"}}}}} \ No newline at end of file diff --git a/jupyter/base/charts/jupyterhub/values.yaml b/jupyter/base/charts/jupyterhub/values.yaml index 4e35607..eaa3875 100644 --- a/jupyter/base/charts/jupyterhub/values.yaml +++ b/jupyter/base/charts/jupyterhub/values.yaml @@ -41,7 +41,6 @@ hub: annotations: {} ports: nodePort: - appProtocol: extraPorts: [] loadBalancerIP: baseUrl: / @@ -85,21 +84,16 @@ hub: extraVolumeMounts: [] image: name: quay.io/jupyterhub/k8s-hub - tag: "4.0.0" + tag: "3.2.1" pullPolicy: pullSecrets: [] resources: {} podSecurityContext: - runAsNonRoot: true fsGroup: 1000 - seccompProfile: - type: "RuntimeDefault" containerSecurityContext: runAsUser: 1000 runAsGroup: 1000 allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] lifecycle: {} loadRoles: {} services: {} @@ -203,20 +197,15 @@ proxy: chp: revisionHistoryLimit: containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" image: name: quay.io/jupyterhub/configurable-http-proxy # tag is automatically bumped to new patch versions by the # watch-dependencies.yaml workflow. # - tag: "4.6.2" # https://github.com/jupyterhub/configurable-http-proxy/tags + tag: "4.6.1" # https://github.com/jupyterhub/configurable-http-proxy/tags pullPolicy: pullSecrets: [] extraCommandLineFlags: [] @@ -261,20 +250,15 @@ proxy: traefik: revisionHistoryLimit: containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" image: name: traefik # tag is automatically bumped to new patch versions by the # watch-dependencies.yaml workflow. # - tag: "v3.2.0" # ref: https://hub.docker.com/_/traefik?tab=tags + tag: "v2.10.5" # ref: https://hub.docker.com/_/traefik?tab=tags pullPolicy: pullSecrets: [] hsts: @@ -316,17 +300,12 @@ proxy: extraPodSpec: {} secretSync: containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" image: name: quay.io/jupyterhub/k8s-secret-sync - tag: "4.0.0" + tag: "3.2.1" pullPolicy: pullSecrets: [] resources: {} @@ -366,7 +345,7 @@ singleuser: networkTools: image: name: quay.io/jupyterhub/k8s-network-tools - tag: "4.0.0" + tag: "3.2.1" pullPolicy: pullSecrets: [] resources: {} @@ -413,13 +392,12 @@ singleuser: homeMountPath: /home/jovyan dynamic: storageClass: - pvcNameTemplate: - volumeNameTemplate: volume-{user_server} + pvcNameTemplate: claim-{username}{servername} + volumeNameTemplate: volume-{username}{servername} storageAccessModes: [ReadWriteOnce] - subPath: image: name: quay.io/jupyterhub/k8s-singleuser-sample - tag: "4.0.0" + tag: "3.2.1" pullPolicy: pullSecrets: [] startTimeout: 300 @@ -454,24 +432,19 @@ scheduling: # plugins: score: - # We make use of the default scoring plugins, but we re-enable some with - # a new priority, leave some enabled with their lower default priority, - # and disable some. + # These scoring plugins are enabled by default according to + # https://kubernetes.io/docs/reference/scheduling/config/#scheduling-plugins + # 2022-02-22. # - # Below are the default scoring plugins as of 2024-09-23 according to - # https://kubernetes.io/docs/reference/scheduling/config/#scheduling-plugins. - # - # Re-enabled with high priority: + # Enabled with high priority: # - NodeAffinity # - InterPodAffinity # - NodeResourcesFit # - ImageLocality - # # Remains enabled with low default priority: # - TaintToleration # - PodTopologySpread # - VolumeBinding - # # Disabled for scoring: # - NodeResourcesBalancedAllocation # @@ -500,25 +473,20 @@ scheduling: - name: NodeResourcesFit args: scoringStrategy: - type: MostAllocated resources: - name: cpu weight: 1 - name: memory weight: 1 + type: MostAllocated containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" image: # IMPORTANT: Bumping the minor version of this binary should go hand in - # hand with an inspection of the user-scheduelr's RBAC - # resources that we have forked in + # hand with an inspection of the user-scheduelrs RBAC resources + # that we have forked in # templates/scheduling/user-scheduler/rbac.yaml. # # Debugging advice: @@ -551,7 +519,7 @@ scheduling: # here. We aim to stay around 1 minor version behind the latest k8s # version. # - tag: "v1.30.6" # ref: https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG + tag: "v1.26.11" # ref: https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG pullPolicy: pullSecrets: [] nodeSelector: {} @@ -583,7 +551,7 @@ scheduling: # # If you update this, also update prePuller.pause.image.tag # - tag: "3.10" + tag: "3.9" pullPolicy: pullSecrets: [] revisionHistoryLimit: @@ -591,14 +559,9 @@ scheduling: labels: {} annotations: {} containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" resources: {} corePods: tolerations: @@ -632,14 +595,9 @@ prePuller: annotations: {} resources: {} containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" extraTolerations: [] # hook relates to the hook-image-awaiter Job and hook-image-puller DaemonSet hook: @@ -648,18 +606,13 @@ prePuller: # image and the configuration below relates to the hook-image-awaiter Job image: name: quay.io/jupyterhub/k8s-image-awaiter - tag: "4.0.0" + tag: "3.2.1" pullPolicy: pullSecrets: [] containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" podSchedulingWaitDuration: 10 nodeSelector: {} tolerations: [] @@ -674,14 +627,9 @@ prePuller: extraImages: {} pause: containerSecurityContext: - runAsNonRoot: true runAsUser: 65534 # nobody user runAsGroup: 65534 # nobody group allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] - seccompProfile: - type: "RuntimeDefault" image: name: registry.k8s.io/pause # tag is automatically bumped to new patch versions by the @@ -689,7 +637,7 @@ prePuller: # # If you update this, also update scheduling.userPlaceholder.image.tag # - tag: "3.10" + tag: "3.9" pullPolicy: pullSecrets: [] @@ -701,7 +649,6 @@ ingress: pathSuffix: pathType: Prefix tls: [] - extraPaths: [] # cull relates to the jupyterhub-idle-culler service, responsible for evicting # inactive singleuser pods. diff --git a/jupyter/overlays/prod/vr/kustomization.yaml b/jupyter/overlays/prod/vr/kustomization.yaml index 8cbec9e..cc2acbe 100644 --- a/jupyter/overlays/prod/vr/kustomization.yaml +++ b/jupyter/overlays/prod/vr/kustomization.yaml @@ -7,7 +7,7 @@ helmCharts: name: jupyterhub releaseName: vr-jupyterhub valuesFile: ./values/values.yaml - version: 4.0.0 + version: 3.2.1 namespace: vr-jupyterhub helmGlobals: chartHome: ../../../base/charts/ diff --git a/jupyter/overlays/test/sunet/kustomization.yaml b/jupyter/overlays/test/sunet/kustomization.yaml index 20bb8dd..6cdd2c8 100644 --- a/jupyter/overlays/test/sunet/kustomization.yaml +++ b/jupyter/overlays/test/sunet/kustomization.yaml @@ -7,7 +7,7 @@ helmCharts: name: jupyterhub releaseName: sunet-jupyterhub valuesFile: ./values/values.yaml - version: 4.0.0 + version: 3.2.1 namespace: sunet-jupyterhub helmGlobals: chartHome: ../../../base/charts/ diff --git a/jupyter/overlays/test/vr/kustomization.yaml b/jupyter/overlays/test/vr/kustomization.yaml index 8cbec9e..cc2acbe 100644 --- a/jupyter/overlays/test/vr/kustomization.yaml +++ b/jupyter/overlays/test/vr/kustomization.yaml @@ -7,7 +7,7 @@ helmCharts: name: jupyterhub releaseName: vr-jupyterhub valuesFile: ./values/values.yaml - version: 4.0.0 + version: 3.2.1 namespace: vr-jupyterhub helmGlobals: chartHome: ../../../base/charts/