Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/_nebari/stages/kubernetes_services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class JupyterLabProfile(schema.Base):
users: Optional[List[str]] = None
groups: Optional[List[str]] = None
kubespawner_override: Optional[KubeSpawner] = None
profile_options: Optional[dict[str, ProfileOption]] = None
profile_options: dict[str, ProfileOption] = {}

@model_validator(mode="after")
def only_yaml_can_have_groups_and_users(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from pathlib import Path

import z2jh
from tornado import gen


def base_profile_home_mounts(username):
Expand Down Expand Up @@ -52,7 +51,7 @@ def base_profile_home_mounts(username):
# Copy skel files/folders not starting with '..' to user home directory.
# Filtering out ..* removes some unneeded folders (k8s configmap mount implementation details).
"find /etc/skel/. -maxdepth 1 -not -name '.' -not -name '..*' -exec "
"cp -rL {escaped_brackets} /mnt/{path} \;"
"cp -rL {escaped_brackets} /mnt/{path} \\;"
)
command = MKDIR_OWN_DIRECTORY.format(
# have to escape the brackets since this string will be formatted later by KubeSpawner
Expand Down Expand Up @@ -512,7 +511,6 @@ def render_profile(
return None

profile = copy.copy(profile)
profile_kubespawner_override = profile.get("kubespawner_override")
profile["kubespawner_override"] = functools.reduce(
deep_merge,
[
Expand All @@ -522,38 +520,27 @@ def render_profile(
base_profile_extra_mounts(),
configure_user(username, groups),
configure_user_provisioned_repositories(username),
profile_kubespawner_override,
profile.get("kubespawner_override"),
],
{},
)

# We need to merge any env vars from the spawner with any overrides from the profile
# This is mainly to ensure JUPYTERHUB_ANYONE/GROUP is passed through from the spawner
# to control dashboard access.
envvars_fixed = {**(profile["kubespawner_override"].get("environment", {}))}

def preserve_envvars(spawner):
# This adds in JUPYTERHUB_ANYONE/GROUP rather than overwrite all env vars,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior of Kubespawner changed in v5 so kubespawner_override's default behavior is merge instead of replace now so I'm now simplifing this part.
reference: https://jupyterhub-kubespawner.readthedocs.io/en/latest/changelog.html#id24

# if set in the spawner for a dashboard to control access.
return {
**envvars_fixed,
**spawner.environment,
profile["kubespawner_override"]["environment"].update(
{
**profile_argo_token(groups),
**profile_conda_store_viewer_token(),
}

profile["kubespawner_override"]["environment"] = preserve_envvars
)

return profile


@gen.coroutine
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flyby: tornado coroutine to native coroutine

def render_profiles(spawner):
async def render_profiles(spawner):
# jupyterhub does not yet manage groups but it will soon
# so for now we rely on auth_state from the keycloak
# userinfo request to have the groups in the key
# "auth_state.oauth_user.groups"
auth_state = yield spawner.user.get_auth_state()
auth_state = await spawner.user.get_auth_state()

username = auth_state["oauth_user"]["preferred_username"]

Expand All @@ -570,7 +557,7 @@ def render_profiles(spawner):

# fetch available profiles and render additional attributes
profile_list = z2jh.get_config("custom.profiles")
return list(
rendered_profiles = list(
filter(
None,
[
Expand All @@ -585,6 +572,7 @@ def render_profiles(spawner):
],
)
)
return rendered_profiles


c.KubeSpawner.args = ["--debug"]
Expand Down
Loading