mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-09 19:13:03 +00:00
Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
94978ea9e0 | ||
![]() |
bf6999e439 | ||
![]() |
020ee7378f | ||
![]() |
e4a0569961 | ||
![]() |
4ff525d5bd | ||
![]() |
37a31b01b2 | ||
![]() |
1604cb1b0b | ||
![]() |
45702ac18c | ||
![]() |
c81e9d60e4 | ||
![]() |
224865b894 | ||
![]() |
3b3bc8224b | ||
![]() |
c56dc2ea6f | ||
![]() |
62202bbb74 | ||
![]() |
7ba28c0207 | ||
![]() |
9392a29dad | ||
![]() |
72ab8f99ec | ||
![]() |
fcf32c7e50 | ||
![]() |
da451d6552 | ||
![]() |
662b1a4d4a | ||
![]() |
732adea997 | ||
![]() |
7e1dbf3515 | ||
![]() |
65b92ec246 | ||
![]() |
dc42ee4779 | ||
![]() |
c04441c1b2 |
@@ -2,6 +2,7 @@
|
|||||||
language: python
|
language: python
|
||||||
sudo: false
|
sudo: false
|
||||||
python:
|
python:
|
||||||
|
- 3.6-dev
|
||||||
- 3.5
|
- 3.5
|
||||||
- 3.4
|
- 3.4
|
||||||
- 3.3
|
- 3.3
|
||||||
|
@@ -131,11 +131,11 @@ Some examples, meant as illustration and testing of this concept:
|
|||||||
----
|
----
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
A ready to go [docker image for JupyterHub](https://hub.docker.com/r/jupyterhub/jupyterhub/) gives a straightforward deployment of JupyterHub.
|
A starter [docker image for JupyterHub](https://hub.docker.com/r/jupyterhub/jupyterhub/) gives a baseline deployment of JupyterHub.
|
||||||
|
|
||||||
*Note: This `jupyterhub/jupyterhub` docker image is only an image for running the Hub service itself.
|
**Important:** This `jupyterhub/jupyterhub` image contains only the Hub itself, with no configuration. In general, one needs
|
||||||
It does not require the other Jupyter components, such as Notebook installation, which are needed by the single-user servers.
|
to make a derivative image, with at least a `jupyterhub_config.py` setting up an Authenticator and/or a Spawner. To run the
|
||||||
To run the single-user servers, which may be on the same system as the Hub or not, Jupyter Notebook version 4 or greater must be installed.*
|
single-user servers, which may be on the same system as the Hub or not, Jupyter Notebook version 4 or greater must be installed.
|
||||||
|
|
||||||
#### Starting JupyterHub with docker
|
#### Starting JupyterHub with docker
|
||||||
The JupyterHub docker image can be started with the following command:
|
The JupyterHub docker image can be started with the following command:
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bootprint": "^0.8.5",
|
"bootprint": "^0.10.0",
|
||||||
"bootprint-openapi": "^0.17.0"
|
"bootprint-openapi": "^0.17.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,20 @@ command line for details.
|
|||||||
|
|
||||||
## 0.7
|
## 0.7
|
||||||
|
|
||||||
|
### [0.7.1] - 2016-01-02
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `Spawner.will_resume` for signalling that a single-user server is paused instead of stopped.
|
||||||
|
This is needed for cases like `DockerSpawner.remove_containers = False`,
|
||||||
|
where the first API token is re-used for subsequent spawns.
|
||||||
|
- Warning on startup about single-character usernames,
|
||||||
|
caused by common `set('string')` typo in config.
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Removed spurious warning about empty `next_url`, which is AOK.
|
||||||
|
|
||||||
### [0.7.0] - 2016-12-2
|
### [0.7.0] - 2016-12-2
|
||||||
|
|
||||||
#### Added
|
#### Added
|
||||||
@@ -118,8 +132,9 @@ Fix removal of `/login` page in 0.4.0, breaking some OAuth providers.
|
|||||||
First preview release
|
First preview release
|
||||||
|
|
||||||
|
|
||||||
[Unreleased]: https://github.com/jupyterhub/jupyterhub/compare/0.7.0...HEAD
|
[Unreleased]: https://github.com/jupyterhub/jupyterhub/compare/0.7.1...HEAD
|
||||||
[Unreleased]: https://github.com/jupyterhub/jupyterhub/compare/0.6.1...0.7.0
|
[0.7.1]: https://github.com/jupyterhub/jupyterhub/compare/0.7.0...0.7.1
|
||||||
|
[0.7.0]: https://github.com/jupyterhub/jupyterhub/compare/0.6.1...0.7.0
|
||||||
[0.6.1]: https://github.com/jupyterhub/jupyterhub/compare/0.6.0...0.6.1
|
[0.6.1]: https://github.com/jupyterhub/jupyterhub/compare/0.6.0...0.6.1
|
||||||
[0.6.0]: https://github.com/jupyterhub/jupyterhub/compare/0.5.0...0.6.0
|
[0.6.0]: https://github.com/jupyterhub/jupyterhub/compare/0.5.0...0.6.0
|
||||||
[0.5]: https://github.com/jupyterhub/jupyterhub/compare/0.4.1...0.5.0
|
[0.5]: https://github.com/jupyterhub/jupyterhub/compare/0.4.1...0.5.0
|
||||||
|
@@ -67,4 +67,4 @@ Note: The Swagger specification is being renamed the [OpenAPI Initiative][].
|
|||||||
|
|
||||||
[on swagger's petstore]: http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyterhub/jupyterhub/master/docs/rest-api.yml#!/default
|
[on swagger's petstore]: http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyterhub/jupyterhub/master/docs/rest-api.yml#!/default
|
||||||
[OpenAPI Initiative]: https://www.openapis.org/
|
[OpenAPI Initiative]: https://www.openapis.org/
|
||||||
[JupyterHub REST API]: ./api/index.html
|
[JupyterHub REST API]: ./_static/rest-api/index.html
|
||||||
|
@@ -54,7 +54,7 @@ If a service is also to be managed by the Hub, it has a few extra options:
|
|||||||
externally.
|
externally.
|
||||||
- If a command is specified for launching the Service, the Service will
|
- If a command is specified for launching the Service, the Service will
|
||||||
be started and managed by the Hub.
|
be started and managed by the Hub.
|
||||||
- `env: dict` - environment variables to add to the current env
|
- `environment: dict` - additional environment variables for the Service.
|
||||||
- `user: str` - the name of a system user to manage the Service. If
|
- `user: str` - the name of a system user to manage the Service. If
|
||||||
unspecified, run as the same user as the Hub.
|
unspecified, run as the same user as the Hub.
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ c.JupyterHub.services = [
|
|||||||
A Hub-Managed Service may also be configured with additional optional
|
A Hub-Managed Service may also be configured with additional optional
|
||||||
parameters, which describe the environment needed to start the Service process:
|
parameters, which describe the environment needed to start the Service process:
|
||||||
|
|
||||||
- `env: dict` - additional environment variables for the Service.
|
- `environment: dict` - additional environment variables for the Service.
|
||||||
- `user: str` - name of the user to run the server if different from the Hub.
|
- `user: str` - name of the user to run the server if different from the Hub.
|
||||||
Requires Hub to be root.
|
Requires Hub to be root.
|
||||||
- `cwd: path` directory in which to run the Service, if different from the
|
- `cwd: path` directory in which to run the Service, if different from the
|
||||||
|
@@ -249,3 +249,26 @@ jupyter kernelspec list
|
|||||||
```bash
|
```bash
|
||||||
jupyterhub --debug
|
jupyterhub --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Toree integration with HDFS rack awareness script
|
||||||
|
|
||||||
|
The Apache Toree kernel will an issue, when running with JupyterHub, if the standard HDFS
|
||||||
|
rack awareness script is used. This will materialize in the logs as a repeated WARN:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
16/11/29 16:24:20 WARN ScriptBasedMapping: Exception running /etc/hadoop/conf/topology_script.py some.ip.address
|
||||||
|
ExitCodeException exitCode=1: File "/etc/hadoop/conf/topology_script.py", line 63
|
||||||
|
print rack
|
||||||
|
^
|
||||||
|
SyntaxError: Missing parentheses in call to 'print'
|
||||||
|
|
||||||
|
at `org.apache.hadoop.util.Shell.runCommand(Shell.java:576)`
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to resolve this issue, there are two potential options.
|
||||||
|
|
||||||
|
1. Update HDFS core-site.xml, so the parameter "net.topology.script.file.name" points to a custom
|
||||||
|
script (e.g. /etc/hadoop/conf/custom_topology_script.py). Copy the original script and change the first line point
|
||||||
|
to a python two installation (e.g. /usr/bin/python).
|
||||||
|
2. In spark-env.sh add a Python 2 installation to your path (e.g. export PATH=/opt/anaconda2/bin:$PATH).
|
||||||
|
|
||||||
|
@@ -454,7 +454,7 @@ class JupyterHub(Application):
|
|||||||
'name': 'formgrader',
|
'name': 'formgrader',
|
||||||
'url': 'http://127.0.0.1:1234',
|
'url': 'http://127.0.0.1:1234',
|
||||||
'token': 'super-secret',
|
'token': 'super-secret',
|
||||||
'env':
|
'environment':
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
|
@@ -56,6 +56,17 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
|
||||||
|
@observe('whitelist')
|
||||||
|
def _check_whitelist(self, change):
|
||||||
|
short_names = [name for name in change['new'] if len(name) <= 1]
|
||||||
|
if short_names:
|
||||||
|
sorted_names = sorted(short_names)
|
||||||
|
single = ''.join(sorted_names)
|
||||||
|
string_set_typo = "set('%s')" % single
|
||||||
|
self.log.warning("whitelist contains single-character names: %s; did you mean set([%r]) instead of %s?",
|
||||||
|
sorted_names[:8], single, string_set_typo,
|
||||||
|
)
|
||||||
|
|
||||||
custom_html = Unicode(
|
custom_html = Unicode(
|
||||||
help="""
|
help="""
|
||||||
HTML form to be overridden by authenticators if they want a custom authentication form.
|
HTML form to be overridden by authenticators if they want a custom authentication form.
|
||||||
|
@@ -28,7 +28,7 @@ class RootHandler(BaseHandler):
|
|||||||
"""
|
"""
|
||||||
def get(self):
|
def get(self):
|
||||||
next_url = self.get_argument('next', '')
|
next_url = self.get_argument('next', '')
|
||||||
if not next_url.startswith('/'):
|
if next_url and not next_url.startswith('/'):
|
||||||
self.log.warning("Disallowing redirect outside JupyterHub: %r", next_url)
|
self.log.warning("Disallowing redirect outside JupyterHub: %r", next_url)
|
||||||
next_url = ''
|
next_url = ''
|
||||||
if next_url and next_url.startswith(url_path_join(self.base_url, 'user/')):
|
if next_url and next_url.startswith(url_path_join(self.base_url, 'user/')):
|
||||||
|
@@ -124,8 +124,8 @@ class Service(LoggingConfigurable):
|
|||||||
Only use this if the service should be a subprocess.
|
Only use this if the service should be a subprocess.
|
||||||
If command is not specified, it is assumed to be managed
|
If command is not specified, it is assumed to be managed
|
||||||
by a
|
by a
|
||||||
- env: dict
|
- environment: dict
|
||||||
environment variables to add to the current env
|
Additional environment variables for the service.
|
||||||
- user: str
|
- user: str
|
||||||
The name of a system user to become.
|
The name of a system user to become.
|
||||||
If unspecified, run as the same user as the Hub.
|
If unspecified, run as the same user as the Hub.
|
||||||
|
@@ -52,6 +52,17 @@ class Spawner(LoggingConfigurable):
|
|||||||
authenticator = Any()
|
authenticator = Any()
|
||||||
api_token = Unicode()
|
api_token = Unicode()
|
||||||
|
|
||||||
|
will_resume = Bool(False,
|
||||||
|
help="""Whether the Spawner will resume on next start
|
||||||
|
|
||||||
|
|
||||||
|
Default is False where each launch of the Spawner will be a new instance.
|
||||||
|
If True, an existing Spawner will resume instead of starting anew
|
||||||
|
(e.g. resuming a Docker container),
|
||||||
|
and API tokens in use when the Spawner stops will not be deleted.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
ip = Unicode('127.0.0.1',
|
ip = Unicode('127.0.0.1',
|
||||||
help="""
|
help="""
|
||||||
The IP address (or hostname) the single-user server should listen on.
|
The IP address (or hostname) the single-user server should listen on.
|
||||||
|
@@ -234,6 +234,12 @@ class User(HasTraits):
|
|||||||
# prior to 0.7, spawners had to store this info in user.server themselves.
|
# prior to 0.7, spawners had to store this info in user.server themselves.
|
||||||
# Handle < 0.7 behavior with a warning, assuming info was stored in db by the Spawner.
|
# Handle < 0.7 behavior with a warning, assuming info was stored in db by the Spawner.
|
||||||
self.log.warning("DEPRECATION: Spawner.start should return (ip, port) in JupyterHub >= 0.7")
|
self.log.warning("DEPRECATION: Spawner.start should return (ip, port) in JupyterHub >= 0.7")
|
||||||
|
if spawner.api_token != api_token:
|
||||||
|
# Spawner re-used an API token, discard the unused api_token
|
||||||
|
orm_token = orm.APIToken.find(self.db, api_token)
|
||||||
|
if orm_token is not None:
|
||||||
|
self.db.delete(orm_token)
|
||||||
|
self.db.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if isinstance(e, gen.TimeoutError):
|
if isinstance(e, gen.TimeoutError):
|
||||||
self.log.warning("{user}'s server failed to start in {s} seconds, giving up".format(
|
self.log.warning("{user}'s server failed to start in {s} seconds, giving up".format(
|
||||||
@@ -313,10 +319,13 @@ class User(HasTraits):
|
|||||||
if self.server:
|
if self.server:
|
||||||
# cleanup server entry from db
|
# cleanup server entry from db
|
||||||
self.db.delete(self.server)
|
self.db.delete(self.server)
|
||||||
|
self.server = None
|
||||||
|
if not spawner.will_resume:
|
||||||
|
# find and remove the API token if the spawner isn't
|
||||||
|
# going to re-use it next time
|
||||||
orm_token = orm.APIToken.find(self.db, api_token)
|
orm_token = orm.APIToken.find(self.db, api_token)
|
||||||
if orm_token:
|
if orm_token:
|
||||||
self.db.delete(orm_token)
|
self.db.delete(orm_token)
|
||||||
self.server = None
|
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
finally:
|
finally:
|
||||||
self.stop_pending = False
|
self.stop_pending = False
|
||||||
|
@@ -6,7 +6,8 @@
|
|||||||
version_info = (
|
version_info = (
|
||||||
0,
|
0,
|
||||||
7,
|
7,
|
||||||
0,
|
1,
|
||||||
|
# 'dev',
|
||||||
)
|
)
|
||||||
|
|
||||||
__version__ = '.'.join(map(str, version_info))
|
__version__ = '.'.join(map(str, version_info))
|
||||||
|
Reference in New Issue
Block a user