diff --git a/integration-tests/plugins/simplest/setup.py b/integration-tests/plugins/simplest/setup.py index 9a34d26..a5b0857 100644 --- a/integration-tests/plugins/simplest/setup.py +++ b/integration-tests/plugins/simplest/setup.py @@ -5,5 +5,3 @@ setup( entry_points={"tljh": ["simplest = tljh_simplest"]}, py_modules=["tljh_simplest"], ) - - diff --git a/setup.py b/setup.py index 5352f2a..e1bb699 100644 --- a/setup.py +++ b/setup.py @@ -18,11 +18,15 @@ setup( 'backoff', 'requests', 'bcrypt', - 'jupyterhub-traefik-proxy==0.2.*' + 'jupyterhub-traefik-proxy==0.2.*', + 'jupyterhub-configurator @ git+https://github.com/yuvipanda/jupyterhub-configurator@ecca97e016e9a939dd48c6c0e66c40e4e2951fa7', ], entry_points={ + 'jupyterhub_configurator': [ + 'schema = tljh.schemas.tljh_configurator', + ], 'console_scripts': [ 'tljh-config = tljh.config:main', - ], + ] }, ) diff --git a/tljh/configurer.py b/tljh/configurer.py index 018c7d2..0281325 100644 --- a/tljh/configurer.py +++ b/tljh/configurer.py @@ -66,6 +66,9 @@ default = { 'concurrency': 5, 'users': False, 'max_age': 0 + }, + 'configurator': { + 'enabled': True } } } @@ -175,8 +178,8 @@ def update_userlists(c, config): """ users = config['users'] - c.Authenticator.whitelist = set(users['allowed']) - c.Authenticator.blacklist = set(users['banned']) + c.Authenticator.allowed_users = set(users['allowed']) + c.Authenticator.blocked_users = set(users['banned']) c.Authenticator.admin_users = set(users['admin']) @@ -249,10 +252,31 @@ def set_cull_idle_service(config): 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): c.JupyterHub.services = [] + if config['services']['cull']['enabled']: 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): diff --git a/tljh/schemas/__init__.py b/tljh/schemas/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tljh/schemas/tljh_configurator.py b/tljh/schemas/tljh_configurator.py new file mode 100644 index 0000000..abd0335 --- /dev/null +++ b/tljh/schemas/tljh_configurator.py @@ -0,0 +1,27 @@ +from jupyterhub_configurator.hooks import hookimpl + +@hookimpl +def jupyterhub_configurator_fields(): + return { + "schema.default_interface": { + "type": "string", + "traitlet": "Spawner.default_url", + "title": "Default User Interface", + "enum": ["/tree", "/lab", "/nteract"], + "default": "/tree", + "enumMetadata": { + "/tree": { + "title": "Classic Notebook", + "description": "The original single-document interface for creating Jupyter Notebooks.", + }, + "/lab": { + "title": "JupyterLab", + "description": "A Powerful next generation notebook interface", + }, + "/nteract": { + "title": "Nteract", + "description": "Nteract notebook interface", + }, + }, + } + } diff --git a/tljh/user_creating_spawner.py b/tljh/user_creating_spawner.py index 35bd0b6..bf75675 100755 --- a/tljh/user_creating_spawner.py +++ b/tljh/user_creating_spawner.py @@ -2,8 +2,9 @@ from tljh.normalize import generate_system_username from tljh import user from systemdspawner import SystemdSpawner from traitlets import Dict, Unicode, List +from jupyterhub_configurator.mixins import ConfiguratorSpawnerMixin -class UserCreatingSpawner(SystemdSpawner): +class UserCreatingSpawner(ConfiguratorSpawnerMixin, SystemdSpawner): """ SystemdSpawner with user creation on spawn.