mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8963e62044 | ||
|
|
daec71b149 | ||
|
|
e17af65b38 | ||
|
|
5c2d688937 | ||
|
|
1df02de795 | ||
|
|
181aa975f5 | ||
|
|
243fcf7be0 | ||
|
|
8b55d5f5bc | ||
|
|
c9d971b239 | ||
|
|
a047de1e79 | ||
|
|
96550b678a | ||
|
|
1bbbeacc06 | ||
|
|
d906fe8c5d | ||
|
|
79adc7de2a | ||
|
|
27cf17d68c | ||
|
|
ca25444915 | ||
|
|
5415cc471a | ||
|
|
5891f0456b | ||
|
|
36efbc52f8 | ||
|
|
dbcaf22ae0 | ||
|
|
74b863ce22 | ||
|
|
0b1da67264 | ||
|
|
9802473764 | ||
|
|
9d8c66467c | ||
|
|
c9efb93278 | ||
|
|
596984ccbd | ||
|
|
a2e80cc89d | ||
|
|
f49c59898a | ||
|
|
fb1e1063d2 | ||
|
|
939c2b37fd | ||
|
|
da5a5abafa | ||
|
|
784e237831 | ||
|
|
50a74417f6 | ||
|
|
72967f2b17 | ||
|
|
6b2d93aacf | ||
|
|
752f605c53 | ||
|
|
0cd259b6a1 | ||
|
|
684481fd5d | ||
|
|
c639c75637 | ||
|
|
45bec8e9f8 | ||
|
|
519415395f | ||
|
|
c3703985ee | ||
|
|
e6851d946d | ||
|
|
f13aef7568 | ||
|
|
354a8d47cc | ||
|
|
4263e4c85e | ||
|
|
4807b7da89 | ||
|
|
ae503c3096 | ||
|
|
512935abb7 | ||
|
|
a4858da978 | ||
|
|
134ddd9ef6 | ||
|
|
7e929fb78c | ||
|
|
3eeb028f1f | ||
|
|
0384a46720 | ||
|
|
142d22616c | ||
|
|
5ff2c8aa6f | ||
|
|
bba39bdfde | ||
|
|
c1134a5341 | ||
|
|
989f772872 | ||
|
|
d5752b6c76 | ||
|
|
dcdf2dc9b4 | ||
|
|
251099caac | ||
|
|
fa83068cdb | ||
|
|
3ee67e1581 | ||
|
|
a1f1c5e046 | ||
|
|
8e318586c3 | ||
|
|
a099bf647d | ||
|
|
8cb42a9fc1 | ||
|
|
29dda40b33 | ||
|
|
4b066766d9 | ||
|
|
947eb028a9 | ||
|
|
d695d29a6d | ||
|
|
53eceabd11 | ||
|
|
0f7d4f4748 | ||
|
|
0907ca4ad4 | ||
|
|
3397e75dc5 | ||
|
|
cd53b41b49 | ||
|
|
5916407a50 | ||
|
|
e515bcad26 | ||
|
|
5a9cb2b395 | ||
|
|
9ed2a92585 | ||
|
|
e7555ae29c | ||
|
|
73331f28fd | ||
|
|
6531b6b7aa | ||
|
|
c0563ab573 |
35
.github/integration-test.py
vendored
35
.github/integration-test.py
vendored
@@ -226,12 +226,35 @@ def main():
|
|||||||
copy_parser.add_argument("src")
|
copy_parser.add_argument("src")
|
||||||
copy_parser.add_argument("dest")
|
copy_parser.add_argument("dest")
|
||||||
|
|
||||||
run_test_parser = subparsers.add_parser("run-test")
|
run_test_parser = subparsers.add_parser(
|
||||||
run_test_parser.add_argument("--installer-args", action="append")
|
"run-test",
|
||||||
run_test_parser.add_argument("--upgrade-from", default="")
|
help="Runs the bootstrap script in a container, then executes specified integration tests.",
|
||||||
run_test_parser.add_argument("--bootstrap-pip-spec", default="/srv/src")
|
)
|
||||||
run_test_parser.add_argument("container_name")
|
run_test_parser.add_argument(
|
||||||
run_test_parser.add_argument("test_files", nargs="+")
|
"--installer-args",
|
||||||
|
action="append",
|
||||||
|
default=[],
|
||||||
|
help="Additional arguments to pass to bootstrap.py during the main installation. Can be used multiple times.",
|
||||||
|
)
|
||||||
|
run_test_parser.add_argument(
|
||||||
|
"--upgrade-from",
|
||||||
|
default="",
|
||||||
|
help="A version/tag (e.g., 'main', 'v0.1.0') to install first, simulating an upgrade to the current source code.",
|
||||||
|
)
|
||||||
|
run_test_parser.add_argument(
|
||||||
|
"--bootstrap-pip-spec",
|
||||||
|
default="/srv/src",
|
||||||
|
help="The pip specification used by the bootstrap script to install TLJH (for example: '--bootstrap-pip-spec=git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name'). Defaults to the local source code path.",
|
||||||
|
)
|
||||||
|
run_test_parser.add_argument(
|
||||||
|
"container_name",
|
||||||
|
help="An identifier for the container/test run (for example: 'basic-tests').",
|
||||||
|
)
|
||||||
|
run_test_parser.add_argument(
|
||||||
|
"test_files",
|
||||||
|
nargs="+",
|
||||||
|
help="A list of one or more test files under 'integration-tests/' to be executed.",
|
||||||
|
)
|
||||||
|
|
||||||
show_logs_parser = subparsers.add_parser("show-logs")
|
show_logs_parser = subparsers.add_parser("show-logs")
|
||||||
show_logs_parser.add_argument("container_name")
|
show_logs_parser.add_argument("container_name")
|
||||||
|
|||||||
11
.github/workflows/integration-test.yaml
vendored
11
.github/workflows/integration-test.yaml
vendored
@@ -51,16 +51,13 @@ jobs:
|
|||||||
- name: "Ubuntu 22.04, Py 3.10, from latest"
|
- name: "Ubuntu 22.04, Py 3.10, from latest"
|
||||||
distro_image: "ubuntu:22.04"
|
distro_image: "ubuntu:22.04"
|
||||||
extra_flags: --upgrade-from=latest
|
extra_flags: --upgrade-from=latest
|
||||||
- name: "Ubuntu 22.04, Py 3.10, from 0.2.0"
|
|
||||||
distro_image: "ubuntu:22.04"
|
|
||||||
extra_flags: --upgrade-from=0.2.0
|
|
||||||
- name: "Ubuntu 22.04, Py 3.10, from 1.*"
|
- name: "Ubuntu 22.04, Py 3.10, from 1.*"
|
||||||
distro_image: "ubuntu:22.04"
|
distro_image: "ubuntu:22.04"
|
||||||
extra_flags: --upgrade-from=1
|
extra_flags: --upgrade-from=1
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
|
||||||
@@ -122,8 +119,8 @@ jobs:
|
|||||||
distro_image: "ubuntu:22.04"
|
distro_image: "ubuntu:22.04"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|||||||
14
.github/workflows/unit-test.yaml
vendored
14
.github/workflows/unit-test.yaml
vendored
@@ -40,9 +40,6 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- name: "Ubuntu 20.04, Py 3.9"
|
|
||||||
ubuntu_version: "20.04"
|
|
||||||
python_version: "3.9"
|
|
||||||
- name: "Ubuntu 22.04, Py 3.10"
|
- name: "Ubuntu 22.04, Py 3.10"
|
||||||
ubuntu_version: "22.04"
|
ubuntu_version: "22.04"
|
||||||
python_version: "3.10"
|
python_version: "3.10"
|
||||||
@@ -51,12 +48,12 @@ jobs:
|
|||||||
python_version: "3.12"
|
python_version: "3.12"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: "${{ matrix.python_version }}"
|
python-version: "${{ matrix.python_version }}"
|
||||||
|
|
||||||
- name: Install venv, git, pip and setup venv
|
- name: Install system dependencies and setup venv
|
||||||
run: |
|
run: |
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
apt-get update
|
apt-get update
|
||||||
@@ -64,7 +61,8 @@ jobs:
|
|||||||
python3-venv \
|
python3-venv \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
bzip2 \
|
bzip2 \
|
||||||
git
|
git \
|
||||||
|
curl
|
||||||
|
|
||||||
python3 -m venv /srv/venv
|
python3 -m venv /srv/venv
|
||||||
echo '/srv/venv/bin' >> $GITHUB_PATH
|
echo '/srv/venv/bin' >> $GITHUB_PATH
|
||||||
@@ -82,4 +80,4 @@ jobs:
|
|||||||
run: pytest tests
|
run: pytest tests
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
|
|
||||||
- uses: codecov/codecov-action@v4
|
- uses: codecov/codecov-action@v5
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
repos:
|
repos:
|
||||||
# Autoformat: Python code, syntax patterns are modernized
|
# Autoformat: Python code, syntax patterns are modernized
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.17.0
|
rev: v3.21.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args:
|
args:
|
||||||
@@ -31,13 +31,13 @@ repos:
|
|||||||
|
|
||||||
# Autoformat: Python code
|
# Autoformat: Python code
|
||||||
- repo: https://github.com/pycqa/isort
|
- repo: https://github.com/pycqa/isort
|
||||||
rev: 5.13.2
|
rev: 7.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
|
||||||
# Autoformat: Python code
|
# Autoformat: Python code
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
rev: 24.8.0
|
rev: 25.9.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ repos:
|
|||||||
|
|
||||||
# Misc...
|
# Misc...
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.6.0
|
rev: v6.0.0
|
||||||
# ref: https://github.com/pre-commit/pre-commit-hooks#hooks-available
|
# ref: https://github.com/pre-commit/pre-commit-hooks#hooks-available
|
||||||
hooks:
|
hooks:
|
||||||
# Autoformat: Makes sure files end in a newline and only a newline.
|
# Autoformat: Makes sure files end in a newline and only a newline.
|
||||||
@@ -64,7 +64,7 @@ repos:
|
|||||||
|
|
||||||
# Lint: Python code
|
# Lint: Python code
|
||||||
- repo: https://github.com/pycqa/flake8
|
- repo: https://github.com/pycqa/flake8
|
||||||
rev: "7.1.1"
|
rev: "7.3.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,12 @@ more information.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The Littlest JupyterHub (TLJH) can run on any server that is running at least
|
The Littlest JupyterHub (TLJH) can run on any server that is running at least
|
||||||
**Ubuntu 20.04**. Earlier versions of Ubuntu are not supported.
|
**Ubuntu 22.04**. Earlier versions of Ubuntu are not supported.
|
||||||
We have several tutorials to get you started.
|
We have several tutorials to get you started.
|
||||||
|
|
||||||
- Tutorials to create a new server from scratch on a cloud provider & run TLJH
|
- Tutorials to create a new server from scratch on a cloud provider & run TLJH
|
||||||
on it. These are **recommended** if you do not have much experience setting up
|
on it. These are **recommended** if you do not have much experience setting up
|
||||||
servers.
|
servers.
|
||||||
|
|
||||||
- [Digital Ocean](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/digitalocean.html)
|
- [Digital Ocean](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/digitalocean.html)
|
||||||
- [OVH](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/ovh.html)
|
- [OVH](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/ovh.html)
|
||||||
- [Google Cloud](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/google.html)
|
- [Google Cloud](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/google.html)
|
||||||
|
|||||||
11
docs/conf.py
11
docs/conf.py
@@ -138,3 +138,14 @@ rediraffe_redirects = {
|
|||||||
"howto/env/notebook-interfaces": "howto/user-env/notebook-interfaces",
|
"howto/env/notebook-interfaces": "howto/user-env/notebook-interfaces",
|
||||||
"howto/env/server-resources": "howto/user-env/server-resources",
|
"howto/env/server-resources": "howto/user-env/server-resources",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
# Enable Plausible.io stats
|
||||||
|
app.add_js_file(
|
||||||
|
"https://plausible.io/js/pa-B75UO5--FNXYQSG7GBWkf.js", loading_method="async"
|
||||||
|
)
|
||||||
|
app.add_js_file(
|
||||||
|
filename=None,
|
||||||
|
body="window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};plausible.init({hashBasedRouting:true})",
|
||||||
|
)
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ The easiest & safest way to develop & test TLJH is with [Docker](https://www.doc
|
|||||||
--detach \
|
--detach \
|
||||||
--name=tljh-dev \
|
--name=tljh-dev \
|
||||||
--publish 12000:80 \
|
--publish 12000:80 \
|
||||||
|
--env TLJH_BOOTSTRAP_DEV=yes \
|
||||||
|
--env TLJH_BOOTSTRAP_PIP_SPEC=/srv/src \
|
||||||
|
--env "PATH=/opt/tljh/hub/bin:${PATH}" \
|
||||||
--mount type=bind,source="$(pwd)",target=/srv/src \
|
--mount type=bind,source="$(pwd)",target=/srv/src \
|
||||||
tljh-systemd
|
tljh-systemd
|
||||||
```
|
```
|
||||||
@@ -58,7 +61,6 @@ The easiest & safest way to develop & test TLJH is with [Docker](https://www.doc
|
|||||||
|
|
||||||
8. Make some changes to the repository. You can test easily depending on what
|
8. Make some changes to the repository. You can test easily depending on what
|
||||||
you changed.
|
you changed.
|
||||||
|
|
||||||
- If you changed the `bootstrap/bootstrap.py` script or any of its dependencies,
|
- If you changed the `bootstrap/bootstrap.py` script or any of its dependencies,
|
||||||
you can test it by running `python3 /srv/src/bootstrap/bootstrap.py`.
|
you can test it by running `python3 /srv/src/bootstrap/bootstrap.py`.
|
||||||
- If you changed the `tljh/installer.py` code (or any of its dependencies),
|
- If you changed the `tljh/installer.py` code (or any of its dependencies),
|
||||||
|
|||||||
@@ -28,17 +28,21 @@ against the same installation of TLJH.
|
|||||||
|
|
||||||
### Running integration tests locally
|
### Running integration tests locally
|
||||||
|
|
||||||
You need `docker` installed and callable by the user running
|
You need `docker` or `podman` installed and callable by the user
|
||||||
the integration tests without needing sudo.
|
running the integration tests without needing sudo.
|
||||||
|
|
||||||
You can then run the tests with:
|
First build the container with a Ubuntu-based image:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.github/integration-test.py run-test <name-of-run> <test-file-names>
|
.github/integration-test.py build-image \
|
||||||
|
--build-arg "BASE_IMAGE=ubuntu:22.04"
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<name-of-run>` is an identifier for the tests - you can choose anything you want
|
Then you can then run the tests with the `run-test` function. For usage run:
|
||||||
- `<test-file-names>>` is list of test files (under `integration-tests`) that should be run in one go.
|
|
||||||
|
```bash
|
||||||
|
.github/integration-test.py run-test --help
|
||||||
|
```
|
||||||
|
|
||||||
For example, to run all the basic tests, you would write:
|
For example, to run all the basic tests, you would write:
|
||||||
|
|
||||||
@@ -50,13 +54,17 @@ For example, to run all the basic tests, you would write:
|
|||||||
test_extensions.py
|
test_extensions.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This will run the tests in the three files against the same installation
|
This will run the tests in the four files against the same installation
|
||||||
of TLJH and report errors.
|
of TLJH and report errors.
|
||||||
|
|
||||||
If you would like to run the tests with a custom pip spec for the bootstrap script, you can use the `--bootstrap-pip-spec`
|
If you would like to run the tests with a custom `pip` spec for the bootstrap script, you can use the `--bootstrap-pip-spec`
|
||||||
parameter:
|
parameter:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.github/integration-test.py run-test <name-of-run> <test-file-names> \
|
.github/integration-test.py run-test custom-pip-spec \
|
||||||
|
test_hub.py \
|
||||||
|
test_proxy.py \
|
||||||
|
test_install.py \
|
||||||
|
test_extensions.py \
|
||||||
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -82,14 +82,13 @@ renew them for you before they expire.
|
|||||||
|
|
||||||
## Manual HTTPS with existing key and certificate
|
## Manual HTTPS with existing key and certificate
|
||||||
|
|
||||||
You may already have an SSL key and certificate.
|
You may already have an SSL key and certificate for your domain.
|
||||||
If so, you can tell your deployment to use these files:
|
If so, you can tell your deployment to use these files:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo tljh-config set https.enabled true
|
sudo tljh-config set https.enabled true
|
||||||
sudo tljh-config set https.tls.key /etc/mycerts/mydomain.key
|
sudo tljh-config set https.tls.key /etc/mycerts/mydomain.key
|
||||||
sudo tljh-config set https.tls.cert /etc/mycerts/mydomain.cert
|
sudo tljh-config set https.tls.cert /etc/mycerts/mydomain.cert
|
||||||
sudo tljh-config add-item https.tls.domains yourhub.yourdomain.edu
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you have loaded this, your config should look like:
|
Once you have loaded this, your config should look like:
|
||||||
@@ -104,8 +103,6 @@ https:
|
|||||||
tls:
|
tls:
|
||||||
key: /etc/mycerts/mydomain.key
|
key: /etc/mycerts/mydomain.key
|
||||||
cert: /etc/mycerts/mydomain.cert
|
cert: /etc/mycerts/mydomain.cert
|
||||||
domains:
|
|
||||||
- yourhub.yourdomain.edu
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, you can reload the proxy to load the new configuration:
|
Finally, you can reload the proxy to load the new configuration:
|
||||||
@@ -114,7 +111,7 @@ Finally, you can reload the proxy to load the new configuration:
|
|||||||
sudo tljh-config reload proxy
|
sudo tljh-config reload proxy
|
||||||
```
|
```
|
||||||
|
|
||||||
and now access your Hub securely at <https://yourhub.yourdomain.edu>.
|
and now access your Hub securely at the domain associated with your certificate.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ these namespacing settings might be a bit too strict and prevent users from acce
|
|||||||
|
|
||||||
To override the `jupyterhub` settings, it is possible to provide a custom `/etc/systemd/system/jupyterhub.service.d/override.conf` file.
|
To override the `jupyterhub` settings, it is possible to provide a custom `/etc/systemd/system/jupyterhub.service.d/override.conf` file.
|
||||||
|
|
||||||
|
You can create this file with `sudo systemctl edit jupyterhub.service`
|
||||||
|
|
||||||
Here is an example for the content of the file:
|
Here is an example for the content of the file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -72,7 +74,7 @@ The output should look like the following:
|
|||||||
```
|
```
|
||||||
|
|
||||||
To override the `traefik` settings, create a new file under `/etc/systemd/system/traefik.service.d/override.conf`
|
To override the `traefik` settings, create a new file under `/etc/systemd/system/traefik.service.d/override.conf`
|
||||||
and follow the same steps.
|
(or use `sudo systemctl edit traefik.service`) and follow the same steps.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ application to your `tljh` configuration.
|
|||||||
1. Create a user pool [Getting Started with User Pool](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-cognito-user-pools.html).
|
1. Create a user pool [Getting Started with User Pool](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-cognito-user-pools.html).
|
||||||
|
|
||||||
When you have completed creating a user pool, app, and domain you should have the following settings available to you:
|
When you have completed creating a user pool, app, and domain you should have the following settings available to you:
|
||||||
|
|
||||||
- **App client id**: From the App client page
|
- **App client id**: From the App client page
|
||||||
|
|
||||||
- **App client secret** From the App client page
|
- **App client secret** From the App client page
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ You'll need a GitHub account in order to complete these steps.
|
|||||||
## Step 1: Create a GitHub application
|
## Step 1: Create a GitHub application
|
||||||
|
|
||||||
1. Go to the [GitHub OAuth app creation page](https://github.com/settings/applications/new).
|
1. Go to the [GitHub OAuth app creation page](https://github.com/settings/applications/new).
|
||||||
|
|
||||||
- **Application name**: Choose a descriptive application name (e.g. `tljh`)
|
- **Application name**: Choose a descriptive application name (e.g. `tljh`)
|
||||||
|
|
||||||
- **Homepage URL**: Use the IP address or URL of your JupyterHub. e.g. `` http(s)://<my-tljh-url>` ``.
|
- **Homepage URL**: Use the IP address or URL of your JupyterHub. e.g. `` http(s)://<my-tljh-url>` ``.
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ and create a new project:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- You will have to fill a form with:
|
- You will have to fill a form with:
|
||||||
|
|
||||||
- **Application type**: Choose _Web application_
|
- **Application type**: Choose _Web application_
|
||||||
|
|
||||||
- **Name**: A descriptive name for your OAuth client ID (e.g. `tljh-client`)
|
- **Name**: A descriptive name for your OAuth client ID (e.g. `tljh-client`)
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ be changed with TLJH config `user_environment.default_app` or with the
|
|||||||
JupyterHub config
|
JupyterHub config
|
||||||
{external:py:attr}`jupyterhub.spawner.Spawner.default_url` directly.
|
{external:py:attr}`jupyterhub.spawner.Spawner.default_url` directly.
|
||||||
|
|
||||||
The TLJH config supports the options `jupyterlab` and `classic`, which
|
The TLJH config supports the options [`jupyterlab`](https://github.com/jupyterlab/jupyterlab/)
|
||||||
|
and [`classic`](https://github.com/jupyter/notebook), which
|
||||||
translates to a `Spawner.default_url` config of `/lab` and `/tree`.
|
translates to a `Spawner.default_url` config of `/lab` and `/tree`.
|
||||||
|
|
||||||
Both these interfaces are also shipped with TLJH by default. You can try them
|
Both these interfaces are also shipped with TLJH by default. You can try them
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ To upgrade the Python version of the user environment, one can:
|
|||||||
environment, but you may do so manually.
|
environment, but you may do so manually.
|
||||||
|
|
||||||
**Steps:**
|
**Steps:**
|
||||||
|
|
||||||
1. Activate the user environment, if using ssh. If the terminal was
|
1. Activate the user environment, if using ssh. If the terminal was
|
||||||
started with JupyterHub, this step can be skipped:
|
started with JupyterHub, this step can be skipped:
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
```
|
```
|
||||||
|
|
||||||
5. **Choose an Ubuntu server for your VM**:
|
5. **Choose an Ubuntu server for your VM**:
|
||||||
|
|
||||||
- Click `Ubuntu Server 22.04 LTS.`
|
- Click `Ubuntu Server 22.04 LTS.`
|
||||||
|
|
||||||
- Make sure `Resource Manager` is selected in the next screen and click **Create**
|
- Make sure `Resource Manager` is selected in the next screen and click **Create**
|
||||||
@@ -61,7 +60,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
```
|
```
|
||||||
|
|
||||||
6. Customise the Virtual Machine basics:
|
6. Customise the Virtual Machine basics:
|
||||||
|
|
||||||
- **Subscription**. Choose the "Free Trial" if this is what you're using. Otherwise, choose a different plan. This is the billing account that will be charged.
|
- **Subscription**. Choose the "Free Trial" if this is what you're using. Otherwise, choose a different plan. This is the billing account that will be charged.
|
||||||
- **Resource group**. Resource groups let you keep your Azure tools/resources together in an availability region (e.g. WestEurope). If you already have one you'd like to use it select that resource.
|
- **Resource group**. Resource groups let you keep your Azure tools/resources together in an availability region (e.g. WestEurope). If you already have one you'd like to use it select that resource.
|
||||||
|
|
||||||
@@ -89,7 +87,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
- **Inbound port rules**. Leave the defaults for now, and we will update these later on in the Network configuration step.
|
- **Inbound port rules**. Leave the defaults for now, and we will update these later on in the Network configuration step.
|
||||||
|
|
||||||
7. Before clicking on "Next" we need to select the RAM size for the image.
|
7. Before clicking on "Next" we need to select the RAM size for the image.
|
||||||
|
|
||||||
- For this we need to make sure we have enough RAM to accommodate your users. For example, if each user needs 2GB of RAM, and you have 10 total users, you need at least 20GB of RAM on the machine. It's also good to have a few GB of "buffer" RAM beyond what you think you'll need.
|
- For this we need to make sure we have enough RAM to accommodate your users. For example, if each user needs 2GB of RAM, and you have 10 total users, you need at least 20GB of RAM on the machine. It's also good to have a few GB of "buffer" RAM beyond what you think you'll need.
|
||||||
|
|
||||||
- Click on **Change size** (see image below)
|
- Click on **Change size** (see image below)
|
||||||
@@ -105,7 +102,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
- Select a suitable image (to check available images and prices in your region [click on this link](https://azuremarketplace.microsoft.com/en-gb/marketplace/apps/Canonical.UbuntuServer?tab=PlansAndPrice/?wt.mc_id=TLJH-github-taallard)).
|
- Select a suitable image (to check available images and prices in your region [click on this link](https://azuremarketplace.microsoft.com/en-gb/marketplace/apps/Canonical.UbuntuServer?tab=PlansAndPrice/?wt.mc_id=TLJH-github-taallard)).
|
||||||
|
|
||||||
8. Disks (Storage):
|
8. Disks (Storage):
|
||||||
|
|
||||||
- **Disk options**: select the OS disk type there are options for SDD and HDD. **SSD persistent disk** gives you a faster but more expensive disk than HDD.
|
- **Disk options**: select the OS disk type there are options for SDD and HDD. **SSD persistent disk** gives you a faster but more expensive disk than HDD.
|
||||||
|
|
||||||
- **Data disk**. Click on create and attach a new disk. Select an appropriate type and size and click ok.
|
- **Data disk**. Click on create and attach a new disk. Select an appropriate type and size and click ok.
|
||||||
@@ -120,7 +116,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
```
|
```
|
||||||
|
|
||||||
9. Networking
|
9. Networking
|
||||||
|
|
||||||
- **Virtual network**. Leave the default values selected.
|
- **Virtual network**. Leave the default values selected.
|
||||||
- **Subnet**. Leave the default values selected.
|
- **Subnet**. Leave the default values selected.
|
||||||
- **Public IP address**.Leave the default values selected. This will make your server accessible from a browser.
|
- **Public IP address**.Leave the default values selected. This will make your server accessible from a browser.
|
||||||
@@ -132,9 +127,7 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
```
|
```
|
||||||
|
|
||||||
10. Management
|
10. Management
|
||||||
|
|
||||||
- Monitoring
|
- Monitoring
|
||||||
|
|
||||||
- **Boot diagnostics**. Choose "On".
|
- **Boot diagnostics**. Choose "On".
|
||||||
- **OS guest diagnostics**. Choose "Off".
|
- **OS guest diagnostics**. Choose "Off".
|
||||||
- **Diagnostics storage account**. Leave as the default.
|
- **Diagnostics storage account**. Leave as the default.
|
||||||
@@ -150,7 +143,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
```
|
```
|
||||||
|
|
||||||
11. Advanced settings
|
11. Advanced settings
|
||||||
|
|
||||||
- **Extensions**. Make sure there are no extensions listed
|
- **Extensions**. Make sure there are no extensions listed
|
||||||
- **Cloud init**. We are going to use this section to install TLJH directly into our Virtual Machine.
|
- **Cloud init**. We are going to use this section to install TLJH directly into our Virtual Machine.
|
||||||
|
|
||||||
@@ -177,7 +169,6 @@ We start by creating the Virtual Machine in which we can run TLJH (The Littlest
|
|||||||
12. Check the summary and confirm the creation of your Virtual Machine.
|
12. Check the summary and confirm the creation of your Virtual Machine.
|
||||||
|
|
||||||
13. Check that the creation of your Virtual Machine worked.
|
13. Check that the creation of your Virtual Machine worked.
|
||||||
|
|
||||||
- Wait for the virtual machine to be created. This might take about 5-10 minutes.
|
- Wait for the virtual machine to be created. This might take about 5-10 minutes.
|
||||||
|
|
||||||
- After completion, you should see a similar screen to the one below:
|
- After completion, you should see a similar screen to the one below:
|
||||||
|
|||||||
@@ -1,152 +1,112 @@
|
|||||||
(install-jetstream)=
|
(install-jetstream)=
|
||||||
|
|
||||||
# Installing on Jetstream
|
# Installing on Jetstream2
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
By the end of this tutorial, you should have a JupyterHub with some admin
|
By the end of this tutorial, you should have a JupyterHub with some admin
|
||||||
users and a user environment with packages you want installed running on
|
users and a user environment with packages you want installed running on
|
||||||
[Jetstream](https://jetstream-cloud.org/).
|
[Jetstream2](https://jetstream-cloud.org/).
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
1. A Jetstream account with an XSEDE allocation; for more information,
|
1. An ACCESS ID, and membership in an allocation with access to Jetstream2 resources; for more information,
|
||||||
see the [Jetstream Allocations help page](http://wiki.jetstream-cloud.org/Jetstream+Allocations).
|
see the [Jetstream2 Allocations Overview page](https://docs.jetstream-cloud.org/alloc/overview/) and the [Get started with Jetstream2 guide](https://jetstream-cloud.org/get-started/).
|
||||||
|
|
||||||
## Step 1: Installing The Littlest JupyterHub
|
## Step 1: Launch a Jetstream2 instance
|
||||||
|
|
||||||
Let's create the server on which we can run JupyterHub.
|
We'll create a new Jetstream2 instance:
|
||||||
|
|
||||||
1. Log in to [the Jetstream portal](https://use.jetstream-cloud.org/). You need an allocation
|
1. Log in to the [Jetstream2 portal](https://use.jetstream-cloud.org/). You must have (and select) an allocation in order to launch instances. Click the allocation you want to charge.
|
||||||
to launch instances.
|
2. Click **Create** ➜ **Instance**.
|
||||||
|
3. From the list of images, select **Ubuntu 24.04** (Jammy or newer is required for current TLJH releases).
|
||||||
|
4. In the **Create Instance** dialog:
|
||||||
|
1. Set a descriptive **Instance Name** (this is used in the default hostname and helps users recognize it).
|
||||||
|
2. Choose an **Instance Size**. We suggest `m3.small` (2 vCPUs / 6 GiB RAM) or larger for more than a couple of users. The absolute minimum TLJH can start with is about **1 GiB** RAM, but you'll quickly run out with real workloads.
|
||||||
|
- See the resource estimation guide: [Choosing resources](/howto/admin/resource-estimation) for help picking CPU, RAM, and disk.
|
||||||
|
3. (Optional) Increase the **Volume Size** if you expect many users or large datasets. You can not easily shrink later.
|
||||||
|
5. Launch the instance (click **Create** button at the bottom of the form).
|
||||||
|
|
||||||
2. Select the **Launch New Instance** option to get going.
|
## Step 2: Install The Littlest JupyterHub
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/launch-instance-first-button.png
|
1. Wait a few minutes for the instance to show the status "Ready"
|
||||||
:alt: Launch new instance button with description.
|
2. Copy the **Hostname** under **Credentials**, it will be of the form: `yourinstancename.xxx0000000.projects.jetstream-cloud.org`, where `xxx000000` is the allocation ID. Keep it handy, we will use it multiple times in the next steps.
|
||||||
```
|
|
||||||
|
|
||||||
This takes you to a page with a list of base images you can choose for your
|
3. SSH into the instance with the `exouser` user:
|
||||||
server.
|
|
||||||
|
|
||||||
3. Under **Image Search**, search for **Ubuntu 22.04**, and select the
|
|
||||||
**Ubuntu 22.04 Devel and Docker** image.
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/select-image.png
|
|
||||||
:alt: Select Ubuntu 22.04 x64 image from image list
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Once selected, you will see more information about this image. Click the
|
|
||||||
**Launch** button on the top right.
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/launch-instance-second-button.png
|
|
||||||
:alt: Launch selected image with Launch button on top right
|
|
||||||
```
|
|
||||||
|
|
||||||
5. A dialog titled **Launch an Instance / Basic Options** pops up, with various
|
|
||||||
options for configuring your instance.
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/launch-instance-dialog.png
|
|
||||||
:alt: Launch an Instance / Basic Options dialog box
|
|
||||||
```
|
|
||||||
|
|
||||||
1. Give your server a descriptive **Instance Name**.
|
|
||||||
|
|
||||||
2. Select an appropriate **Instance Size**. We suggest m1.medium or larger.
|
|
||||||
Make sure your instance has at least **1GB** of RAM.
|
|
||||||
|
|
||||||
Check out our guide on How To [](/howto/admin/resource-estimation) to help pick
|
|
||||||
how much Memory, CPU & disk space your server needs.
|
|
||||||
|
|
||||||
3. If you have multiple allocations, make sure you are 'charging' this server
|
|
||||||
to the correct allocation.
|
|
||||||
|
|
||||||
6. Click the **Advanced Options** link in the bottom left of the popup. This
|
|
||||||
lets us configure what the server should do when it starts up. We will use
|
|
||||||
this to install The Littlest JupyterHub.
|
|
||||||
|
|
||||||
A dialog titled **Launch an Instance / Advanced Options** should pop up.
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/add-deployment-script-dialog.png
|
|
||||||
:alt: Dialog box allowing you to add a new script.
|
|
||||||
```
|
|
||||||
|
|
||||||
7. Click the **Create New Script** button. This will open up another dialog
|
|
||||||
box!
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/create-script-dialog.png
|
|
||||||
:alt: Launch an Instance / Advanced Options dialog box
|
|
||||||
```
|
|
||||||
|
|
||||||
8. Under **Input Type**, select **Raw Text**. This should make a text box titled
|
|
||||||
**Raw Text** visible on the right side of the dialog box.
|
|
||||||
Copy the text below, and paste it into the **Raw Text** text box. Replace
|
|
||||||
`<admin-user-name>` with the name of the first **admin user** for this
|
|
||||||
JupyterHub. This admin user can log in after the JupyterHub is set up, and
|
|
||||||
can configure it to their needs. **Remember to add your username**!
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
ssh exouser@yourinstancename.xxx0000000.projects.jetstream-cloud.org
|
||||||
curl -L https://tljh.jupyter.org/bootstrap.py \
|
|
||||||
| sudo python3 - \
|
|
||||||
--admin <admin-user-name>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
:::{note}
|
Need the passphrase? In Exosphere, open **Instances**, select your
|
||||||
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
|
JupyterHub instance, and expand **Credentials**. Click **Show Passphrase**
|
||||||
[](/topic/customizing-installer) documents other options that can be passed to the installer.
|
next to the `exouser` entry to reveal or copy it before running the
|
||||||
:::
|
`ssh` command.
|
||||||
|
|
||||||
9. Under **Execution Strategy Type**, select **Run script on first boot**.
|
4. Run the TLJH bootstrap script, replace <admin-user-name> with the name of the first admin user for this JupyterHub. Choose any name you like (don’t forget to remove the brackets!). This admin user can log in after the JupyterHub is set up, and can configure it to their needs.
|
||||||
|
|
||||||
10. Under **Deployment Type**, select **Wait for script to complete**.
|
```bash
|
||||||
|
curl -L https://tljh.jupyter.org/bootstrap.py | sudo -E python3 - --admin <admin-user-name>
|
||||||
11. Click the **Save and Add Script** button on the bottom right. This should hide
|
|
||||||
the dialog box.
|
|
||||||
|
|
||||||
12. Click the **Continue to Launch** button on the bottom right. This should put you
|
|
||||||
back in the **Launch an Instance / Basic Options** dialog box again.
|
|
||||||
|
|
||||||
13. Click the **Launch Instance** button on the bottom right. This should turn it
|
|
||||||
into a spinner, and your server is getting created!
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/launching-spinner.png
|
|
||||||
:alt: Launch button turns into a spinner
|
|
||||||
```
|
```
|
||||||
|
|
||||||
14. You'll now be shown a dashboard with all your servers and their states. The
|
5. Open the Hostname in a web browser (http on port 80). You should see the JupyterHub login page. Your browser will warn about the site not being secure (no HTTPS)—we'll enable HTTPS in the next step. Do not login yet, first setup HTTPS, so we avoid transmitting the password in clear text.
|
||||||
server you just launched will progress through various stages of set up,
|
|
||||||
and you can see the progress here.
|
|
||||||
|
|
||||||
```{image} ../images/providers/jetstream/deployment-in-progress.png
|
## Step 2: Enable HTTPS
|
||||||
:alt: Instances dashboard showing deployment in progress.
|
|
||||||
|
Encrypted (HTTPS) access is strongly recommended before inviting users.
|
||||||
|
|
||||||
|
See the full guide: [Enable HTTPS](/howto/admin/https). Below is a quick recipe for using the default Jetstream-provided hostname.
|
||||||
|
|
||||||
|
1. In the terminal inside the instance, configure Let's Encrypt (replace with a real email you control, and the correct hostname):
|
||||||
|
```bash
|
||||||
|
sudo tljh-config set https.enabled true
|
||||||
|
sudo tljh-config set https.letsencrypt.email you@example.com
|
||||||
|
sudo tljh-config add-item https.letsencrypt.domains yourinstancename.xxx0000000.projects.jetstream-cloud.org
|
||||||
|
sudo tljh-config reload proxy
|
||||||
|
```
|
||||||
|
2. Wait ~30–60 seconds, then reload the site using https://. If certificate issuance fails, check the logs:
|
||||||
|
```bash
|
||||||
|
sudo journalctl -u traefik --since "10 minutes ago" | grep -i acme
|
||||||
```
|
```
|
||||||
|
|
||||||
15. It will take about ten minutes for your server to come up. The status will
|
Tips:
|
||||||
say **Active** and the progress bar will be a solid green. At this point,
|
|
||||||
your JupyterHub is ready for use!
|
|
||||||
|
|
||||||
16. Copy the **IP Address** of your server, and try accessing it from a web
|
- Make sure ports 80 and 443 are open in your Jetstream security group (they are open by default for new projects; adjust only if you customized network policies).
|
||||||
browser. It should give you a JupyterHub login page.
|
- If you later attach a custom domain, add it with another `add-item` command and reload the proxy again.
|
||||||
|
|
||||||
```{image} ../images/first-login.png
|
## Step 3: Log in as the administrative user and set a password
|
||||||
:alt: JupyterHub log-in page
|
|
||||||
```
|
|
||||||
|
|
||||||
17. Login using the **admin user name** you used in step 8, and a password. Use a
|
1. Now log in with the `<admin-user-name>` at https://yourinstancename.xxx000000.projects.jetstream-cloud.org. Since this is the first login, you'll be prompted to set a password. Choose a strong password and store it safely. This password is now the credential for that admin user.
|
||||||
strong password & note it down somewhere, since this will be the password for
|
2. Congratulations, you have a running working JupyterHub!
|
||||||
the admin user account from now on.
|
|
||||||
|
|
||||||
18. Congratulations, you have a running working JupyterHub!
|
## Step 4: Adding more users
|
||||||
|
|
||||||
## Step 2: Adding more users
|
|
||||||
|
|
||||||
```{include} add-users.md
|
```{include} add-users.md
|
||||||
|
|
||||||
```
|
|
||||||
|
Next common tasks:
|
||||||
## Step 3: Install conda / pip packages for all users
|
|
||||||
|
- [](howto-admin-admin-users)
|
||||||
```{include} add-packages.md
|
- [](howto-user-env-user-environment-apt)
|
||||||
|
- [](howto-admin-enable-extensions)
|
||||||
|
- []topic-installer-upgrade-actions)
|
||||||
|
|
||||||
|
Browse the full [How-To index](/howto/index) for more.
|
||||||
|
|
||||||
|
## Ask for help
|
||||||
|
|
||||||
|
Need a hand?
|
||||||
|
|
||||||
|
- For Jetstream2 specific questions (allocations, quotas, instance lifecycle, networking, etc.), use the [Jetstream support resources](https://docs.jetstream-cloud.org/overview/support/).
|
||||||
|
- For The Littlest JupyterHub usage, configuration, or upgrade questions, search or post in the [Jupyter forum TLJH category](https://discourse.jupyter.org/c/jupyterhub/tljh).
|
||||||
|
- If you believe you have found a TLJH bug or have a clear documentation improvement, open an issue (or pull request if you have a proposed fix) in the [TLJH GitHub repository](https://github.com/jupyterhub/the-littlest-jupyterhub).
|
||||||
|
|
||||||
|
When asking for help about TLJH, it is often useful to provide:
|
||||||
|
|
||||||
|
- A short description of what you were trying to do and what happened instead
|
||||||
|
- Relevant log excerpts (see [](/troubleshooting/logs))
|
||||||
|
- Your TLJH version (`sudo tljh-config show | grep version` if present in config) and the output of `lsb_release -a` for the OS
|
||||||
|
- Any custom installer flags or `tljh-config` changes you have applied
|
||||||
|
|
||||||
|
This information helps others debug and answer more quickly.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ the idle culler configuration can be extended beyond tljh-config options, using
|
|||||||
|
|
||||||
## Default settings
|
## Default settings
|
||||||
|
|
||||||
By default, JupyterHub will ping the user notebook servers every 60s to check their
|
By default, JupyterHub will ping the user notebook servers every 10 min to check their
|
||||||
status. Every server found to be idle for more than 10 minutes will be culled.
|
status. Every server found to be idle for more than 1 hour will be culled.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
services.cull.every = 60
|
services.cull.every = 600
|
||||||
services.cull.timeout = 600
|
services.cull.timeout = 3600
|
||||||
```
|
```
|
||||||
|
|
||||||
Because the servers don't have a maximum age set, an active server will not be shut down
|
Because the servers don't have a maximum age set, an active server will not be shut down
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ it after an argument like `remove-item` gives information about this specific co
|
|||||||
```bash
|
```bash
|
||||||
sudo tljh-config --help
|
sudo tljh-config --help
|
||||||
|
|
||||||
usage: tljh-config [-h] [--config-path CONFIG_PATH] {show,unset,set,add-item,remove-item,reload} ...
|
usage: tljh-config [-h] [--config-path CONFIG_PATH] [--validate] [--no-validate] {show,unset,set,add-item,remove-item,reload} ...
|
||||||
|
|
||||||
positional arguments:
|
positional arguments:
|
||||||
{show,unset,set,add-item,remove-item,reload}
|
{show,unset,set,add-item,remove-item,reload}
|
||||||
@@ -238,10 +238,12 @@ positional arguments:
|
|||||||
remove-item Remove a value from a list for a configuration property
|
remove-item Remove a value from a list for a configuration property
|
||||||
reload Reload a component to apply configuration change
|
reload Reload a component to apply configuration change
|
||||||
|
|
||||||
optional arguments:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--config-path CONFIG_PATH
|
--config-path CONFIG_PATH
|
||||||
Path to TLJH config.yaml file
|
Path to TLJH config.yaml file
|
||||||
|
--validate Validate the TLJH config
|
||||||
|
--no-validate Do not validate the TLJH config
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -22,11 +22,9 @@ container technology in administering user sessions.
|
|||||||
The choice between TLJH and Z2JH ultimately comes down to only a few questions:
|
The choice between TLJH and Z2JH ultimately comes down to only a few questions:
|
||||||
|
|
||||||
1. Do you want your hub and all users to live on a **single, larger machine** vs. spreading users on a **cluster of smaller machines** that are scaled up or down?
|
1. Do you want your hub and all users to live on a **single, larger machine** vs. spreading users on a **cluster of smaller machines** that are scaled up or down?
|
||||||
|
|
||||||
- If you can use a single machine, we recommend **The Littlest JupyterHub**.
|
- If you can use a single machine, we recommend **The Littlest JupyterHub**.
|
||||||
- If you wish to use multiple machines, we recommend **Zero to JupyterHub for Kubernetes**.
|
- If you wish to use multiple machines, we recommend **Zero to JupyterHub for Kubernetes**.
|
||||||
|
|
||||||
2. Do you **need to use container technology**?
|
2. Do you **need to use container technology**?
|
||||||
|
|
||||||
- If no, we recommend **The Littlest JupyterHub**.
|
- If no, we recommend **The Littlest JupyterHub**.
|
||||||
- If yes, we recommend **Zero to JupyterHub for Kubernetes**.
|
- If yes, we recommend **Zero to JupyterHub for Kubernetes**.
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ easier. Here are some very basic tips on effective `journalctl` usage.
|
|||||||
[less](<https://en.wikipedia.org/wiki/Less_(Unix)>). This allows you to
|
[less](<https://en.wikipedia.org/wiki/Less_(Unix)>). This allows you to
|
||||||
scroll up / down, search for specific words, etc. Some common keyboard shortcuts
|
scroll up / down, search for specific words, etc. Some common keyboard shortcuts
|
||||||
are:
|
are:
|
||||||
|
|
||||||
- Arrow keys to move up / down / left / right
|
- Arrow keys to move up / down / left / right
|
||||||
- `G` to navigate to the end of the logs
|
- `G` to navigate to the end of the logs
|
||||||
- `g` to navigate to the start of the logs
|
- `g` to navigate to the start of the logs
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Systemd inside a Docker container, for CI only
|
# Systemd inside a Docker container, for CI and local development
|
||||||
ARG BASE_IMAGE=ubuntu:22.04
|
ARG BASE_IMAGE=ubuntu:22.04
|
||||||
FROM $BASE_IMAGE
|
FROM $BASE_IMAGE
|
||||||
|
|
||||||
@@ -28,9 +28,4 @@ RUN systemctl set-default multi-user.target
|
|||||||
|
|
||||||
STOPSIGNAL SIGRTMIN+3
|
STOPSIGNAL SIGRTMIN+3
|
||||||
|
|
||||||
# Uncomment these lines for a development install
|
|
||||||
# ENV TLJH_BOOTSTRAP_DEV=yes
|
|
||||||
# ENV TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
|
|
||||||
# ENV PATH=/opt/tljh/hub/bin:${PATH}
|
|
||||||
|
|
||||||
CMD ["/bin/bash", "-c", "exec /lib/systemd/systemd --log-target=journal 3>&1"]
|
CMD ["/bin/bash", "-c", "exec /lib/systemd/systemd --log-target=journal 3>&1"]
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ def test_serverextensions():
|
|||||||
# jupyter-serverextension writes to stdout and stderr weirdly
|
# jupyter-serverextension writes to stdout and stderr weirdly
|
||||||
proc = subprocess.run(
|
proc = subprocess.run(
|
||||||
["/opt/tljh/user/bin/jupyter-server", "extension", "list", "--sys-prefix"],
|
["/opt/tljh/user/bin/jupyter-server", "extension", "list", "--sys-prefix"],
|
||||||
stderr=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
output = proc.stdout.decode()
|
||||||
|
|
||||||
extensions = [
|
extensions = [
|
||||||
"jupyterlab",
|
"jupyterlab",
|
||||||
"nbgitpuller",
|
"nbgitpuller",
|
||||||
@@ -19,7 +22,7 @@ def test_serverextensions():
|
|||||||
]
|
]
|
||||||
|
|
||||||
for e in extensions:
|
for e in extensions:
|
||||||
assert e in proc.stderr.decode()
|
assert e in output, f"'{e}' not found in server extensions: {output}"
|
||||||
|
|
||||||
|
|
||||||
def test_labextensions():
|
def test_labextensions():
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ omit = [
|
|||||||
github_url = "https://github.com/jupyterhub/the-littlest-jupyterhub"
|
github_url = "https://github.com/jupyterhub/the-littlest-jupyterhub"
|
||||||
|
|
||||||
[tool.tbump.version]
|
[tool.tbump.version]
|
||||||
current = "2.0.0"
|
current = "2.0.1.dev"
|
||||||
regex = '''
|
regex = '''
|
||||||
(?P<major>\d+)
|
(?P<major>\d+)
|
||||||
\.
|
\.
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="the-littlest-jupyterhub",
|
name="the-littlest-jupyterhub",
|
||||||
version="2.0.0",
|
version="2.0.1.dev",
|
||||||
description="A small JupyterHub distribution",
|
description="A small JupyterHub distribution",
|
||||||
url="https://github.com/jupyterhub/the-littlest-jupyterhub",
|
url="https://github.com/jupyterhub/the-littlest-jupyterhub",
|
||||||
author="Jupyter Development Team",
|
author="Jupyter Development Team",
|
||||||
|
|||||||
@@ -220,7 +220,8 @@ def test_cli_remove_int(tljh_dir):
|
|||||||
("x", "x"),
|
("x", "x"),
|
||||||
("1x", "1x"),
|
("1x", "1x"),
|
||||||
("1.2x", "1.2x"),
|
("1.2x", "1.2x"),
|
||||||
(None, None),
|
("None", None),
|
||||||
|
("none", None),
|
||||||
("", ""),
|
("", ""),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
13
tests/test_config_schema.py
Normal file
13
tests/test_config_schema.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
"""
|
||||||
|
Unit test functions to test JSON Schema validation
|
||||||
|
"""
|
||||||
|
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
|
from tljh.config_schema import config_schema
|
||||||
|
|
||||||
|
|
||||||
|
def test_valid_config_json_schema():
|
||||||
|
"""Validate that the JSON schema fits its $schema specification"""
|
||||||
|
validator_class = jsonschema.validators.validator_for(config_schema)
|
||||||
|
validator_class.check_schema(config_schema)
|
||||||
@@ -161,12 +161,6 @@ def _specifier(version):
|
|||||||
"mamba": ">=1.1.0",
|
"mamba": ">=1.1.0",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
# too-old Python (3.7), abort
|
|
||||||
(
|
|
||||||
"miniconda",
|
|
||||||
"4.7.10",
|
|
||||||
ValueError,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_ensure_user_environment(
|
def test_ensure_user_environment(
|
||||||
|
|||||||
@@ -317,8 +317,8 @@ def reload_component(component):
|
|||||||
|
|
||||||
def parse_value(value_str):
|
def parse_value(value_str):
|
||||||
"""Parse a value string"""
|
"""Parse a value string"""
|
||||||
if value_str is None:
|
if value_str.lower() == "none":
|
||||||
return value_str
|
return None
|
||||||
if re.match(r"^\d+$", value_str):
|
if re.match(r"^\d+$", value_str):
|
||||||
return int(value_str)
|
return int(value_str)
|
||||||
elif re.match(r"^\d+\.\d*$", value_str):
|
elif re.match(r"^\d+\.\d*$", value_str):
|
||||||
|
|||||||
@@ -79,7 +79,20 @@ config_schema = {
|
|||||||
"description": "User CPU and memory limits.",
|
"description": "User CPU and memory limits.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": False,
|
"additionalProperties": False,
|
||||||
"properties": {"memory": {"type": "string"}, "cpu": {"type": "integer"}},
|
"properties": {
|
||||||
|
"memory": {
|
||||||
|
"anyOf": [
|
||||||
|
{"type": "string"},
|
||||||
|
{"type": "null"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
"anyOf": [
|
||||||
|
{"type": "number", "minimum": 0},
|
||||||
|
{"type": "null"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"UserEnvironment": {
|
"UserEnvironment": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ Config should never append or mutate, only set. Functions here could
|
|||||||
be called many times per lifetime of a jupyterhub.
|
be called many times per lifetime of a jupyterhub.
|
||||||
|
|
||||||
Traitlets that modify the startup of JupyterHub should not be here.
|
Traitlets that modify the startup of JupyterHub should not be here.
|
||||||
FIXME: A strong feeling that JSON Schema should be involved somehow.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -293,12 +293,16 @@ def ensure_user_environment(user_requirements_txt_file):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if user_requirements_txt_file:
|
if user_requirements_txt_file:
|
||||||
# FIXME: This currently fails hard, should fail soft and not abort installer
|
try:
|
||||||
conda.ensure_pip_requirements(
|
conda.ensure_pip_requirements(
|
||||||
USER_ENV_PREFIX,
|
USER_ENV_PREFIX,
|
||||||
user_requirements_txt_file,
|
user_requirements_txt_file,
|
||||||
upgrade=True,
|
upgrade=True,
|
||||||
)
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(
|
||||||
|
f"Failed to install requirements for user env from {user_requirements_txt_file}: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def ensure_admins(admin_password_list):
|
def ensure_admins(admin_password_list):
|
||||||
@@ -530,7 +534,7 @@ def main():
|
|||||||
ensure_admins(args.admin)
|
ensure_admins(args.admin)
|
||||||
ensure_usergroups()
|
ensure_usergroups()
|
||||||
if args.user_requirements_txt_url:
|
if args.user_requirements_txt_url:
|
||||||
logger.info("installing packages from user_requirements_txt_url")
|
logger.info("Installing packages from user_requirements_txt_url")
|
||||||
ensure_user_environment(args.user_requirements_txt_url)
|
ensure_user_environment(args.user_requirements_txt_url)
|
||||||
|
|
||||||
logger.info("Setting up JupyterHub...")
|
logger.info("Setting up JupyterHub...")
|
||||||
|
|||||||
@@ -25,7 +25,4 @@ jupyterhub-idle-culler>=1.4.0,<2
|
|||||||
# ref: https://www.tornadoweb.org/en/stable/httpclient.html#module-tornado.simple_httpclient
|
# ref: https://www.tornadoweb.org/en/stable/httpclient.html#module-tornado.simple_httpclient
|
||||||
# ref: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/289
|
# ref: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/289
|
||||||
#
|
#
|
||||||
# FIXME: pycurl is installed from source without its wheel for 7.45.3 has an
|
pycurl>=7.45.7,<8
|
||||||
# issue reported in https://github.com/pycurl/pycurl/issues/834.
|
|
||||||
#
|
|
||||||
pycurl>=7.45.3,<8 --no-binary=pycurl
|
|
||||||
|
|||||||
Reference in New Issue
Block a user