diff --git a/config/clusters/maap/staging.values.yaml b/config/clusters/maap/staging.values.yaml index 660a3b5504..6390d5d00a 100644 --- a/config/clusters/maap/staging.values.yaml +++ b/config/clusters/maap/staging.values.yaml @@ -9,6 +9,25 @@ jupyterhub: 2i2c: add_staff_user_ids_to_admin_users: false singleuser: + storage: + extraVolumes: + # Volume mounts for shared group directories are nested + # under /home/jovyan/shared-group/. When group membership changes and a mount is + # removed, Kubernetes unmounts the volume but leaves behind an empty directory at the + # mount point. This creates confusing leftover empty directories that don't reflect current + # group membership. + # To avoid this, we mount an emptyDir volume on /home/jovyan/shared-group. Group-specific + # directories are then mounted on top. When a group mount is removed, + # it reveals the empty base layer underneath - no leftover directories. + 00-shared-group-placeholder: + name: shared-group-placeholder + emptyDir: + medium: Memory + sizeLimit: 1Mi + extraVolumeMounts: + 00-shared-group-placeholder: + name: shared-group-placeholder + mountPath: /home/jovyan/shared-group extraEnv: SCRATCH_BUCKET: s3://maap-scratch-staging/$(JUPYTERHUB_USER) nodeSelector: @@ -192,6 +211,25 @@ jupyterhub: config: JupyterHub: authenticator_class: generic-oauth + KubeSpawner: + group_overrides: + # Explicitly mount the shared group folders based on group membership + 00-group-CPU-L-extra-volume-mounts: + groups: [CPU:L] + spawner_override: + volume_mounts: + 00-group-CPU-L-extra-volume-mounts: + name: home + mountPath: /home/jovyan/shared-group/CPU_L + subPath: _shared-group/CPU_L + 01-group-GPU-T4-extra-volume-mounts: + groups: [GPU:T4] + spawner_override: + volume_mounts: + 01-group-GPU-T4-extra-volume-mounts: + name: home + mountPath: /home/jovyan/shared-group/GPU_T4 + subPath: _shared-group/GPU_T4 Authenticator: admin_users: [] GenericOAuthenticator: @@ -222,53 +260,6 @@ jupyterhub: - CPU:XXL - CPU:XXXL - GPU:T4 - extraConfig: - 00-volumes-and-volume-mounts-as-dict: | - # The base jupyterhub config in zero-to-jupyterhub defines - # volumes and volume_mounts as lists. - # But we can't add new volumes or volume_mounts to the list - # as that replaces the entire list. - # So we convert them to dictionaries, which allows us to - # add new volumes and volume_mounts as needed. - if isinstance(c.KubeSpawner.volumes, list): - existing_volumes = c.KubeSpawner.volumes - c.KubeSpawner.volumes = {} - for volume in existing_volumes: - c.KubeSpawner.volumes[volume["name"]] = volume - if isinstance(c.KubeSpawner.volume_mounts, list): - existing_volume_mounts = c.KubeSpawner.volume_mounts - c.KubeSpawner.volume_mounts = {} - for idx, volume_mount in enumerate(existing_volume_mounts): - c.KubeSpawner.volume_mounts[f"{idx}-{volume_mount['name']}"] = volume_mount - 01-group-shared-directories: | - c.KubeSpawner.group_overrides = { - "00-group-CPU-L-extra-volume-mounts": { - "groups": ["CPU:L"], - "spawner_override": { - "volume_mounts": { - "00-group-CPU-L-shared-dir": { - "name": "home", - "mountPath": "/home/jovyan/shared-group/CPU_L", - "subPath": "_shared-group/CPU_L", - "readOnly": False - }, - } - }, - }, - "01-group-GPU-T4-extra-volume-mounts": { - "groups": ["GPU:T4"], - "spawner_override": { - "volume_mounts": { - "00-group-GPU-T4-shared-dir": { - "name": "home", - "mountPath": "/home/jovyan/shared-group/GPU_T4", - "subPath": "_shared-group/GPU_T4", - "readOnly": False - }, - } - }, - } - } ingress: hosts: [staging.hub.maap.2i2c.cloud] tls: diff --git a/helm-charts/basehub/Chart.yaml b/helm-charts/basehub/Chart.yaml index 346fefe130..3684b2d8ad 100644 --- a/helm-charts/basehub/Chart.yaml +++ b/helm-charts/basehub/Chart.yaml @@ -12,7 +12,7 @@ dependencies: # images/hub/Dockerfile, and will also involve manually building and pushing # the Dockerfile to https://quay.io/2i2c/pilot-hub. Details about this can # be found in the Dockerfile's comments. - version: 4.0.0 + version: 4.3.0 repository: https://jupyterhub.github.io/helm-chart/ - name: binderhub-service version: 0.1.0-0.dev.git.316.h27f15f4