diff --git a/jupyterhub_config.py b/jupyterhub_config.py index dd28dcc72b93b1d13d25258039bec54127cf0e39..74ac18abf248405306249b20c367ea1c8c4c5d86 100644 --- a/jupyterhub_config.py +++ b/jupyterhub_config.py @@ -1000,1481 +1000,114 @@ c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner' # Default: None # c.JupyterHub.user_redirect_hook = None -#------------------------------------------------------------------------------ -# CryptKeeper(SingletonConfigurable) configuration -#------------------------------------------------------------------------------ -## Encapsulate encryption configuration -# -# Use via the encryption_config singleton below. - -# Default: [] -# c.CryptKeeper.keys = [] - -## The number of threads to allocate for encryption -# Default: 16 -# c.CryptKeeper.n_threads = 16 - -#------------------------------------------------------------------------------ -# Authenticator(LoggingConfigurable) configuration -#------------------------------------------------------------------------------ -## Base class for implementing an authentication provider for JupyterHub - -## Set of users that will be granted admin rights on this JupyterHub. -# -# Note: -# -# As of JupyterHub 2.0, -# full admin rights should not be required, -# and more precise permissions can be managed via roles. -# -# Caution: -# -# Adding users to `admin_users` can only *grant* admin rights, -# removing a username from the admin_users set **DOES NOT** remove admin rights previously granted. -# -# For an authoritative, restricted set of admins, -# assign explicit membership of the `admin` *role*:: -# -# c.JupyterHub.load_roles = [ -# { -# "name": "admin", -# "users": ["admin1", "..."], -# } -# ] -# -# Admin users can take every possible action on behalf of all users, for -# example: -# -# - Use the admin panel to see list of users logged in - Add / remove users in -# some authenticators - Restart / halt the hub - Start / stop users' single-user -# servers - Can access each individual users' single-user server -# -# Admin access should be treated the same way root access is. -# -# Defaults to an empty set, in which case no user has admin access. -# Default: set() -# c.Authenticator.admin_users = set() - -## Allow every user who can successfully authenticate to access JupyterHub. -# -# False by default, which means for most Authenticators, _some_ allow-related -# configuration is required to allow users to log in. -# -# Authenticator subclasses may override the default with e.g.:: -# -# @default("allow_all") -# def _default_allow_all(self): -# # if _any_ auth config (depends on the Authenticator) -# if self.allowed_users or self.allowed_groups or self.allow_existing_users: -# return False -# else: -# return True -# -# .. versionadded:: 5.0 -# -# .. versionchanged:: 5.0 -# Prior to 5.0, `allow_all` wasn't defined on its own, -# and was instead implicitly True when no allow config was provided, -# i.e. `allowed_users` unspecified or empty on the base Authenticator class. -# -# To preserve pre-5.0 behavior, -# set `allow_all = True` if you have no other allow configuration. -# Default: False -c.Authenticator.allow_all = True - -## Allow existing users to login. -# -# Defaults to True if `allowed_users` is set for historical reasons, and False -# otherwise. -# -# With this enabled, all users present in the JupyterHub database are allowed to -# login. This has the effect of any user who has _previously_ been allowed to -# login via any means will continue to be allowed until the user is deleted via -# the /hub/admin page or REST API. -# -# .. warning:: -# -# Before enabling this you should review the existing users in the -# JupyterHub admin panel at `/hub/admin`. You may find users existing -# there because they have previously been declared in config such as -# `allowed_users` or allowed to sign in. -# -# .. warning:: -# -# When this is enabled and you wish to remove access for one or more -# users previously allowed, you must make sure that they -# are removed from the jupyterhub database. This can be tricky to do -# if you stop allowing an externally managed group of users for example. -# -# With this enabled, JupyterHub admin users can visit `/hub/admin` or use -# JupyterHub's REST API to add and remove users to manage who can login. -# -# .. versionadded:: 5.0 -# Default: False -# c.Authenticator.allow_existing_users = False - -## Set of usernames that are allowed to log in. -# -# Use this to limit which authenticated users may login. Default behavior: only -# users in this set are allowed. -# -# If empty, does not perform any restriction, in which case any authenticated -# user is allowed. -# -# Authenticators may extend :meth:`.Authenticator.check_allowed` to combine -# `allowed_users` with other configuration to either expand or restrict access. -# -# .. versionchanged:: 1.2 -# `Authenticator.whitelist` renamed to `allowed_users` -# Default: set() -# c.Authenticator.allowed_users = set() - -## Is there any allow config? -# -# Used to show a warning if it looks like nobody can access the Hub, -# which can happen when upgrading to JupyterHub 5, -# now that `allow_all` defaults to False. -# -# Deployments can set this explicitly to True to suppress -# the "No allow config found" warning. -# -# Will be True if any config tagged with `.tag(allow_config=True)` -# or starts with `allow` is truthy. -# -# .. versionadded:: 5.0 -# Default: False -# c.Authenticator.any_allow_config = False - -## The max age (in seconds) of authentication info -# before forcing a refresh of user auth info. -# -# Refreshing auth info allows, e.g. requesting/re-validating auth -# tokens. -# -# See :meth:`.refresh_user` for what happens when user auth info is refreshed -# (nothing by default). -# Default: 300 -# c.Authenticator.auth_refresh_age = 300 - -## Automatically begin the login process -# -# rather than starting with a "Login with..." link at `/hub/login` -# -# To work, `.login_url()` must give a URL other than the default `/hub/login`, -# such as an oauth handler or another automatic login handler, -# registered with `.get_handlers()`. -# -# .. versionadded:: 0.8 -# Default: False -# c.Authenticator.auto_login = False - -## Automatically begin login process for OAuth2 authorization requests -# -# When another application is using JupyterHub as OAuth2 provider, it sends -# users to `/hub/api/oauth2/authorize`. If the user isn't logged in already, and -# auto_login is not set, the user will be dumped on the hub's home page, without -# any context on what to do next. -# -# Setting this to true will automatically redirect users to login if they aren't -# logged in *only* on the `/hub/api/oauth2/authorize` endpoint. -# -# .. versionadded:: 1.5 -# Default: False -# c.Authenticator.auto_login_oauth2_authorize = False - -## Set of usernames that are not allowed to log in. -# -# Use this with supported authenticators to restrict which users can not log in. -# This is an additional block list that further restricts users, beyond whatever -# restrictions the authenticator has in place. -# -# If empty, does not perform any additional restriction. -# -# .. versionadded: 0.9 -# -# .. versionchanged:: 5.2 -# Users blocked via `blocked_users` that may have logged in in the past -# have all permissions and group membership revoked -# and all servers stopped at JupyterHub startup. -# Previously, User permissions (e.g. API tokens) -# and servers were unaffected and required additional -# administrator operations to block after a user is added to `blocked_users`. -# -# .. versionchanged:: 1.2 -# `Authenticator.blacklist` renamed to `blocked_users` -# Default: set() -# c.Authenticator.blocked_users = set() - -## Delete any users from the database that do not pass validation -# -# When JupyterHub starts, `.add_user` will be called -# on each user in the database to verify that all users are still valid. -# -# If `delete_invalid_users` is True, -# any users that do not pass validation will be deleted from the database. -# Use this if users might be deleted from an external system, -# such as local user accounts. -# -# If False (default), invalid users remain in the Hub's database -# and a warning will be issued. -# This is the default to avoid data loss due to config changes. -# Default: False -# c.Authenticator.delete_invalid_users = False - -## Enable persisting auth_state (if available). -# -# auth_state will be encrypted and stored in the Hub's database. -# This can include things like authentication tokens, etc. -# to be passed to Spawners as environment variables. -# -# Encrypting auth_state requires the cryptography package. -# -# Additionally, the JUPYTERHUB_CRYPT_KEY environment variable must -# contain one (or more, separated by ;) 32B encryption keys. -# These can be either base64 or hex-encoded. -# -# If encryption is unavailable, auth_state cannot be persisted. -# -# New in JupyterHub 0.8 -# Default: False -# c.Authenticator.enable_auth_state = False - -## Let authenticator manage user groups -# -# If True, Authenticator.authenticate and/or .refresh_user -# may return a list of group names in the 'groups' field, -# which will be assigned to the user. -# -# All group-assignment APIs are disabled if this is True. -# Default: False -# c.Authenticator.manage_groups = False - -## Let authenticator manage roles -# -# If True, Authenticator.authenticate and/or .refresh_user -# may return a list of roles in the 'roles' field, -# which will be added to the database. -# -# When enabled, all role management will be handled by the -# authenticator; in particular, assignment of roles via -# `JupyterHub.load_roles` traitlet will not be possible. -# -# .. versionadded:: 5.0 -# Default: False -# c.Authenticator.manage_roles = False - -## The prompt string for the extra OTP (One Time Password) field. -# -# .. versionadded:: 5.0 -# Default: 'OTP:' -# c.Authenticator.otp_prompt = 'OTP:' - -## An optional hook function that you can implement to do some bootstrapping work -# during authentication. For example, loading user account details from an -# external system. -# -# This function is called after the user has passed all authentication checks -# and is ready to successfully authenticate. This function must return the -# auth_model dict reguardless of changes to it. The hook is called with 3 -# positional arguments: `(authenticator, handler, auth_model)`. -# -# This may be a coroutine. -# -# .. versionadded: 1.0 -# -# Example:: -# -# import os -# import pwd -# def my_hook(authenticator, handler, auth_model): -# user_data = pwd.getpwnam(auth_model['name']) -# spawn_data = { -# 'pw_data': user_data -# 'gid_list': os.getgrouplist(auth_model['name'], user_data.pw_gid) -# } -# -# if auth_model['auth_state'] is None: -# auth_model['auth_state'] = {} -# auth_model['auth_state']['spawn_data'] = spawn_data -# -# return auth_model -# -# c.Authenticator.post_auth_hook = my_hook -# Default: None -# c.Authenticator.post_auth_hook = None - -## Force refresh of auth prior to spawn. -# -# This forces :meth:`.refresh_user` to be called prior to launching -# a server, to ensure that auth state is up-to-date. -# -# This can be important when e.g. auth tokens that may have expired -# are passed to the spawner via environment variables from auth_state. -# -# If refresh_user cannot refresh the user auth data, -# launch will fail until the user logs in again. -# Default: False -# c.Authenticator.refresh_pre_spawn = False - -## Prompt for OTP (One Time Password) in the login form. -# -# .. versionadded:: 5.0 -# Default: False -# c.Authenticator.request_otp = False - -## Reset managed roles to result of `load_managed_roles()` on startup. -# -# If True: -# - stale managed roles will be removed, -# - stale assignments to managed roles will be removed. -# -# Any role not present in `load_managed_roles()` will be considered -# 'stale'. -# -# The 'stale' status for role assignments is also determined from -# `load_managed_roles()` result: -# -# - user role assignments status will depend on whether the `users` key -# is defined or not: -# -# * if a list is defined under the `users` key and the user is not listed, then the user role assignment will be considered 'stale', -# * if the `users` key is not provided, the user role assignment will be preserved; -# - service and group role assignments will be considered 'stale': -# -# * if not included in the `services` and `groups` list, -# * if the `services` and `groups` keys are not provided. -# -# .. versionadded:: 5.0 -# Default: False -# c.Authenticator.reset_managed_roles_on_startup = False - -## Dictionary mapping authenticator usernames to JupyterHub users. -# -# Primarily used to normalize OAuth user names to local users. -# Default: {} -# c.Authenticator.username_map = {} - -## Regular expression pattern that all valid usernames must match. -# -# If a username does not match the pattern specified here, authentication will -# not be attempted. -# -# If not set, allow any username. -# Default: '' -# c.Authenticator.username_pattern = '' - -## Deprecated, use `Authenticator.allowed_users` -# Default: set() -# c.Authenticator.whitelist = set() - -#------------------------------------------------------------------------------ -# DummyAuthenticator(Authenticator) configuration -#------------------------------------------------------------------------------ -## Dummy Authenticator for testing -# -# By default, any username + password is allowed -# If a non-empty password is set, any username will be allowed -# if it logs in with that password. -# -# .. versionadded:: 1.0 -# -# .. versionadded:: 5.0 -# `allow_all` defaults to True, -# preserving default behavior. - -## -# See also: Authenticator.admin_users -# c.DummyAuthenticator.admin_users = set() - -## -# See also: Authenticator.allow_all -# c.DummyAuthenticator.allow_all = False - -## -# See also: Authenticator.allow_existing_users -# c.DummyAuthenticator.allow_existing_users = False - -## -# See also: Authenticator.allowed_users -# c.DummyAuthenticator.allowed_users = set() - -## Is there any allow config? -# See also: Authenticator.any_allow_config -# c.DummyAuthenticator.any_allow_config = False - -## The max age (in seconds) of authentication info -# See also: Authenticator.auth_refresh_age -# c.DummyAuthenticator.auth_refresh_age = 300 - -## Automatically begin the login process -# See also: Authenticator.auto_login -# c.DummyAuthenticator.auto_login = False - -## -# See also: Authenticator.auto_login_oauth2_authorize -# c.DummyAuthenticator.auto_login_oauth2_authorize = False - -## -# See also: Authenticator.blocked_users -# c.DummyAuthenticator.blocked_users = set() - -## Delete any users from the database that do not pass validation -# See also: Authenticator.delete_invalid_users -# c.DummyAuthenticator.delete_invalid_users = False - -## Enable persisting auth_state (if available). -# See also: Authenticator.enable_auth_state -# c.DummyAuthenticator.enable_auth_state = False - -## Let authenticator manage user groups -# See also: Authenticator.manage_groups -# c.DummyAuthenticator.manage_groups = False - -## Let authenticator manage roles -# See also: Authenticator.manage_roles -# c.DummyAuthenticator.manage_roles = False - -## -# See also: Authenticator.otp_prompt -# c.DummyAuthenticator.otp_prompt = 'OTP:' - -## Set a global password for all users wanting to log in. -# -# This allows users with any username to log in with the same static password. -# Default: '' -# c.DummyAuthenticator.password = '' - -## -# See also: Authenticator.post_auth_hook -# c.DummyAuthenticator.post_auth_hook = None - -## Force refresh of auth prior to spawn. -# See also: Authenticator.refresh_pre_spawn -# c.DummyAuthenticator.refresh_pre_spawn = False - -## -# See also: Authenticator.request_otp -# c.DummyAuthenticator.request_otp = False - -## Reset managed roles to result of `load_managed_roles()` on startup. -# See also: Authenticator.reset_managed_roles_on_startup -# c.DummyAuthenticator.reset_managed_roles_on_startup = False - -## Dictionary mapping authenticator usernames to JupyterHub users. -# See also: Authenticator.username_map -# c.DummyAuthenticator.username_map = {} - -## -# See also: Authenticator.username_pattern -# c.DummyAuthenticator.username_pattern = '' - -## Deprecated, use `Authenticator.allowed_users` -# See also: Authenticator.whitelist -# c.DummyAuthenticator.whitelist = set() - -#------------------------------------------------------------------------------ -# Proxy(LoggingConfigurable) configuration -#------------------------------------------------------------------------------ -## Base class for configurable proxies that JupyterHub can use. -# -# A proxy implementation should subclass this and must define the following -# methods: -# -# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes -# - :meth:`.add_route` adds a route -# - :meth:`.delete_route` deletes a route -# -# In addition to these, the following method(s) may need to be implemented: -# -# - :meth:`.start` start the proxy, if it should be launched by the Hub -# instead of externally managed. -# If the proxy is externally managed, it should set :attr:`should_start` to False. -# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used. -# -# And the following method(s) are optional, but can be provided: -# -# - :meth:`.get_route` gets a single route. -# There is a default implementation that extracts data from :meth:`.get_all_routes`, -# but implementations may choose to provide a more efficient implementation -# of fetching a single route. - -## Additional routes to be maintained in the proxy. -# -# A dictionary with a route specification as key, and a URL as target. The hub -# will ensure this route is present in the proxy. -# -# If the hub is running in host based mode (with JupyterHub.subdomain_host set), -# the routespec *must* have a domain component (example.com/my-url/). If the hub -# is not running in host based mode, the routespec *must not* have a domain -# component (/my-url/). -# -# Helpful when the hub is running in API-only mode. -# Default: {} -# c.Proxy.extra_routes = {} - -## Should the Hub start the proxy -# -# If True, the Hub will start the proxy and stop it. -# Set to False if the proxy is managed externally, -# such as by systemd, docker, or another service manager. -# Default: True -# c.Proxy.should_start = True - -#------------------------------------------------------------------------------ -# ConfigurableHTTPProxy(Proxy) configuration -#------------------------------------------------------------------------------ -## Proxy implementation for the default configurable-http-proxy. -# -# This is the default proxy implementation -# for running the nodejs proxy `configurable-http-proxy`. -# -# If the proxy should not be run as a subprocess of the Hub, -# (e.g. in a separate container), -# set:: -# -# c.ConfigurableHTTPProxy.should_start = False - -## The ip (or hostname) of the proxy's API endpoint -# Default: '' -# c.ConfigurableHTTPProxy.api_url = '' - -## The Proxy auth token -# -# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. -# Default: '' -# c.ConfigurableHTTPProxy.auth_token = '' - -## Interval (in seconds) at which to check if the proxy is running. -# Default: 5 -# c.ConfigurableHTTPProxy.check_running_interval = 5 - -## The command to start the proxy -# Default: ['configurable-http-proxy'] -# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy'] - -## The number of requests allowed to be concurrently outstanding to the proxy -# -# Limiting this number avoids potential timeout errors by sending too many -# requests to update the proxy at once -# Default: 10 -# c.ConfigurableHTTPProxy.concurrency = 10 - -## Add debug-level logging to the Proxy. -# Default: False -# c.ConfigurableHTTPProxy.debug = False - -## -# See also: Proxy.extra_routes -# c.ConfigurableHTTPProxy.extra_routes = {} - -## Proxy log level -# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive) -# Default: 'info' -# c.ConfigurableHTTPProxy.log_level = 'info' - -## File in which to write the PID of the proxy process. -# Default: 'jupyterhub-proxy.pid' -# c.ConfigurableHTTPProxy.pid_file = 'jupyterhub-proxy.pid' - -## Should the Hub start the proxy -# See also: Proxy.should_start -# c.ConfigurableHTTPProxy.should_start = True - -#------------------------------------------------------------------------------ -# NullAuthenticator(Authenticator) configuration -#------------------------------------------------------------------------------ -## Null Authenticator for JupyterHub -# -# For cases where authentication should be disabled, -# e.g. only allowing access via API tokens. -# -# .. versionadded:: 2.0 - -## -# See also: Authenticator.admin_users -# c.NullAuthenticator.admin_users = set() - -## -# See also: Authenticator.allow_all -# c.NullAuthenticator.allow_all = False - -## -# See also: Authenticator.allow_existing_users -# c.NullAuthenticator.allow_existing_users = False - -## -# See also: Authenticator.allowed_users -# c.NullAuthenticator.allowed_users = set() - -## Is there any allow config? -# See also: Authenticator.any_allow_config -# c.NullAuthenticator.any_allow_config = False - -## The max age (in seconds) of authentication info -# See also: Authenticator.auth_refresh_age -# c.NullAuthenticator.auth_refresh_age = 300 - -## -# See also: Authenticator.auto_login_oauth2_authorize -# c.NullAuthenticator.auto_login_oauth2_authorize = False - -## -# See also: Authenticator.blocked_users -# c.NullAuthenticator.blocked_users = set() - -## Delete any users from the database that do not pass validation -# See also: Authenticator.delete_invalid_users -# c.NullAuthenticator.delete_invalid_users = False - -## Enable persisting auth_state (if available). -# See also: Authenticator.enable_auth_state -# c.NullAuthenticator.enable_auth_state = False - -## Let authenticator manage user groups -# See also: Authenticator.manage_groups -# c.NullAuthenticator.manage_groups = False - -## Let authenticator manage roles -# See also: Authenticator.manage_roles -# c.NullAuthenticator.manage_roles = False - -## -# See also: Authenticator.otp_prompt -# c.NullAuthenticator.otp_prompt = 'OTP:' - -## -# See also: Authenticator.post_auth_hook -# c.NullAuthenticator.post_auth_hook = None - -## Force refresh of auth prior to spawn. -# See also: Authenticator.refresh_pre_spawn -# c.NullAuthenticator.refresh_pre_spawn = False - -## -# See also: Authenticator.request_otp -# c.NullAuthenticator.request_otp = False - -## Reset managed roles to result of `load_managed_roles()` on startup. -# See also: Authenticator.reset_managed_roles_on_startup -# c.NullAuthenticator.reset_managed_roles_on_startup = False - -## Dictionary mapping authenticator usernames to JupyterHub users. -# See also: Authenticator.username_map -# c.NullAuthenticator.username_map = {} - -## -# See also: Authenticator.username_pattern -# c.NullAuthenticator.username_pattern = '' - -## Deprecated, use `Authenticator.allowed_users` -# See also: Authenticator.whitelist -# c.NullAuthenticator.whitelist = set() - -#------------------------------------------------------------------------------ -# Spawner(LoggingConfigurable) configuration -#------------------------------------------------------------------------------ -## Base class for spawning single-user notebook servers. -# -# Subclass this, and override the following methods: -# -# - load_state -# - get_state -# - start -# - stop -# - poll -# -# As JupyterHub supports multiple users, an instance of the Spawner subclass -# is created for each user. If there are 20 JupyterHub users, there will be 20 -# instances of the subclass. - -## Extra arguments to be passed to the single-user server. -# -# Some spawners allow shell-style expansion here, allowing you to use -# environment variables here. Most, including the default, do not. Consult the -# documentation for your spawner to verify! -# Default: [] -# c.Spawner.args = [] - -## An optional hook function that you can implement to pass `auth_state` to the -# spawner after it has been initialized but before it starts. The `auth_state` -# dictionary may be set by the `.authenticate()` method of the authenticator. -# This hook enables you to pass some or all of that information to your spawner. -# -# Example:: -# -# def userdata_hook(spawner, auth_state): -# spawner.userdata = auth_state["userdata"] -# -# c.Spawner.auth_state_hook = userdata_hook -# Default: None -# c.Spawner.auth_state_hook = None - -## The command used for starting the single-user server. -# -# Provide either a string or a list containing the path to the startup script -# command. Extra arguments, other than this path, should be provided via `args`. -# -# This is usually set if you want to start the single-user server in a different -# python environment (with virtualenv/conda) than JupyterHub itself. -# -# Some spawners allow shell-style expansion here, allowing you to use -# environment variables. Most, including the default, do not. Consult the -# documentation for your spawner to verify! -# Default: ['jupyterhub-singleuser'] -# c.Spawner.cmd = ['jupyterhub-singleuser'] - -## Maximum number of consecutive failures to allow before shutting down -# JupyterHub. -# -# This helps JupyterHub recover from a certain class of problem preventing -# launch in contexts where the Hub is automatically restarted (e.g. systemd, -# docker, kubernetes). -# -# A limit of 0 means no limit and consecutive failures will not be tracked. -# Default: 0 -# c.Spawner.consecutive_failure_limit = 0 - -## Minimum number of cpu-cores a single-user notebook server is guaranteed to -# have available. -# -# If this value is set to 0.5, allows use of 50% of one CPU. If this value is -# set to 2, allows use of up to 2 CPUs. -# -# **This is a configuration setting. Your spawner must implement support for the -# limit to work.** The default spawner, `LocalProcessSpawner`, does **not** -# implement this support. A custom spawner **must** add support for this setting -# for it to be enforced. -# Default: None -# c.Spawner.cpu_guarantee = None - -## Maximum number of cpu-cores a single-user notebook server is allowed to use. -# -# If this value is set to 0.5, allows use of 50% of one CPU. If this value is -# set to 2, allows use of up to 2 CPUs. -# -# The single-user notebook server will never be scheduled by the kernel to use -# more cpu-cores than this. There is no guarantee that it can access this many -# cpu-cores. -# -# **This is a configuration setting. Your spawner must implement support for the -# limit to work.** The default spawner, `LocalProcessSpawner`, does **not** -# implement this support. A custom spawner **must** add support for this setting -# for it to be enforced. -# Default: None -# c.Spawner.cpu_limit = None - -## Enable debug-logging of the single-user server -# Default: False -# c.Spawner.debug = False - -## The URL the single-user server should start in. -# -# `{username}` will be expanded to the user's username -# -# Example uses: -# -# - You can set `notebook_dir` to `/` and `default_url` to `/tree/home/{username}` to allow people to -# navigate the whole filesystem from their notebook server, but still start in their home directory. -# - Start with `/notebooks` instead of `/tree` if `default_url` points to a notebook instead of a directory. -# - You can set this to `/lab` to have JupyterLab start by default, rather than Jupyter Notebook. -# Default: '' -# c.Spawner.default_url = '' - -## Disable per-user configuration of single-user servers. -# -# When starting the user's single-user server, any config file found in the -# user's $HOME directory will be ignored. -# -# Note: a user could circumvent this if the user modifies their Python -# environment, such as when they have their own conda environments / virtualenvs -# / containers. -# Default: False -# c.Spawner.disable_user_config = False - -## List of environment variables for the single-user server to inherit from the -# JupyterHub process. -# -# This list is used to ensure that sensitive information in the JupyterHub -# process's environment (such as `CONFIGPROXY_AUTH_TOKEN`) is not passed to the -# single-user server's process. -# Default: ['JUPYTERHUB_SINGLEUSER_APP'] -# c.Spawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP'] - -## Extra environment variables to set for the single-user server's process. -# -# Environment variables that end up in the single-user server's process come from 3 sources: -# - This `environment` configurable -# - The JupyterHub process' environment variables that are listed in `env_keep` -# - Variables to establish contact between the single-user notebook and the hub (such as JUPYTERHUB_API_TOKEN) -# -# The `environment` configurable should be set by JupyterHub administrators to -# add installation specific environment variables. It is a dict where the key is -# the name of the environment variable, and the value can be a string or a -# callable. If it is a callable, it will be called with one parameter (the -# spawner instance), and should return a string fairly quickly (no blocking -# operations please!). -# -# Note that the spawner class' interface is not guaranteed to be exactly same -# across upgrades, so if you are using the callable take care to verify it -# continues to work after upgrades! -# -# .. versionchanged:: 1.2 -# environment from this configuration has highest priority, -# allowing override of 'default' env variables, -# such as JUPYTERHUB_API_URL. -# Default: {} -# c.Spawner.environment = {} - -## Override specific traitlets based on group membership of the user. -# -# This can be a dict, or a callable that returns a dict. The keys of the dict -# are *only* used for lexicographical sorting, to guarantee consistent ordering -# of the overrides. If it is a callable, it may be async, and will be passed one -# parameter - the spawner instance. It should return a dictionary. -# -# The values of the dict are dicts with the following keys: -# -# - `"groups"` - If the user belongs to *any* of these groups, these overrides are -# applied to their server before spawning. -# - `"spawner_override"` - a dictionary with overrides to apply to the Spawner -# settings. Each value can be either the final value to change or a callable that -# take the `Spawner` instance as parameter and returns the final value. -# If the traitlet being overriden is a *dictionary*, the dictionary -# will be *recursively updated*, rather than overriden. If you want to -# remove a key, set its value to `None`. -# -# Example: -# -# The following example config will: -# -# 1. Add the environment variable "AM_I_GROUP_ALPHA" to everyone in the "group-alpha" group -# 2. Add the environment variable "AM_I_GROUP_BETA" to everyone in the "group-beta" group. -# If a user is part of both "group-beta" and "group-alpha", they will get *both* these env -# vars, due to the dictionary merging functionality. -# 3. Add a higher memory limit for everyone in the "group-beta" group. -# -# :: -# -# c.Spawner.group_overrides = { -# "01-group-alpha-env-add": { -# "groups": ["group-alpha"], -# "spawner_override": {"environment": {"AM_I_GROUP_ALPHA": "yes"}}, -# }, -# "02-group-beta-env-add": { -# "groups": ["group-beta"], -# "spawner_override": {"environment": {"AM_I_GROUP_BETA": "yes"}}, -# }, -# "03-group-beta-mem-limit": { -# "groups": ["group-beta"], -# "spawner_override": {"mem_limit": "2G"} -# } -# } -# Default: traitlets.Undefined -# c.Spawner.group_overrides = traitlets.Undefined - -## Timeout (in seconds) before giving up on a spawned HTTP server -# -# Once a server has successfully been spawned, this is the amount of time we -# wait before assuming that the server is unable to accept connections. -# Default: 30 -# c.Spawner.http_timeout = 30 - -## The URL the single-user server should connect to the Hub. -# -# If the Hub URL set in your JupyterHub config is not reachable from spawned -# notebooks, you can set differnt URL by this config. -# -# Is None if you don't need to change the URL. -# Default: None -# c.Spawner.hub_connect_url = None - -## The IP address (or hostname) the single-user server should listen on. -# -# Usually either '127.0.0.1' (default) or '0.0.0.0'. -# -# The JupyterHub proxy implementation should be able to send packets to this -# interface. -# -# Subclasses which launch remotely or in containers should override the default -# to '0.0.0.0'. -# -# .. versionchanged:: 2.0 -# Default changed to '127.0.0.1', from ''. -# In most cases, this does not result in a change in behavior, -# as '' was interpreted as 'unspecified', -# which used the subprocesses' own default, itself usually '127.0.0.1'. -# Default: '127.0.0.1' -# c.Spawner.ip = '127.0.0.1' - -## Minimum number of bytes a single-user notebook server is guaranteed to have -# available. -# -# Allows the following suffixes: -# - K -> Kilobytes -# - M -> Megabytes -# - G -> Gigabytes -# - T -> Terabytes -# -# **This is a configuration setting. Your spawner must implement support for the -# limit to work.** The default spawner, `LocalProcessSpawner`, does **not** -# implement this support. A custom spawner **must** add support for this setting -# for it to be enforced. -# Default: None -# c.Spawner.mem_guarantee = None - -## Maximum number of bytes a single-user notebook server is allowed to use. -# -# Allows the following suffixes: -# - K -> Kilobytes -# - M -> Megabytes -# - G -> Gigabytes -# - T -> Terabytes -# -# If the single user server tries to allocate more memory than this, it will -# fail. There is no guarantee that the single-user notebook server will be able -# to allocate this much memory - only that it can not allocate more than this. -# -# **This is a configuration setting. Your spawner must implement support for the -# limit to work.** The default spawner, `LocalProcessSpawner`, does **not** -# implement this support. A custom spawner **must** add support for this setting -# for it to be enforced. -# Default: None -# c.Spawner.mem_limit = None - -## Path to the notebook directory for the single-user server. -# -# The user sees a file listing of this directory when the notebook interface is -# started. The current interface does not easily allow browsing beyond the -# subdirectories in this directory's tree. -# -# `~` will be expanded to the home directory of the user, and {username} will be -# replaced with the name of the user. -# -# Note that this does *not* prevent users from accessing files outside of this -# path! They can do so with many other means. -# Default: '' -c.Spawner.notebook_dir = '' - -## Allowed scopes for oauth tokens issued by this server's oauth client. -# -# This sets the maximum and default scopes -# assigned to oauth tokens issued by a single-user server's -# oauth client (i.e. tokens stored in browsers after authenticating with the server), -# defining what actions the server can take on behalf of logged-in users. -# -# Default is an empty list, meaning minimal permissions to identify users, -# no actions can be taken on their behalf. -# -# If callable, will be called with the Spawner as a single argument. -# Callables may be async. -# Default: traitlets.Undefined -# c.Spawner.oauth_client_allowed_scopes = traitlets.Undefined - -## Allowed roles for oauth tokens. -# -# Deprecated in 3.0: use oauth_client_allowed_scopes -# -# This sets the maximum and default roles -# assigned to oauth tokens issued by a single-user server's -# oauth client (i.e. tokens stored in browsers after authenticating with the server), -# defining what actions the server can take on behalf of logged-in users. -# -# Default is an empty list, meaning minimal permissions to identify users, -# no actions can be taken on their behalf. -# Default: traitlets.Undefined -# c.Spawner.oauth_roles = traitlets.Undefined - -## An HTML form for options a user can specify on launching their server. -# -# The surrounding `<form>` element and the submit button are already provided. -# -# For example: -# -# .. code:: html -# -# Set your key: -# <input name="key" val="default_key"></input> -# <br> -# Choose a letter: -# <select name="letter" multiple="true"> -# <option value="A">The letter A</option> -# <option value="B">The letter B</option> -# </select> -# -# The data from this form submission will be passed on to your spawner in -# `self.user_options` -# -# Instead of a form snippet string, this could also be a callable that takes as -# one parameter the current spawner instance and returns a string. The callable -# will be called asynchronously if it returns a future, rather than a str. Note -# that the interface of the spawner class is not deemed stable across versions, -# so using this functionality might cause your JupyterHub upgrades to break. -# Default: traitlets.Undefined -# c.Spawner.options_form = traitlets.Undefined - -## Interpret HTTP form data -# -# Form data will always arrive as a dict of lists of strings. Override this -# function to understand single-values, numbers, etc. -# -# This should coerce form data into the structure expected by self.user_options, -# which must be a dict, and should be JSON-serializeable, though it can contain -# bytes in addition to standard JSON data types. -# -# This method should not have any side effects. Any handling of `user_options` -# should be done in `.start()` to ensure consistent behavior across servers -# spawned via the API and form submission page. -# -# Instances will receive this data on self.user_options, after passing through -# this function, prior to `Spawner.start`. -# -# .. versionchanged:: 1.0 -# user_options are persisted in the JupyterHub database to be reused -# on subsequent spawns if no options are given. -# user_options is serialized to JSON as part of this persistence -# (with additional support for bytes in case of uploaded file data), -# and any non-bytes non-jsonable values will be replaced with None -# if the user_options are re-used. -# Default: traitlets.Undefined -# c.Spawner.options_from_form = traitlets.Undefined - -## Interval (in seconds) on which to poll the spawner for single-user server's -# status. -# -# At every poll interval, each spawner's `.poll` method is called, which checks -# if the single-user server is still running. If it isn't running, then -# JupyterHub modifies its own state accordingly and removes appropriate routes -# from the configurable proxy. -# Default: 30 -# c.Spawner.poll_interval = 30 - -## Jitter fraction for poll_interval. -# -# Avoids alignment of poll calls for many Spawners, e.g. when restarting -# JupyterHub, which restarts all polls for running Spawners. -# -# `poll_jitter=0` means no jitter, 0.1 means 10%, etc. -# Default: 0.1 -# c.Spawner.poll_jitter = 0.1 - -## The port for single-user servers to listen on. -# -# Defaults to `0`, which uses a randomly allocated port number each time. -# -# If set to a non-zero value, all Spawners will use the same port, which only -# makes sense if each server is on a different address, e.g. in containers. -# -# New in version 0.7. -# Default: 0 -# c.Spawner.port = 0 - -## An optional hook function that you can implement to do work after the spawner -# stops. -# -# This can be set independent of any concrete spawner implementation. -# Default: None -# c.Spawner.post_stop_hook = None - -## An optional hook function that you can implement to do some bootstrapping work -# before the spawner starts. For example, create a directory for your user or -# load initial content. -# -# This can be set independent of any concrete spawner implementation. -# -# This maybe a coroutine. -# -# Example:: -# -# def my_hook(spawner): -# username = spawner.user.name -# spawner.environment["GREETING"] = f"Hello {username}" -# -# c.Spawner.pre_spawn_hook = my_hook -# Default: None -# c.Spawner.pre_spawn_hook = None - -## An optional hook function that you can implement to modify the ready event, -# which will be shown to the user on the spawn progress page when their server -# is ready. -# -# This can be set independent of any concrete spawner implementation. -# -# This maybe a coroutine. -# -# Example:: -# -# async def my_ready_hook(spawner, ready_event): -# ready_event["html_message"] = f"Server {spawner.name} is ready for {spawner.user.name}" -# return ready_event -# -# c.Spawner.progress_ready_hook = my_ready_hook -# Default: None -# c.Spawner.progress_ready_hook = None - -## The list of scopes to request for $JUPYTERHUB_API_TOKEN -# -# If not specified, the scopes in the `server` role will be used -# (unchanged from pre-4.0). -# -# If callable, will be called with the Spawner instance as its sole argument -# (JupyterHub user available as spawner.user). -# -# JUPYTERHUB_API_TOKEN will be assigned the _subset_ of these scopes -# that are held by the user (as in oauth_client_allowed_scopes). -# -# .. versionadded:: 4.0 -# Default: traitlets.Undefined -# c.Spawner.server_token_scopes = traitlets.Undefined - -## List of SSL alt names -# -# May be set in config if all spawners should have the same value(s), -# or set at runtime by Spawner that know their names. -# Default: [] -# c.Spawner.ssl_alt_names = [] - -## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names -# Default: True -# c.Spawner.ssl_alt_names_include_local = True - -## Timeout (in seconds) before giving up on starting of single-user server. -# -# This is the timeout for start to return, not the timeout for the server to -# respond. Callers of spawner.start will assume that startup has failed if it -# takes longer than this. start should return when the server process is started -# and its location is known. -# Default: 60 -# c.Spawner.start_timeout = 60 - -#------------------------------------------------------------------------------ -# LocalProcessSpawner(Spawner) configuration -#------------------------------------------------------------------------------ -## A Spawner that uses `subprocess.Popen` to start single-user servers as local -# processes. -# -# Requires local UNIX users matching the authenticated users to exist. Does not -# work on Windows. -# -# This is the default spawner for JupyterHub. -# -# Note: This spawner does not implement CPU / memory guarantees and limits. - -## -# See also: Spawner.args -# c.LocalProcessSpawner.args = [] - -## -# See also: Spawner.auth_state_hook -# c.LocalProcessSpawner.auth_state_hook = None - -## -# See also: Spawner.cmd -# c.LocalProcessSpawner.cmd = ['jupyterhub-singleuser'] - -## -# See also: Spawner.consecutive_failure_limit -# c.LocalProcessSpawner.consecutive_failure_limit = 0 - -## -# See also: Spawner.cpu_guarantee -# c.LocalProcessSpawner.cpu_guarantee = None - -## -# See also: Spawner.cpu_limit -# c.LocalProcessSpawner.cpu_limit = None - -## Enable debug-logging of the single-user server -# See also: Spawner.debug -# c.LocalProcessSpawner.debug = False - -## -# See also: Spawner.default_url -# c.LocalProcessSpawner.default_url = '' - -## -# See also: Spawner.disable_user_config -# c.LocalProcessSpawner.disable_user_config = False - -## -# See also: Spawner.env_keep -# c.LocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP'] - -## -# See also: Spawner.environment -# c.LocalProcessSpawner.environment = {} - -## -# See also: Spawner.group_overrides -# c.LocalProcessSpawner.group_overrides = traitlets.Undefined - -## -# See also: Spawner.http_timeout -# c.LocalProcessSpawner.http_timeout = 30 - -## -# See also: Spawner.hub_connect_url -# c.LocalProcessSpawner.hub_connect_url = None - -## Seconds to wait for single-user server process to halt after SIGINT. -# -# If the process has not exited cleanly after this many seconds, a SIGTERM is -# sent. -# Default: 10 -# c.LocalProcessSpawner.interrupt_timeout = 10 - -## -# See also: Spawner.ip -# c.LocalProcessSpawner.ip = '127.0.0.1' - -## Seconds to wait for process to halt after SIGKILL before giving up. -# -# If the process does not exit cleanly after this many seconds of SIGKILL, it -# becomes a zombie process. The hub process will log a warning and then give up. -# Default: 5 -# c.LocalProcessSpawner.kill_timeout = 5 - -## -# See also: Spawner.mem_guarantee -# c.LocalProcessSpawner.mem_guarantee = None - -## -# See also: Spawner.mem_limit -# c.LocalProcessSpawner.mem_limit = None - -## -# See also: Spawner.notebook_dir -# c.LocalProcessSpawner.notebook_dir = '' - -## Allowed scopes for oauth tokens issued by this server's oauth client. -# See also: Spawner.oauth_client_allowed_scopes -# c.LocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined - -## Allowed roles for oauth tokens. -# See also: Spawner.oauth_roles -# c.LocalProcessSpawner.oauth_roles = traitlets.Undefined - -## -# See also: Spawner.options_form -# c.LocalProcessSpawner.options_form = traitlets.Undefined - -## -# See also: Spawner.options_from_form -# c.LocalProcessSpawner.options_from_form = traitlets.Undefined - -## -# See also: Spawner.poll_interval -# c.LocalProcessSpawner.poll_interval = 30 - -## -# See also: Spawner.poll_jitter -# c.LocalProcessSpawner.poll_jitter = 0.1 -## Extra keyword arguments to pass to Popen +#------------------------------------------------------------------------------ +# Proxy(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ +## Base class for configurable proxies that JupyterHub can use. # -# when spawning single-user servers. +# A proxy implementation should subclass this and must define the following +# methods: # -# For example:: +# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes +# - :meth:`.add_route` adds a route +# - :meth:`.delete_route` deletes a route # -# popen_kwargs = dict(shell=True) -# Default: {} -# c.LocalProcessSpawner.popen_kwargs = {} - -## -# See also: Spawner.port -# c.LocalProcessSpawner.port = 0 - -## -# See also: Spawner.post_stop_hook -# c.LocalProcessSpawner.post_stop_hook = None - -## -# See also: Spawner.pre_spawn_hook -# c.LocalProcessSpawner.pre_spawn_hook = None - -## -# See also: Spawner.progress_ready_hook -# c.LocalProcessSpawner.progress_ready_hook = None - -## The list of scopes to request for $JUPYTERHUB_API_TOKEN -# See also: Spawner.server_token_scopes -# c.LocalProcessSpawner.server_token_scopes = traitlets.Undefined - -## Specify a shell command to launch. +# In addition to these, the following method(s) may need to be implemented: # -# The single-user command will be appended to this list, -# so it sould end with `-c` (for bash) or equivalent. +# - :meth:`.start` start the proxy, if it should be launched by the Hub +# instead of externally managed. +# If the proxy is externally managed, it should set :attr:`should_start` to False. +# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used. # -# For example:: +# And the following method(s) are optional, but can be provided: # -# c.LocalProcessSpawner.shell_cmd = ['bash', '-l', '-c'] +# - :meth:`.get_route` gets a single route. +# There is a default implementation that extracts data from :meth:`.get_all_routes`, +# but implementations may choose to provide a more efficient implementation +# of fetching a single route. + +## Additional routes to be maintained in the proxy. # -# to launch with a bash login shell, which would set up the user's own -# complete environment. +# A dictionary with a route specification as key, and a URL as target. The hub +# will ensure this route is present in the proxy. # -# .. warning:: +# If the hub is running in host based mode (with JupyterHub.subdomain_host set), +# the routespec *must* have a domain component (example.com/my-url/). If the hub +# is not running in host based mode, the routespec *must not* have a domain +# component (/my-url/). # -# Using shell_cmd gives users control over PATH, etc., -# which could change what the jupyterhub-singleuser launch command does. -# Only use this for trusted users. -# Default: [] -# c.LocalProcessSpawner.shell_cmd = [] - -## List of SSL alt names -# See also: Spawner.ssl_alt_names -# c.LocalProcessSpawner.ssl_alt_names = [] - -## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names -# See also: Spawner.ssl_alt_names_include_local -# c.LocalProcessSpawner.ssl_alt_names_include_local = True - -## -# See also: Spawner.start_timeout -# c.LocalProcessSpawner.start_timeout = 60 +# Helpful when the hub is running in API-only mode. +# Default: {} +# c.Proxy.extra_routes = {} -## Seconds to wait for single-user server process to halt after SIGTERM. +## Should the Hub start the proxy # -# If the process does not exit cleanly after this many seconds of SIGTERM, a -# SIGKILL is sent. -# Default: 5 -# c.LocalProcessSpawner.term_timeout = 5 +# If True, the Hub will start the proxy and stop it. +# Set to False if the proxy is managed externally, +# such as by systemd, docker, or another service manager. +# Default: True +# c.Proxy.should_start = True #------------------------------------------------------------------------------ -# LocalAuthenticator(Authenticator) configuration +# ConfigurableHTTPProxy(Proxy) configuration #------------------------------------------------------------------------------ -## Base class for Authenticators that work with local Linux/UNIX users -# -# Checks for local users, and can attempt to create them if they exist. - -## The command to use for creating users as a list of strings -# -# For each element in the list, the string USERNAME will be replaced with the -# user's username. The username will also be appended as the final argument. -# -# For Linux, the default value is: -# -# ['adduser', '-q', '--gecos', '""', '--disabled-password'] -# -# To specify a custom home directory, set this to: -# -# ['adduser', '-q', '--gecos', '""', '--home', '/customhome/USERNAME', '-- -# disabled-password'] +## Proxy implementation for the default configurable-http-proxy. # -# This will run the command: +# This is the default proxy implementation +# for running the nodejs proxy `configurable-http-proxy`. # -# adduser -q --gecos "" --home /customhome/river --disabled-password river +# If the proxy should not be run as a subprocess of the Hub, +# (e.g. in a separate container), +# set:: # -# when the user 'river' is created. -# Default: [] -# c.LocalAuthenticator.add_user_cmd = [] - -## -# See also: Authenticator.admin_users -# c.LocalAuthenticator.admin_users = set() - -## -# See also: Authenticator.allow_all -# c.LocalAuthenticator.allow_all = False +# c.ConfigurableHTTPProxy.should_start = False -## -# See also: Authenticator.allow_existing_users -# c.LocalAuthenticator.allow_existing_users = False +## The ip (or hostname) of the proxy's API endpoint +# Default: '' +# c.ConfigurableHTTPProxy.api_url = '' -## Allow login from all users in these UNIX groups. +## The Proxy auth token # -# .. versionchanged:: 5.0 -# `allowed_groups` may be specified together with allowed_users, -# to grant access by group OR name. -# Default: set() -# c.LocalAuthenticator.allowed_groups = set() - -## -# See also: Authenticator.allowed_users -# c.LocalAuthenticator.allowed_users = set() - -## Is there any allow config? -# See also: Authenticator.any_allow_config -# c.LocalAuthenticator.any_allow_config = False - -## The max age (in seconds) of authentication info -# See also: Authenticator.auth_refresh_age -# c.LocalAuthenticator.auth_refresh_age = 300 - -## Automatically begin the login process -# See also: Authenticator.auto_login -# c.LocalAuthenticator.auto_login = False +# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. +# Default: '' +# c.ConfigurableHTTPProxy.auth_token = '' -## -# See also: Authenticator.auto_login_oauth2_authorize -# c.LocalAuthenticator.auto_login_oauth2_authorize = False +## Interval (in seconds) at which to check if the proxy is running. +# Default: 5 +# c.ConfigurableHTTPProxy.check_running_interval = 5 -## -# See also: Authenticator.blocked_users -# c.LocalAuthenticator.blocked_users = set() +## The command to start the proxy +# Default: ['configurable-http-proxy'] +# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy'] -## If set to True, will attempt to create local system users if they do not exist -# already. +## The number of requests allowed to be concurrently outstanding to the proxy # -# Supports Linux and BSD variants only. -# Default: False -# c.LocalAuthenticator.create_system_users = False - -## Delete any users from the database that do not pass validation -# See also: Authenticator.delete_invalid_users -# c.LocalAuthenticator.delete_invalid_users = False - -## Enable persisting auth_state (if available). -# See also: Authenticator.enable_auth_state -# c.LocalAuthenticator.enable_auth_state = False - -## DEPRECATED: use allowed_groups -# Default: set() -# c.LocalAuthenticator.group_whitelist = set() - -## Let authenticator manage user groups -# See also: Authenticator.manage_groups -# c.LocalAuthenticator.manage_groups = False - -## Let authenticator manage roles -# See also: Authenticator.manage_roles -# c.LocalAuthenticator.manage_roles = False - -## -# See also: Authenticator.otp_prompt -# c.LocalAuthenticator.otp_prompt = 'OTP:' - -## -# See also: Authenticator.post_auth_hook -# c.LocalAuthenticator.post_auth_hook = None +# Limiting this number avoids potential timeout errors by sending too many +# requests to update the proxy at once +# Default: 10 +# c.ConfigurableHTTPProxy.concurrency = 10 -## Force refresh of auth prior to spawn. -# See also: Authenticator.refresh_pre_spawn -# c.LocalAuthenticator.refresh_pre_spawn = False +## Add debug-level logging to the Proxy. +# Default: False +# c.ConfigurableHTTPProxy.debug = False ## -# See also: Authenticator.request_otp -# c.LocalAuthenticator.request_otp = False - -## Reset managed roles to result of `load_managed_roles()` on startup. -# See also: Authenticator.reset_managed_roles_on_startup -# c.LocalAuthenticator.reset_managed_roles_on_startup = False - -## Dictionary of uids to use at user creation time. This helps ensure that users -# created from the database get the same uid each time they are created in -# temporary deployments or containers. -# Default: {} -# c.LocalAuthenticator.uids = {} +# See also: Proxy.extra_routes +# c.ConfigurableHTTPProxy.extra_routes = {} -## Dictionary mapping authenticator usernames to JupyterHub users. -# See also: Authenticator.username_map -# c.LocalAuthenticator.username_map = {} +## Proxy log level +# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive) +# Default: 'info' +# c.ConfigurableHTTPProxy.log_level = 'info' -## -# See also: Authenticator.username_pattern -# c.LocalAuthenticator.username_pattern = '' +## File in which to write the PID of the proxy process. +# Default: 'jupyterhub-proxy.pid' +# c.ConfigurableHTTPProxy.pid_file = 'jupyterhub-proxy.pid' -## Deprecated, use `Authenticator.allowed_users` -# See also: Authenticator.whitelist -# c.LocalAuthenticator.whitelist = set() +## Should the Hub start the proxy +# See also: Proxy.should_start +# c.ConfigurableHTTPProxy.should_start = Tru #------------------------------------------------------------------------------ # PAMAuthenticator(LocalAuthenticator) configuration @@ -2649,166 +1282,32 @@ c.Spawner.notebook_dir = '' # See also: Authenticator.whitelist # c.PAMAuthenticator.whitelist = set() -#------------------------------------------------------------------------------ -# SimpleLocalProcessSpawner(LocalProcessSpawner) configuration -#------------------------------------------------------------------------------ -## A version of LocalProcessSpawner that doesn't require users to exist on the -# system beforehand. -# -# Only use this for testing. -# -# Note: DO NOT USE THIS FOR PRODUCTION USE CASES! It is very insecure, and -# provides absolutely no isolation between different users! - -## -# See also: Spawner.args -# c.SimpleLocalProcessSpawner.args = [] - -## -# See also: Spawner.auth_state_hook -# c.SimpleLocalProcessSpawner.auth_state_hook = None - -## -# See also: Spawner.cmd -# c.SimpleLocalProcessSpawner.cmd = ['jupyterhub-singleuser'] - -## -# See also: Spawner.consecutive_failure_limit -# c.SimpleLocalProcessSpawner.consecutive_failure_limit = 0 - -## -# See also: Spawner.cpu_guarantee -# c.SimpleLocalProcessSpawner.cpu_guarantee = None - -## -# See also: Spawner.cpu_limit -# c.SimpleLocalProcessSpawner.cpu_limit = None - -## Enable debug-logging of the single-user server -# See also: Spawner.debug -# c.SimpleLocalProcessSpawner.debug = False - -## -# See also: Spawner.default_url -# c.SimpleLocalProcessSpawner.default_url = '' - -## -# See also: Spawner.disable_user_config -# c.SimpleLocalProcessSpawner.disable_user_config = False - -## -# See also: Spawner.env_keep -# c.SimpleLocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP'] - -## -# See also: Spawner.environment -# c.SimpleLocalProcessSpawner.environment = {} - -## -# See also: Spawner.group_overrides -# c.SimpleLocalProcessSpawner.group_overrides = traitlets.Undefined - -## Template to expand to set the user home. {username} is expanded to the -# jupyterhub username. -# Default: '/tmp/{username}' -# c.SimpleLocalProcessSpawner.home_dir_template = '/tmp/{username}' - -## -# See also: Spawner.http_timeout -# c.SimpleLocalProcessSpawner.http_timeout = 30 - -## -# See also: Spawner.hub_connect_url -# c.SimpleLocalProcessSpawner.hub_connect_url = None - -## -# See also: LocalProcessSpawner.interrupt_timeout -# c.SimpleLocalProcessSpawner.interrupt_timeout = 10 - -## -# See also: Spawner.ip -# c.SimpleLocalProcessSpawner.ip = '127.0.0.1' - -## -# See also: LocalProcessSpawner.kill_timeout -# c.SimpleLocalProcessSpawner.kill_timeout = 5 - -## -# See also: Spawner.mem_guarantee -# c.SimpleLocalProcessSpawner.mem_guarantee = None - -## -# See also: Spawner.mem_limit -# c.SimpleLocalProcessSpawner.mem_limit = None - -## -# See also: Spawner.notebook_dir -# c.SimpleLocalProcessSpawner.notebook_dir = '' - -## Allowed scopes for oauth tokens issued by this server's oauth client. -# See also: Spawner.oauth_client_allowed_scopes -# c.SimpleLocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined - -## Allowed roles for oauth tokens. -# See also: Spawner.oauth_roles -# c.SimpleLocalProcessSpawner.oauth_roles = traitlets.Undefined - -## -# See also: Spawner.options_form -# c.SimpleLocalProcessSpawner.options_form = traitlets.Undefined - -## -# See also: Spawner.options_from_form -# c.SimpleLocalProcessSpawner.options_from_form = traitlets.Undefined - -## -# See also: Spawner.poll_interval -# c.SimpleLocalProcessSpawner.poll_interval = 30 - -## -# See also: Spawner.poll_jitter -# c.SimpleLocalProcessSpawner.poll_jitter = 0.1 - -## Extra keyword arguments to pass to Popen -# See also: LocalProcessSpawner.popen_kwargs -# c.SimpleLocalProcessSpawner.popen_kwargs = {} -## -# See also: Spawner.port -# c.SimpleLocalProcessSpawner.port = 0 - -## -# See also: Spawner.post_stop_hook -# c.SimpleLocalProcessSpawner.post_stop_hook = None - -## -# See also: Spawner.pre_spawn_hook -# c.SimpleLocalProcessSpawner.pre_spawn_hook = None +## DockerSpawner Config -## -# See also: Spawner.progress_ready_hook -# c.SimpleLocalProcessSpawner.progress_ready_hook = None +import os -## The list of scopes to request for $JUPYTERHUB_API_TOKEN -# See also: Spawner.server_token_scopes -# c.SimpleLocalProcessSpawner.server_token_scopes = traitlets.Undefined +# Spawn containers from this image +c.DockerSpawner.image = os.environ["DOCKER_NOTEBOOK_IMAGE"] -## Specify a shell command to launch. -# See also: LocalProcessSpawner.shell_cmd -# c.SimpleLocalProcessSpawner.shell_cmd = [] +# Connect containers to this Docker network +network_name = os.environ["DOCKER_NETWORK_NAME"] +c.DockerSpawner.use_internal_ip = True +c.DockerSpawner.network_name = network_name -## List of SSL alt names -# See also: Spawner.ssl_alt_names -# c.SimpleLocalProcessSpawner.ssl_alt_names = [] +# Explicitly set notebook directory because we'll be mounting a volume to it. +# Most `jupyter/docker-stacks` *-notebook images run the Notebook server as +# user `jovyan`, and set the notebook directory to `/home/jovyan/work`. +# We follow the same convention. +notebook_dir = os.environ.get("DOCKER_NOTEBOOK_DIR", "/home/jovyan/work") +c.DockerSpawner.notebook_dir = notebook_dir -## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names -# See also: Spawner.ssl_alt_names_include_local -# c.SimpleLocalProcessSpawner.ssl_alt_names_include_local = True +# Mount the real user's Docker volume on the host to the notebook user's +# notebook directory in the container +c.DockerSpawner.volumes = {"jupyterhub-user-{username}": notebook_dir} -## -# See also: Spawner.start_timeout -# c.SimpleLocalProcessSpawner.start_timeout = 60 +# Remove containers once they are stopped +c.DockerSpawner.remove = True -## -# See also: LocalProcessSpawner.term_timeout -# c.SimpleLocalProcessSpawner.term_timeout = 5 +# For debugging arguments passed to spawned containers +c.DockerSpawner.debug = True