Merge pull request #676 from GeorgianaElena/try-configurator

Add the jupyterhub-configurator service
This commit is contained in:
Georgiana Elena
2021-04-07 12:17:53 +03:00
committed by GitHub
8 changed files with 72 additions and 9 deletions

View File

@@ -12,9 +12,9 @@ jobs:
- uses: actions/setup-python@v2 - uses: actions/setup-python@v2
with: with:
python-version: 3.6 python-version: 3.6
- name: Install and setup venv - name: Install venv, git and setup venv
run: | run: |
apt-get update --yes && apt-get install --yes python3-venv apt-get update --yes && apt-get install --yes python3-venv git
python3 -m venv /srv/venv python3 -m venv /srv/venv
echo '/srv/venv/bin' >> $GITHUB_PATH echo '/srv/venv/bin' >> $GITHUB_PATH
- name: Cache pip deps - name: Cache pip deps

View File

@@ -17,3 +17,4 @@ Topic guides provide in-depth explanations of specific topics.
authenticator-configuration authenticator-configuration
escape-hatch escape-hatch
idle-culler idle-culler
jupyterhub-configurator

View File

@@ -0,0 +1,28 @@
.. _topic/jupyterhub-configurator:
=======================
JupyterHub Configurator
=======================
The `JupyterHub configurator <https://github.com/yuvipanda/jupyterhub-configurator>`_ allows admins to change a subset of hub settings via a GUI.
.. image:: ../images/jupyterhub-configurator.png
:alt: Changing the default JupyterHub interface
Enabling the configurator
=========================
Because the configurator is under continue development and it might change over time, it is disabled by default in TLJH.
If you want to experiment with it, it can be enabled using ``tljh-config``:
.. code-block:: bash
sudo tljh-config set services.configurator.enabled True
sudo tljh-config reload
Accessing the Configurator
==========================
After enabling the configurator using ``tljh-config``, the service will only be available to hub admins, from within the control panel.
The configurator can be accessed from under ``Services`` in the top navigation bar. It will ask to authenticate, so it knows the user is an admin.
Once done, the configurator interface will be available.

View File

@@ -5,5 +5,3 @@ setup(
entry_points={"tljh": ["simplest = tljh_simplest"]}, entry_points={"tljh": ["simplest = tljh_simplest"]},
py_modules=["tljh_simplest"], py_modules=["tljh_simplest"],
) )

View File

@@ -18,11 +18,11 @@ setup(
'backoff', 'backoff',
'requests', 'requests',
'bcrypt', 'bcrypt',
'jupyterhub-traefik-proxy==0.2.*' 'jupyterhub-traefik-proxy==0.2.*',
], ],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'tljh-config = tljh.config:main', 'tljh-config = tljh.config:main',
], ]
}, },
) )

View File

@@ -66,6 +66,9 @@ default = {
'concurrency': 5, 'concurrency': 5,
'users': False, 'users': False,
'max_age': 0 'max_age': 0
},
'configurator': {
'enabled': False
} }
} }
} }
@@ -175,8 +178,8 @@ def update_userlists(c, config):
""" """
users = config['users'] users = config['users']
c.Authenticator.whitelist = set(users['allowed']) c.Authenticator.allowed_users = set(users['allowed'])
c.Authenticator.blacklist = set(users['banned']) c.Authenticator.blocked_users = set(users['banned'])
c.Authenticator.admin_users = set(users['admin']) c.Authenticator.admin_users = set(users['admin'])
@@ -249,10 +252,31 @@ def set_cull_idle_service(config):
return cull_service return cull_service
def set_configurator(config):
"""
Set the JupyterHub Configurator service
"""
HERE = os.path.abspath(os.path.dirname(__file__))
configurator_cmd = [
sys.executable, "-m", "jupyterhub_configurator.app",
f"--Configurator.config_file={HERE}/jupyterhub_configurator_config.py"
]
configurator_service = {
'name': 'configurator',
'url': 'http://127.0.0.1:10101',
'command': configurator_cmd,
}
return configurator_service
def update_services(c, config): def update_services(c, config):
c.JupyterHub.services = [] c.JupyterHub.services = []
if config['services']['cull']['enabled']: if config['services']['cull']['enabled']:
c.JupyterHub.services.append(set_cull_idle_service(config)) c.JupyterHub.services.append(set_cull_idle_service(config))
if config['services']['configurator']['enabled']:
c.JupyterHub.services.append(set_configurator(config))
def _merge_dictionaries(a, b, path=None, update=True): def _merge_dictionaries(a, b, path=None, update=True):

View File

@@ -141,6 +141,7 @@ def ensure_jupyterhub_package(prefix):
"oauthenticator==0.10.0", "oauthenticator==0.10.0",
"jupyterhub-idle-culler==1.0", "jupyterhub-idle-culler==1.0",
"chardet==3.0.4", "chardet==3.0.4",
"git+https://github.com/yuvipanda/jupyterhub-configurator@317759e17c8e48de1b1352b836dac2a230536dba"
], ],
) )
traefik.ensure_traefik_binary(prefix) traefik.ensure_traefik_binary(prefix)

View File

@@ -1,9 +1,11 @@
from tljh.normalize import generate_system_username from tljh.normalize import generate_system_username
from tljh import user from tljh import user
from tljh import configurer
from systemdspawner import SystemdSpawner from systemdspawner import SystemdSpawner
from traitlets import Dict, Unicode, List from traitlets import Dict, Unicode, List
from jupyterhub_configurator.mixins import ConfiguratorSpawnerMixin
class UserCreatingSpawner(SystemdSpawner): class CustomSpawner(SystemdSpawner):
""" """
SystemdSpawner with user creation on spawn. SystemdSpawner with user creation on spawn.
@@ -32,3 +34,12 @@ class UserCreatingSpawner(SystemdSpawner):
user.ensure_user_group(system_username, group) user.ensure_user_group(system_username, group)
return super().start() return super().start()
cfg = configurer.load_config()
# Use the jupyterhub-configurator mixin only if configurator is enabled
# otherwise, any bugs in the configurator backend will stop new user spawns!
if cfg['services']['configurator']['enabled']:
# Dynamically create the Spawner class using `type`(https://docs.python.org/3/library/functions.html?#type),
# based on whether or not it should inherit from ConfiguratorSpawnerMixin
UserCreatingSpawner = type('UserCreatingSpawner', (ConfiguratorSpawnerMixin, CustomSpawner), {})
else:
UserCreatingSpawner = type('UserCreatingSpawner', (CustomSpawner,), {})