-
Notifications
You must be signed in to change notification settings - Fork 7
Refactor Jupyterhub configuration files #625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: gpu-resource-allocation
Are you sure you want to change the base?
Changes from all commits
7a9c432
1dc038f
dbea9c8
b887f4e
445bd8d
9f52946
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| name: pre-commit | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, ready_for_review] | ||
|
|
||
| jobs: | ||
| pre-commit: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v3 | ||
| - uses: pre-commit/[email protected] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| repos: | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| # Ruff version. | ||
| rev: v0.14.9 | ||
| hooks: | ||
| # Run the linter. | ||
| - id: ruff-check | ||
| files: birdhouse/components/jupyterhub/jupyterhub_custom/jupyterhub_custom/ | ||
| args: [ --config=birdhouse/components/jupyterhub/jupyterhub_custom/ruff.toml ] | ||
| # Run the formatter. | ||
| - id: ruff-format | ||
| files: birdhouse/components/jupyterhub/jupyterhub_custom/jupyterhub_custom/ | ||
| args: [ --config=birdhouse/components/jupyterhub/jupyterhub_custom/ruff.toml ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,60 @@ | |
|
|
||
| Also changes the format for `JUPYTERHUB_RESOURCE_LIMITS` to a yaml or JSON string. | ||
|
|
||
| - Refactor Jupyterhub configuration files | ||
|
|
||
| Previously the jupyterhub configuration was defined in `components/jupyterhub/jupyterhub_config.py.template` | ||
| except for the custom authenticator which was included in the `pavics/jupyterhub` docker image. This was fine, | ||
| except that the configuration was split across two projects and as the configuration got more complex, | ||
| maintaining these was getting more difficult. | ||
|
|
||
| This moves all configuration code including the authenticator to a python package named `jupyterhub_custom` | ||
| located at `components/jupyterhub/jupyterhub_custom/`. It moves all configurations for the authenticator | ||
| to the `magpie_authenticator.py` file and all the configurations for the spawner to the `custom_spawner.py` | ||
| file. All variables that are settable by environment variables are moved to the `constants.py` file. This | ||
| makes it much easier to see which variables are configurable using environment variables all in one place. | ||
|
|
||
| This change introduces unit tests and style policies (enforced by [ruff](https://docs.astral.sh/ruff/) and | ||
| [pre-commit](https://pre-commit.com/)) for this package to encourage better code practices. | ||
|
|
||
| This change should be fully backwards compatible with the exception of the change to how settings for | ||
| `deprecated-components/catalog` is handled (see below). However, it does deprecate some environment variables in | ||
| favour of better configuration solutions: | ||
|
|
||
| - using the `JUPYTERHUB_ENABLE_MULTI_NOTEBOOKS` variable to set the `DockerSpawner.allowed_images` variable | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the change, but I guess it could have been used for setting other definitions? If such custom overrides were applied/needed, should they be moved to Will the effect be equivalent, or other considerations would be necessary (eg: overrides not applying the same way since more changes could happen in between the "allowe_image" step and the final config object)? Some guidances along those lines could be relevant here if there is anything notable to consider.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It could have but I hope that it wasn't since any changes made there were prone to being overridden later on in the file.
Yes for sure, by deprecating
It should be unless they're using that to set a variable that is interpreted differently later on in the code. But I would definitely consider that a hack since the rest of the code could change later on and break any customizations done there. It's much safer to add in any custom overrides at the end of the configuration so that you know for sure that your changes are applied last.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok. I guess let's see if @tlvu was using it in such way.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tlvu do you have a situation where you're using |
||
| is deprecated. | ||
| - why?: this variable could be used to insert any python code into the middle of the | ||
| `jupyterhub_config.py.template` file. This makes it too easy to accidentally insert code that breaks | ||
| the configuration settings later on. We should avoid code insertion like this whenever possible. | ||
| - new method: by default `DockerSpawner.allowed_images` will be set based on the values of | ||
| `JUPYTERHUB_IMAGE_SELECTION_NAMES` and `JUPYTERHUB_DOCKER_NOTEBOOK_IMAGES`. If more than one image | ||
| is specified by those variables then the user will be able to select which one they want. If you | ||
| want to specify images other than those in the default, those can be set using the `JUPYTERHUB_ALLOWED_IMAGES` | ||
| which is a yaml or JSON mapping of image names to jupyterlab docker image tags. | ||
| - using the `JUPYTERHUB_ADMIN_USERS` variable to set the `DockerSpawner.admin_users` variable is deprecated. | ||
mishaschwartz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - why?: this also executes arbitrary code (like above). Also, jupyterhub encourages assigning admin permissions | ||
| based on | ||
| [roles](https://jupyterhub.readthedocs.io/en/latest/tutorial/getting-started/authenticators-users-basics.html#configure-admins-admin-users), | ||
| not by assigning them to the `admin_users` attribute. This makes it possible to easily revoke admin | ||
| permissions as well and does not require us to restart Jupyterhub to do so. | ||
| - new method: a new Magpie group is created. Its name is determined by the `JUPYTERHUB_ADMIN_GROUP_NAME` | ||
| variable (default is "jupyterhub-admin"). Add users to this group in Magpie in order to give them admin permissions on Jupyterhub. | ||
| - using lowercase constants in `JUPYTERHUB_CONFIG_OVERRIDE` is deprecated. | ||
| - why?: [PEP8 recommends](https://peps.python.org/pep-0008/#constants) constants be written with capitals | ||
| with underscores separating them. | ||
| - new method: all the constants that were previously named with lowercase have an uppercase equivalent | ||
| in `constants.py`. For example: `notebook_dir == constants.NOTEBOOK_DIR`. The uppercase version is | ||
| preferred. | ||
|
|
||
| Note: if your deployment is still using the `deprecated-components/catalog` component. You may want to manually set the | ||
| following in `JUPYTERHUB_CONFIG_OVERRIDE` since the automatic addition of the the `CATALOG_USERNAME` to the `blocked_users` | ||
| set is no longer part of the default settings (since the `deprecated-components/catalog` component has been deprecated for | ||
| a long time): | ||
|
|
||
| ```python | ||
| c.MagpieAuthenticator.blocked_users.add("${CATALOG_USERNAME}") | ||
fmigneault marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| [2.21.0](https://github.com/bird-house/birdhouse-deploy/tree/2.21.0) (2026-01-27) | ||
| ------------------------------------------------------------------------------------------------------------------ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,3 +8,15 @@ providers: | |
| c4i: false | ||
| type: api | ||
| sync_type: api | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious, this rename from
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The magpie doc used to have YAML was used at that point to reflect the actual data structure. You can actually use many extensions interchangeably. Magpie doesn't care as long as it loads as JSON-like. https://pavics-magpie.readthedocs.io/en/latest/configuration.html#configuration-file-formats |
||
| groups: | ||
| - name: ${JUPYTERHUB_ADMIN_GROUP_NAME} | ||
| description: Members of this group are given admin permissions on jupyterhub | ||
| discoverable: false | ||
|
|
||
| permissions: | ||
| - service: jupyterhub | ||
| resource: / | ||
| permission: read | ||
| group: ${JUPYTERHUB_ADMIN_GROUP_NAME} | ||
| action: create | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| services: | ||
| magpie: | ||
| volumes: | ||
| - ./components/jupyterhub/config/magpie/providers.cfg:${MAGPIE_PROVIDERS_CONFIG_PATH}/jupyter.cfg:ro | ||
| - ./components/jupyterhub/config/magpie/config.yml:${MAGPIE_PROVIDERS_CONFIG_PATH}/jupyter.yml:ro | ||
| - ./components/jupyterhub/config/magpie/config.yml:${MAGPIE_PERMISSIONS_CONFIG_PATH}/jupyter.yml:ro |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -9,7 +9,7 @@ services: | |||
| DOCKER_NETWORK_NAME: jupyterhub_network | ||||
| JUPYTERHUB_USER_DATA_DIR: ${JUPYTERHUB_USER_DATA_DIR} | ||||
| WORKSPACE_DIR: ${JUPYTERHUB_USER_DATA_DIR} | ||||
| JUPYTERHUB_ADMIN_USERS: ${JUPYTERHUB_ADMIN_USERS} | ||||
| JUPYTERHUB_ADMIN_USERS: ${JUPYTERHUB_ADMIN_USERS} # DEPRECATED: see default.env for details | ||||
| JUPYTER_DEMO_USER: ${JUPYTER_DEMO_USER} | ||||
| JUPYTER_DEMO_USER_MEM_LIMIT: ${JUPYTER_DEMO_USER_MEM_LIMIT} | ||||
| JUPYTER_DEMO_USER_CPU_LIMIT: ${JUPYTER_DEMO_USER_CPU_LIMIT} | ||||
|
|
@@ -20,7 +20,19 @@ services: | |||
| USER_WORKSPACE_GID: ${USER_WORKSPACE_GID} | ||||
| JUPYTERHUB_CRYPT_KEY: ${JUPYTERHUB_CRYPT_KEY} | ||||
| JUPYTERHUB_DOCKER_EXTRA_HOSTS: ${JUPYTERHUB_DOCKER_EXTRA_HOSTS:-} | ||||
| JUPYTERHUB_AUTHENTICATOR_AUTHORIZATION_URL: ${JUPYTERHUB_AUTHENTICATOR_AUTHORIZATION_URL:-} | ||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some of the new env vars here redefine a default value different than in
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you give an example?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Example this
Then example So the consistency question is 2 folds. Why sometime we redefine the default and sometime we don't? And then when we do redefine the default, why it is not the same value as in
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I see. |
||||
| JUPYTERHUB_AUTHENTICATOR_REFRESH_AGE: ${JUPYTERHUB_AUTHENTICATOR_REFRESH_AGE:-} | ||||
| JUPYTERHUB_ADMIN_GROUP_NAME: ${JUPYTERHUB_ADMIN_GROUP_NAME} | ||||
| BIRDHOUSE_FQDN_PUBLIC: ${BIRDHOUSE_FQDN_PUBLIC} | ||||
| BIRDHOUSE_PROXY_SCHEME: ${BIRDHOUSE_PROXY_SCHEME} | ||||
| JUPYTER_IDLE_SERVER_CULL_TIMEOUT: ${JUPYTER_IDLE_SERVER_CULL_TIMEOUT:-} | ||||
| JUPYTER_IDLE_KERNEL_CULL_TIMEOUT: ${JUPYTER_IDLE_KERNEL_CULL_TIMEOUT:-} | ||||
| JUPYTER_IDLE_KERNEL_CULL_INTERVAL: ${JUPYTER_IDLE_KERNEL_CULL_INTERVAL:-} | ||||
| JUPYTERHUB_ALLOWED_IMAGES: ${JUPYTERHUB_ALLOWED_IMAGES:-} | ||||
| JUPYTERHUB_RESOURCE_LIMITS: ${JUPYTERHUB_RESOURCE_LIMITS:-} | ||||
| PYTHONPATH: /srv/jupyterhub/jupyterhub_custom | ||||
| volumes: | ||||
| - ./components/jupyterhub/jupyterhub_custom:/srv/jupyterhub/jupyterhub_custom:ro | ||||
| - ./components/jupyterhub/jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro | ||||
| - ./components/jupyterhub/custom_templates:/custom_templates:ro | ||||
| - ${JUPYTERHUB_USER_DATA_DIR}:${JUPYTERHUB_USER_DATA_DIR} | ||||
|
|
||||
Uh oh!
There was an error while loading. Please reload this page.