From 769a118efdea5eaa69670b0248dc6d9891e55f9d Mon Sep 17 00:00:00 2001 From: Mert Acar <25368652+M4C4R@users.noreply.github.com> Date: Wed, 26 Jul 2023 23:43:09 +0100 Subject: [PATCH 1/3] feature: each file in singleusers.extraFiles is mounted is a separate secret --- jupyterhub/files/hub/jupyterhub_config.py | 46 ++++++++------------- jupyterhub/templates/hub/secret.yaml | 6 +++ jupyterhub/templates/singleuser/secret.yaml | 13 +++--- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/jupyterhub/files/hub/jupyterhub_config.py b/jupyterhub/files/hub/jupyterhub_config.py index e30be9aa34..0402325db0 100644 --- a/jupyterhub/files/hub/jupyterhub_config.py +++ b/jupyterhub/files/hub/jupyterhub_config.py @@ -295,37 +295,25 @@ def camelCaseify(s): # the dedicated k8s Secret prepared to hold the extraFiles actual content. extra_files = get_config("singleuser.extraFiles", {}) if extra_files: - volume = { - "name": "files", - } - items = [] - for file_key, file_details in extra_files.items(): - # Each item is a mapping of a key in the k8s Secret to a path in this - # abstract volume, the goal is to enable us to set the mode / - # permissions only though so we don't change the mapping. - item = { - "key": file_key, - "path": file_key, - } - if "mode" in file_details: - item["mode"] = file_details["mode"] - items.append(item) - volume["secret"] = { - "secretName": get_name("singleuser"), - "items": items, - } - c.KubeSpawner.volumes.append(volume) - - volume_mounts = [] for file_key, file_details in extra_files.items(): - volume_mounts.append( - { - "mountPath": file_details["mountPath"], - "subPath": file_key, - "name": "files", + # Make the key RFC 1035 Label Naming compliant + file_key = file_key.lower().replace("_", "-").replace(".", "-") + c.KubeSpawner.volumes.append({ + "name": file_key, + "secret": { + "secretName": f"singleuser-{file_key}", + "items": [{ + "key": file_key, + "path": file_key, + "mode": file_details.get("mode") + }] } - ) - c.KubeSpawner.volume_mounts.extend(volume_mounts) + }) + c.KubeSpawner.volume_mounts.append({ + "mountPath": file_details["mountPath"], + "subPath": file_key, + "name": file_key, + }) # Inject extraVolumes / extraVolumeMounts c.KubeSpawner.volumes.extend(get_config("singleuser.storage.extraVolumes", [])) diff --git a/jupyterhub/templates/hub/secret.yaml b/jupyterhub/templates/hub/secret.yaml index 851bda0ce2..231f488690 100644 --- a/jupyterhub/templates/hub/secret.yaml +++ b/jupyterhub/templates/hub/secret.yaml @@ -7,6 +7,12 @@ metadata: type: Opaque data: {{- $values := merge dict .Values }} + {{- range $k, $v := dig "singleuser" "extraFiles" dict $values }} + {{- /* we must unset these large values as they result in us hitting the size limit of K8s Secrets */}} + {{- $_ := unset $v "data" }} + {{- $_ := unset $v "stringData" }} + {{- $_ := unset $v "binaryData" }} + {{- end }} {{- /* also passthrough subset of Chart / Release */}} {{- $_ := set $values "Chart" (dict "Name" .Chart.Name "Version" .Chart.Version) }} {{- $_ := set $values "Release" (pick .Release "Name" "Namespace" "Service") }} diff --git a/jupyterhub/templates/singleuser/secret.yaml b/jupyterhub/templates/singleuser/secret.yaml index f4a5fe2b42..a56b4c2dda 100644 --- a/jupyterhub/templates/singleuser/secret.yaml +++ b/jupyterhub/templates/singleuser/secret.yaml @@ -1,16 +1,19 @@ -{{- if .Values.singleuser.extraFiles }} +{{- range $name, $details := .Values.singleuser.extraFiles }} +{{- /* Make the key RFC 1035 Label Naming compliant */}} +{{- $name = $name | lower | replace "_" "-" | replace "." "-" }} +--- kind: Secret apiVersion: v1 metadata: - name: {{ include "jupyterhub.singleuser.fullname" . }} + name: {{ include "jupyterhub.singleuser.fullname" $ }}-{{ $name }} labels: - {{- include "jupyterhub.labels" . | nindent 4 }} + {{- include "jupyterhub.labels" $ | nindent 4 }} type: Opaque -{{- with include "jupyterhub.extraFiles.data" .Values.singleuser.extraFiles }} +{{- with include "jupyterhub.extraFiles.data" (dict $name $details) }} data: {{- . | nindent 2 }} {{- end }} -{{- with include "jupyterhub.extraFiles.stringData" .Values.singleuser.extraFiles }} +{{- with include "jupyterhub.extraFiles.stringData" (dict $name $details) }} stringData: {{- . | nindent 2 }} {{- end }} From 854f4fb45ea394131d6d476b3688a527278f2a84 Mon Sep 17 00:00:00 2001 From: Mert Acar <25368652+M4C4R@users.noreply.github.com> Date: Wed, 26 Jul 2023 23:54:46 +0100 Subject: [PATCH 2/3] docs: update file size limitation doc --- jupyterhub/values.schema.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/jupyterhub/values.schema.yaml b/jupyterhub/values.schema.yaml index f2756d8880..6e506d29ce 100644 --- a/jupyterhub/values.schema.yaml +++ b/jupyterhub/values.schema.yaml @@ -389,11 +389,10 @@ properties: 1. File size - The files in `hub.extraFiles` and `singleuser.extraFiles` are - respectively stored in their own k8s Secret resource. As k8s - Secret's are limited, typically to 1MB, you will be limited to a - total file size of less than 1MB as there is also base64 encoding - that takes place reducing available capacity to 75%. + The files in `hub.extraFiles` is stored within a k8s Secret + resource. As k8s Secret's are limited, typically to 1MB, you will + be limited to a total file size of less than 1MB as there is also + base64 encoding that takes place reducing available capacity to 75%. 2. File updates From 53c3c90e96beaa34b5a69137e3334cee00082dd6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Jul 2023 22:58:53 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- jupyterhub/files/hub/jupyterhub_config.py | 36 +++++++++++++---------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/jupyterhub/files/hub/jupyterhub_config.py b/jupyterhub/files/hub/jupyterhub_config.py index 0402325db0..724c4f911b 100644 --- a/jupyterhub/files/hub/jupyterhub_config.py +++ b/jupyterhub/files/hub/jupyterhub_config.py @@ -298,22 +298,28 @@ def camelCaseify(s): for file_key, file_details in extra_files.items(): # Make the key RFC 1035 Label Naming compliant file_key = file_key.lower().replace("_", "-").replace(".", "-") - c.KubeSpawner.volumes.append({ - "name": file_key, - "secret": { - "secretName": f"singleuser-{file_key}", - "items": [{ - "key": file_key, - "path": file_key, - "mode": file_details.get("mode") - }] + c.KubeSpawner.volumes.append( + { + "name": file_key, + "secret": { + "secretName": f"singleuser-{file_key}", + "items": [ + { + "key": file_key, + "path": file_key, + "mode": file_details.get("mode"), + } + ], + }, } - }) - c.KubeSpawner.volume_mounts.append({ - "mountPath": file_details["mountPath"], - "subPath": file_key, - "name": file_key, - }) + ) + c.KubeSpawner.volume_mounts.append( + { + "mountPath": file_details["mountPath"], + "subPath": file_key, + "name": file_key, + } + ) # Inject extraVolumes / extraVolumeMounts c.KubeSpawner.volumes.extend(get_config("singleuser.storage.extraVolumes", []))