Merge pull request #360 from yuvipanda/repo2dockerspawner

Add custom hub package & config hooks
This commit is contained in:
Georgiana Elena
2019-06-05 16:49:11 +03:00
committed by GitHub
5 changed files with 67 additions and 10 deletions

View File

@@ -17,6 +17,11 @@ def tljh_extra_user_pip_packages():
'django', 'django',
] ]
@hookimpl
def tljh_extra_hub_pip_packages():
return [
'there',
]
@hookimpl @hookimpl
def tljh_extra_apt_packages(): def tljh_extra_apt_packages():
@@ -30,4 +35,8 @@ def tljh_config_post_install(config):
# Put an arbitrary marker we can test for # Put an arbitrary marker we can test for
config['simplest_plugin'] = { config['simplest_plugin'] = {
'present': True 'present': True
} }
@hookimpl
def tljh_custom_jupyterhub_config(c):
c.JupyterHub.authenticator_class = 'tmpauthenticator.TmpAuthenticator'

View File

@@ -2,9 +2,10 @@
Test simplest plugin Test simplest plugin
""" """
from ruamel.yaml import YAML from ruamel.yaml import YAML
import requests
import os import os
import subprocess import subprocess
from tljh.config import CONFIG_FILE, USER_ENV_PREFIX from tljh.config import CONFIG_FILE, USER_ENV_PREFIX, HUB_ENV_PREFIX
yaml = YAML(typ='rt') yaml = YAML(typ='rt')
@@ -18,7 +19,7 @@ def test_apt_packages():
def test_pip_packages(): def test_pip_packages():
""" """
Test extra user pip packages are installed Test extra user & hub pip packages are installed
""" """
subprocess.check_call([ subprocess.check_call([
f'{USER_ENV_PREFIX}/bin/python3', f'{USER_ENV_PREFIX}/bin/python3',
@@ -26,6 +27,12 @@ def test_pip_packages():
'import django' 'import django'
]) ])
subprocess.check_call([
f'{HUB_ENV_PREFIX}/bin/python3',
'-c',
'import there'
])
def test_conda_packages(): def test_conda_packages():
""" """
@@ -46,3 +53,11 @@ def test_config_hook():
data = yaml.load(f) data = yaml.load(f)
assert data['simplest_plugin']['present'] assert data['simplest_plugin']['present']
def test_jupyterhub_config_hook():
"""
Test that tmpauthenticator is enabled by our custom config plugin
"""
resp = requests.get('http://localhost/hub/tmplogin', allow_redirects=False)
assert resp.status_code == 302
assert resp.headers['Location'] == '/hub/spawn'

View File

@@ -22,6 +22,12 @@ def tljh_extra_user_pip_packages():
""" """
pass pass
@hookspec
def tljh_extra_hub_pip_packages():
"""
Return list of extra pip packages to install in the hub environment.
"""
pass
@hookspec @hookspec
def tljh_extra_apt_packages(): def tljh_extra_apt_packages():
@@ -32,6 +38,15 @@ def tljh_extra_apt_packages():
""" """
pass pass
@hookspec
def tljh_custom_jupyterhub_config(c):
"""
Provide custom traitlet based config to JupyterHub.
Anything you can put in `jupyterhub_config.py` can
be here.
"""
pass
@hookspec @hookspec
def tljh_config_post_install(config): def tljh_config_post_install(config):

View File

@@ -381,21 +381,29 @@ def run_plugin_actions(plugin_manager, plugins):
)) ))
apt.install_packages(apt_packages) apt.install_packages(apt_packages)
# Install hub pip packages
hub_pip_packages = list(set(itertools.chain(*hook.tljh_extra_hub_pip_packages())))
if hub_pip_packages:
logger.info('Installing {} hub pip packages collected from plugins: {}'.format(
len(hub_pip_packages), ' '.join(hub_pip_packages)
))
conda.ensure_pip_packages(HUB_ENV_PREFIX, hub_pip_packages)
# Install conda packages # Install conda packages
conda_packages = list(set(itertools.chain(*hook.tljh_extra_user_conda_packages()))) conda_packages = list(set(itertools.chain(*hook.tljh_extra_user_conda_packages())))
if conda_packages: if conda_packages:
logger.info('Installing {} conda packages collected from plugins: {}'.format( logger.info('Installing {} user conda packages collected from plugins: {}'.format(
len(conda_packages), ' '.join(conda_packages) len(conda_packages), ' '.join(conda_packages)
)) ))
conda.ensure_conda_packages(USER_ENV_PREFIX, conda_packages) conda.ensure_conda_packages(USER_ENV_PREFIX, conda_packages)
# Install pip packages # Install pip packages
pip_packages = list(set(itertools.chain(*hook.tljh_extra_user_pip_packages()))) user_pip_packages = list(set(itertools.chain(*hook.tljh_extra_user_pip_packages())))
if pip_packages: if user_pip_packages:
logger.info('Installing {} pip packages collected from plugins: {}'.format( logger.info('Installing {} user pip packages collected from plugins: {}'.format(
len(pip_packages), ' '.join(pip_packages) len(user_pip_packages), ' '.join(user_pip_packages)
)) ))
conda.ensure_pip_packages(USER_ENV_PREFIX, pip_packages) conda.ensure_pip_packages(USER_ENV_PREFIX, user_pip_packages)
def ensure_config_yaml(plugin_manager): def ensure_config_yaml(plugin_manager):

View File

@@ -4,9 +4,10 @@ JupyterHub config for the littlest jupyterhub.
from glob import glob from glob import glob
import os import os
import pluggy
from systemdspawner import SystemdSpawner from systemdspawner import SystemdSpawner
from tljh import configurer, user from tljh import configurer, user, hooks
from tljh.config import INSTALL_PREFIX, USER_ENV_PREFIX, CONFIG_DIR from tljh.config import INSTALL_PREFIX, USER_ENV_PREFIX, CONFIG_DIR
from tljh.normalize import generate_system_username from tljh.normalize import generate_system_username
from tljh.yaml import yaml from tljh.yaml import yaml
@@ -57,6 +58,15 @@ c.SystemdSpawner.unit_name_template = 'jupyter-{USERNAME}'
tljh_config = configurer.load_config() tljh_config = configurer.load_config()
configurer.apply_config(tljh_config, c) configurer.apply_config(tljh_config, c)
# Let TLJH hooks modify `c` if they want
# Set up plugin infrastructure
pm = pluggy.PluginManager('tljh')
pm.add_hookspecs(hooks)
pm.load_setuptools_entrypoints('tljh')
# Call our custom configuration plugin
pm.hook.tljh_custom_jupyterhub_config(c=c)
# Load arbitrary .py config files if they exist. # Load arbitrary .py config files if they exist.
# This is our escape hatch # This is our escape hatch
extra_configs = sorted(glob(os.path.join(CONFIG_DIR, 'jupyterhub_config.d', '*.py'))) extra_configs = sorted(glob(os.path.join(CONFIG_DIR, 'jupyterhub_config.d', '*.py')))