Some suggestions from reading through the docs

Thanks to @willingc, @minrk and @manics for the review so far.
This commit is the PR so far rebased onto master and squashed.
This commit is contained in:
Eric Dill
2019-06-12 07:34:31 -04:00
parent 47cf1915ff
commit e243812745
19 changed files with 83 additions and 61 deletions

View File

@@ -188,7 +188,7 @@ this a good choice for **testing JupyterHub on your desktop or laptop**.
If you want to run docker on a computer that has a public IP then you should If you want to run docker on a computer that has a public IP then you should
(as in MUST) **secure it with ssl** by adding ssl options to your docker (as in MUST) **secure it with ssl** by adding ssl options to your docker
configuration or by using a ssl enabled proxy. configuration or by using an ssl enabled proxy.
[Mounting volumes](https://docs.docker.com/engine/admin/volumes/volumes/) will [Mounting volumes](https://docs.docker.com/engine/admin/volumes/volumes/) will
allow you to **store data outside the docker image (host system) so it will be persistent**, even when you start allow you to **store data outside the docker image (host system) so it will be persistent**, even when you start

View File

@@ -27,7 +27,7 @@ change renders correctly, it is good practice to test it locally.
python3 -m pip install -r docs/requirements.txt python3 -m pip install -r docs/requirements.txt
#. Build the html version of the docs. This is the most commonly used #. Build the html version of the docs. This is the most commonly used
output format, so verifying it renders as you should is usually good output format, so verifying it renders correctly is usually good
enough. enough.
.. code-block:: bash .. code-block:: bash
@@ -46,6 +46,8 @@ change renders correctly, it is good practice to test it locally.
On macOS, you can open a file from the terminal with ``open <path-to-file>``. On macOS, you can open a file from the terminal with ``open <path-to-file>``.
On Linux, you can do the same with ``xdg-open <path-to-file>``. On Linux, you can do the same with ``xdg-open <path-to-file>``.
After opening index.html in your browser you can just refresh the page whenever
you rebuild the docs via ``make html``
.. _contributing/docs/conventions: .. _contributing/docs/conventions:

View File

@@ -30,6 +30,9 @@ JupyterHub, is written in Javascript to run on `NodeJS
recommend installing it in the ``miniconda`` environment you set up for recommend installing it in the ``miniconda`` environment you set up for
Python. You can do so with ``conda install nodejs``. Python. You can do so with ``conda install nodejs``.
Many in the Jupyter community use [``nvm``](https://github.com/nvm-sh/nvm) to
managing node dependencies.
Install git Install git
----------- -----------
@@ -75,9 +78,9 @@ happen.
npm install -g configurable-http-proxy npm install -g configurable-http-proxy
If you get an error that says ``Error: EACCES: permission denied``, If you get an error that says ``Error: EACCES: permission denied``, you might need to prefix the command with ``sudo``.
you might need to prefix the command with ``sudo``. If you do not ``sudo`` may be required to perform a system-wide install.
have access to sudo, you may instead run the following commands: If you do not have access to sudo, you may instead run the following commands:
.. code:: bash .. code:: bash

View File

@@ -4,7 +4,7 @@
Testing JupyterHub Testing JupyterHub
================== ==================
Unit test help validate that JupyterHub works the way we think it does, Unit testing helps to validate that JupyterHub works the way we think it does,
and continues to do so when changes occur. They also help communicate and continues to do so when changes occur. They also help communicate
precisely what we expect our code to do. precisely what we expect our code to do.

View File

@@ -101,6 +101,9 @@ popular services:
- Okpy - Okpy
- OpenShift - OpenShift
NOTE: Open issue asking for more details on this generic implementation.
It's not clear if this is a different implementation or if the JupyterHub OAuth
_is_ the generic implementation.
A generic implementation, which you can use for OAuth authentication A generic implementation, which you can use for OAuth authentication
with any provider, is also available. with any provider, is also available.

View File

@@ -93,7 +93,7 @@ use a custom proxy (e.g. Traefik), this also not needed.
Connections to user servers go through the proxy, and *not* the hub Connections to user servers go through the proxy, and *not* the hub
itself. If the proxy stays running when the hub restarts (for itself. If the proxy stays running when the hub restarts (for
maintenance, re-configuration, etc.), then use connections are not maintenance, re-configuration, etc.), then user connections are not
interrupted. For simplicity, by default the hub starts the proxy interrupted. For simplicity, by default the hub starts the proxy
automatically, so if the hub restarts, the proxy restarts, and user automatically, so if the hub restarts, the proxy restarts, and user
connections are interrupted. It is easy to run the proxy separately, connections are interrupted. It is easy to run the proxy separately,

View File

@@ -41,9 +41,9 @@ port.
## Set the Proxy's REST API communication URL (optional) ## Set the Proxy's REST API communication URL (optional)
By default, this REST API listens on port 8081 of `localhost` only. By default, the proxy's REST API listens on port 8081 of `localhost` only.
The Hub service talks to the proxy via a REST API on a secondary port. The The Hub service talks to the proxy via a REST API on a secondary port.
API URL can be configured separately and override the default settings. The REST API URL (hostname and port) can be configured separately and override the default settings.
### Set api_url ### Set api_url

View File

@@ -76,9 +76,9 @@ In certain cases, for example if the hub is running behind a reverse proxy, and
`SSL termination is being provided by NGINX <https://www.nginx.com/resources/admin-guide/nginx-ssl-termination/>`_, `SSL termination is being provided by NGINX <https://www.nginx.com/resources/admin-guide/nginx-ssl-termination/>`_,
it is reasonable to run the hub without SSL. it is reasonable to run the hub without SSL.
To achieve this, simply omit the configuration settings To achieve this, remove ``c.JupyterHub.ssl_key`` and ``c.JupyterHub.ssl_cert``
``c.JupyterHub.ssl_key`` and ``c.JupyterHub.ssl_cert`` from your configuration (setting them to ``None`` or an empty string does not
(setting them to ``None`` does not have the same effect, and is an error). have the same effect, and will result in an error).
.. _cookie-secret: .. _cookie-secret:

View File

@@ -67,7 +67,7 @@ c.JupyterHub.services = [
Upon restarting JupyterHub, you should see a message like below in the Upon restarting JupyterHub, you should see a message like below in the
logs: logs:
``` ```none
Adding API token for <username> Adding API token for <username>
``` ```

View File

@@ -35,7 +35,7 @@ this a good choice for **testing JupyterHub on your desktop or laptop**.
If you want to run docker on a computer that has a public IP then you should If you want to run docker on a computer that has a public IP then you should
(as in MUST) **secure it with ssl** by adding ssl options to your docker (as in MUST) **secure it with ssl** by adding ssl options to your docker
configuration or using a ssl enabled proxy. configuration or using an ssl enabled proxy.
`Mounting volumes <https://docs.docker.com/engine/admin/volumes/volumes/>`_ `Mounting volumes <https://docs.docker.com/engine/admin/volumes/volumes/>`_
will allow you to store data outside the docker image (host system) so it will will allow you to store data outside the docker image (host system) so it will

View File

@@ -31,8 +31,7 @@ popular services:
- Okpy - Okpy
- OpenShift - OpenShift
A generic implementation, which you can use for OAuth authentication A [generic implementation](https://github.com/jupyterhub/oauthenticator/blob/master/oauthenticator/generic.py), which you can use for OAuth authentication with any provider, is also available.
with any provider, is also available.
## The Dummy Authenticator ## The Dummy Authenticator
@@ -114,6 +113,8 @@ service that allows multiple usernames mapping to the same user (such
as ActiveDirectory, yes, this really happens). When as ActiveDirectory, yes, this really happens). When
`pam_normalize_username` is on, usernames are *not* normalized to `pam_normalize_username` is on, usernames are *not* normalized to
lowercase. lowercase.
NOTE: Earlier it says that usernames are normalized using PAM.
I guess that doesn't normalize them?
#### Validate usernames #### Validate usernames
@@ -169,7 +170,7 @@ setup(
``` ```
If you have added this metadata to your package, If you have added this metadata to your package,
users can select your authenticator with the configuration: admins can select your authenticator with the configuration:
```python ```python
c.JupyterHub.authenticator_class = 'myservice' c.JupyterHub.authenticator_class = 'myservice'
@@ -259,8 +260,8 @@ class MyAuthenticator(Authenticator):
## pre_spawn_start and post_spawn_stop hooks ## pre_spawn_start and post_spawn_stop hooks
Authenticators uses two hooks, [pre_spawn_start(user, spawner)][] and Authenticators uses two hooks, [pre_spawn_start(user, spawner)][] and
[post_spawn_stop(user, spawner)][] to add pass additional state information [post_spawn_stop(user, spawner)][] to pass additional state information
between the authenticator and a spawner. These hooks are typically used auth-related between the authenticator and a spawner. These hooks are typically used for auth-related
startup, i.e. opening a PAM session, and auth-related cleanup, i.e. closing a startup, i.e. opening a PAM session, and auth-related cleanup, i.e. closing a
PAM session. PAM session.

View File

@@ -207,8 +207,8 @@ httpd.conf amendments:
``` ```
jupyterhub_config.py amendments: jupyterhub_config.py amendments:
```bash ```python
--The public facing URL of the whole JupyterHub application. # The public facing URL of the whole JupyterHub application.
--This is the address on which the proxy will bind. Sets protocol, ip, base_url # This is the address on which the proxy will bind. Sets protocol, ip, base_url
c.JupyterHub.bind_url = 'http://127.0.0.1:8000/jhub/' c.JupyterHub.bind_url = 'http://127.0.0.1:8000/jhub/'
``` ```

View File

@@ -70,7 +70,8 @@ Cmnd_Alias JUPYTER_CMD = /usr/local/bin/sudospawner
rhea ALL=(JUPYTER_USERS) NOPASSWD:JUPYTER_CMD rhea ALL=(JUPYTER_USERS) NOPASSWD:JUPYTER_CMD
``` ```
It might be useful to modify `secure_path` to add commands in path. It might be useful to modify `secure_path` to add commands in path. (Search for
`secure_path` in the [sudo docs](https://www.sudo.ws/man/1.8.14/sudoers.man.html)
As an alternative to adding every user to the `/etc/sudoers` file, you can As an alternative to adding every user to the `/etc/sudoers` file, you can
use a group in the last line above, instead of `JUPYTER_USERS`: use a group in the last line above, instead of `JUPYTER_USERS`:
@@ -153,6 +154,7 @@ then you will need to give `node` permission to do so:
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/node sudo setcap 'cap_net_bind_service=+ep' /usr/bin/node
``` ```
However, you may want to further understand the consequences of this. However, you may want to further understand the consequences of this.
([Further reading](http://man7.org/linux/man-pages/man7/capabilities.7.html))
You may also be interested in limiting the amount of CPU any process can use You may also be interested in limiting the amount of CPU any process can use
on your server. `cpulimit` is a useful tool that is available for many Linux on your server. `cpulimit` is a useful tool that is available for many Linux
@@ -163,7 +165,8 @@ instructions](http://ubuntuforums.org/showthread.php?t=992706).
### Shadow group (FreeBSD) ### Shadow group (FreeBSD)
**NOTE:** This has not been tested and may not work as expected. **NOTE:** This has not been tested on FreeBSD and may not work as expected on
the FreeBSD platform. *Do not use in production without verifying that it works properly!*
```bash ```bash
$ ls -l /etc/spwd.db /etc/master.passwd $ ls -l /etc/spwd.db /etc/master.passwd
@@ -249,6 +252,6 @@ $ semodule -i sudo_exec_selinux.pp
## Troubleshooting: PAM session errors ## Troubleshooting: PAM session errors
If the PAM authentication doesn't work and you see errors for If the PAM authentication doesn't work and you see errors for
`login:session-auth`, or similar, considering updating to a more recent version `login:session-auth`, or similar, consider updating to a more recent version
of jupyterhub and disabling the opening of PAM sessions with of jupyterhub and disabling the opening of PAM sessions with
`c.PAMAuthenticator.open_sessions=False`. `c.PAMAuthenticator.open_sessions=False`.

View File

@@ -7,8 +7,8 @@ environment in some way.
Since the `jupyterhub-singleuser` server extends the standard Jupyter notebook Since the `jupyterhub-singleuser` server extends the standard Jupyter notebook
server, most configuration and documentation that applies to Jupyter Notebook server, most configuration and documentation that applies to Jupyter Notebook
applies to the single-user environments. Configuration of user environments applies to the single-user environments. Configuration of user environments
typically does not occur through JupyterHub itself, but rather through system- typically does not occur through JupyterHub itself, but rather through system-wide
wide configuration of Jupyter, which is inherited by `jupyterhub-singleuser`. configuration of Jupyter, which is inherited by `jupyterhub-singleuser`.
**Tip:** When searching for configuration tips for JupyterHub user **Tip:** When searching for configuration tips for JupyterHub user
environments, try removing JupyterHub from your search because there are a lot environments, try removing JupyterHub from your search because there are a lot
@@ -43,9 +43,13 @@ sudo python3 -m pip install numpy
to install the numpy package in the default system Python 3 environment to install the numpy package in the default system Python 3 environment
(typically `/usr/local`). (typically `/usr/local`).
TODO: Get a link from the conda team for a description of what "appropriate permissions for users" is
You may also use conda to install packages. If you do, you should make sure You may also use conda to install packages. If you do, you should make sure
that the conda environment has appropriate permissions for users to be able to that the conda environment has appropriate permissions for users to be able to
run Python code in the env. run Python code in the env. The env must be *readable and executable* by all
users. Additionally it must be *writeable* if you want users to install
additional packages.
## Configuring Jupyter and IPython ## Configuring Jupyter and IPython

View File

@@ -138,7 +138,7 @@ async def delete_route(self, routespec):
For retrieval, you only *need* to implement a single method that retrieves all For retrieval, you only *need* to implement a single method that retrieves all
routes. The return value for this function should be a dictionary, keyed by routes. The return value for this function should be a dictionary, keyed by
`routespect`, of dicts whose keys are the same three arguments passed to `routespec`, of dicts whose keys are the same three arguments passed to
`add_route` (`routespec`, `target`, `data`) `add_route` (`routespec`, `target`, `data`)
```python ```python
@@ -204,7 +204,7 @@ setup(
``` ```
If you have added this metadata to your package, If you have added this metadata to your package,
users can select your proxy with the configuration: admins can select your authenticator with the configuration:
```python ```python
c.JupyterHub.proxy_class = 'mything' c.JupyterHub.proxy_class = 'mything'
@@ -216,7 +216,7 @@ instead of the full
c.JupyterHub.proxy_class = 'mypackage:MyProxy' c.JupyterHub.proxy_class = 'mypackage:MyProxy'
``` ```
previously required. as previously required.
Additionally, configurable attributes for your proxy will Additionally, configurable attributes for your proxy will
appear in jupyterhub help output and auto-generated configuration files appear in jupyterhub help output and auto-generated configuration files
via `jupyterhub --generate-config`. via `jupyterhub --generate-config`.

View File

@@ -14,8 +14,8 @@ because the proxy is automatically managed by the hub. This is great
for getting started and even most use, but everytime you restart the for getting started and even most use, but everytime you restart the
hub, all user connections also get restarted. But it's also simple to hub, all user connections also get restarted. But it's also simple to
run the proxy as a service separate from the hub, so that you are free run the proxy as a service separate from the hub, so that you are free
to reconfigure the hub while only interrupting users who are currently to reconfigure the hub while only interrupting users who are waiting for their notebook server to start.
actively starting the hub. starting their notebook server.
The default JupyterHub proxy is The default JupyterHub proxy is
[configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy), [configurable-http-proxy](https://github.com/jupyterhub/configurable-http-proxy),

View File

@@ -65,7 +65,7 @@ If a service is also to be managed by the Hub, it has a few extra options:
A **Hub-Managed Service** is started by the Hub, and the Hub is responsible A **Hub-Managed Service** is started by the Hub, and the Hub is responsible
for the Service's actions. A Hub-Managed Service can only be a local for the Service's actions. A Hub-Managed Service can only be a local
subprocess of the Hub. The Hub will take care of starting the process and subprocess of the Hub. The Hub will take care of starting the process and
restarts it if it stops. restart the service if the service stops.
While Hub-Managed Services share some similarities with notebook Spawners, While Hub-Managed Services share some similarities with notebook Spawners,
there are no plans for Hub-Managed Services to support the same spawning there are no plans for Hub-Managed Services to support the same spawning
@@ -201,8 +201,18 @@ below.
The reference, or base, implementation is the [`HubAuth`][HubAuth] class, The reference, or base, implementation is the [`HubAuth`][HubAuth] class,
which implements the requests to the Hub. which implements the requests to the Hub.
To use HubAuth, you must set the `.api_token`, either programmatically when constructing the class, To use HubAuth, you must set the `.api_token` instance variable. This can be
or via the `JUPYTERHUB_API_TOKEN` environment variable. done either programmatically when constructing the class, or via the
`JUPYTERHUB_API_TOKEN` environment variable. A number of the examples in the
root of the jupyterhub git repository set the `JUPYTERHUB_API_TOKEN` variable
so consider having a look at those for futher reading
([cull-idle](https://github.com/jupyterhub/jupyterhub/tree/master/examples/cull-idle),
[external-oauth](https://github.com/jupyterhub/jupyterhub/tree/master/examples/external-oauth),
[service-notebook](https://github.com/jupyterhub/jupyterhub/tree/master/examples/service-notebook)
and [service-whoiami](https://github.com/jupyterhub/jupyterhub/tree/master/examples/service-whoami))
(TODO: Where is this API TOKen set?)
Most of the logic for authentication implementation is found in the Most of the logic for authentication implementation is found in the
[`HubAuth.user_for_cookie`][HubAuth.user_for_cookie] [`HubAuth.user_for_cookie`][HubAuth.user_for_cookie]
@@ -353,13 +363,13 @@ and taking note of the following process:
```json ```json
{ {
"name": "inara", "name": "inara",
"groups": ["serenity", "guild"], "groups": ["serenity", "guild"]
} }
``` ```
An example of using an Externally-Managed Service and authentication is An example of using an Externally-Managed Service and authentication is
in [nbviewer README][nbviewer example] section on securing the notebook viewer, in the [nbviewer README][nbviewer example] section on securing the notebook viewer,
and an example of its configuration is found [here](https://github.com/jupyter/nbviewer/blob/master/nbviewer/providers/base.py#L94). and an example of its configuration is found [here](https://github.com/jupyter/nbviewer/blob/master/nbviewer/providers/base.py#L94).
nbviewer can also be run as a Hub-Managed Service as described [nbviewer README][nbviewer example] nbviewer can also be run as a Hub-Managed Service as described [nbviewer README][nbviewer example]
section on securing the notebook viewer. section on securing the notebook viewer.

View File

@@ -16,9 +16,9 @@ Some examples include:
- [DockerSpawner](https://github.com/jupyterhub/dockerspawner) for spawning user servers in Docker containers - [DockerSpawner](https://github.com/jupyterhub/dockerspawner) for spawning user servers in Docker containers
* `dockerspawner.DockerSpawner` for spawning identical Docker containers for * `dockerspawner.DockerSpawner` for spawning identical Docker containers for
each users each user
* `dockerspawner.SystemUserSpawner` for spawning Docker containers with an * `dockerspawner.SystemUserSpawner` for spawning Docker containers with an
environment and home directory for each users environment and home directory for each user
* both `DockerSpawner` and `SystemUserSpawner` also work with Docker Swarm for * both `DockerSpawner` and `SystemUserSpawner` also work with Docker Swarm for
launching containers on remote machines launching containers on remote machines
- [SudoSpawner](https://github.com/jupyterhub/sudospawner) enables JupyterHub to - [SudoSpawner](https://github.com/jupyterhub/sudospawner) enables JupyterHub to
@@ -222,8 +222,8 @@ discover these resource limits and guarantees, such as for memory and CPU.
For the limits and guarantees to be useful, **the spawner must implement For the limits and guarantees to be useful, **the spawner must implement
support for them**. For example, LocalProcessSpawner, the default support for them**. For example, LocalProcessSpawner, the default
spawner, does not support limits and guarantees. One of the spawners spawner, does not support limits and guarantees. One of the spawners
that supports limits and guarantees is the `systemdspawner`. that supports limits and guarantees is the
[`systemdspawner`](https://github.com/jupyterhub/systemdspawner).
### Memory Limits & Guarantees ### Memory Limits & Guarantees
@@ -283,9 +283,10 @@ container `ip` prior to starting and pass that to `.create_certs` (TODO: edit).
In general though, this method will not need to be changed and the default In general though, this method will not need to be changed and the default
`ip`/`dns` (localhost) info will suffice. `ip`/`dns` (localhost) info will suffice.
When `.create_certs` is run, it will `.create_certs` in a default, central When `.create_certs` is run, it will create the certificates in a default,
location specified by `c.JupyterHub.internal_certs_location`. For `Spawners` central location specified by `c.JupyterHub.internal_certs_location`. For
that need access to these certs elsewhere (i.e. on another host altogether), `Spawners` that need access to these certs elsewhere (i.e. on another host
the `.move_certs` method can be overridden to move the certs appropriately. altogether), the `.move_certs` method can be overridden to move the certs
Again, using `DockerSpawner` as an example, this would entail moving certs appropriately. Again, using `DockerSpawner` as an example, this would entail
to a directory that will get mounted into the container this spawner starts. moving certs to a directory that will get mounted into the container this
spawner starts.

View File

@@ -119,14 +119,9 @@ This URL indicates a request for a user server that is not running
(because `/user/...` would have been handled by the notebook server (because `/user/...` would have been handled by the notebook server
if the specified server were running). if the specified server were running).
Handling this URL is the most complicated condition in JupyterHub, Handling this URL depends on two conditions: whether a requested user is found
because there can be many states: as a match and the state of the requested user's notebook server.
1. server is not active
a. user matches
b. user doesn't match
2. server is ready
3. server is pending, but not ready
If the server is pending spawn, If the server is pending spawn,
the browser will be redirected to `/hub/spawn-pending/:username/:servername` the browser will be redirected to `/hub/spawn-pending/:username/:servername`