mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-15 05:53:00 +00:00
use traitlets-4.1 .tag(config=True)
API
This commit is contained in:
@@ -175,66 +175,65 @@ class JupyterHub(Application):
|
|||||||
PAMAuthenticator,
|
PAMAuthenticator,
|
||||||
])
|
])
|
||||||
|
|
||||||
config_file = Unicode('jupyterhub_config.py', config=True,
|
config_file = Unicode('jupyterhub_config.py',
|
||||||
help="The config file to load",
|
help="The config file to load",
|
||||||
)
|
).tag(config=True)
|
||||||
generate_config = Bool(False, config=True,
|
generate_config = Bool(False,
|
||||||
help="Generate default config file",
|
help="Generate default config file",
|
||||||
)
|
).tag(config=True)
|
||||||
answer_yes = Bool(False, config=True,
|
answer_yes = Bool(False,
|
||||||
help="Answer yes to any questions (e.g. confirm overwrite)"
|
help="Answer yes to any questions (e.g. confirm overwrite)"
|
||||||
)
|
).tag(config=True)
|
||||||
pid_file = Unicode('', config=True,
|
pid_file = Unicode('',
|
||||||
help="""File to write PID
|
help="""File to write PID
|
||||||
Useful for daemonizing jupyterhub.
|
Useful for daemonizing jupyterhub.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
cookie_max_age_days = Float(14, config=True,
|
cookie_max_age_days = Float(14,
|
||||||
help="""Number of days for a login cookie to be valid.
|
help="""Number of days for a login cookie to be valid.
|
||||||
Default is two weeks.
|
Default is two weeks.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
last_activity_interval = Integer(300, config=True,
|
last_activity_interval = Integer(300,
|
||||||
help="Interval (in seconds) at which to update last-activity timestamps."
|
help="Interval (in seconds) at which to update last-activity timestamps."
|
||||||
)
|
).tag(config=True)
|
||||||
proxy_check_interval = Integer(30, config=True,
|
proxy_check_interval = Integer(30,
|
||||||
help="Interval (in seconds) at which to check if the proxy is running."
|
help="Interval (in seconds) at which to check if the proxy is running."
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
data_files_path = Unicode(DATA_FILES_PATH, config=True,
|
data_files_path = Unicode(DATA_FILES_PATH,
|
||||||
help="The location of jupyterhub data files (e.g. /usr/local/share/jupyter/hub)"
|
help="The location of jupyterhub data files (e.g. /usr/local/share/jupyter/hub)"
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
template_paths = List(
|
template_paths = List(
|
||||||
config=True,
|
|
||||||
help="Paths to search for jinja templates.",
|
help="Paths to search for jinja templates.",
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
def _template_paths_default(self):
|
def _template_paths_default(self):
|
||||||
return [os.path.join(self.data_files_path, 'templates')]
|
return [os.path.join(self.data_files_path, 'templates')]
|
||||||
|
|
||||||
confirm_no_ssl = Bool(False, config=True,
|
confirm_no_ssl = Bool(False,
|
||||||
help="""Confirm that JupyterHub should be run without SSL.
|
help="""Confirm that JupyterHub should be run without SSL.
|
||||||
This is **NOT RECOMMENDED** unless SSL termination is being handled by another layer.
|
This is **NOT RECOMMENDED** unless SSL termination is being handled by another layer.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
ssl_key = Unicode('', config=True,
|
ssl_key = Unicode('',
|
||||||
help="""Path to SSL key file for the public facing interface of the proxy
|
help="""Path to SSL key file for the public facing interface of the proxy
|
||||||
|
|
||||||
Use with ssl_cert
|
Use with ssl_cert
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
ssl_cert = Unicode('', config=True,
|
ssl_cert = Unicode('',
|
||||||
help="""Path to SSL certificate file for the public facing interface of the proxy
|
help="""Path to SSL certificate file for the public facing interface of the proxy
|
||||||
|
|
||||||
Use with ssl_key
|
Use with ssl_key
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
ip = Unicode('', config=True,
|
ip = Unicode('',
|
||||||
help="The public facing ip of the whole application (the proxy)"
|
help="The public facing ip of the whole application (the proxy)"
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
subdomain_host = Unicode('', config=True,
|
subdomain_host = Unicode('',
|
||||||
help="""Run single-user servers on subdomains of this host.
|
help="""Run single-user servers on subdomains of this host.
|
||||||
|
|
||||||
This should be the full https://hub.domain.tld[:port]
|
This should be the full https://hub.domain.tld[:port]
|
||||||
@@ -246,42 +245,45 @@ class JupyterHub(Application):
|
|||||||
In general, this is most easily achieved with wildcard DNS.
|
In general, this is most easily achieved with wildcard DNS.
|
||||||
|
|
||||||
When using SSL (i.e. always) this also requires a wildcard SSL certificate.
|
When using SSL (i.e. always) this also requires a wildcard SSL certificate.
|
||||||
""")
|
"""
|
||||||
|
).tag(config=True)
|
||||||
def _subdomain_host_changed(self, name, old, new):
|
def _subdomain_host_changed(self, name, old, new):
|
||||||
if new and '://' not in new:
|
if new and '://' not in new:
|
||||||
# host should include '://'
|
# host should include '://'
|
||||||
# if not specified, assume https: You have to be really explicit about HTTP!
|
# if not specified, assume https: You have to be really explicit about HTTP!
|
||||||
self.subdomain_host = 'https://' + new
|
self.subdomain_host = 'https://' + new
|
||||||
|
|
||||||
port = Integer(8000, config=True,
|
port = Integer(8000,
|
||||||
help="The public facing port of the proxy"
|
help="The public facing port of the proxy"
|
||||||
)
|
).tag(config=True)
|
||||||
base_url = URLPrefix('/', config=True,
|
base_url = URLPrefix('/',
|
||||||
help="The base URL of the entire application"
|
help="The base URL of the entire application"
|
||||||
)
|
).tag(config=True)
|
||||||
logo_file = Unicode('', config=True,
|
logo_file = Unicode('',
|
||||||
help="Specify path to a logo image to override the Jupyter logo in the banner."
|
help="Specify path to a logo image to override the Jupyter logo in the banner."
|
||||||
)
|
).tag(config=True)
|
||||||
def _logo_file_default(self):
|
def _logo_file_default(self):
|
||||||
return os.path.join(self.data_files_path, 'static', 'images', 'jupyter.png')
|
return os.path.join(self.data_files_path, 'static', 'images', 'jupyter.png')
|
||||||
|
|
||||||
jinja_environment_options = Dict(config=True,
|
jinja_environment_options = Dict(
|
||||||
help="Supply extra arguments that will be passed to Jinja environment."
|
help="Supply extra arguments that will be passed to Jinja environment."
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
proxy_cmd = Command('configurable-http-proxy', config=True,
|
proxy_cmd = Command('configurable-http-proxy',
|
||||||
help="""The command to start the http proxy.
|
help="""The command to start the http proxy.
|
||||||
|
|
||||||
Only override if configurable-http-proxy is not on your PATH
|
Only override if configurable-http-proxy is not on your PATH
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
debug_proxy = Bool(False, config=True, help="show debug output in configurable-http-proxy")
|
debug_proxy = Bool(False,
|
||||||
proxy_auth_token = Unicode(config=True,
|
help="show debug output in configurable-http-proxy"
|
||||||
|
).tag(config=True)
|
||||||
|
proxy_auth_token = Unicode(
|
||||||
help="""The Proxy Auth token.
|
help="""The Proxy Auth token.
|
||||||
|
|
||||||
Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default.
|
Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
def _proxy_auth_token_default(self):
|
def _proxy_auth_token_default(self):
|
||||||
token = os.environ.get('CONFIGPROXY_AUTH_TOKEN', None)
|
token = os.environ.get('CONFIGPROXY_AUTH_TOKEN', None)
|
||||||
if not token:
|
if not token:
|
||||||
@@ -294,24 +296,24 @@ class JupyterHub(Application):
|
|||||||
token = orm.new_token()
|
token = orm.new_token()
|
||||||
return token
|
return token
|
||||||
|
|
||||||
proxy_api_ip = Unicode('127.0.0.1', config=True,
|
proxy_api_ip = Unicode('127.0.0.1',
|
||||||
help="The ip for the proxy API handlers"
|
help="The ip for the proxy API handlers"
|
||||||
)
|
).tag(config=True)
|
||||||
proxy_api_port = Integer(config=True,
|
proxy_api_port = Integer(
|
||||||
help="The port for the proxy API handlers"
|
help="The port for the proxy API handlers"
|
||||||
)
|
).tag(config=True)
|
||||||
def _proxy_api_port_default(self):
|
def _proxy_api_port_default(self):
|
||||||
return self.port + 1
|
return self.port + 1
|
||||||
|
|
||||||
hub_port = Integer(8081, config=True,
|
hub_port = Integer(8081,
|
||||||
help="The port for this process"
|
help="The port for this process"
|
||||||
)
|
).tag(config=True)
|
||||||
hub_ip = Unicode('127.0.0.1', config=True,
|
hub_ip = Unicode('127.0.0.1',
|
||||||
help="The ip for this process"
|
help="The ip for this process"
|
||||||
)
|
).tag(config=True)
|
||||||
hub_prefix = URLPrefix('/hub/', config=True,
|
hub_prefix = URLPrefix('/hub/',
|
||||||
help="The prefix for the hub server. Must not be '/'"
|
help="The prefix for the hub server. Must not be '/'"
|
||||||
)
|
).tag(config=True)
|
||||||
def _hub_prefix_default(self):
|
def _hub_prefix_default(self):
|
||||||
return url_path_join(self.base_url, '/hub/')
|
return url_path_join(self.base_url, '/hub/')
|
||||||
|
|
||||||
@@ -321,19 +323,18 @@ class JupyterHub(Application):
|
|||||||
if not new.startswith(self.base_url):
|
if not new.startswith(self.base_url):
|
||||||
self.hub_prefix = url_path_join(self.base_url, new)
|
self.hub_prefix = url_path_join(self.base_url, new)
|
||||||
|
|
||||||
cookie_secret = Bytes(config=True, env='JPY_COOKIE_SECRET',
|
cookie_secret = Bytes(env='JPY_COOKIE_SECRET',
|
||||||
help="""The cookie secret to use to encrypt cookies.
|
help="""The cookie secret to use to encrypt cookies.
|
||||||
|
|
||||||
Loaded from the JPY_COOKIE_SECRET env variable by default.
|
Loaded from the JPY_COOKIE_SECRET env variable by default.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
cookie_secret_file = Unicode('jupyterhub_cookie_secret', config=True,
|
cookie_secret_file = Unicode('jupyterhub_cookie_secret',
|
||||||
help="""File in which to store the cookie secret."""
|
help="""File in which to store the cookie secret."""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
authenticator_class = Type(PAMAuthenticator, Authenticator,
|
authenticator_class = Type(PAMAuthenticator, Authenticator,
|
||||||
config=True,
|
|
||||||
help="""Class for authenticating users.
|
help="""Class for authenticating users.
|
||||||
|
|
||||||
This should be a class with the following form:
|
This should be a class with the following form:
|
||||||
@@ -346,7 +347,7 @@ class JupyterHub(Application):
|
|||||||
where `handler` is the calling web.RequestHandler,
|
where `handler` is the calling web.RequestHandler,
|
||||||
and `data` is the POST form data from the login page.
|
and `data` is the POST form data from the login page.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
authenticator = Instance(Authenticator)
|
authenticator = Instance(Authenticator)
|
||||||
def _authenticator_default(self):
|
def _authenticator_default(self):
|
||||||
@@ -354,33 +355,32 @@ class JupyterHub(Application):
|
|||||||
|
|
||||||
# class for spawning single-user servers
|
# class for spawning single-user servers
|
||||||
spawner_class = Type(LocalProcessSpawner, Spawner,
|
spawner_class = Type(LocalProcessSpawner, Spawner,
|
||||||
config=True,
|
|
||||||
help="""The class to use for spawning single-user servers.
|
help="""The class to use for spawning single-user servers.
|
||||||
|
|
||||||
Should be a subclass of Spawner.
|
Should be a subclass of Spawner.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
db_url = Unicode('sqlite:///jupyterhub.sqlite', config=True,
|
db_url = Unicode('sqlite:///jupyterhub.sqlite',
|
||||||
help="url for the database. e.g. `sqlite:///jupyterhub.sqlite`"
|
help="url for the database. e.g. `sqlite:///jupyterhub.sqlite`"
|
||||||
)
|
).tag(config=True)
|
||||||
def _db_url_changed(self, name, old, new):
|
def _db_url_changed(self, name, old, new):
|
||||||
if '://' not in new:
|
if '://' not in new:
|
||||||
# assume sqlite, if given as a plain filename
|
# assume sqlite, if given as a plain filename
|
||||||
self.db_url = 'sqlite:///%s' % new
|
self.db_url = 'sqlite:///%s' % new
|
||||||
|
|
||||||
db_kwargs = Dict(config=True,
|
db_kwargs = Dict(
|
||||||
help="""Include any kwargs to pass to the database connection.
|
help="""Include any kwargs to pass to the database connection.
|
||||||
See sqlalchemy.create_engine for details.
|
See sqlalchemy.create_engine for details.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
reset_db = Bool(False, config=True,
|
reset_db = Bool(False,
|
||||||
help="Purge and reset the database."
|
help="Purge and reset the database."
|
||||||
)
|
).tag(config=True)
|
||||||
debug_db = Bool(False, config=True,
|
debug_db = Bool(False,
|
||||||
help="log all database transactions. This has A LOT of output"
|
help="log all database transactions. This has A LOT of output"
|
||||||
)
|
).tag(config=True)
|
||||||
session_factory = Any()
|
session_factory = Any()
|
||||||
|
|
||||||
users = Instance(UserDict)
|
users = Instance(UserDict)
|
||||||
@@ -388,19 +388,21 @@ class JupyterHub(Application):
|
|||||||
assert self.tornado_settings
|
assert self.tornado_settings
|
||||||
return UserDict(db_factory=lambda : self.db, settings=self.tornado_settings)
|
return UserDict(db_factory=lambda : self.db, settings=self.tornado_settings)
|
||||||
|
|
||||||
admin_access = Bool(False, config=True,
|
admin_access = Bool(False,
|
||||||
help="""Grant admin users permission to access single-user servers.
|
help="""Grant admin users permission to access single-user servers.
|
||||||
|
|
||||||
Users should be properly informed if this is enabled.
|
Users should be properly informed if this is enabled.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
admin_users = Set(config=True,
|
admin_users = Set(
|
||||||
help="""DEPRECATED, use Authenticator.admin_users instead."""
|
help="""DEPRECATED, use Authenticator.admin_users instead."""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
tornado_settings = Dict(config=True)
|
tornado_settings = Dict(
|
||||||
|
help="Extra settings overrides to pass to the tornado application."
|
||||||
|
).tag(config=True)
|
||||||
|
|
||||||
cleanup_servers = Bool(True, config=True,
|
cleanup_servers = Bool(True,
|
||||||
help="""Whether to shutdown single-user servers when the Hub shuts down.
|
help="""Whether to shutdown single-user servers when the Hub shuts down.
|
||||||
|
|
||||||
Disable if you want to be able to teardown the Hub while leaving the single-user servers running.
|
Disable if you want to be able to teardown the Hub while leaving the single-user servers running.
|
||||||
@@ -410,9 +412,9 @@ class JupyterHub(Application):
|
|||||||
|
|
||||||
The Hub should be able to resume from database state.
|
The Hub should be able to resume from database state.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
cleanup_proxy = Bool(True, config=True,
|
cleanup_proxy = Bool(True,
|
||||||
help="""Whether to shutdown the proxy when the Hub shuts down.
|
help="""Whether to shutdown the proxy when the Hub shuts down.
|
||||||
|
|
||||||
Disable if you want to be able to teardown the Hub while leaving the proxy running.
|
Disable if you want to be able to teardown the Hub while leaving the proxy running.
|
||||||
@@ -424,7 +426,7 @@ class JupyterHub(Application):
|
|||||||
|
|
||||||
The Hub should be able to resume from database state.
|
The Hub should be able to resume from database state.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
handlers = List()
|
handlers = List()
|
||||||
|
|
||||||
@@ -445,15 +447,12 @@ class JupyterHub(Application):
|
|||||||
return "%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s %(module)s:%(lineno)d]%(end_color)s %(message)s"
|
return "%(color)s[%(levelname)1.1s %(asctime)s.%(msecs).03d %(name)s %(module)s:%(lineno)d]%(end_color)s %(message)s"
|
||||||
|
|
||||||
extra_log_file = Unicode(
|
extra_log_file = Unicode(
|
||||||
"",
|
|
||||||
config=True,
|
|
||||||
help="Set a logging.FileHandler on this file."
|
help="Set a logging.FileHandler on this file."
|
||||||
)
|
).tag(config=True)
|
||||||
extra_log_handlers = List(
|
extra_log_handlers = List(
|
||||||
Instance(logging.Handler),
|
Instance(logging.Handler),
|
||||||
config=True,
|
|
||||||
help="Extra log handlers to set on JupyterHub logger",
|
help="Extra log handlers to set on JupyterHub logger",
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
def init_logging(self):
|
def init_logging(self):
|
||||||
# This prevents double log messages because tornado use a root logger that
|
# This prevents double log messages because tornado use a root logger that
|
||||||
|
@@ -29,19 +29,19 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
db = Any()
|
db = Any()
|
||||||
admin_users = Set(config=True,
|
admin_users = Set(
|
||||||
help="""set of usernames of admin users
|
help="""set of usernames of admin users
|
||||||
|
|
||||||
If unspecified, only the user that launches the server will be admin.
|
If unspecified, only the user that launches the server will be admin.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
whitelist = Set(config=True,
|
whitelist = Set(
|
||||||
help="""Username whitelist.
|
help="""Username whitelist.
|
||||||
|
|
||||||
Use this to restrict which users can login.
|
Use this to restrict which users can login.
|
||||||
If empty, allow any user to attempt login.
|
If empty, allow any user to attempt login.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
custom_html = Unicode('',
|
custom_html = Unicode('',
|
||||||
help="""HTML login form for custom handlers.
|
help="""HTML login form for custom handlers.
|
||||||
Override in form-based custom authenticators
|
Override in form-based custom authenticators
|
||||||
@@ -55,12 +55,12 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
username_pattern = Unicode(config=True,
|
username_pattern = Unicode(
|
||||||
help="""Regular expression pattern for validating usernames.
|
help="""Regular expression pattern for validating usernames.
|
||||||
|
|
||||||
If not defined: allow any username.
|
If not defined: allow any username.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
def _username_pattern_changed(self, name, old, new):
|
def _username_pattern_changed(self, name, old, new):
|
||||||
if not new:
|
if not new:
|
||||||
self.username_regex = None
|
self.username_regex = None
|
||||||
@@ -77,14 +77,14 @@ class Authenticator(LoggingConfigurable):
|
|||||||
return True
|
return True
|
||||||
return bool(self.username_regex.match(username))
|
return bool(self.username_regex.match(username))
|
||||||
|
|
||||||
username_map = Dict(config=True,
|
username_map = Dict(
|
||||||
help="""Dictionary mapping authenticator usernames to JupyterHub users.
|
help="""Dictionary mapping authenticator usernames to JupyterHub users.
|
||||||
|
|
||||||
Can be used to map OAuth service names to local users, for instance.
|
Can be used to map OAuth service names to local users, for instance.
|
||||||
|
|
||||||
Used in normalize_username.
|
Used in normalize_username.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
def normalize_username(self, username):
|
def normalize_username(self, username):
|
||||||
"""Normalize a username.
|
"""Normalize a username.
|
||||||
@@ -246,12 +246,12 @@ class LocalAuthenticator(Authenticator):
|
|||||||
Checks for local users, and can attempt to create them if they exist.
|
Checks for local users, and can attempt to create them if they exist.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
create_system_users = Bool(False, config=True,
|
create_system_users = Bool(False,
|
||||||
help="""If a user is added that doesn't exist on the system,
|
help="""If a user is added that doesn't exist on the system,
|
||||||
should I try to create the system user?
|
should I try to create the system user?
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
add_user_cmd = Command(config=True,
|
add_user_cmd = Command(
|
||||||
help="""The command to use for creating users as a list of strings.
|
help="""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
|
For each element in the list, the string USERNAME will be replaced with
|
||||||
@@ -271,7 +271,7 @@ class LocalAuthenticator(Authenticator):
|
|||||||
|
|
||||||
when the user 'river' is created.
|
when the user 'river' is created.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
def _add_user_cmd_default(self):
|
def _add_user_cmd_default(self):
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
raise ValueError("I don't know how to create users on OS X")
|
raise ValueError("I don't know how to create users on OS X")
|
||||||
@@ -283,9 +283,8 @@ class LocalAuthenticator(Authenticator):
|
|||||||
return ['adduser', '-q', '--gecos', '""', '--disabled-password']
|
return ['adduser', '-q', '--gecos', '""', '--disabled-password']
|
||||||
|
|
||||||
group_whitelist = Set(
|
group_whitelist = Set(
|
||||||
config=True,
|
|
||||||
help="Automatically whitelist anyone in this group.",
|
help="Automatically whitelist anyone in this group.",
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
def _group_whitelist_changed(self, name, old, new):
|
def _group_whitelist_changed(self, name, old, new):
|
||||||
if self.whitelist:
|
if self.whitelist:
|
||||||
@@ -351,13 +350,13 @@ class LocalAuthenticator(Authenticator):
|
|||||||
|
|
||||||
class PAMAuthenticator(LocalAuthenticator):
|
class PAMAuthenticator(LocalAuthenticator):
|
||||||
"""Authenticate local Linux/UNIX users with PAM"""
|
"""Authenticate local Linux/UNIX users with PAM"""
|
||||||
encoding = Unicode('utf8', config=True,
|
encoding = Unicode('utf8',
|
||||||
help="""The encoding to use for PAM"""
|
help="""The encoding to use for PAM"""
|
||||||
)
|
).tag(config=True)
|
||||||
service = Unicode('login', config=True,
|
service = Unicode('login',
|
||||||
help="""The PAM service to use for authentication."""
|
help="""The PAM service to use for authentication."""
|
||||||
)
|
).tag(config=True)
|
||||||
open_sessions = Bool(True, config=True,
|
open_sessions = Bool(True,
|
||||||
help="""Whether to open PAM sessions when spawners are started.
|
help="""Whether to open PAM sessions when spawners are started.
|
||||||
|
|
||||||
This may trigger things like mounting shared filsystems,
|
This may trigger things like mounting shared filsystems,
|
||||||
@@ -368,7 +367,7 @@ class PAMAuthenticator(LocalAuthenticator):
|
|||||||
|
|
||||||
c.PAMAuthenticator.open_sessions = False
|
c.PAMAuthenticator.open_sessions = False
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def authenticate(self, handler, data):
|
def authenticate(self, handler, data):
|
||||||
|
@@ -41,39 +41,38 @@ class Spawner(LoggingConfigurable):
|
|||||||
hub = Any()
|
hub = Any()
|
||||||
authenticator = Any()
|
authenticator = Any()
|
||||||
api_token = Unicode()
|
api_token = Unicode()
|
||||||
ip = Unicode('127.0.0.1', config=True,
|
ip = Unicode('127.0.0.1',
|
||||||
help="The IP address (or hostname) the single-user server should listen on"
|
help="The IP address (or hostname) the single-user server should listen on"
|
||||||
)
|
).tag(config=True)
|
||||||
start_timeout = Integer(60, config=True,
|
start_timeout = Integer(60,
|
||||||
help="""Timeout (in seconds) before giving up on the spawner.
|
help="""Timeout (in seconds) before giving up on the spawner.
|
||||||
|
|
||||||
This is the timeout for start to return, not the timeout for the server to respond.
|
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.
|
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.
|
start should return when the server process is started and its location is known.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
http_timeout = Integer(
|
http_timeout = Integer(30,
|
||||||
30, config=True,
|
|
||||||
help="""Timeout (in seconds) before giving up on a spawned HTTP server
|
help="""Timeout (in seconds) before giving up on a spawned HTTP server
|
||||||
|
|
||||||
Once a server has successfully been spawned, this is the amount of time
|
Once a server has successfully been spawned, this is the amount of time
|
||||||
we wait before assuming that the server is unable to accept
|
we wait before assuming that the server is unable to accept
|
||||||
connections.
|
connections.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
poll_interval = Integer(30, config=True,
|
poll_interval = Integer(30,
|
||||||
help="""Interval (in seconds) on which to poll the spawner."""
|
help="""Interval (in seconds) on which to poll the spawner."""
|
||||||
)
|
).tag(config=True)
|
||||||
_callbacks = List()
|
_callbacks = List()
|
||||||
_poll_callback = Any()
|
_poll_callback = Any()
|
||||||
|
|
||||||
debug = Bool(False, config=True,
|
debug = Bool(False,
|
||||||
help="Enable debug-logging of the single-user server"
|
help="Enable debug-logging of the single-user server"
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
options_form = Unicode("", config=True, help="""
|
options_form = Unicode("", help="""
|
||||||
An HTML form for options a user can specify on launching their server.
|
An HTML form for options a user can specify on launching their server.
|
||||||
The surrounding `<form>` element and the submit button are already provided.
|
The surrounding `<form>` element and the submit button are already provided.
|
||||||
|
|
||||||
@@ -87,7 +86,7 @@ class Spawner(LoggingConfigurable):
|
|||||||
<option value="A">The letter A</option>
|
<option value="A">The letter A</option>
|
||||||
<option value="B">The letter B</option>
|
<option value="B">The letter B</option>
|
||||||
</select>
|
</select>
|
||||||
""")
|
""").tag(config=True)
|
||||||
|
|
||||||
def options_from_form(self, form_data):
|
def options_from_form(self, form_data):
|
||||||
"""Interpret HTTP form data
|
"""Interpret HTTP form data
|
||||||
@@ -113,35 +112,35 @@ class Spawner(LoggingConfigurable):
|
|||||||
'VIRTUAL_ENV',
|
'VIRTUAL_ENV',
|
||||||
'LANG',
|
'LANG',
|
||||||
'LC_ALL',
|
'LC_ALL',
|
||||||
], config=True,
|
],
|
||||||
help="Whitelist of environment variables for the subprocess to inherit"
|
help="Whitelist of environment variables for the subprocess to inherit"
|
||||||
)
|
).tag(config=True)
|
||||||
env = Dict(help="""Deprecated: use Spawner.get_env or Spawner.environment
|
env = Dict(help="""Deprecated: use Spawner.get_env or Spawner.environment
|
||||||
|
|
||||||
- extend Spawner.get_env for adding required env in Spawner subclasses
|
- extend Spawner.get_env for adding required env in Spawner subclasses
|
||||||
- Spawner.environment for config-specified env
|
- Spawner.environment for config-specified env
|
||||||
""")
|
""")
|
||||||
|
|
||||||
environment = Dict(config=True,
|
environment = Dict(
|
||||||
help="Environment variables to load for the Spawner."
|
help="Environment variables to load for the Spawner."
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
cmd = Command(['jupyterhub-singleuser'], config=True,
|
cmd = Command(['jupyterhub-singleuser'],
|
||||||
help="""The command used for starting notebooks."""
|
help="""The command used for starting notebooks."""
|
||||||
)
|
).tag(config=True)
|
||||||
args = List(Unicode, config=True,
|
args = List(Unicode,
|
||||||
help="""Extra arguments to be passed to the single-user server"""
|
help="""Extra arguments to be passed to the single-user server"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
notebook_dir = Unicode('', config=True,
|
notebook_dir = Unicode('',
|
||||||
help="""The notebook directory for the single-user server
|
help="""The notebook directory for the single-user server
|
||||||
|
|
||||||
`~` will be expanded to the user's home directory
|
`~` will be expanded to the user's home directory
|
||||||
`%U` will be expanded to the user's username
|
`%U` will be expanded to the user's username
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
default_url = Unicode('', config=True,
|
default_url = Unicode('',
|
||||||
help="""The default URL for the single-user server.
|
help="""The default URL for the single-user server.
|
||||||
|
|
||||||
Can be used in conjunction with --notebook-dir=/ to enable
|
Can be used in conjunction with --notebook-dir=/ to enable
|
||||||
@@ -150,15 +149,15 @@ class Spawner(LoggingConfigurable):
|
|||||||
|
|
||||||
`%U` will be expanded to the user's username
|
`%U` will be expanded to the user's username
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
disable_user_config = Bool(False, config=True,
|
disable_user_config = Bool(False,
|
||||||
help="""Disable per-user configuration of single-user servers.
|
help="""Disable per-user configuration of single-user servers.
|
||||||
|
|
||||||
This prevents any config in users' $HOME directories
|
This prevents any config in users' $HOME directories
|
||||||
from having an effect on their server.
|
from having an effect on their server.
|
||||||
"""
|
"""
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(Spawner, self).__init__(**kwargs)
|
super(Spawner, self).__init__(**kwargs)
|
||||||
@@ -385,15 +384,15 @@ class LocalProcessSpawner(Spawner):
|
|||||||
This is the default spawner for JupyterHub.
|
This is the default spawner for JupyterHub.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
INTERRUPT_TIMEOUT = Integer(10, config=True,
|
INTERRUPT_TIMEOUT = Integer(10,
|
||||||
help="Seconds to wait for process to halt after SIGINT before proceeding to SIGTERM"
|
help="Seconds to wait for process to halt after SIGINT before proceeding to SIGTERM"
|
||||||
)
|
).tag(config=True)
|
||||||
TERM_TIMEOUT = Integer(5, config=True,
|
TERM_TIMEOUT = Integer(5,
|
||||||
help="Seconds to wait for process to halt after SIGTERM before proceeding to SIGKILL"
|
help="Seconds to wait for process to halt after SIGTERM before proceeding to SIGKILL"
|
||||||
)
|
).tag(config=True)
|
||||||
KILL_TIMEOUT = Integer(5, config=True,
|
KILL_TIMEOUT = Integer(5,
|
||||||
help="Seconds to wait for process to halt after SIGKILL before giving up"
|
help="Seconds to wait for process to halt after SIGKILL before giving up"
|
||||||
)
|
).tag(config=True)
|
||||||
|
|
||||||
proc = Instance(Popen, allow_none=True)
|
proc = Instance(Popen, allow_none=True)
|
||||||
pid = Integer(0)
|
pid = Integer(0)
|
||||||
|
Reference in New Issue
Block a user