394 Commits
0.2.0 ... 2.0.0

Author SHA1 Message Date
Erik Sundell
a47a171850 Bump to 2.0.0 2024-10-21 10:25:07 +02:00
Erik Sundell
04e2568fb3 Merge pull request #1010 from consideRatio/pr/cl200
Add changelog for 2.0.0
2024-10-21 10:24:18 +02:00
Erik Sundell
145d58f86e Add changelog for 2.0.0 2024-10-20 21:22:24 +02:00
Erik Sundell
3ebdbe1d83 Merge pull request #1009 from consideRatio/pr/betastate
Remove mention about beta state
2024-10-20 21:05:00 +02:00
Erik Sundell
f573525bf0 Remove mention about beta state 2024-10-20 21:01:28 +02:00
Erik Sundell
0370b57b32 Merge pull request #1008 from consideRatio/pr/unpin-jh
Update jupyterhub pinning to >=5.2.0,<6 from ==5.1.0
2024-10-20 15:49:33 +02:00
Erik Sundell
cbe577e596 Update systemdspawner pinning to >=1.0.2,<2 from >=1.0.1,<2 2024-10-20 14:53:50 +02:00
Erik Sundell
64790b4c95 Update jupyterhub pinning to >=5.2.0,<6 from ==5.1.0 2024-10-20 10:32:17 +02:00
Min RK
d2b0fd2c6c Merge pull request #1006 from consideRatio/pr/pycurl 2024-10-19 11:57:39 +02:00
Erik Sundell
e581232920 hub env: avoid installing pycurl using wheel with an issue 2024-10-18 23:10:01 +02:00
Erik Sundell
7514616e23 Merge pull request #1007 from consideRatio/pr/pin-jh
hub env: pin to jupyterhub 5.1.0
2024-10-18 23:07:47 +02:00
Erik Sundell
06d4670512 hub env: pin to jupyterhub 5.1.0 2024-10-18 22:51:31 +02:00
Erik Sundell
f4538ab06b Merge pull request #1004 from consideRatio/pr/lower-bound-user-env
hub env: bump to ldapauthenticator 2.0.0 and other lower bounds
2024-10-18 22:38:45 +02:00
Erik Sundell
bb17a1b980 hub env: bump to ldapauthenticator 2.0.0 and other lower bounds 2024-10-18 22:37:23 +02:00
Erik Sundell
8e68745e38 Bump to 2.0.0b1 2024-09-30 15:27:34 +02:00
Erik Sundell
a49f0a6889 Merge pull request #1000 from consideRatio/pr/changelog-2.0.0b1
Add changelog for 2.0.0b1
2024-09-30 15:25:48 +02:00
Min RK
bcfb426b5c Merge pull request #1003 from manics/upgrade-1 2024-09-29 08:26:31 +02:00
Simon Li
59fb7fb8a2 Test upgrade from 1.* 2024-09-28 15:38:32 +01:00
Erik Sundell
95b54414ca Add changelog for 2.0.0b1 2024-09-28 11:14:55 +02:00
Erik Sundell
eb5c0e4758 Merge pull request #1001 from consideRatio/pr/traefik-bump
Update traefik from 2.10.1 to 3.1.4
2024-09-28 10:59:38 +02:00
Erik Sundell
92e317d41f Merge pull request #1002 from consideRatio/pr/lower-bound-user-env
Bump the requirements-user-env-extras.txt lower version bounds
2024-09-28 10:59:00 +02:00
Erik Sundell
812be54635 Bump the requirements-user-env-extras.txt lower version bounds
By declaring these lower bounds, it becomes a bit easier to help others
using tljh, because we can know that fresh installations of tljh should
have at least these versions of software etc.
2024-09-28 10:49:03 +02:00
Erik Sundell
3ddc1e8d59 refactor: exctract calling traefik setup from ensure_jupyterhub_package func 2024-09-26 22:32:26 +02:00
Erik Sundell
a059d6ffbb Update traefik from 2.10.1 to 3.1.4 2024-09-26 16:29:51 +02:00
Erik Sundell
856c647e88 Merge pull request #999 from consideRatio/pr/bump-miniforge
Update to install miniforge 24.7.1-2 from 24.7.1-0
2024-09-26 13:42:04 +02:00
Erik Sundell
a89021c49e Update to install miniforge 24.7.1-2 from 24.7.1-0 2024-09-26 13:32:07 +02:00
Erik Sundell
a98299c629 Merge pull request #998 from consideRatio/pr/bump-drop
Drop ubuntu 20.04, require py39, traefik-proxy v2, and ldapauthenticator v2
2024-09-26 13:25:45 +02:00
Erik Sundell
e8602fc4a1 Update lower bounds on dependencies for tljh 2 beta release 2024-09-26 13:16:17 +02:00
Erik Sundell
0de2db365a pre-commit: run hooks 2024-09-20 22:25:46 +02:00
Erik Sundell
436c81f26d tljh package: require python 3.9+ 2024-09-20 22:25:46 +02:00
Erik Sundell
363dc45b52 tljh package: bump to traefik-proxy v2 2024-09-20 22:25:46 +02:00
Erik Sundell
1a9f3d65a4 tljh package: bump to ruamel.yaml==0.18.* 2024-09-20 22:25:46 +02:00
Erik Sundell
3f55ac2912 Drop support for ubuntu 20.04 and Python 3.8 2024-09-20 22:25:46 +02:00
Erik Sundell
92465ade36 Bump to 2.0.0.dev 2024-09-20 22:25:46 +02:00
Erik Sundell
2282e61894 Merge pull request #997 from consideRatio/main
ci: cache pip only when no container is used
2024-09-20 22:14:40 +02:00
Erik Sundell
94a16d6ddd ci: cache pip only when no container is used 2024-09-20 21:57:55 +02:00
Erik Sundell
7be7eb4968 Merge pull request #994 from minrk/consolidate_lock
consolidate lock file handling
2024-09-17 00:55:46 +02:00
Min RK
0c322774e2 filelock is a dependency of tljh 2024-09-05 12:03:26 +02:00
Min RK
13c8946d8c consolidate lock file handling
- adds config_file_lock context manager to re-use
- moves filelock import to module level
- fixes exit codes, stderr messages
2024-09-05 11:58:51 +02:00
Erik Sundell
f7118edf48 Merge pull request #993 from consideRatio/pr/unit-test-24.04
ci: run unit tests in ubuntu-24.04 github actions environment as well
2024-09-05 11:16:36 +02:00
Min RK
b034fc6713 fix calls to assert_called_with
it's not `assert ...called_with`
2024-09-05 11:07:22 +02:00
Erik Sundell
3321a50f31 ci: run unit tests in ubuntu-24.04 github actions environment as well 2024-09-04 16:16:31 +02:00
Erik Sundell
73f8833f0a Merge pull request #992 from minrk/oauth17
update oauthenticator to 17
2024-09-04 16:16:17 +02:00
Erik Sundell
5834f14b83 Merge pull request #942 from yuvipanda/conda-channels
Add the ability to define conda channels in plugins via `tljh_extra_user_conda_channels`
2024-09-04 16:14:10 +02:00
Erik Sundell
9111b73cee tests: reduce a test to only one package per conda channel 2024-09-04 16:04:29 +02:00
Min RK
3bd739e8dc update oauthenticator to 17
azuread no longer has its own dependencies
2024-09-04 13:25:10 +02:00
Erik Sundell
7a491e403c Merge branch 'main' into conda-channels 2024-09-04 13:16:58 +02:00
Erik Sundell
50c1b5f894 Merge pull request #990 from minrk/miniforge
Update base user environment to miniforge 24.7.1-0 (Python 3.12)
2024-09-04 13:08:17 +02:00
Min RK
5c8cb5bb26 Merge pull request #976 from jrdnbradford/add-conf-lockfile
Add TLJH config lockfile
2024-09-04 03:56:12 -07:00
Erik Sundell
8490ef2949 Update lower version bound on filelock, and add comment 2024-09-04 12:21:18 +02:00
Erik Sundell
5172ceb4f9 Update base user environment to miniforge 24.7.1-0 (Python 3.12) 2024-09-04 12:10:29 +02:00
Min RK
634956c33e Update base user environment to miniforge 24.5.0-0 (Python 3.12)
mambaforge is deprecated, mamba has been in miniforge for some time now
2024-08-27 10:54:07 +02:00
Simon Li
5278351eb1 Merge pull request #989 from minrk/hub5
jupyterhub 5
2024-08-25 15:09:36 +01:00
Simon Li
22e08a458b Merge pull request #988 from minrk/fix-launch
fix `-m` invocation of jupyterhub
2024-08-25 14:59:47 +01:00
Min RK
dcbb37688e doc adding users with github, since they won't be allowed by default 2024-08-23 11:40:07 +02:00
Min RK
c492c176bc allow all by default with default FirstUseAuthenticator
doesn't take effect if there's any auth config
2024-08-23 11:40:07 +02:00
Min RK
65c5d78ea5 jupyterhub 5
require 5.1.0 for security fixes
2024-08-23 10:02:58 +02:00
Min RK
5abf657bdf fix -m invocation of jupyterhub
-m jupyterhub.app results in multiple JupyterHub classes being defined
and jupyterhub.app.JupyterHub never being instantiated
2024-08-23 08:32:24 +02:00
Min RK
c49fada1c8 Merge pull request #985 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-08-06 08:59:46 +02:00
pre-commit-ci[bot]
708bbec2a4 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.16.0 → v3.17.0](https://github.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0)
- [github.com/psf/black: 24.4.2 → 24.8.0](https://github.com/psf/black/compare/24.4.2...24.8.0)
- [github.com/pycqa/flake8: 7.1.0 → 7.1.1](https://github.com/pycqa/flake8/compare/7.1.0...7.1.1)
2024-08-05 23:07:01 +00:00
Min RK
729a3ceb28 Merge pull request #984 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-07-02 09:09:38 +02:00
pre-commit-ci[bot]
9c7427923d [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.15.2 → v3.16.0](https://github.com/asottile/pyupgrade/compare/v3.15.2...v3.16.0)
- [github.com/pycqa/flake8: 7.0.0 → 7.1.0](https://github.com/pycqa/flake8/compare/7.0.0...7.1.0)
2024-07-02 00:12:39 +00:00
Yuvi Panda
bcc64e0d8b Merge pull request #983 from josedaudi/patch-1
Added missing details on how to add custom domain from manual HTTPS  configuration
2024-06-10 19:13:05 -07:00
Joseph Daudi
a5f966927f Added missing details on how to add custom domain form manual HTTPS configuration 2024-05-23 21:49:15 +03:00
Erik Sundell
d0fb92eda5 Merge pull request #981 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-05-07 07:39:17 +02:00
pre-commit-ci[bot]
52478abb65 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black: 24.3.0 → 24.4.2](https://github.com/psf/black/compare/24.3.0...24.4.2)
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0)
2024-05-06 22:03:37 +00:00
Jordan Bradford
96ac0d3538 Add filelock to dev-requirements 2024-04-06 11:03:24 -04:00
Jordan Bradford
13ed32b499 Add lockfile to integration tests 2024-04-06 10:51:51 -04:00
Jordan Bradford
bdbb3adbbc Add config lockfile 2024-04-06 10:49:07 -04:00
Erik Sundell
2b29bd9f0a Merge pull request #975 from consideRatio/pr/fix-tests
tests: fix to catch test failure earlier when they really happen
2024-04-04 22:53:32 +02:00
Erik Sundell
8fd41cc77a tests: strengthen tests to fail earlier on issues 2024-04-04 22:39:33 +02:00
Erik Sundell
7e39e993da Merge pull request #962 from jrdnbradford/validate-config-yaml
Validate tljh specific config
2024-04-04 07:45:42 +02:00
Jordan Bradford
5469e21e74 Fix removal of https.enabled 2024-04-03 16:19:45 -04:00
Jordan Bradford
38a01e8406 Use default true for validate 2024-04-03 16:09:18 -04:00
Jordan
9bcfa70326 Update tljh/config.py
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
2024-04-03 16:05:16 -04:00
Jordan Bradford
7474b876f1 Remove unneeded validate code 2024-04-03 16:04:29 -04:00
Jordan
5ae31ce169 Update tljh/config.py
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
2024-04-03 16:03:14 -04:00
Jordan
b94a281ff8 Update tljh/config.py
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
2024-04-03 16:03:05 -04:00
Jordan
67dd3c8abe Update tljh/config.py
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
2024-04-03 16:02:55 -04:00
Jordan Bradford
c578a7bec0 Update step name 2024-04-03 14:10:16 -04:00
Jordan Bradford
51f8470535 Fix unit tests with pip 2024-04-03 14:05:32 -04:00
Jordan Bradford
196208ae58 Remove argparse.BooleanOptionalAction for Python 3.8 compatibility 2024-04-03 13:30:32 -04:00
Erik Sundell
242dca4376 Merge pull request #973 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-04-02 09:54:01 +02:00
pre-commit-ci[bot]
5169301a0a [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.15.0 → v3.15.2](https://github.com/asottile/pyupgrade/compare/v3.15.0...v3.15.2)
- [github.com/PyCQA/autoflake: v2.2.1 → v2.3.1](https://github.com/PyCQA/autoflake/compare/v2.2.1...v2.3.1)
- [github.com/psf/black: 24.1.1 → 24.3.0](https://github.com/psf/black/compare/24.1.1...24.3.0)
2024-04-01 22:10:42 +00:00
Jordan Bradford
4ddd798928 Add docstring from config_schema.py 2024-03-27 12:08:28 -04:00
Jordan Bradford
f921acc183 Bump ubuntu image to 22.04 2024-03-20 15:09:07 -04:00
Jordan Bradford
46e4045568 Update test_proxy tests 2024-03-20 15:08:21 -04:00
Jordan Bradford
743f729902 Update set_config_value tests 2024-03-20 14:45:36 -04:00
Jordan Bradford
48fe440372 Add --[no-]validation flag for tljh-config 2024-03-20 14:36:49 -04:00
Min RK
8348d4ad96 Merge pull request #968 from consideRatio/pr/fix-tests
Re-install conda/mamba for every tljh upgrade (doesn't imply upgrade)
2024-03-18 09:26:46 +01:00
Erik Sundell
579b7eb5ba Merge pull request #969 from davidalber/fix-install-typo
Fix typo and replace word
2024-03-09 19:38:05 +01:00
Erik Sundell
0248785aed Merge pull request #970 from davidalber/reword-sg-sentence
Reword documentation sentence
2024-03-09 19:37:18 +01:00
David Alber
beed70060c Reword sentence 2024-03-01 12:09:17 -08:00
David Alber
d9a0a5fc7a Fix typo and replace word: "disitnguishing" --> "distinctive"
The typo is of "distinguishing", but "distinctive" makes more sense
to me in the context of the sentence it is in.
2024-03-01 11:50:47 -08:00
Erik Sundell
4e397bc687 Re-install conda/mamba for every tljh upgrade (doesn't imply upgrade) 2024-02-26 16:44:12 +01:00
Erik Sundell
7d8a84860f tests: show mamba list for the user environment before/after upgrade
This can help us check if a package has been installed from PyPI via
pip, or from conda-forge or other channel via conda/mamba.
2024-02-26 16:44:12 +01:00
Erik Sundell
2fe9912333 tests: test pip install plugin with no-dependency package
This is a simplification to help ensure we don't run into issues like
below because requests gets installed via pip.

```
RemoveError: 'requests' is a dependency of conda and cannot be removed from conda's operating environment.
```
2024-02-26 16:44:12 +01:00
Erik Sundell
02c3d7539b Merge pull request #967 from consideRatio/pr/ci-add-tests
ci: add tests for debian 12 and ubuntu 24.04
2024-02-26 16:43:57 +01:00
Erik Sundell
10ba571bde ci: add test for ubuntu 24.04 2024-02-26 16:24:29 +01:00
Erik Sundell
7fa4e2bcec ci: add test for debian 12 2024-02-24 21:47:36 +01:00
Erik Sundell
2faf0d3a5f Merge pull request #963 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-02-06 08:26:09 +01:00
pre-commit-ci[bot]
b35851f2b7 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2024-02-05 20:29:33 +00:00
pre-commit-ci[bot]
9755938d7d [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black: 23.12.1 → 24.1.1](https://github.com/psf/black/compare/23.12.1...24.1.1)
- [github.com/pycqa/flake8: 6.1.0 → 7.0.0](https://github.com/pycqa/flake8/compare/6.1.0...7.0.0)
2024-02-05 20:27:06 +00:00
Jordan Bradford
1f7d6d1c55 Add doc string for validate_config 2024-02-05 14:52:31 -05:00
Jordan Bradford
9060267458 Add LetsEncrypt.staging; run pre-commit 2024-02-03 13:39:17 -05:00
Jordan Bradford
4912cffe65 Fix parse_value 2024-02-03 13:27:58 -05:00
Jordan Bradford
d0c9aa263a Remove TLS required properties 2024-02-03 13:18:39 -05:00
Jordan Bradford
fa363658df Update schema based on values in configurer.py 2024-02-03 13:08:27 -05:00
Jordan Bradford
166eba6735 Switch from JSON to py 2024-02-03 12:48:31 -05:00
Jordan Bradford
5a0de137d2 Do not allow additionalProperties for Users 2024-02-02 23:22:57 -05:00
Jordan Bradford
929536de7b Run pre-commit hooks 2024-02-02 23:07:38 -05:00
Jordan Bradford
ef5c6c56b7 print human readable error message 2024-02-02 23:06:31 -05:00
Jordan Bradford
fb01dea5e4 Working schema path 2024-02-02 23:01:36 -05:00
Jordan Bradford
78d4b7fbc4 Test config setup 2024-02-02 22:52:16 -05:00
Jordan Bradford
d292457803 Initial config setup 2024-02-02 21:51:23 -05:00
Erik Sundell
6dd2ee812a Merge pull request #961 from jupyterhub/dependabot/github_actions/actions/cache-4
build(deps): bump actions/cache from 3 to 4
2024-02-01 10:57:26 +01:00
Erik Sundell
641a02ed07 Merge pull request #960 from jupyterhub/dependabot/github_actions/codecov/codecov-action-4
build(deps): bump codecov/codecov-action from 3 to 4
2024-02-01 10:25:36 +01:00
dependabot[bot]
1c9301e4d7 build(deps): bump actions/cache from 3 to 4
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 05:26:48 +00:00
dependabot[bot]
723c4e756d build(deps): bump codecov/codecov-action from 3 to 4
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 05:26:45 +00:00
Erik Sundell
eeae5f06be Merge pull request #959 from consideRatio/pr/add-azure-ad-dependency
Add missing oauthenticator dependency for AzureADOAuthenticator
2024-01-25 07:05:32 +01:00
Erik Sundell
4abf3f003f Add optional oauthenticator dependency for AzureAD 2024-01-04 02:28:28 +01:00
Erik Sundell
3da9743640 Merge pull request #956 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-01-04 01:06:36 +01:00
Erik Sundell
aec331b114 Merge pull request #958 from jupyterhub/dependabot/github_actions/actions/setup-python-5
build(deps): bump actions/setup-python from 4 to 5
2024-01-04 00:51:38 +01:00
pre-commit-ci[bot]
0f5a0ccbe0 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/pycqa/isort: 5.12.0 → 5.13.2](https://github.com/pycqa/isort/compare/5.12.0...5.13.2)
- [github.com/psf/black: 23.10.1 → 23.12.1](https://github.com/psf/black/compare/23.10.1...23.12.1)
- [github.com/pre-commit/mirrors-prettier: v3.0.3 → v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.3...v4.0.0-alpha.8)
2024-01-01 20:22:48 +00:00
dependabot[bot]
f1c7e2d90f build(deps): bump actions/setup-python from 4 to 5
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-01 05:51:55 +00:00
Min RK
5cb6b69020 Merge pull request #949 from pdebuyl/patch-1
Fix URL syntax in nativeauth.md
2023-11-22 14:25:22 +01:00
Min RK
7faf997c7b Merge pull request #953 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-11-07 10:03:44 +01:00
pre-commit-ci[bot]
79134e3a2f [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.14.0 → v3.15.0](https://github.com/asottile/pyupgrade/compare/v3.14.0...v3.15.0)
- [github.com/psf/black: 23.9.1 → 23.10.1](https://github.com/psf/black/compare/23.9.1...23.10.1)
- [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0)
2023-11-06 20:28:01 +00:00
Pierre de Buyl
e869633871 Fix URL syntax in nativeauth.md 2023-10-27 11:56:22 +02:00
Erik Sundell
793f6237b4 Merge pull request #945 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-10-03 12:42:12 +02:00
pre-commit-ci[bot]
caab46e08a [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.10.1 → v3.14.0](https://github.com/asottile/pyupgrade/compare/v3.10.1...v3.14.0)
- [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1)
2023-10-03 10:35:43 +00:00
Erik Sundell
dcb91d4e6a Merge pull request #943 from jupyterhub/dependabot/github_actions/actions/checkout-4
build(deps): bump actions/checkout from 3 to 4
2023-10-01 10:12:17 +02:00
dependabot[bot]
ed6ff645c2 build(deps): bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-01 05:45:52 +00:00
YuviPanda
291c096a17 Fix argument name of channels 2023-09-29 14:47:53 -07:00
pre-commit-ci[bot]
eafc10e82a [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-09-29 21:39:30 +00:00
YuviPanda
58a679f584 Fix how channels are added to -c command 2023-09-29 14:39:12 -07:00
pre-commit-ci[bot]
9bde7e4680 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-09-29 21:35:50 +00:00
YuviPanda
6359bf498c Merge remote-tracking branch 'upstream/main' into conda-channels 2023-09-29 14:27:25 -07:00
Yuvi Panda
44bdaf2fa4 Merge pull request #939 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-09-29 14:19:34 -07:00
pre-commit-ci[bot]
1d1aefd518 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/PyCQA/autoflake: v2.2.0 → v2.2.1](https://github.com/PyCQA/autoflake/compare/v2.2.0...v2.2.1)
- [github.com/pre-commit/mirrors-prettier: v3.0.0 → v3.0.3](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.0...v3.0.3)
2023-09-05 08:11:29 +00:00
Min RK
542cf4de6b Merge pull request #935 from schwebke/main
adapt install documentation for new /lab default interface
2023-08-14 11:32:15 +02:00
Kai G. Schwebke
46b49c819c adapt install documentation for new /lab default interface 2023-08-12 08:47:23 +02:00
Erik Sundell
c7507fd799 Bump to 1.0.1.dev 2023-08-11 14:46:52 +02:00
Erik Sundell
fc8e19b1b5 Bump to 1.0.0 2023-08-11 14:46:14 +02:00
Erik Sundell
1f21e3cb26 Merge pull request #933 from consideRatio/pr/add-1.0.0-changelog
Update changelog for 1.0.0 release
2023-08-11 14:45:03 +02:00
Erik Sundell
b13f09564d docs: update changelog for 1.0.0 release 2023-08-11 14:31:41 +02:00
Min RK
c40d95c02a Merge pull request #932 from consideRatio/pr/add-upgrade-docs
docs: add docs about environments and upgrades
2023-08-11 11:46:45 +02:00
Min RK
c35a4cbe65 typo 2023-08-11 11:46:37 +02:00
Erik Sundell
fb78464dec docs: fix broken link 2023-08-10 15:19:26 +02:00
Erik Sundell
9efe59f4f7 docs: add how-to section on making upgrades 2023-08-10 15:18:25 +02:00
Erik Sundell
e14b8d8b77 docs: add section on whats done during upgrades 2023-08-10 15:17:03 +02:00
Erik Sundell
cc00bf3a1a docs: add docs on the system, hub, user environments 2023-08-10 15:16:11 +02:00
Erik Sundell
c6d86d059f docs: ensure intersphinx extension is enabled 2023-08-10 15:14:37 +02:00
Erik Sundell
4cd5da40c3 Update to jupyterhub >=4.0.2,<5 2023-08-10 15:14:09 +02:00
Erik Sundell
55db9c5d0b Merge pull request #775 from raybellwaves/patch-4
Launch into `/lab` by default by changing TLJH config's default value
2023-08-09 15:28:24 +02:00
Erik Sundell
e893959ce5 Update tests to reflect jupyterlab by default 2023-08-09 10:31:32 +02:00
Erik Sundell
5fdc31f9a9 docs: adjust docs to reflect jupyterlab as default 2023-08-09 10:28:46 +02:00
Ray Bell
a8c6c40b2b switch jhub to classic test 2023-08-09 09:40:27 +02:00
Ray Bell
854f5edd06 WIP: try default_app 2023-08-09 09:40:26 +02:00
Erik Sundell
0122a21c71 Merge pull request #922 from jrdnbradford/override-default-settings-docs
Add `JupyterLab` setting overrides docs
2023-08-09 09:30:50 +02:00
pre-commit-ci[bot]
e9de9f6042 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-08-09 07:28:47 +00:00
Erik Sundell
2b1b6787b8 Apply suggestions from code review 2023-08-09 09:28:37 +02:00
Erik Sundell
3a7c6f7b38 Merge pull request #929 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-08-09 09:23:08 +02:00
Erik Sundell
1a83791191 Merge pull request #928 from jtpio/lab4-nb7
Update Notebook, JupyterLab, Jupyter Resource Usage
2023-08-09 09:22:58 +02:00
Jeremy Tuloup
0f03f40eff Re-add nbgitpuller 2023-08-09 05:25:21 +00:00
pre-commit-ci[bot]
6801c68333 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.8.0 → v3.10.1](https://github.com/asottile/pyupgrade/compare/v3.8.0...v3.10.1)
- [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0)
- [github.com/pre-commit/mirrors-prettier: v3.0.0-alpha.9-for-vscode → v3.0.0](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.0-alpha.9-for-vscode...v3.0.0)
- [github.com/pycqa/flake8: 6.0.0 → 6.1.0](https://github.com/pycqa/flake8/compare/6.0.0...6.1.0)
2023-08-01 08:36:35 +00:00
Jeremy Tuloup
2fbe803530 add missing import 2023-08-01 07:40:29 +00:00
pre-commit-ci[bot]
0da7d09298 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-08-01 07:39:11 +00:00
Jeremy Tuloup
91af54ade3 typo 2023-08-01 07:38:54 +00:00
Jeremy Tuloup
645251a134 update test for labextensions 2023-08-01 07:38:32 +00:00
Jeremy Tuloup
dfeddc2e53 tmp: do not check nbgitpuller 2023-08-01 07:01:58 +00:00
Jeremy Tuloup
4b13303d01 test nbgitpuller only 2023-08-01 07:01:41 +00:00
Jeremy Tuloup
ad1455e4da update jupyter server command for now 2023-08-01 06:52:56 +00:00
Jeremy Tuloup
6f38ec6a95 test for lab extensions 2023-08-01 06:43:49 +00:00
Jeremy Tuloup
b6ee97c770 do not check the lab version 2023-08-01 06:28:39 +00:00
Jeremy Tuloup
bdfabc5ce8 Update tests 2023-08-01 06:26:18 +00:00
Jeremy Tuloup
86a4bb67c8 Update Notebook, JupyterLab, Jupyter Resource Usage 2023-08-01 06:12:05 +00:00
Erik Sundell
3ea72c8a85 Bump to 1.0.0b1 2023-07-07 18:33:24 +02:00
Erik Sundell
b76db83c36 Add tbump config 2023-07-07 18:28:55 +02:00
Erik Sundell
301f9db059 Merge pull request #888 from consideRatio/pr/add-changelog-1.0.0
Add changelog for 1.0.0b1
2023-07-07 18:22:57 +02:00
Erik Sundell
bdd0b3124e Bump oauthenticator to 16.0.2 and update 1.0.0b1 release date 2023-07-07 18:21:52 +02:00
Erik Sundell
0ce328555c docs: put changelog in tljh's built documentation under a new reference section 2023-07-07 18:21:52 +02:00
Erik Sundell
51c501b9f1 Add changelog for 1.0.0b1 2023-07-07 18:21:52 +02:00
Erik Sundell
156553937b Merge pull request #924 from consideRatio/pr/update-oauthenticator-16
breaking: update oauthenticator from 15.1.0 to >=16.0.2,<17, make tljh auth docs link out
2023-07-07 18:17:31 +02:00
Erik Sundell
c6fed712d4 docs: add warning to authenticator docs, linking to official docs 2023-07-06 21:35:57 +02:00
Erik Sundell
831a368b5a breaking: update oauthenticator from 15.1.0 to >=16.0.2,<17 2023-07-06 21:35:40 +02:00
Erik Sundell
e1d25e721f Merge pull request #923 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-07-05 14:34:18 +02:00
pre-commit-ci[bot]
d20344cb1d [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.4.0 → v3.8.0](https://github.com/asottile/pyupgrade/compare/v3.4.0...v3.8.0)
- [github.com/PyCQA/autoflake: v2.1.1 → v2.2.0](https://github.com/PyCQA/autoflake/compare/v2.1.1...v2.2.0)
2023-07-04 06:28:38 +00:00
pre-commit-ci[bot]
259d2ff11d [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-06-14 02:10:29 +00:00
Jordan Bradford
3753a3c775 Update heading 1 2023-06-13 22:05:55 -04:00
Jordan Bradford
bc09121677 Add JupyterLab setting overrides docs 2023-06-13 21:57:17 -04:00
Erik Sundell
f55192d922 Merge pull request #921 from consideRatio/pr/add-comment
test refactor: add comment about python/conda/mamba
2023-06-09 17:23:45 +02:00
Erik Sundell
54bc5fb81b test refactor: add comment about python/conda/mamba 2023-06-09 17:08:12 +02:00
Erik Sundell
55eec52fd9 Merge pull request #920 from minrk/upgrade-mamba-conda
--force-reinstall conda to ensure it's working before we try to install conda packages
2023-06-09 15:56:30 +02:00
Min RK
39b1e1a7c7 preserve version pin when reinstalling conda
avoids upgrade on older versions
2023-06-09 15:33:36 +02:00
Min RK
ee23e041de reinstall conda/mamba in a separate, unconditional step
makes it more likely that subsequent conda installs will succeed

- fix indentation on the upgrade steps so they aren't run every iteration
- no longer need to bump required versions
2023-06-09 15:00:00 +02:00
Min RK
29b354b42b use force-reinstall
not deprecated --force
2023-06-09 14:16:27 +02:00
Min RK
4cc55df2a4 force upgrade of conda itself
if conda upgrade conda is broken, we are in trouble

this is required to avoid the RemoveError
2023-06-09 14:08:03 +02:00
Min RK
4f0179a84c bump minimum conda/mamba versions
an old conda bug causes RemoveError: requests is a dependency of conda
when installing other packages

upgrading conda itself avoids this bug.
It's unclear what the true minimum version is to fix this,
but the important thing is that it will be upgraded if it's still the version in 0.2.0 (4.10),
so pick the version from today which we know works
2023-06-09 13:58:32 +02:00
Erik Sundell
e6fe1f2ddf Merge pull request #919 from consideRatio/pr/isolate-bootstraptests-to-a-dedicated-job
test refactor: put bootstrap tests in an isolated job, save ~3 min in each of the integration test jobs
2023-06-09 13:11:56 +02:00
Erik Sundell
33643ba25b Merge pull request #906 from jrdnbradford/google-troubleshooting-updates
Google Cloud troubleshooting and configuration updates
2023-06-09 13:00:36 +02:00
Erik Sundell
0c914afeab test refactor: put bootstrap tests in an isolated job 2023-06-09 12:51:09 +02:00
Min RK
d5f688eebd Merge pull request #916 from consideRatio/pr/refactor-tests
maint: refactor tests, fix upgrade tests (now correctly failing)
2023-06-09 12:43:48 +02:00
Erik Sundell
cb200d9702 test refactor: comment about test_bootstrap.py 2023-06-09 03:40:36 +02:00
Erik Sundell
b02a8b044f test refactor: mitigate persisted state between tests 2023-06-09 03:37:39 +02:00
Erik Sundell
b1822d7098 test refactor: small details in test_hub.py 2023-06-09 03:37:39 +02:00
Erik Sundell
1d203ccd2a test refactor: reduce time spent waiting on culling/not culling 2023-06-09 03:37:39 +02:00
Erik Sundell
3e9ee8ca8f test refactor: remove test with broken assumption
To remove a user from the admin list doesn't matter, even though its
clearly something one may expect should matter.

The issue is that JupyterHub itself makes use of the admin_users list as
a way to declare new admins, not to remove users having been marked as
admin in the past.

What to do about this is not clear, but having a test for this doesn't
make sense.
2023-06-09 03:37:39 +02:00
Erik Sundell
ec3ee03dc8 test refactor: ignore code coverage warning 2023-06-09 03:37:39 +02:00
Erik Sundell
d1c2e51525 test refactor: avoid a redundant server startup test 2023-06-09 03:37:39 +02:00
Erik Sundell
b1c7e53be4 test refactor: try decouple admin tests from other tests 2023-06-09 03:37:39 +02:00
Erik Sundell
111e9bee86 test refactor: combine two separate installation setups 2023-06-09 03:37:39 +02:00
Erik Sundell
40b88cb780 test refactor: update simplest plugin tests
With this refactor, the simplest plugin stops interfering with other
tests.
2023-06-09 03:34:06 +02:00
Erik Sundell
971b7d5c7e test refactor: show logs from jupyterhub and traefik after tests 2023-06-09 03:34:06 +02:00
Erik Sundell
cdc4a9d388 test refactor: reduce timeout for starting user server, sleep less 2023-06-09 03:34:06 +02:00
Erik Sundell
f127322aa3 test refactor: be more generous with timeout values 2023-06-09 03:34:06 +02:00
Erik Sundell
7f873966b5 test refactor: combine admin and plugin tests 2023-06-09 03:34:06 +02:00
Erik Sundell
835c6a1154 test refactor: refactoring of .github/integration-test.py 2023-06-09 03:34:06 +02:00
Erik Sundell
8f4cee1e46 test refactor: test_bootstrap.py, let container mount local dir and expose port 2023-06-09 03:34:06 +02:00
Erik Sundell
73e8eb2252 test refactor: slim down workflow for readability 2023-06-09 03:34:06 +02:00
Erik Sundell
e579d288c7 test refactor: remove re-specification of hub_url 2023-06-09 03:34:06 +02:00
Erik Sundell
2182f246ae test refactor: remove redundant pytest.mark.asyncio 2023-06-09 03:34:06 +02:00
Erik Sundell
06edf1a76b test refactor: put pytest config in pyproject.toml 2023-06-09 03:34:06 +02:00
Erik Sundell
9e95961886 bootstrap.py: extract get_os_release_variable to make testing easier 2023-06-08 23:13:26 +02:00
Erik Sundell
ecf11f0f27 bootstrap.py: let --version flag take precedence over env vars 2023-06-08 23:13:26 +02:00
Erik Sundell
ab947333d2 bootstrap.py: fix docstring summarizing --help output 2023-06-08 23:12:28 +02:00
Erik Sundell
d4c6da52e1 maint: let installer ensure /etc/sudoers.d directory exists 2023-06-08 23:11:58 +02:00
Erik Sundell
7974981f2d Merge pull request #915 from consideRatio/pr/update-systemdspawner
Update systemdspawner from version 0.17.* to >=1.0.1,<2
2023-06-08 15:37:16 +02:00
Erik Sundell
c5eae3386a SystemdSpawner 1: don't prevent admins from sudo / privilege escalation
Having upgraded systemdspawner to 1.0.0, its configuration option
`disable_user_sudo` now defaults to True. This would be a breaking
unwanted change for our jupyterhub admin users who are configured with
passwordless sudo.

Its unlikeley a breaking change for other users, but could be if they
are granted sudo rights without being a jupyterhub admin. But, if they
are, then they could grant themself such rights anyhow so its reasonable
to assume jupyterhub admins only should have sudo rights in a TLJH
installation.
2023-06-08 15:16:35 +02:00
Erik Sundell
a373b2108c Update systemdspawner from v0.17 to v1.0.1+ 2023-06-08 15:16:35 +02:00
Erik Sundell
84ea18991a Merge pull request #917 from jrdnbradford/docker-mount-source-fix
Quote `pwd` to prevent error if dir has spaces
2023-06-06 17:06:48 +02:00
Jordan Bradford
08a787fd82 Quote pwd to prevent error if dir has spaces 2023-06-06 09:40:32 -04:00
Erik Sundell
f00e17b3d7 Merge pull request #912 from consideRatio/pr/remove-configurator
Stop bundling jupyterhub-configurator which has been disabled by default
2023-06-06 12:16:47 +02:00
Erik Sundell
93515a8086 Merge pull request #914 from consideRatio/pr/fix-typo-in-bounding-systemdspawner
Fix recently introduced failure to upper bound systemdspawner
2023-06-06 00:09:52 +02:00
Erik Sundell
78bc5bcedd Fix recently introduced failure to upper bound systemdspawner 2023-06-05 23:12:20 +02:00
Jordan Bradford
6a7cbc8681 Add intro description of boot disk 2023-06-05 10:53:12 -04:00
Erik Sundell
ebb3d9bef1 Stop bundling jupyterhub-configurator which has been disabled by default 2023-06-02 16:57:39 +02:00
pre-commit-ci[bot]
232d595d49 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-29 01:09:08 +00:00
Jordan Bradford
b5bb25b559 Add instance logs and disk space to troubleshooting page 2023-05-28 20:58:33 -04:00
Jordan Bradford
9a1b600d99 Add Google Cloud config page 2023-05-28 20:56:57 -04:00
Min RK
2d645a7d89 Merge pull request #905 from nsurleraux-railnova/bind_address
Add a Traefik configuration to listen on a specific address (#903)
2023-05-25 15:29:37 +02:00
pre-commit-ci[bot]
0f385af837 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-25 12:56:22 +00:00
Nicolas Surleraux
d637325152 Add https requirements in tests 2023-05-25 14:41:26 +02:00
Min RK
ca476c97cf Merge pull request #900 from consideRatio/pr/bump-nativeauth-and-configurator
Update nativeauthenticator, tmpauthenticator, and jupyterhub-configurator
2023-05-24 12:36:30 +02:00
Nicolas Surleraux
bf360ec332 Enable https in test_listen_address so it renders 2023-05-24 11:53:18 +02:00
Nicolas Surleraux
bbc6c465ac Allow to listen on a specific address via TLJH config 2023-05-24 11:42:27 +02:00
Erik Sundell
1e095f3a3e Merge pull request #902 from jrdnbradford/add-user-env
Add user env doc files
2023-05-24 11:02:52 +02:00
Erik Sundell
88ec6f4038 docs: setup redirects to ensure we don't get broken links 2023-05-24 10:56:37 +02:00
pre-commit-ci[bot]
31add381e4 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-23 00:52:06 +00:00
Jordan Bradford
5803e2ab3b Re-add user env files 2023-05-22 20:33:07 -04:00
Jordan Bradford
14af23ea2e Add link to resource resizing page 2023-05-22 20:32:27 -04:00
Jordan Bradford
230f16ba4a Fix broken link to admin page 2023-05-22 20:31:22 -04:00
Jordan Bradford
d700d28b1f Update package and user included files to .md 2023-05-22 20:28:16 -04:00
Erik Sundell
270ec00343 Update tmpauthenticator from 0.6 to 1.0.0 2023-05-22 16:09:54 +02:00
Erik Sundell
27a94f4645 Update jupyterhub-configurator to latest 2023-05-22 12:38:27 +02:00
Erik Sundell
d4ef212b05 Update nativeauthenticator from 1.1.0 to 1.2.0 to support jh4 2023-05-22 12:37:51 +02:00
Erik Sundell
c6c3c96f9a Merge pull request #890 from consideRatio/pr/only-upgrade-whats-unconditionally-required
Only upgrade jupyterhub in user env when upgrading tljh, ensure pip>=23.1.2 in user env
2023-05-22 12:23:10 +02:00
Erik Sundell
21312b2cfd user env: upgrade jh based on hub spec 2023-05-18 23:56:46 +02:00
Erik Sundell
c1aa30a479 hub env: remove pip pinning, always upgrade pip 2023-05-18 23:52:14 +02:00
Erik Sundell
6388d390e1 refactor: improve readability of a section 2023-05-18 23:51:41 +02:00
Erik Sundell
9c83e9000e user env: ensure pip>=23.1.2 on install 2023-05-18 23:51:41 +02:00
Erik Sundell
eaa16babb5 hub env: use req. file and add lower bounds for readability 2023-05-18 23:51:41 +02:00
Erik Sundell
a86e4ce153 user env: only upgrade jupyterhub in user env when upgrading tljh 2023-05-18 23:51:29 +02:00
Erik Sundell
282af833bf Merge pull request #898 from jrdnbradford/update-google-auth-docs
Update Google auth docs
2023-05-18 17:05:07 +02:00
pre-commit-ci[bot]
eeb76c0894 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-18 14:08:35 +00:00
Jordan
8d7b9b5f92 Merge branch 'jupyterhub:main' into update-google-auth-docs 2023-05-18 10:02:28 -04:00
Erik Sundell
814c6daa40 Merge pull request #861 from minrk/traefik-v2
Traefik v2, TraefikProxy v1
2023-05-18 14:25:03 +02:00
Erik Sundell
324ded0003 Consistent whitespace chomping in jinja templates
Always chomp left, never right. This is what we do in the helm chart templates and has been very easy to be consistent with for a good result with little to no issues.
2023-05-18 11:18:09 +02:00
Jordan Bradford
be4580c21e Update user config language 2023-05-17 23:01:01 -04:00
Jordan Bradford
8ecb158bc9 Update Google auth docs 2023-05-17 22:58:07 -04:00
Min RK
c5dec7f3b4 update test expectations for traefik ssl 2023-05-17 09:41:55 +02:00
Min RK
aee707c68c Specify tls cipher suites
Co-authored-by: Mridul Seth <mail@mriduls.com>
2023-05-16 21:12:10 +02:00
Min RK
59648b79d4 increase progress page test timeout
seems to be why it fails sometimes
2023-05-16 21:10:44 +02:00
Min RK
dfc8b5557c debugging progress page output 2023-05-16 21:07:20 +02:00
Min RK
33ac7239fe jupyterhub-traefik-proxy 1.0 2023-05-16 20:58:53 +02:00
Erik Sundell
05ed42a0b1 Merge pull request #896 from MridulS/arrow_key_disable_navigation
docs: disable navigation with arrow keys
2023-05-16 19:23:34 +02:00
Mridul Seth
f0de1db607 docs: disable navigation with arrow keys 2023-05-16 21:01:15 +04:00
Erik Sundell
95a24e8968 Merge pull request #895 from minrk/hub-path
ensure hub env is on $PATH in jupyterhub service
2023-05-16 18:30:13 +02:00
Min RK
7f53a4f14c update traefik checksums 2023-05-16 14:57:39 +02:00
Min RK
5763758fa4 traefik v2.10.1
Co-authored-by: Erik Sundell <erik.i.sundell@gmail.com>
2023-05-16 14:53:27 +02:00
Min RK
0e76f6dff9 support letsencrypt staging server
for easier testing
2023-05-16 13:27:23 +02:00
Min RK
776ff5273b update letsEncrypt config after testing
verified this works now
2023-05-16 13:27:23 +02:00
Min RK
2600e5ddc4 ensure hub env is on $PATH in jupyterhub service
required for `--upgrade-db` to work, since it assumes `alembic` is on $PATH
2023-05-16 13:24:16 +02:00
Min RK
a58956f14b update for traefik v2, treafik-proxy v1
- tls config is no longer allowed in static config file, add separate dynamic config
- no longer need to persist auth config ourselves (TraefikProxy handles this)
- make sure to reload proxy before reloading hub in tests
2023-05-16 11:47:23 +02:00
Min RK
e353ab80c3 traefik 2.9.9
- traefik releases are tarballs now
- move traefik platform check to download function
  for easier unit testing on unsupported platforms
2023-05-15 15:27:52 +02:00
Erik Sundell
af1511cc46 Merge pull request #892 from consideRatio/pr/upgrade-pip
Upgrade pip in hub env from 21.3 to to 23.1 when bootstrap script runs
2023-05-15 11:54:41 +02:00
Erik Sundell
2fdae421da Merge pull request #893 from consideRatio/pr/add-pre-commit-isort-and-autoflake
pre-commit: add isort and autoflake
2023-05-15 11:54:17 +02:00
pre-commit-ci[bot]
e95942d61b [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-15 08:51:36 +00:00
Erik Sundell
b366d6b63f Remove unused copy-paste remnants in tests 2023-05-15 10:49:56 +02:00
Erik Sundell
c093aa0e50 pre-commit: add autoflake and isort, include autoformatter config 2023-05-15 10:43:59 +02:00
Erik Sundell
6622c60d01 Merge pull request #891 from consideRatio/pr/pre-com-up
pre-commit.ci configured to update pre-commit hooks on a monthly basis
2023-05-15 10:33:41 +02:00
Erik Sundell
4c6d54c79d Upgrade pip in hub env from 21.3 to to 23.1 when bootstrap script runs 2023-05-13 23:30:26 +02:00
Erik Sundell
7b8d6dffcc pre-commit.ci configured to update pre-commit hooks on a monthly basis 2023-05-13 23:26:54 +02:00
Erik Sundell
3e2f8cabfd Merge pull request #887 from consideRatio/pr/awscogito-example
docs(awscognito): add custom claims example
2023-05-13 20:04:49 +02:00
Erik Sundell
186ae7171c Merge pull request #881 from consideRatio/curvenote/main
added `remove_named_servers` setting for jupyterhub-idle-culler
2023-05-13 20:04:15 +02:00
Fabian Fischer
8dba109c43 docs(awscognito): add custom claims example
After struggling with my custom department claim and getting helped in https://discourse.jupyter.org/t/genericauthenticator-with-cognito-how-to-check-for-department-match/18105/1 I wanted to give back to the community.

Rebased by Erik Sundell, originally committed in .rst, now transferred
to .md
2023-05-13 19:56:56 +02:00
Min RK
bdc90d6ba4 Merge pull request #880 from consideRatio/pr/bump-jupyterhub
update: jupyterhub 4
2023-05-12 00:16:58 +02:00
pre-commit-ci[bot]
922db1ae8e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-05-11 21:47:14 +00:00
Erik Sundell
c09e83a6c8 Pass xsrf token in tests to /hub/api requests 2023-05-11 23:46:55 +02:00
Erik Sundell
b3365fbe45 update: jupyterhub 4 2023-05-11 23:19:27 +02:00
Erik Sundell
7431151ed3 Merge pull request #886 from minrk/test-hub-version
add integration test for hub version
2023-05-11 23:16:44 +02:00
Min RK
83452500fb Merge pull request #882 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-05-11 10:56:07 +02:00
Min RK
c1df7e9735 integration test: include pip freeze in output 2023-05-11 10:55:35 +02:00
Min RK
1dd25392a2 add integration test for hub version
make sure the hub has the version we expect
2023-05-11 10:55:17 +02:00
pre-commit-ci[bot]
5cbd7533e8 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v3.3.1 → v3.4.0](https://github.com/asottile/pyupgrade/compare/v3.3.1...v3.4.0)
- [github.com/pre-commit/mirrors-prettier: v3.0.0-alpha.6 → v3.0.0-alpha.9-for-vscode](https://github.com/pre-commit/mirrors-prettier/compare/v3.0.0-alpha.6...v3.0.0-alpha.9-for-vscode)
2023-05-09 05:05:28 +00:00
Erik Sundell
b048a56a30 Merge pull request #883 from audiodude/update-do
Docs: Update DigitalOcean install instructions with new screenshot for "user data"
2023-05-08 23:10:37 +02:00
Travis Briggs
b9e3cfe867 Update cost of Digital Ocean server and add new screenshot of Advanced Options -> User Data 2023-04-24 19:26:56 -07:00
pre-commit-ci[bot]
e6994aab2d [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-04-24 00:10:25 +00:00
stevejpurves
836056f404 💚 green tests 2023-04-24 02:05:30 +02:00
stevejpurves
3f180a939f 🧪 add test 2023-04-24 02:05:30 +02:00
stevejpurves
fc34bc74aa added remove_named_servers setting 2023-04-24 02:05:28 +02:00
Erik Sundell
4aa96d92c3 Merge pull request #879 from Rom1deTroyes/patch-1
Typo : username -> admin-user-name
2023-04-24 01:58:02 +02:00
Romain Heller
ad5743c837 Typo : username -> admin-user-name 2023-04-23 21:52:47 +02:00
Erik Sundell
cca199ea68 Merge pull request #878 from consideRatio/pr/fix-readme-badge
docs: fix readme badge for tests
2023-04-17 15:13:16 +02:00
Erik Sundell
7cc4ebc7b2 docs: fix readme badge for tests 2023-04-17 15:08:07 +02:00
Erik Sundell
578e0a1fa1 Merge pull request #858 from minrk/update-base-env
Update base user environment to mambaforge 23.1.0-1 (Python 3.10)
2023-04-17 11:54:10 +02:00
Min RK
2fcd8efde3 increase test timeout
15 minutes isn't always enough for integration tests
2023-04-17 11:00:18 +02:00
Min RK
f13a31c20c update upgrade expectation for test_installer
it may not upgrade all the way to 1.4 if other packages are pinned in the base env
2023-04-17 10:56:24 +02:00
Erik Sundell
438df10e1a Fix tests for update of mambaforge from 22.11.1-4 to 23.1.0-1 2023-04-17 10:26:38 +02:00
Min RK
000e4f2540 sync with main 2023-04-17 09:44:58 +02:00
Min RK
8a174da59a Merge pull request #876 from consideRatio/pr/add-upgrade-tests
maint: add upgrade test from main branch, latest release, and 0.2.0
2023-04-17 09:43:23 +02:00
Erik Sundell
acd420765a ci: cleanup no longer needed .rst file type reference 2023-04-15 11:45:44 +02:00
Erik Sundell
6883316c36 Update mambaforge from 22.11.1-4 to 23.1.0-1 2023-04-15 11:06:29 +02:00
Erik Sundell
f219acd041 ci: remove unimportant and complicated job filtering 2023-04-15 10:56:44 +02:00
Erik Sundell
6ecbe083d5 ci: use non-deprecated codecov action 2023-04-15 10:49:40 +02:00
Erik Sundell
d531a127d8 ci: shorten job names 2023-04-15 10:49:40 +02:00
Erik Sundell
8e94bbe468 ci: add upgrade tests from: main, latest, and 0.2.0 2023-04-15 10:49:40 +02:00
Erik Sundell
17bbd6116b bootstrap.py: update documentation for consistency 2023-04-15 10:35:12 +02:00
Erik Sundell
7859e7f01b refactor: name pip_bin etc to clarify the python environment 2023-04-15 10:34:55 +02:00
Erik Sundell
ed334ac050 ci/docs: finalize transition to main branch 2023-04-15 08:40:06 +02:00
Yuvi Panda
ff276d1a29 Merge pull request #869 from consideRatio/pr/remove-nteract
breaking, maint: remove deprecated nteract-on-jupyter
2023-04-10 12:36:33 +05:30
Erik Sundell
7fd97ad5e0 Merge pull request #871 from consideRatio/pr/dependabot-monthly
dependabot: monthly updates of github actions
2023-04-07 15:58:16 +02:00
Erik Sundell
0324d88da2 dependabot: rename to .yaml 2023-04-05 10:19:27 +02:00
Erik Sundell
9144828e5b dependabot: monthly updates of github actions 2023-04-04 22:58:47 +02:00
Erik Sundell
9e1bc61519 breaking, maint: remove deprecated use of nteract-on-jupyter 2023-04-04 22:00:44 +02:00
Erik Sundell
f55e4cf615 Merge pull request #870 from consideRatio/pr/misc-rst-followups
docs: fix remaining issues following rst to myst transition
2023-04-04 21:58:09 +02:00
Erik Sundell
3ebe974de4 Merge pull request #862 from minrk/init-loggers
avoid registering duplicate log handlers
2023-04-04 21:54:45 +02:00
Erik Sundell
f9b2a05e18 docs: fix remaining issues following rst to myst transition 2023-04-04 21:48:13 +02:00
Erik Sundell
fa4a8bf6cb Merge pull request #863 from minrk/myst
docs: transition from rst to myst markdown using rst2myst
2023-04-04 21:35:43 +02:00
pre-commit-ci[bot]
ee0a2c9b66 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-04-04 19:31:36 +00:00
Erik Sundell
77e8544d80 docs: additional manual fixes for rst to myst 2023-04-04 21:31:24 +02:00
pre-commit-ci[bot]
f7b55c43aa [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-04-04 19:26:44 +00:00
Erik Sundell
153d575ae5 docs: manual formatting fixes following rst to myst conversion 2023-04-04 21:25:55 +02:00
Erik Sundell
82aac067b6 docs: add dollarmath myst extension
Enables use of `$$...$$` math blocks, see https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#math-shortcuts
2023-04-04 20:51:22 +02:00
Simon Li
25e4290f79 Merge pull request #842 from yuvipanda/upgrade-things
update: jupyterhub 3, oauthenticator 15, systemdspawner 0.17 (user env: ipywidgets 8)
2023-04-04 19:20:19 +01:00
Min RK
adbd41dcb0 Merge pull request #867 from jupyterhub/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-04-04 13:04:16 +02:00
pre-commit-ci[bot]
6b39d025bc [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/asottile/pyupgrade: v2.34.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v3.3.1)
- [github.com/psf/black: 22.3.0 → 23.3.0](https://github.com/psf/black/compare/22.3.0...23.3.0)
- [github.com/pre-commit/mirrors-prettier: v2.7.1 → v3.0.0-alpha.6](https://github.com/pre-commit/mirrors-prettier/compare/v2.7.1...v3.0.0-alpha.6)
- [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0)
- [github.com/pycqa/flake8: 4.0.1 → 6.0.0](https://github.com/pycqa/flake8/compare/4.0.1...6.0.0)
2023-04-04 06:23:11 +00:00
Min RK
2d1c584eca Fix wait/fail conditions in hub culling tests
- actually check for running server, matching comments, not just user existence
- catch asyncio.TimeoutError, not TimeoutError
- fail if condition is not met, rather than passing in both cases
- update some comments for accuracy (max age and timeout aren't the same)
2023-03-28 15:48:35 +02:00
Min RK
9b940c34fd don't let conda install wait for input 2023-03-27 15:43:46 +02:00
Min RK
b5a6b3f590 Avoid downgrading user-env conda/mamba
- Only check lower bound on conda/mamba, upgrade unbounded if not matched (let conda apply upper bound according to existing pins, such as Python)
- handle missing mamba
- avoid upgrading Python by aborting the install, instead of keeping old envs
- minimum supported Python for user env is 3.9
- Fix output reporting of conda install step (no need for json capture when we don't parse the output - exit codes will do)
2023-03-27 13:20:22 +02:00
Min RK
214635bf87 update doc contributing guide to point to markdown instead of rst 2023-03-27 10:25:18 +02:00
Min RK
1ac6f9983d markdownify add_users/packages included files
not caught in initial rst2myst
2023-03-27 10:22:45 +02:00
Min RK
76dadd7ef9 fix absolute refs
myst seems to create different refs than sphinx
2023-03-27 10:16:51 +02:00
Min RK
de36cfc116 adopt myst
run rst2myst, with minimal manual formatting fixes
2023-03-27 09:40:35 +02:00
Min RK
5980cb3ef2 log commands before they start (at debug level)
so you know what you're waiting for
2023-03-24 11:58:32 +01:00
Min RK
6b0b5f2998 add bzip2 to test env
required for testing against miniconda 4.5
2023-03-24 11:58:12 +01:00
Min RK
5da2859408 avoid registering duplicate log handlers
init_logging is called many times in test_config,
which has been registering numerous duplicate log handlers,
attached to stderr that's closed between tests
2023-03-24 11:31:44 +01:00
Min RK
755d0d02fb avoid auto-updating conda in test env
because then we don't get the version we expect to test with!
2023-03-23 16:26:34 +01:00
Min RK
5ec167ff0f Sync with main
updates required Python version to exclude 3.6
2023-03-23 15:45:54 +01:00
Min RK
a24e038136 get canary package from conda-forge 2023-03-23 15:39:46 +01:00
Min RK
285a1e93f2 Sync with main
now that base OS version is updated
2023-03-23 12:38:28 +01:00
Min RK
4d42f24e48 test ensure_user_environment
verify behavior for:

- current version (no change)
- old, supported version (upgrade, but not too far)
- too old, re-run installer
- directory exists, no conda
2023-03-23 12:34:44 +01:00
Min RK
594b61003f add some logging to conda setup 2023-03-23 12:31:50 +01:00
Erik Sundell
a5e72046ab Merge pull request #856 from minrk/ubuntu-bump
require ubuntu 20.04, test on debian 11, require Python 3.8
2023-03-23 10:25:38 +01:00
Min RK
27c9761f1c Apply suggestions from code review
Co-authored-by: Simon Li <orpheus+devel@gmail.com>
2023-03-23 09:39:17 +01:00
Simon Li
8711a58d70 Merge pull request #859 from minrk/10
bump version to 1.0.0.dev0
2023-03-22 09:44:35 +00:00
Min RK
5e6f68eb32 bump version to 1.0.0.dev0 2023-03-21 16:27:39 +01:00
Min RK
6d0c1cbf63 Remove very old conda versions from installer.py
- 4.7.10 was Python 3.7 (no longer supported)
- 4.5.4 was Python 3.6
2023-03-21 15:59:37 +01:00
Min RK
1a3c48a500 Update base user environment to mambaforge 22.11.1-4
shift some duplicated code into utility functions and constants
2023-03-21 14:37:50 +01:00
Min RK
f53b0b86a2 Merge with pr 843 2023-03-21 12:13:29 +01:00
Min RK
ecc832f9ad Merge pull request #849 from jawiv/patch-1
Update user-environment.rst
2023-03-21 12:09:10 +01:00
Min RK
6f852d173d add note that newer OS will _probably_ work, but LTS are supported 2023-03-21 11:15:13 +01:00
Min RK
c80e5f6854 add python3 to integration test
debian base image doesn't include Python3
2023-03-21 11:05:25 +01:00
Min RK
e03f5ec2cd Require Debian 11, not 10
10 has too-old Python by default
2023-03-21 10:47:55 +01:00
Min RK
150a3f62d6 parse distro version tuples
instead of using floats
2023-03-21 10:39:40 +01:00
Min RK
de1fc86b5e only pin major versions in requirements-base.txt, installer.py 2023-03-21 10:30:59 +01:00
Min RK
aa72179afa require ubuntu 20.04, test on debian 10 2023-03-21 10:17:02 +01:00
Min RK
fcf6164e31 Merge pull request #800 from jochym/main
Add support for debian >=10 to bootstrap.py
2023-03-21 09:32:45 +01:00
YuviPanda
12316c3256 Upgrade some packages
Should upgrade base python version separately
2023-03-21 09:27:56 +01:00
Paweł T. Jochym
0b63febdde Merge pull request #2 from jupyterhub/main
Sync with upstream development
2023-02-23 11:34:51 +01:00
James A. Webb, IV
b827de31dd Update user-environment.rst
Minor typo
2023-02-06 09:23:37 -06:00
Paweł T. Jochym
a43872176a Merge pull request #1 from jupyterhub/main
Merge upstream development
2023-02-03 13:17:29 +01:00
Adon Metcalfe
3b0ab71fe7 General revamp of docs to point to newer ubuntu LTS 2023-01-14 10:33:39 +08:00
Adon Metcalfe
d4f12e3789 Update custom-server.rst
Just noting that TLJH works on newer versions of ubuntu in docs
2023-01-14 10:21:34 +08:00
Paweł T. Jochym
5f2e3b1726 Reflect distro support i comment 2022-09-21 20:28:25 +02:00
Paweł T. Jochym
45abba3c37 Add requested comments specific to debian 2022-09-15 17:34:25 +02:00
Paweł T. Jochym
d0204e23ac Merge branch 'jupyterhub:main' into main 2022-09-15 16:57:05 +02:00
Will Dampier
ff1f612d10 adding content to docs 2022-09-02 14:47:41 -04:00
Will Dampier
58181c9671 adjusted integration test to call new hook 2022-09-02 14:47:25 -04:00
Will Dampier
8d1033393c adding tljh_extra_user_conda_channels hook to the hooks and installer 2022-09-02 14:46:55 -04:00
Will Dampier
fc8f70463c Adding the ability to define conda channels 2022-09-02 14:10:43 -04:00
Paweł T. Jochym
e408d99a5a Missing negation 2022-02-20 10:44:24 +01:00
Paweł T. Jochym
48a8e5fcb5 Typo 2022-02-20 10:41:36 +01:00
Paweł T. Jochym
94f57fc3dd Add Debian >10 to supported distros 2022-02-20 10:33:23 +01:00
176 changed files with 7587 additions and 5994 deletions

View File

@@ -113,7 +113,7 @@ jobs:
- run:
name: Check upgrade testing
command: |
if [ "$CIRCLE_BRANCH" == "master" ]; then
if [ "$CIRCLE_BRANCH" == "main" ]; then
echo "On master, no upgrade to test..."
circleci-agent step halt
else

View File

@@ -1,4 +1,4 @@
# dependabot.yml reference: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
# dependabot.yaml reference: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
#
# Notes:
# - Status and logs from dependabot are provided at
@@ -9,8 +9,9 @@ version: 2
updates:
# Maintain dependencies in our GitHub Workflows
- package-ecosystem: github-actions
directory: "/" # This should be / rather than .github/workflows
directory: /
labels: [ci]
schedule:
interval: weekly
interval: monthly
time: "05:00"
timezone: "Etc/UTC"
timezone: Etc/UTC

View File

@@ -1,184 +1,207 @@
#!/usr/bin/env python3
import argparse
from shutil import which
import functools
import os
import subprocess
import time
import os
from shutil import which
GIT_REPO_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
TEST_IMAGE_NAME = "test-systemd"
def container_runtime():
@functools.lru_cache
def _get_container_runtime_cli():
runtimes = ["docker", "podman"]
for runtime in runtimes:
if which(runtime):
return runtime
raise RuntimeError(f"No container runtime found, tried: {' '.join(runtimes)}")
raise RuntimeError(f"No container runtime CLI found, tried: {' '.join(runtimes)}")
def container_check_output(*args, **kwargs):
cmd = [container_runtime()] + list(*args)
print(f"Running {cmd} {kwargs}")
return subprocess.check_output(cmd, **kwargs)
def _cli(args, log_failure=True):
cmd = [_get_container_runtime_cli(), *args]
try:
return subprocess.check_output(cmd, text=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
if log_failure:
print(f"{cmd} failed!", flush=True)
raise
def container_run(*args, **kwargs):
cmd = [container_runtime()] + list(*args)
print(f"Running {cmd} {kwargs}")
return subprocess.run(cmd, **kwargs)
def build_systemd_image(image_name, source_path, build_args=None):
def _await_container_startup(container_name, timeout=60):
"""
Build docker image with systemd at source_path.
Built image is tagged with image_name
Await container to become ready, as checked by attempting to run a basic
command (id) inside it.
"""
cmd = ["build", f"-t={image_name}", source_path]
if build_args:
cmd.extend([f"--build-arg={ba}" for ba in build_args])
container_check_output(cmd)
def check_container_ready(container_name, timeout=60):
"""
Check if container is ready to run tests
"""
now = time.time()
start = time.time()
while True:
try:
out = container_check_output(["exec", "-t", container_name, "id"])
print(out.decode())
_cli(["exec", "-t", container_name, "id"], log_failure=False)
return
except subprocess.CalledProcessError as e:
print(e)
except subprocess.CalledProcessError:
if time.time() - start > timeout:
inspect = ""
logs = ""
try:
out = container_check_output(["inspect", container_name])
print(out.decode())
inspect = _cli(["inspect", container_name], log_failure=False)
except subprocess.CalledProcessError as e:
print(e)
inspect = e.output
try:
out = container_check_output(["logs", container_name])
print(out.decode())
logs = _cli(["logs", container_name], log_failure=False)
except subprocess.CalledProcessError as e:
print(e)
if time.time() - now > timeout:
raise RuntimeError(f"Container {container_name} hasn't started")
time.sleep(5)
logs = e.output
raise RuntimeError(
f"Container {container_name} failed to start! Debugging info follows...\n\n"
f"> docker inspect {container_name}\n"
"----------------------------------------\n"
f"{inspect}\n"
f"> docker logs {container_name}\n"
"----------------------------------------\n"
f"{logs}\n"
)
time.sleep(1)
def run_systemd_image(image_name, container_name, bootstrap_pip_spec):
def build_image(build_args=None):
"""
Run docker image with systemd
Build Dockerfile with systemd in the integration-tests folder to run tests
from.
"""
cmd = [
_get_container_runtime_cli(),
"build",
f"--tag={TEST_IMAGE_NAME}",
"integration-tests",
]
if build_args:
cmd.extend([f"--build-arg={ba}" for ba in build_args])
Image named image_name should be built with build_systemd_image.
subprocess.run(cmd, check=True, text=True)
Container named container_name will be started.
def start_container(container_name, bootstrap_pip_spec):
"""
Starts a container based on an image expected to start systemd.
"""
cmd = [
"run",
"--privileged",
"--rm",
"--detach",
"--privileged",
f"--name={container_name}",
# A bit less than 1GB to ensure TLJH runs on 1GB VMs.
# If this is changed all docs references to the required memory must be changed too.
"--memory=900m",
]
if bootstrap_pip_spec:
cmd.append("-e")
cmd.append(f"TLJH_BOOTSTRAP_PIP_SPEC={bootstrap_pip_spec}")
cmd.append(f"--env=TLJH_BOOTSTRAP_PIP_SPEC={bootstrap_pip_spec}")
else:
cmd.append("--env=TLJH_BOOTSTRAP_DEV=yes")
cmd.append("--env=TLJH_BOOTSTRAP_PIP_SPEC=/srv/src")
cmd.append(TEST_IMAGE_NAME)
cmd.append(image_name)
container_check_output(cmd)
return _cli(cmd)
def stop_container(container_name):
"""
Stop & remove docker container if it exists.
Stop and remove docker container if it exists.
"""
try:
container_check_output(["inspect", container_name], stderr=subprocess.STDOUT)
return _cli(["rm", "--force", container_name], log_failure=False)
except subprocess.CalledProcessError:
# No such container exists, nothing to do
return
container_check_output(["rm", "-f", container_name])
pass
def run_container_command(container_name, cmd):
def run_command(container_name, command):
"""
Run cmd in a running container with a bash shell
Run a bash command in a running container and error if it fails
"""
proc = container_run(
["exec", "-t", container_name, "/bin/bash", "-c", cmd],
check=True,
)
cmd = [
_get_container_runtime_cli(),
"exec",
"-t",
container_name,
"/bin/bash",
"-c",
command,
]
print(f"\nRunning: {cmd}\n----------------------------------------", flush=True)
subprocess.run(cmd, check=True, text=True)
def copy_to_container(container_name, src_path, dest_path):
"""
Copy files from src_path to dest_path inside container_name
Copy files from a path on the local file system to a destination in a
running container
"""
container_check_output(["cp", src_path, f"{container_name}:{dest_path}"])
_cli(["cp", src_path, f"{container_name}:{dest_path}"])
def run_test(
image_name, test_name, bootstrap_pip_spec, test_files, upgrade, installer_args
container_name,
bootstrap_pip_spec,
test_files,
upgrade_from,
installer_args,
):
"""
Wrapper that sets up tljh with installer_args & runs test_name
(Re-)starts a named container with given (Systemd based) image, then runs
the bootstrap script inside it to setup tljh with installer_args.
Thereafter, source files are copied to the container and
"""
stop_container(test_name)
run_systemd_image(image_name, test_name, bootstrap_pip_spec)
stop_container(container_name)
start_container(container_name, bootstrap_pip_spec)
_await_container_startup(container_name)
copy_to_container(container_name, GIT_REPO_PATH, "/srv/src")
check_container_ready(test_name)
# To test upgrades, we run a bootstrap.py script two times instead of one,
# where the initial run first installs some older version.
#
# We want to support testing a PR by upgrading from "main", "latest" (latest
# released version), and from a previous major-like version.
#
if upgrade_from:
command = f"python3 /srv/src/bootstrap/bootstrap.py --version={upgrade_from}"
run_command(container_name, command)
source_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
# show user environment
command = "/opt/tljh/user/bin/mamba list"
run_command(container_name, command)
copy_to_container(test_name, os.path.join(source_path, "bootstrap/."), "/srv/src")
copy_to_container(
test_name, os.path.join(source_path, "integration-tests/"), "/srv/src"
)
command = f"python3 /srv/src/bootstrap/bootstrap.py {' '.join(installer_args)}"
run_command(container_name, command)
# These logs can be very relevant to debug a container startup failure
print(f"--- Start of logs from the container: {test_name}")
print(container_check_output(["logs", test_name]).decode())
print(f"--- End of logs from the container: {test_name}")
# Install TLJH from the default branch first to test upgrades
if upgrade:
run_container_command(
test_name, "curl -L https://tljh.jupyter.org/bootstrap.py | python3 -"
)
run_container_command(test_name, f"python3 /srv/src/bootstrap.py {installer_args}")
# show user environment (again if upgrade)
command = "/opt/tljh/user/bin/mamba list"
run_command(container_name, command)
# Install pkgs from requirements in hub's pip, where
# the bootstrap script installed the others
run_container_command(
test_name,
"/opt/tljh/hub/bin/python3 -m pip install -r /srv/src/integration-tests/requirements.txt",
)
run_container_command(
test_name,
# We abort pytest after two failures as a compromise between wanting to
# avoid a flood of logs while still understanding if multiple tests
# would fail.
"/opt/tljh/hub/bin/python3 -m pytest --verbose --maxfail=2 --color=yes --durations=10 --capture=no {}".format(
" ".join(
[os.path.join("/srv/src/integration-tests/", f) for f in test_files]
)
),
)
command = "/opt/tljh/hub/bin/python3 -m pip install -r /srv/src/integration-tests/requirements.txt"
run_command(container_name, command)
# show hub environment
command = "/opt/tljh/hub/bin/python3 -m pip freeze"
run_command(container_name, command)
# run tests
test_files = " ".join([f"/srv/src/integration-tests/{f}" for f in test_files])
command = f"/opt/tljh/hub/bin/python3 -m pytest {test_files}"
run_command(container_name, command)
def show_logs(container_name):
"""
Print logs from inside container to stdout
Print jupyterhub and traefik status and logs from both.
tljh logs ref: https://tljh.jupyter.org/en/latest/troubleshooting/logs.html
"""
run_container_command(container_name, "journalctl --no-pager")
run_container_command(
container_name, "systemctl --no-pager status jupyterhub traefik"
)
run_command(container_name, "systemctl --no-pager status jupyterhub traefik")
run_command(container_name, "journalctl --no-pager -u jupyterhub")
run_command(container_name, "journalctl --no-pager -u traefik")
def main():
@@ -186,15 +209,13 @@ def main():
subparsers = argparser.add_subparsers(dest="action")
build_image_parser = subparsers.add_parser("build-image")
build_image_parser.add_argument(
"--build-arg",
action="append",
dest="build_args",
)
build_image_parser.add_argument("--build-arg", action="append", dest="build_args")
subparsers.add_parser("stop-container").add_argument("container_name")
start_container_parser = subparsers.add_parser("start-container")
start_container_parser.add_argument("container_name")
subparsers.add_parser("start-container").add_argument("container_name")
stop_container_parser = subparsers.add_parser("stop-container")
stop_container_parser.add_argument("container_name")
run_parser = subparsers.add_parser("run")
run_parser.add_argument("container_name")
@@ -206,12 +227,10 @@ def main():
copy_parser.add_argument("dest")
run_test_parser = subparsers.add_parser("run-test")
run_test_parser.add_argument("--installer-args", default="")
run_test_parser.add_argument("--upgrade", action="store_true")
run_test_parser.add_argument(
"--bootstrap-pip-spec", nargs="?", default="", type=str
)
run_test_parser.add_argument("test_name")
run_test_parser.add_argument("--installer-args", action="append")
run_test_parser.add_argument("--upgrade-from", default="")
run_test_parser.add_argument("--bootstrap-pip-spec", default="/srv/src")
run_test_parser.add_argument("container_name")
run_test_parser.add_argument("test_files", nargs="+")
show_logs_parser = subparsers.add_parser("show-logs")
@@ -219,29 +238,26 @@ def main():
args = argparser.parse_args()
image_name = "tljh-systemd"
if args.action == "run-test":
if args.action == "build-image":
build_image(args.build_args)
elif args.action == "start-container":
start_container(args.container_name, args.bootstrap_pip_spec)
elif args.action == "stop-container":
stop_container(args.container_name)
elif args.action == "run":
run_command(args.container_name, args.command)
elif args.action == "copy":
copy_to_container(args.container_name, args.src, args.dest)
elif args.action == "run-test":
run_test(
image_name,
args.test_name,
args.container_name,
args.bootstrap_pip_spec,
args.test_files,
args.upgrade,
args.upgrade_from,
args.installer_args,
)
elif args.action == "show-logs":
show_logs(args.container_name)
elif args.action == "run":
run_container_command(args.container_name, args.command)
elif args.action == "copy":
copy_to_container(args.container_name, args.src, args.dest)
elif args.action == "start-container":
run_systemd_image(image_name, args.container_name, args.bootstrap_pip_spec)
elif args.action == "stop-container":
stop_container(args.container_name)
elif args.action == "build-image":
build_systemd_image(image_name, "integration-tests", args.build_args)
if __name__ == "__main__":

View File

@@ -8,14 +8,12 @@ on:
paths-ignore:
- "docs/**"
- "**.md"
- "**.rst"
- ".github/workflows/*"
- "!.github/workflows/integration-test.yaml"
push:
paths-ignore:
- "docs/**"
- "**.md"
- "**.rst"
- ".github/workflows/*"
- "!.github/workflows/integration-test.yaml"
branches-ignore:
@@ -24,158 +22,132 @@ on:
workflow_dispatch:
jobs:
# This job is used as a workaround to a limitation when using a matrix of
# variations that a job should be executed against. The limitation is that a
# matrix once defined can't include any conditions.
#
# What this job does before our real test job with a matrix of variations run,
# is to decide on that matrix of variations a conditional logic of our choice.
#
# For more details, see this excellent stack overflow answer:
# https://stackoverflow.com/a/65434401/2220152
#
decide-on-test-jobs-to-run:
name: Decide on test jobs to run
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# Currently, this logic filters out a matrix entry equaling a specific git
# reference identified by "dont_run_on_ref".
- name: Decide on test jobs to run
id: set-matrix
run: |
matrix_post_filter=$(
echo "$matrix_include_pre_filter" \
| yq e --output-format=json '.' - \
| jq -c '{"include": map( . | select(.dont_run_on_ref != "${{ github.ref }}" ))}'
)
echo "matrix=$matrix_post_filter" >> $GITHUB_OUTPUT
echo "The subsequent job's matrix are:"
echo $matrix_post_filter | jq -C '.'
env:
matrix_include_pre_filter: |
- name: "Int. tests: Ubuntu 18.04, Py 3.6"
ubuntu_version: "18.04"
python_version: "3.6"
extra_flags: ""
- name: "Int. tests: Ubuntu 20.04, Py 3.9"
ubuntu_version: "20.04"
python_version: "3.9"
extra_flags: ""
- name: "Int. tests: Ubuntu 22.04, Py 3.10"
ubuntu_version: "22.04"
python_version: "3.10"
extra_flags: ""
- name: "Int. tests: Ubuntu 22.04, Py 3.10, --upgrade"
ubuntu_version: "22.04"
python_version: "3.10"
extra_flags: --upgrade
dont_run_on_ref: refs/heads/master
integration-tests:
needs: decide-on-test-jobs-to-run
# runs-on can only be configured to the LTS releases of ubuntu (20.04,
# 22.04, ...), so if we want to test against the latest non-LTS release, we
# must compromise when configuring runs-on and configure runs-on to be the
# latest LTS release instead.
#
# This can have consequences because actions like actions/setup-python will
# mount cached installations associated with the chosen runs-on environment.
#
runs-on: ${{ format('ubuntu-{0}', matrix.runs_on || matrix.ubuntu_version) }}
# integration tests run in a container,
# not in the worker, so this version is not relevant to the tests
# and can be the same for all tested versions
runs-on: ubuntu-22.04
name: ${{ matrix.name }}
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.decide-on-test-jobs-to-run.outputs.matrix) }}
matrix:
include:
- name: "Debian 11, Py 3.9"
distro_image: "debian:11"
extra_flags: ""
- name: "Debian 12, Py 3.11"
distro_image: "debian:12"
extra_flags: ""
- name: "Ubuntu 22.04 Py 3.10"
distro_image: "ubuntu:22.04"
extra_flags: ""
- name: "Ubuntu 24.04 Py 3.12"
distro_image: "ubuntu:24.04"
extra_flags: ""
- name: "Ubuntu 22.04, Py 3.10, from main"
distro_image: "ubuntu:22.04"
extra_flags: --upgrade-from=main
- name: "Ubuntu 22.04, Py 3.10, from latest"
distro_image: "ubuntu:22.04"
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.*"
distro_image: "ubuntu:22.04"
extra_flags: --upgrade-from=1
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python_version }}"
python-version: "3.10"
- name: Install pytest
run: python3 -m pip install pytest
# We abort pytest after two failures as a compromise between wanting to
# avoid a flood of logs while still understanding if multiple tests would
# fail.
- name: Run bootstrap tests (Runs in/Builds ubuntu:${{ matrix.ubuntu_version }} derived image)
run: |
pytest --verbose --maxfail=2 --color=yes --durations=10 --capture=no \
integration-tests/test_bootstrap.py
timeout-minutes: 15
env:
# integration-tests/test_bootstrap.py will build and start containers
# based on this environment variable. This is similar to how
# .github/integration-test.py build-image can take a --build-arg
# setting the ubuntu_version.
UBUNTU_VERSION: ${{ matrix.ubuntu_version }}
# We build a docker image from wherein we will work
- name: Build systemd image (Builds ubuntu:${{ matrix.ubuntu_version }} derived image)
- name: Build systemd image, derived from ${{ matrix.distro_image }}
run: |
.github/integration-test.py build-image \
--build-arg "ubuntu_version=${{ matrix.ubuntu_version }}"
--build-arg "BASE_IMAGE=${{ matrix.distro_image }}"
# FIXME: Make the logic below easier to follow.
# - In short, setting BOOTSTRAP_PIP_SPEC here, specifies from what
# location the tljh python package should be installed from. In this
# GitHub Workflow's test job, we provide a remote reference to itself as
# found on GitHub - this could be the HEAD of a PR branch or the default
# branch on merge.
#
# Overview of how this logic influences the end result.
# - integration-test.yaml:
# Runs integration-test.py by passing --bootstrap-pip-spec flag with a
# reference to the pull request on GitHub.
# - integration-test.py:
# Starts a pre-build systemd container, setting the
# TLJH_BOOTSTRAP_PIP_SPEC based on its passed --bootstrap-pip-spec value.
# - systemd container:
# Runs bootstrap.py
# - bootstrap.py
# Makes use of TLJH_BOOTSTRAP_PIP_SPEC environment variable to install
# the tljh package from a given location, which could be a local git
# clone of this repo where setup.py resides, or a reference to some
# GitHub branch for example.
- name: Set BOOTSTRAP_PIP_SPEC value
#
# - Runs integration-test.py build-image, to build a systemd based image
# to use later.
#
# - Runs integration-test.py run-tests, to start a systemd based
# container, run the bootstrap.py script inside it, and then run
# pytest from the hub python environment setup by the bootstrap
# script.
#
# About passed --installer-args:
#
# - --admin admin:admin
# Required for test_admin_installer.py
#
# - --plugin /srv/src/integration-tests/plugins/simplest
# Required for test_simplest_plugin.py
#
- name: pytest integration-tests/
id: integration-tests
run: |
BOOTSTRAP_PIP_SPEC="git+https://github.com/$GITHUB_REPOSITORY.git@$GITHUB_REF"
echo "BOOTSTRAP_PIP_SPEC=$BOOTSTRAP_PIP_SPEC" >> $GITHUB_ENV
echo $BOOTSTRAP_PIP_SPEC
- name: Run basic tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
run: |
.github/integration-test.py run-test basic-tests \
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
.github/integration-test.py run-test integration-tests \
--installer-args "--admin test-admin-username:test-admin-password" \
--installer-args "--plugin /srv/src/integration-tests/plugins/simplest" \
${{ matrix.extra_flags }} \
test_hub.py \
test_proxy.py \
test_install.py \
test_extensions.py
timeout-minutes: 15
- name: Run admin tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
run: |
.github/integration-test.py run-test admin-tests \
--installer-args "--admin admin:admin" \
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
${{ matrix.extra_flags }} \
test_admin_installer.py
timeout-minutes: 15
- name: Run plugin tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
run: |
.github/integration-test.py run-test plugin-tests \
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
--installer-args "--plugin /srv/src/integration-tests/plugins/simplest" \
${{ matrix.extra_flags }} \
test_extensions.py \
test_admin_installer.py \
test_simplest_plugin.py
timeout-minutes: 15
- name: show logs
if: always() && steps.integration-tests.outcome != 'skipped'
run: |
.github/integration-test.py show-logs integration-tests
integration-tests-bootstrap:
# integration tests run in a container,
# not in the worker, so this version is not relevant to the tests
# and can be the same for all tested versions
runs-on: ubuntu-22.04
name: ${{ matrix.name }}
strategy:
fail-fast: false
matrix:
include:
- name: "Ubuntu 22.04 Py 3.10 (test_bootstrap.py)"
distro_image: "ubuntu:22.04"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: pip
cache-dependency-path: |
integration-tests/requirements.txt
# FIXME: The test_bootstrap.py script has duplicated logic to run build
# and start images and run things in them. This makes tests slower,
# and adds code to maintain. Let's try to remove it.
#
# - bootstrap.py's failure detections, put in unit tests?
# - bootstrap.py's --show-progress-page test, include as a normal
# integration test?
#
- name: Install integration-tests/requirements.txt for test_bootstrap.py
run: pip install -r integration-tests/requirements.txt
- name: Run bootstrap tests (Runs in/Builds ${{ matrix.distro_image }} derived image)
run: |
pytest integration-tests/test_bootstrap.py
timeout-minutes: 10
env:
# integration-tests/test_bootstrap.py will build and start containers
# based on this environment variable. This is similar to how
# .github/integration-test.py build-image can take a --build-arg
# setting the base image via a Dockerfile ARG.
BASE_IMAGE: ${{ matrix.distro_image }}

View File

@@ -8,14 +8,12 @@ on:
paths-ignore:
- "docs/**"
- "**.md"
- "**.rst"
- ".github/workflows/*"
- "!.github/workflows/unit-test.yaml"
push:
paths-ignore:
- "docs/**"
- "**.md"
- "**.rst"
- ".github/workflows/*"
- "!.github/workflows/unit-test.yaml"
branches-ignore:
@@ -42,63 +40,46 @@ jobs:
fail-fast: false
matrix:
include:
- name: "Unit tests: Ubuntu 18.04, Py 3.6"
ubuntu_version: "18.04"
python_version: "3.6"
- name: "Unit tests: Ubuntu 20.04, Py 3.9"
- name: "Ubuntu 20.04, Py 3.9"
ubuntu_version: "20.04"
python_version: "3.9"
- name: "Unit tests: Ubuntu 22.04, Py 3.10"
- name: "Ubuntu 22.04, Py 3.10"
ubuntu_version: "22.04"
python_version: "3.10"
- name: "Ubuntu 24.04, Py 3.12"
ubuntu_version: "24.04"
python_version: "3.12"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python_version }}"
- name: Install venv, git and setup venv
- name: Install venv, git, pip and setup venv
run: |
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install --yes \
python3-venv \
python3-pip \
bzip2 \
git
python3 -m venv /srv/venv
echo '/srv/venv/bin' >> $GITHUB_PATH
# WARNING: This action loads a cache of pip dependencies based on the
# declared key, and it will save a cache for that key on job
# completion. Make sure to update the key to bust the cache
# properly if you make a change that should influence it.
- name: Load cached Python dependencies
uses: actions/cache@v3
with:
path: /srv/venv/
key: >-
pip-
${{ matrix.runs_on }}-
${{ matrix.ubuntu_version }}-
${{ matrix.python_version }}-
${{ hashFiles('setup.py', 'dev-requirements.txt', '.github/workflows/unit-test.yaml') }}
- name: Install Python dependencies
# Keep pip version pinning in sync with the one in bootstrap.py!
# See changelog at https://pip.pypa.io/en/latest/news/#changelog
run: |
python3 -m pip install -U "pip==21.3.*"
python3 -m pip install -r dev-requirements.txt
python3 -m pip install -e .
pip install -r dev-requirements.txt
pip install -e .
- name: List Python dependencies
run: |
pip freeze
# We abort pytest after two failures as a compromise between wanting to
# avoid a flood of logs while still understanding if multiple tests would
# fail.
- name: Run unit tests
run: pytest --verbose --maxfail=2 --color=yes --durations=10 --cov=tljh tests/
run: pytest tests
timeout-minutes: 15
- name: Upload code coverage stats
run: codecov
- uses: codecov/codecov-action@v4

View File

@@ -11,30 +11,45 @@
repos:
# Autoformat: Python code, syntax patterns are modernized
- repo: https://github.com/asottile/pyupgrade
rev: v2.34.0
rev: v3.17.0
hooks:
- id: pyupgrade
args:
- --py36-plus
# We need the bootstrap.py script to be parsable with Python 3.5, so we
- --py39-plus
# We need the bootstrap.py script to be parsable with Python 3.8, so we
# exclude it from the pyupgrade hook that will apply f-strings etc.
exclude: bootstrap/bootstrap.py
# Autoformat: Python code
- repo: https://github.com/PyCQA/autoflake
rev: v2.3.1
hooks:
- id: autoflake
# args ref: https://github.com/PyCQA/autoflake#advanced-usage
args:
- --in-place
# Autoformat: Python code
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
# Autoformat: Python code
- repo: https://github.com/psf/black
rev: 22.3.0
rev: 24.8.0
hooks:
- id: black
# Autoformat: markdown, yaml
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
rev: v4.0.0-alpha.8
hooks:
- id: prettier
# Misc...
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.6.0
# ref: https://github.com/pre-commit/pre-commit-hooks#hooks-available
hooks:
# Autoformat: Makes sure files end in a newline and only a newline.
@@ -49,6 +64,10 @@ repos:
# Lint: Python code
- repo: https://github.com/pycqa/flake8
rev: "4.0.1"
rev: "7.1.1"
hooks:
- id: flake8
# pre-commit.ci config reference: https://pre-commit.ci/#configuration
ci:
autoupdate_schedule: monthly

1
CHANGELOG.md Normal file
View File

@@ -0,0 +1 @@
The changelog now lives in [TLJH's documentation](https://tljh.jupyter.org/en/stable/reference/changelog.html).

View File

@@ -1,8 +0,0 @@
Contributing to The Littlest JupyterHub development
---------------------------------------------------
This is an open source project that is developed and maintained by volunteers.
Your contribution is integral to the future of the project. Thank you!
See the `contributing guide <https://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/index.html>`_
for information on the different ways of contributing to The Littlest JupyterHub.

View File

@@ -1,3 +1,3 @@
include tljh/systemd-units/*
include tljh/*.tpl
include tljh/requirements-base.txt
include tljh/requirements-*.txt

View File

@@ -1,8 +1,8 @@
# The Littlest JupyterHub
[![Documentation build status](https://img.shields.io/readthedocs/the-littlest-jupyterhub?logo=read-the-docs)](https://tljh.jupyter.org/en/latest/?badge=latest)
[![GitHub Workflow Status - Test](https://img.shields.io/github/workflow/status/jupyterhub/the-littlest-jupyterhub/Unit%20tests?logo=github&label=tests)](https://github.com/jupyterhub/the-littlest-jupyterhub/actions)
[![Test coverage of code](https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub/branch/master/graph/badge.svg)](https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub)
[![GitHub Workflow Status - Test](https://img.shields.io/github/actions/workflow/status/jupyterhub/the-littlest-jupyterhub/integration-test.yaml?logo=github&label=tests)](https://github.com/jupyterhub/the-littlest-jupyterhub/actions)
[![Test coverage of code](https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub/branch/main/graph/badge.svg)](https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub)
[![GitHub](https://img.shields.io/badge/issue_tracking-github-blue?logo=github)](https://github.com/jupyterhub/the-littlest-jupyterhub/issues)
[![Discourse](https://img.shields.io/badge/help_forum-discourse-blue?logo=discourse)](https://discourse.jupyter.org/c/jupyterhub/tljh)
[![Gitter](https://img.shields.io/badge/social_chat-gitter-blue?logo=gitter)](https://gitter.im/jupyterhub/jupyterhub)
@@ -27,16 +27,10 @@ for information on the different ways of contributing to The Littlest JupyterHub
See [this blog post](http://words.yuvi.in/post/the-littlest-jupyterhub/) for
more information.
## Development Status
This project is currently in **beta** state. Folks have been using installations
of TLJH for more than a year now to great success. While we try hard not to, we
might still make breaking changes that have no clear upgrade pathway.
## Installation
The Littlest JupyterHub (TLJH) can run on any server that is running at least
**Ubuntu 18.04**. Earlier versions of Ubuntu are not supported.
**Ubuntu 20.04**. Earlier versions of Ubuntu are not supported.
We have several tutorials to get you started.
- Tutorials to create a new server from scratch on a cloud provider & run TLJH

View File

@@ -9,11 +9,10 @@ This script is run as:
Constraints:
- The entire script should be compatible with Python 3.6, which is the on
Ubuntu 18.04+.
- The script should parse in Python 3.5 as we print error messages for using
Ubuntu 16.04+ which comes with Python 3.5 by default. This means no
f-strings can be used.
- The entire script should be compatible with Python 3.9, which is the default on
Debian 11.
- The script should parse in Python 3.8 as we print error messages for using
Ubuntu 20.04 which comes with Python 3.8 by default.
- The script must depend only on stdlib modules, as no previous installation
of dependencies can be assumed.
@@ -27,7 +26,7 @@ Environment variables:
installing the tljh installer. Pass the values
yes or no.
Command line flags:
Command line flags, from "bootstrap.py --help":
The bootstrap.py script accept the following command line flags. All other
flags are passed through to the tljh installer without interception by this
@@ -37,17 +36,23 @@ Command line flags:
logs can be accessed during installation. If this is
passed, it will pass --progress-page-server-pid=<pid>
to the tljh installer for later termination.
--version VERSION TLJH version or Git reference. Default 'latest' is
the most recent release. Partial versions can be
specified, for example '1', '1.0' or '1.0.0'. You
can also pass a branch name such as 'main' or a
commit hash.
"""
from argparse import ArgumentParser
import os
from http.server import SimpleHTTPRequestHandler, HTTPServer
import logging
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import logging
import shutil
import urllib.request
from argparse import ArgumentParser
from http.server import HTTPServer, SimpleHTTPRequestHandler
progress_page_favicon_url = "https://raw.githubusercontent.com/jupyterhub/jupyterhub/main/share/jupyterhub/static/favicon.ico"
progress_page_html = """
@@ -133,6 +138,11 @@ progress_page_html = """
logger = logging.getLogger(__name__)
def _parse_version(vs):
"""Parse a simple version into a tuple of ints"""
return tuple(int(part) for part in vs.split("."))
# This function is needed both by the process starting this script, and by the
# TLJH installer that this script execs in the end. Make sure its replica at
# tljh/utils.py stays in sync with this version!
@@ -174,13 +184,7 @@ def run_subprocess(cmd, *args, **kwargs):
return output
def ensure_host_system_can_install_tljh():
"""
Check if TLJH is installable in current host system and exit with a clear
error message otherwise.
"""
def get_os_release_variable(key):
def get_os_release_variable(key):
"""
Return value for key from /etc/os-release
@@ -200,19 +204,28 @@ def ensure_host_system_can_install_tljh():
.strip()
)
# Require Ubuntu 18.04+
def ensure_host_system_can_install_tljh():
"""
Check if TLJH is installable in current host system and exit with a clear
error message otherwise.
"""
# Require Ubuntu 22.04+ or Debian 11+
distro = get_os_release_variable("ID")
version = float(get_os_release_variable("VERSION_ID"))
if distro != "ubuntu":
print("The Littlest JupyterHub currently supports Ubuntu Linux only")
version = get_os_release_variable("VERSION_ID")
if distro not in ["ubuntu", "debian"]:
print("The Littlest JupyterHub currently supports Ubuntu or Debian Linux only")
sys.exit(1)
elif float(version) < 18.04:
print("The Littlest JupyterHub requires Ubuntu 18.04 or higher")
elif distro == "ubuntu" and _parse_version(version) < (22, 4):
print("The Littlest JupyterHub requires Ubuntu 22.04 or higher")
sys.exit(1)
elif distro == "debian" and _parse_version(version) < (11,):
print("The Littlest JupyterHub requires Debian 11 or higher")
sys.exit(1)
# Require Python 3.6+
if sys.version_info < (3, 6):
print("bootstrap.py must be run with at least Python 3.6")
# Require Python 3.9+
if sys.version_info < (3, 9):
print(f"bootstrap.py must be run with at least Python 3.9, found {sys.version}")
sys.exit(1)
# Require systemd (systemctl is a part of systemd)
@@ -228,6 +241,7 @@ def ensure_host_system_can_install_tljh():
"For local development, see http://tljh.jupyter.org/en/latest/contributing/dev-setup.html"
)
sys.exit(1)
return distro, version
class ProgressPageRequestHandler(SimpleHTTPRequestHandler):
@@ -330,13 +344,28 @@ def main():
start a local webserver temporarily and report its installation progress via
a web site served locally on port 80.
"""
ensure_host_system_can_install_tljh()
distro, version = ensure_host_system_can_install_tljh()
parser = ArgumentParser()
parser.add_argument("--show-progress-page", action="store_true")
parser = ArgumentParser(
description=(
"The bootstrap.py script accept the following command line flags. "
"All other flags are passed through to the tljh installer without "
"interception by this script."
)
)
parser.add_argument(
"--show-progress-page",
action="store_true",
help=(
"Starts a local web server listening on port 80 where logs can be "
"accessed during installation. If this is passed, it will pass "
"--progress-page-server-pid=<pid> to the tljh installer for later "
"termination."
),
)
parser.add_argument(
"--version",
default="latest",
default="",
help=(
"TLJH version or Git reference. "
"Default 'latest' is the most recent release. "
@@ -348,10 +377,10 @@ def main():
# Various related constants
install_prefix = os.environ.get("TLJH_INSTALL_PREFIX", "/opt/tljh")
hub_prefix = os.path.join(install_prefix, "hub")
python_bin = os.path.join(hub_prefix, "bin", "python3")
pip_bin = os.path.join(hub_prefix, "bin", "pip")
initial_setup = not os.path.exists(python_bin)
hub_env_prefix = os.path.join(install_prefix, "hub")
hub_env_python = os.path.join(hub_env_prefix, "bin", "python3")
hub_env_pip = os.path.join(hub_env_prefix, "bin", "pip")
initial_setup = not os.path.exists(hub_env_python)
# Attempt to start a web server to serve a progress page reporting
# installation progress.
@@ -425,6 +454,8 @@ def main():
["apt-get", "install", "--yes", "software-properties-common"],
env=apt_get_adjusted_env,
)
# Section "universe" exists and is required only in ubuntu.
if distro == "ubuntu":
run_subprocess(["add-apt-repository", "universe", "--yes"])
run_subprocess(["apt-get", "update"])
run_subprocess(
@@ -436,35 +467,38 @@ def main():
"python3-venv",
"python3-pip",
"git",
"sudo", # sudo is missing in default debian install
],
env=apt_get_adjusted_env,
)
logger.info("Setting up virtual environment at {}".format(hub_prefix))
os.makedirs(hub_prefix, exist_ok=True)
run_subprocess(["python3", "-m", "venv", hub_prefix])
logger.info("Setting up virtual environment at {}".format(hub_env_prefix))
os.makedirs(hub_env_prefix, exist_ok=True)
run_subprocess(["python3", "-m", "venv", hub_env_prefix])
# Upgrade pip
# Keep pip version pinning in sync with the one in unit-test.yml!
# See changelog at https://pip.pypa.io/en/latest/news/#changelog
logger.info("Upgrading pip...")
run_subprocess([pip_bin, "install", "--upgrade", "pip==21.3.*"])
# Install/upgrade TLJH installer
tljh_install_cmd = [pip_bin, "install", "--upgrade"]
if os.environ.get("TLJH_BOOTSTRAP_DEV", "no") == "yes":
logger.info("Selected TLJH_BOOTSTRAP_DEV=yes...")
tljh_install_cmd.append("--editable")
run_subprocess([hub_env_pip, "install", "--upgrade", "pip"])
# pip install TLJH installer based on
#
# 1. --version, _resolve_git_version is used
# 2. TLJH_BOOTSTRAP_PIP_SPEC (then also respect TLJH_BOOTSTRAP_DEV)
# 3. latest, _resolve_git_version is used
#
tljh_install_cmd = [hub_env_pip, "install", "--upgrade"]
bootstrap_pip_spec = os.environ.get("TLJH_BOOTSTRAP_PIP_SPEC")
if not bootstrap_pip_spec:
if args.version or not bootstrap_pip_spec:
version_to_resolve = args.version or "latest"
bootstrap_pip_spec = (
"git+https://github.com/jupyterhub/the-littlest-jupyterhub.git@{}".format(
_resolve_git_version(args.version)
_resolve_git_version(version_to_resolve)
)
)
elif os.environ.get("TLJH_BOOTSTRAP_DEV", "no") == "yes":
logger.info("Selected TLJH_BOOTSTRAP_DEV=yes...")
tljh_install_cmd.append("--editable")
tljh_install_cmd.append(bootstrap_pip_spec)
if initial_setup:
logger.info("Installing TLJH installer...")
else:
@@ -473,7 +507,9 @@ def main():
# Run TLJH installer
logger.info("Running TLJH installer...")
os.execv(python_bin, [python_bin, "-m", "tljh.installer"] + tljh_installer_flags)
os.execv(
hub_env_python, [hub_env_python, "-m", "tljh.installer"] + tljh_installer_flags
)
if __name__ == "__main__":

View File

@@ -1,4 +1,5 @@
packaging
pytest
pytest-cov
pytest-asyncio
pytest-mock
codecov

View File

@@ -1,4 +0,0 @@
- [ ] Add / update documentation
- [ ] Add tests
<!-- Read more about our code-review guidelines at https://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/code-review.html -->

View File

@@ -4,7 +4,6 @@
#
import datetime
# -- Project information -----------------------------------------------------
# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
#
@@ -21,11 +20,13 @@ author = "Project Jupyter Contributors"
#
extensions = [
"sphinx_copybutton",
"sphinx.ext.intersphinx",
"sphinxext.opengraph",
"sphinxext.rediraffe",
"myst_parser",
]
root_doc = "index"
source_suffix = [".rst"]
source_suffix = [".md"]
# -- Options for HTML output -------------------------------------------------
@@ -38,6 +39,7 @@ html_static_path = ["_static"]
# pydata_sphinx_theme reference: https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html
html_theme = "pydata_sphinx_theme"
html_theme_options = {
"navigation_with_keys": False,
"icon_links": [
{
"name": "GitHub",
@@ -59,6 +61,45 @@ html_context = {
"doc_path": "docs",
}
# -- MyST configuration ------------------------------------------------------
# ref: https://myst-parser.readthedocs.io/en/latest/configuration.html
#
myst_heading_anchors = 2
myst_enable_extensions = [
# available extensions: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html
"attrs_inline",
"colon_fence",
"deflist",
"dollarmath",
"fieldlist",
]
# -- Options for intersphinx extension ---------------------------------------
# ref: https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration
#
# The extension makes us able to link like to other projects like below.
#
# rST - :external:py:class:`jupyterhub.spawner.Spawner`
# MyST - {external:py:class}`jupyterhub.spawner.Spawner`
#
# rST - :external:py:attribute:`jupyterhub.spawner.Spawner.default_url`
# MyST - {external:py:attribute}`jupyterhub.spawner.Spawner.default_url`
#
# To see what we can link to, do the following where "objects.inv" is appended
# to the sphinx based website:
#
# python -m sphinx.ext.intersphinx https://jupyterhub.readthedocs.io/en/stable/objects.inv
#
intersphinx_mapping = {
"jupyterhub": ("https://jupyterhub.readthedocs.io/en/stable/", None),
}
# intersphinx_disabled_reftypes set based on recommendation in
# https://docs.readthedocs.io/en/stable/guides/intersphinx.html#using-intersphinx
intersphinx_disabled_reftypes = ["*"]
# -- Options for linkcheck builder -------------------------------------------
# ref: https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-the-linkcheck-builder
@@ -93,4 +134,7 @@ ogp_use_first_image = True
rediraffe_branch = "main"
rediraffe_redirects = {
# "old-file": "new-folder/new-file-name",
"howto/env/user-environment": "howto/user-env/user-environment",
"howto/env/notebook-interfaces": "howto/user-env/notebook-interfaces",
"howto/env/server-resources": "howto/user-env/server-resources",
}

View File

@@ -1,21 +1,17 @@
.. _contributing/code-review:
(contributing-code-review)=
======================
Code Review guidelines
======================
# Code Review guidelines
This document outlines general guidelines to follow when you are making
or reviewing a Pull Request.
Have empathy
============
## Have empathy
We recommend reading `On Empathy & Pull Requests <https://slack.engineering/on-empathy-pull-requests-979e4257d158>`_
and `How about code reviews <https://slack.engineering/how-about-code-reviews-2695fb10d034>`_
We recommend reading [On Empathy & Pull Requests](https://slack.engineering/on-empathy-pull-requests-979e4257d158)
and [How about code reviews](https://slack.engineering/how-about-code-reviews-2695fb10d034)
to learn more about being empathetic in code reviews.
Write documentation
===================
## Write documentation
If your pull request touches any code, you must write or update documentation
for it. For this project, documentation is a lot more important than the code.
@@ -24,14 +20,13 @@ it is a bug.
Do not worry about having perfect documentation! Documentation improves over
time. The requirement is to have documentation before merging a pull request,
not to have *perfect* documentation before merging a pull request. If you
not to have _perfect_ documentation before merging a pull request. If you
are new and not sure how to add documentation, other contributors will
be happy to guide you.
See :ref:`contributing/docs` for guidelines on writing documentation.
See [](/contributing/docs) for guidelines on writing documentation.
Write tests
===========
## Write tests
If your pull request touches any code, you must write unit or integration tests
to exercise it. This helps validate & communicate that your pull request works
@@ -48,4 +43,4 @@ add more tests.
If you are unsure what kind of tests to add for your pull request, other
contributors to the repo will be happy to help guide you!
See :ref:`contributing/tests` for guidelines on writing tests.
See [](/contributing/tests) for guidelines on writing tests.

View File

@@ -0,0 +1,72 @@
(contributing-dev-setup)=
# Setting up Development Environment
The easiest & safest way to develop & test TLJH is with [Docker](https://www.docker.com/).
1. Install Docker Community Edition by following the instructions on
[their website](https://www.docker.com/community-edition).
2. Clone the [git repo](https://github.com/jupyterhub/the-littlest-jupyterhub) (or your fork of it).
3. Build a docker image that has a functional systemd in it.
```bash
docker build -t tljh-systemd . -f integration-tests/Dockerfile
```
4. Run a docker container with the image in the background, while bind mounting
your TLJH repository under `/srv/src`.
```bash
docker run \
--privileged \
--detach \
--name=tljh-dev \
--publish 12000:80 \
--mount type=bind,source="$(pwd)",target=/srv/src \
tljh-systemd
```
5. Get a shell inside the running docker container.
```bash
docker exec -it tljh-dev /bin/bash
```
6. Run the bootstrapper from inside the container (see step above):
The container image is already set up to default to a `dev` install, so
it'll install from your local repo rather than from github.
```console
python3 /srv/src/bootstrap/bootstrap.py --admin admin
```
Or, if you would like to setup the admin's password during install,
you can use this command (replace "admin" with the desired admin username
and "password" with the desired admin password):
```console
python3 /srv/src/bootstrap/bootstrap.py --admin admin:password
```
The primary hub environment will also be in your PATH already for convenience.
7. You should be able to access the JupyterHub from your browser now at
[http://localhost:12000](http://localhost:12000). Congratulations, you are
set up to develop TLJH!
8. Make some changes to the repository. You can test easily depending on what
you changed.
- 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`.
- If you changed the `tljh/installer.py` code (or any of its dependencies),
you can test it by running `python3 -m tljh.installer`.
- If you changed `tljh/jupyterhub_config.py`, `tljh/configurer.py`,
`/opt/tljh/config/` or any of their dependencies, you only need to
restart jupyterhub for them to take effect. `tljh-config reload hub`
should do that.
[](/troubleshooting/logs) has information on looking at various logs in the container
to debug issues you might have.

View File

@@ -1,75 +0,0 @@
.. _contributing/dev-setup:
==================================
Setting up Development Environment
==================================
The easiest & safest way to develop & test TLJH is with `Docker <https://www.docker.com/>`_.
#. Install Docker Community Edition by following the instructions on
`their website <https://www.docker.com/community-edition>`_.
#. Clone the `git repo <https://github.com/jupyterhub/the-littlest-jupyterhub>`_ (or your fork of it).
#. Build a docker image that has a functional systemd in it.
.. code-block:: bash
docker build -t tljh-systemd . -f integration-tests/Dockerfile
#. Run a docker container with the image in the background, while bind mounting
your TLJH repository under ``/srv/src``.
.. code-block:: bash
docker run \
--privileged \
--detach \
--name=tljh-dev \
--publish 12000:80 \
--mount type=bind,source=$(pwd),target=/srv/src \
tljh-systemd
#. Get a shell inside the running docker container.
.. code-block:: bash
docker exec -it tljh-dev /bin/bash
#. Run the bootstrapper from inside the container (see step above):
The container image is already set up to default to a ``dev`` install, so
it'll install from your local repo rather than from github.
.. code-block:: console
python3 /srv/src/bootstrap/bootstrap.py --admin admin
Or, if you would like to setup the admin's password during install,
you can use this command (replace "admin" with the desired admin username
and "password" with the desired admin password):
.. code-block:: console
python3 /srv/src/bootstrap/bootstrap.py --admin admin:password
The primary hub environment will also be in your PATH already for convenience.
#. You should be able to access the JupyterHub from your browser now at
`http://localhost:12000 <http://localhost:12000>`_. Congratulations, you are
set up to develop TLJH!
#. Make some changes to the repository. You can test easily depending on what
you changed.
* 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``.
* If you changed the ``tljh/installer.py`` code (or any of its dependencies),
you can test it by running ``python3 -m tljh.installer``.
* If you changed ``tljh/jupyterhub_config.py``, ``tljh/configurer.py``,
``/opt/tljh/config/`` or any of their dependencies, you only need to
restart jupyterhub for them to take effect. ``tljh-config reload hub``
should do that.
:ref:`troubleshooting/logs` has information on looking at various logs in the container
to debug issues you might have.

View File

@@ -1,13 +1,11 @@
.. _contributing/docs:
(contributing-docs)=
=====================
Writing documentation
=====================
# Writing documentation
.. note::
Heavily inspired by the
`django project's guidelines <https://docs.djangoproject.com/en/dev/internals/contributing/writing-documentation/>`_
:::{note}
Heavily inspired by the
[django project's guidelines](https://docs.djangoproject.com/en/dev/internals/contributing/writing-documentation/)
:::
We place a high importance on consistency, readability and completeness of documentation.
If a feature is not documented, it does not exist. If a behavior is not documented,
@@ -17,70 +15,62 @@ possible.
Documentation changes generally come in two forms:
* General improvements: typo corrections, error fixes and better
- General improvements: typo corrections, error fixes and better
explanations through clearer writing and more examples.
* New features: documentation of features that have been added to the
- New features: documentation of features that have been added to the
framework since the last release.
This section explains how writers can craft their documentation changes
in the most useful and least error-prone ways.
Getting the raw documentation
=============================
## Getting the raw documentation
Though TLJH's documentation is intended to be read as HTML at
https://the-littlest-jupyterhub.readthedocs.io/, we edit it as a collection of text files for
maximum flexibility. These files live in the top-level ``docs/`` directory of
<https://the-littlest-jupyterhub.readthedocs.io/>, we edit it as a collection of text files for
maximum flexibility. These files live in the top-level `docs/` directory of
TLJH's repository.
If you'd like to start contributing to our docs, get the development version of
TLJH from the source code repository. The development version has the
latest-and-greatest documentation, just as it has latest-and-greatest code.
Getting started with Sphinx
===========================
## Getting started with Sphinx
TLJH's documentation uses the Sphinx__ documentation system, which in turn
is based on docutils__. The basic idea is that lightly-formatted plain-text
TLJH's documentation uses the [Sphinx](http://sphinx-doc.org/) documentation system, which in turn
is based on [docutils](http://docutils.sourceforge.net/). The basic idea is that lightly-formatted plain-text
documentation is transformed into HTML, PDF, and any other output format.
__ http://sphinx-doc.org/
__ http://docutils.sourceforge.net/
To build the documentation locally, install the Sphinx dependencies:
.. code-block:: console
```console
$ cd docs/
$ pip install -r requirements.txt
```
$ cd docs/
$ pip install -r requirements.txt
Then from the `docs` directory, build the HTML:
Then from the ``docs`` directory, build the HTML:
.. code-block:: console
$ make html
```console
$ make html
```
If you encounter this error, it's likely that you are running inside a virtual environment.
.. code-block:: console
```console
Error in "currentmodule" directive:
```
Error in "currentmodule" directive:
To get started contributing, you'll want to read the :ref:`reStructuredText
reference <sphinx:rst-index>`
To get started contributing, you'll want to get familiar with [markdown](https://commonmark.org/help/) and [MyST](https://myst-parser.readthedocs.io).
Your locally-built documentation will be themed differently than the
documentation at `the-littlest-jupyterhub.readthedocs.io <https://the-littlest-jupyterhub.readthedocs.io>`_.
documentation at [the-littlest-jupyterhub.readthedocs.io](https://the-littlest-jupyterhub.readthedocs.io).
This is OK! If your changes look good on your local machine, they'll look good
on the website.
How the documentation is organized
==================================
## How the documentation is organized
The documentation is organized into several categories:
* **Tutorials** take the reader by the hand through a series
- **Tutorials** take the reader by the hand through a series
of steps to create something.
The important thing in a tutorial is to help the reader achieve something
@@ -97,7 +87,7 @@ The documentation is organized into several categories:
systems. These should cross-link a lot to other parts of the documentation,
avoid forcing the user to learn to SSH if possible & have lots of screenshots.
* **Topic guides** aim to explain a concept or subject at a
- **Topic guides** aim to explain a concept or subject at a
fairly high level.
Link to reference material rather than repeat it. Use examples and don't be
@@ -107,7 +97,7 @@ The documentation is organized into several categories:
Providing background context helps a newcomer connect the topic to things
that they already know.
* **Reference guides** contain technical reference for APIs.
- **Reference guides** contain technical reference for APIs.
They describe the functioning of TLJH's internal machinery and instruct in
its use.
@@ -119,7 +109,7 @@ The documentation is organized into several categories:
yourself explaining basic concepts, you may want to move that material to a
topic guide.
* **How-to guides** are recipes that take the reader through
- **How-to guides** are recipes that take the reader through
steps in key subjects.
What matters most in a how-to guide is what a user wants to achieve.
@@ -131,83 +121,56 @@ The documentation is organized into several categories:
hesitate to refer the reader back to the appropriate tutorial rather than
repeat the same material.
* **Troubleshooting guides** help reader answer the question "Why is my JupyterHub
- **Troubleshooting guides** help reader answer the question "Why is my JupyterHub
not working?".
These guides help readers try find causes for their symptoms, and hopefully fix
the issues. Some of these need to be specific to cloud providers, and that is
acceptable.
Writing style
=============
## Writing style
Typically, documentation is written in second person, referring to the reader as “you”.
When using pronouns in reference to a hypothetical person, such as "a user with
a running notebook", gender neutral pronouns (they/their/them) should be used.
Instead of:
* he or she... use they.
* him or her... use them.
* his or her... use their.
* his or hers... use theirs.
* himself or herself... use themselves.
- he or she... use they.
- him or her... use them.
- his or her... use their.
- his or hers... use theirs.
- himself or herself... use themselves.
Commonly used terms
===================
## Commonly used terms
Here are some style guidelines on commonly used terms throughout the
documentation:
* **TLJH** -- common abbreviation of The Littlest JupyterHub. Fully
- **TLJH** -- common abbreviation of The Littlest JupyterHub. Fully
capitalized except when used in code / the commandline.
- **Python** -- when referring to the language, capitalize Python.
- **Notebook Interface** -- generic term for referring to JupyterLab,
classic notebook & other user interfaces for accessing.
* **Python** -- when referring to the language, capitalize Python.
## Guidelines for markdown files
* **Notebook Interface** -- generic term for referring to JupyterLab,
nteract, classic notebook & other user interfaces for accessing
Guidelines for reStructuredText files
=====================================
These guidelines regulate the format of our reST (reStructuredText)
These guidelines regulate the format of our markdown
documentation:
* In section titles, capitalize only initial words and proper nouns.
- In section titles, capitalize only initial words and proper nouns.
* Wrap the documentation at 120 characters wide, unless a code example
- Wrap the documentation at sentence breaks or around 120 characters wide, unless a code example
is significantly less readable when split over two lines, or for another
good reason.
* Use these heading styles::
===
One
===
Two
===
Three
-----
Four
~~~~
Five
^^^^
Documenting new features
========================
## Documenting new features
Our policy for new features is:
All new features must have appropriate documentation before they
can be merged.
> All new features must have appropriate documentation before they
> can be merged.
Choosing image size
===================
## Choosing image size
When adding images to the documentation, try to keep them as small as possible.
Larger images make the site load more slowly on browsers, and may make the site
@@ -217,37 +180,34 @@ If you're adding screenshots, make the size of your shot as small as possible.
If you're uploading large images, consider using an image optimizer in order
to reduce its size.
For example, for PNG files, use OptiPNG and AdvanceCOMP's ``advpng``:
For example, for PNG files, use OptiPNG and AdvanceCOMP's `advpng`:
.. code-block:: console
$ cd docs
$ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*.png"`
$ advpng -z4 `find . -type f -not -path "./_build/*" -name "*.png"`
```console
$ cd docs
$ optipng -o7 -zm1-9 -i0 -strip all `find . -type f -not -path "./_build/*" -name "*.png"`
$ advpng -z4 `find . -type f -not -path "./_build/*" -name "*.png"`
```
This is based on OptiPNG version 0.7.5. Older versions may complain about the
``--strip all`` option being lossy.
`--strip all` option being lossy.
Spelling check
==============
## Spelling check
Before you commit your docs, it's a good idea to run the spelling checker.
You'll need to install a couple packages first:
* `pyenchant <https://pypi.org/project/pyenchant/>`_ (which requires
`enchant <https://www.abisource.com/projects/enchant/>`_)
- [pyenchant](https://pypi.org/project/pyenchant/) (which requires
[enchant](https://www.abisource.com/projects/enchant/))
- [sphinxcontrib-spelling](https://pypi.org/project/sphinxcontrib-spelling/)
* `sphinxcontrib-spelling
<https://pypi.org/project/sphinxcontrib-spelling/>`_
Then from the ``docs`` directory, run ``make spelling``. Wrong words (if any)
Then from the `docs` directory, run `make spelling`. Wrong words (if any)
along with the file and line number where they occur will be saved to
``_build/spelling/output.txt``.
`_build/spelling/output.txt`.
If you encounter false-positives (error output that actually is correct), do
one of the following:
* Surround inline code or brand/technology names with grave accents (`).
* Find synonyms that the spell checker recognizes.
* If, and only if, you are sure the word you are using is correct - add it
to ``docs/spelling_wordlist`` (please keep the list in alphabetical order).
- Surround inline code or brand/technology names with grave accents (\`).
- Find synonyms that the spell checker recognizes.
- If, and only if, you are sure the word you are using is correct - add it
to `docs/spelling_wordlist` (please keep the list in alphabetical order).

View File

@@ -1,6 +1,4 @@
============
Contributing
============
# Contributing
✨ Thank you for thinking about contributing to the littlest JupyterHub! ✨
@@ -9,14 +7,15 @@ Your contribution is integral to the future of the project. Thank you!
This section contains documentation for people who want to contribute.
You can find the `source code on GitHub <https://github.com/jupyterhub/the-littlest-jupyterhub/tree/HEAD/tljh>`_
You can find the [source code on GitHub](https://github.com/jupyterhub/the-littlest-jupyterhub/tree/HEAD/tljh)
.. toctree::
:titlesonly:
```{toctree}
:titlesonly: true
docs
dev-setup
tests
plugins
code-review
packages
docs
dev-setup
tests
plugins
code-review
packages
```

View File

@@ -1,46 +1,40 @@
.. _contributing/packages:
(contributing-packages)=
=======================
Environments & Packages
=======================
# Environments & Packages
TLJH installs packages from different sources during installation.
This document describes the various sources and how to upgrade
versions of packages installed.
Python Environments
===================
## Python Environments
TLJH sets up two python environments during installation.
1. **Hub Environment**. JupyterHub, authenticators, spawners, TLJH plugins
and the TLJH configuration management code is installed into this
environment. A `venv <https://docs.python.org/3/library/venv.html>`_ is used,
environment. A [venv](https://docs.python.org/3/library/venv.html) is used,
primarily since conda does not support ARM CPUs and we'd like to support the
RaspberryPI someday. Admins generally do not install custom packages
in this environment.
2. **User Environment**. Jupyter Notebook, JupyterLab, nteract, kernels,
2. **User Environment**. Jupyter Notebook, JupyterLab, kernels,
and packages the users wanna use (such as numpy, scipy, etc) are installed
here. A `conda <https://conda.io>`_ environment is used here, since
a lot of scientific packages are available from Conda. ``pip`` is still
here. A [conda](https://conda.io) environment is used here, since
a lot of scientific packages are available from Conda. `pip` is still
used to install Jupyter specific packages, primarily because most notebook
extensions are still available only on `PyPI <https://pypi.org>`_.
extensions are still available only on [PyPI](https://pypi.org).
Admins can install packages here for use by all users.
Python package versions
=======================
## Python package versions
In ``installer.py``, most Python packages have a version specified. This
In `installer.py`, most Python packages have a version specified. This
can be upgraded freely whenever needed. Some of them have version checks
in ``integration-tests/test_extensions.py``, so those might need
in `integration-tests/test_extensions.py`, so those might need
updating too.
Apt packages
============
## Apt packages
Base operating system packages, including Python itself, are installed
via ``apt`` from the base Ubuntu repositories.
via `apt` from the base Ubuntu repositories.
We generally do not pin versions of packages provided by apt, instead
just using the latest versions provided by Ubuntu.

View File

@@ -0,0 +1,132 @@
(contributing-plugins)=
# TLJH Plugins
TLJH plugins are the official way to make customized 'spins' or 'stacks'
with TLJH as the base. For example, the earth sciences community can make
a plugin that installs commonly used packages, set up authentication
and pre-download useful datasets. The mybinder.org community can
make a plugin that gives you a single-node, single-repository mybinder.org.
Plugins are very powerful, so the possibilities are endless.
## Design
[pluggy](https://github.com/pytest-dev/pluggy) is used to implement
plugin functionality. TLJH exposes specific **hooks** that your plugin
can provide implementations for. This allows us to have specific hook
points in the application that can be explicitly extended by plugins,
balancing the need to change TLJH internals in the future with the
stability required for a good plugin ecosystem.
## Installing Plugins
Include `--plugin <install_name>` in the Installer script. See [](/topic/customizing-installer) for more info.
## Writing a simple plugins
We shall try to write a simple plugin that installs a few libraries,
and use it to explain how the plugin mechanism works. We shall call
this plugin `tljh-simple`.
### Plugin directory layout
We recommend creating a new git repo for your plugin. Plugins are
normal python packages - however, since they are usually simpler,
we recommend they live in one file.
For `tljh-simple`, the repository's structure should look like:
```none
tljh_simple:
- tljh_simple.py
- setup.py
- README.md
- LICENSE
```
The `README.md` (or `README.rst` file) contains human readable
information about what your plugin does for your users. `LICENSE`
specifies the license used by your plugin - we recommend the
3-Clause BSD License, since that is what is used by TLJH itself.
### `setup.py` - metadata & registration
`setup.py` marks this as a python package, and contains metadata
about the package itself. It should look something like:
```python
from setuptools import setup
setup(
name="tljh-simple",
author="YuviPanda",
version="0.1",
license="3-clause BSD",
url='https://github.com/yuvipanda/tljh-simple',
entry_points={"tljh": ["simple = tljh_simple"]},
py_modules=["tljh_simple"],
)
```
This is a mostly standard `setup.py` file. `entry_points={"tljh": ["simple = tljh_simple]}`
'registers' the module `tljh_simple` (in file `tljh_simple.py`) with TLJH as a plugin.
### `tljh_simple.py` - implementation
In `tljh_simple.py`, you provide implementations for whichever hooks
you want to extend.
A hook implementation is a function that has the following characteristics:
1. Has same name as the hook
2. Accepts some or all of the parameters defined for the hook
3. Is decorated with the `hookimpl` decorator function, imported from
`tljh.hooks`.
The current list of available hooks and when they are called can be
seen in [tljh/hooks.py](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/tljh/hooks.py)
in the source repository. Example implementations of each hook can be referenced from
[integration-tests/plugins/simplest/tljh_simplest.py](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/integration-tests/plugins/simplest/tljh_simplest.py).
This example provides an implementation for the `tljh_extra_user_conda_packages`
hook, which can return a list of conda packages that'll be installed in users'
environment from conda-forge.
```python
from tljh.hooks import hookimpl
@hookimpl
def tljh_extra_user_conda_packages():
return [
'xarray',
'iris',
'dask',
]
```
## Publishing plugins
Plugins are python packages and should be published on PyPI. Users
can also install them directly from GitHub - although this is
not good long term practice.
The python package should be named `tljh-<pluginname>`.
## List of known plugins
If you are looking for a way to extend or customize your TLJH deployment, you might want to look for existing plugins.
Here is a non-exhaustive list of known TLJH plugins:
- [tljh-pangeo](https://github.com/yuvipanda/tljh-pangeo): TLJH plugin for setting up the Pangeo Stack.
- [tljh-voila-gallery](https://github.com/voila-dashboards/tljh-voila-gallery): TLJH plugin that installs a gallery of Voilà dashboards.
- [tljh-repo2docker](https://github.com/plasmabio/tljh-repo2docker): TLJH plugin to build multiple user environments with
[repo2docker](https://repo2docker.readthedocs.io).
- [tljh-shared-directory](https://github.com/kafonek/tljh-shared-directory): TLJH plugin which sets up a _shared directory_
for the Hub users in `/srv/scratch`.
- [tljh-db](https://github.com/sinzlab/tljh-db): TLJH plugin for working with mysql databases.
If you have authored a plugin, please open a PR to add it to this list!
We also recommend adding the `tljh-plugin` topic to the GitHub repository to make it more discoverable:
[https://github.com/topics/tljh-plugin](https://github.com/topics/tljh-plugin)

View File

@@ -1,147 +0,0 @@
.. _contributing/plugins:
============
TLJH Plugins
============
TLJH plugins are the official way to make customized 'spins' or 'stacks'
with TLJH as the base. For example, the earth sciences community can make
a plugin that installs commonly used packages, set up authentication
and pre-download useful datasets. The mybinder.org community can
make a plugin that gives you a single-node, single-repository mybinder.org.
Plugins are very powerful, so the possibilities are endless.
Design
======
`pluggy <https://github.com/pytest-dev/pluggy>`_ is used to implement
plugin functionality. TLJH exposes specific **hooks** that your plugin
can provide implementations for. This allows us to have specific hook
points in the application that can be explicitly extended by plugins,
balancing the need to change TLJH internals in the future with the
stability required for a good plugin ecosystem.
Installing Plugins
==================
Include ``--plugin <install_name>`` in the Installer script. See :ref:`topic/customizing-installer` for more info.
Writing a simple plugins
========================
We shall try to write a simple plugin that installs a few libraries,
and use it to explain how the plugin mechanism works. We shall call
this plugin ``tljh-simple``.
Plugin directory layout
-----------------------
We recommend creating a new git repo for your plugin. Plugins are
normal python packages - however, since they are usually simpler,
we recommend they live in one file.
For ``tljh-simple``, the repository's structure should look like:
.. code-block:: none
tljh_simple:
- tljh_simple.py
- setup.py
- README.md
- LICENSE
The ``README.md`` (or ``README.rst`` file) contains human readable
information about what your plugin does for your users. ``LICENSE``
specifies the license used by your plugin - we recommend the
3-Clause BSD License, since that is what is used by TLJH itself.
``setup.py`` - metadata & registration
--------------------------------------
``setup.py`` marks this as a python package, and contains metadata
about the package itself. It should look something like:
.. code-block:: python
from setuptools import setup
setup(
name="tljh-simple",
author="YuviPanda",
version="0.1",
license="3-clause BSD",
url='https://github.com/yuvipanda/tljh-simple',
entry_points={"tljh": ["simple = tljh_simple"]},
py_modules=["tljh_simple"],
)
This is a mostly standard ``setup.py`` file. ``entry_points={"tljh": ["simple = tljh_simple]}``
'registers' the module ``tljh_simple`` (in file ``tljh_simple.py``) with TLJH as a plugin.
``tljh_simple.py`` - implementation
-----------------------------------
In ``tljh_simple.py``, you provide implementations for whichever hooks
you want to extend.
A hook implementation is a function that has the following characteristics:
#. Has same name as the hook
#. Accepts some or all of the parameters defined for the hook
#. Is decorated with the ``hookimpl`` decorator function, imported from
``tljh.hooks``.
The current list of available hooks and when they are called can be
seen in `tljh/hooks.py <https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/tljh/hooks.py>`_
in the source repository. Example implementations of each hook can be referenced from
`integration-tests/plugins/simplest/tljh_simplest.py
<https://github.com/jupyterhub/the-littlest-jupyterhub/blob/main/integration-tests/plugins/simplest/tljh_simplest.py>`_.
This example provides an implementation for the ``tljh_extra_user_conda_packages``
hook, which can return a list of conda packages that'll be installed in users'
environment from conda-forge.
.. code-block:: python
from tljh.hooks import hookimpl
@hookimpl
def tljh_extra_user_conda_packages():
return [
'xarray',
'iris',
'dask',
]
Publishing plugins
==================
Plugins are python packages and should be published on PyPI. Users
can also install them directly from GitHub - although this is
not good long term practice.
The python package should be named ``tljh-<pluginname>``.
List of known plugins
=====================
If you are looking for a way to extend or customize your TLJH deployment, you might want to look for existing plugins.
Here is a non-exhaustive list of known TLJH plugins:
- `tljh-pangeo <https://github.com/yuvipanda/tljh-pangeo>`_: TLJH plugin for setting up the Pangeo Stack.
- `tljh-voila-gallery <https://github.com/voila-dashboards/tljh-voila-gallery>`_: TLJH plugin that installs a gallery of Voilà dashboards.
- `tljh-repo2docker <https://github.com/plasmabio/tljh-repo2docker>`_: TLJH plugin to build multiple user environments with
`repo2docker <https://repo2docker.readthedocs.io>`_.
- `tljh-shared-directory <https://github.com/kafonek/tljh-shared-directory>`_: TLJH plugin which sets up a *shared directory*
for the Hub users in ``/srv/scratch``.
- `tljh-db <https://github.com/sinzlab/tljh-db>`_: TLJH plugin for working with mysql databases.
If you have authored a plugin, please open a PR to add it to this list!
We also recommend adding the ``tljh-plugin`` topic to the GitHub repository to make it more discoverable:
`https://github.com/topics/tljh-plugin <https://github.com/topics/tljh-plugin>`_

View File

@@ -0,0 +1,62 @@
(contributing-tests)=
# Testing TLJH
Unit and integration tests are a core part of TLJH, as important as
the code & documentation. They help validate that the code works as
we think it does, and continues to do so when changes occur. They
also help communicate in precise terms what we expect our code
to do.
## Integration tests
TLJH is a _distribution_ where the primary value is the many
opinionated choices we have made on components to use and how
they fit together. Integration tests are perfect for testing
that the various components fit together and work as they should.
So we write a lot of integration tests, and put in more effort
towards them than unit tests.
All integration tests are run in [GitHub Actions](https://github.com/jupyterhub/the-littlest-jupyterhub/actions)
for each PR and merge, making sure we don't have broken tests
for too long.
The integration tests are in the `integration-tests` directory
in the git repository. `py.test` is used to write the integration
tests. Each file should contain tests that can be run in any order
against the same installation of TLJH.
### Running integration tests locally
You need `docker` installed and callable by the user running
the integration tests without needing sudo.
You can then run the tests with:
```bash
.github/integration-test.py run-test <name-of-run> <test-file-names>
```
- `<name-of-run>` is an identifier for the tests - you can choose anything you want
- `<test-file-names>>` is list of test files (under `integration-tests`) that should be run in one go.
For example, to run all the basic tests, you would write:
```bash
.github/integration-test.py run-test basic-tests \
test_hub.py \
test_proxy.py \
test_install.py \
test_extensions.py
```
This will run the tests in the three files against the same installation
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`
parameter:
```bash
.github/integration-test.py run-test <name-of-run> <test-file-names> \
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
```

View File

@@ -1,66 +0,0 @@
.. _contributing/tests:
============
Testing TLJH
============
Unit and integration tests are a core part of TLJH, as important as
the code & documentation. They help validate that the code works as
we think it does, and continues to do so when changes occur. They
also help communicate in precise terms what we expect our code
to do.
Integration tests
=================
TLJH is a *distribution* where the primary value is the many
opinionated choices we have made on components to use and how
they fit together. Integration tests are perfect for testing
that the various components fit together and work as they should.
So we write a lot of integration tests, and put in more effort
towards them than unit tests.
All integration tests are run in `GitHub Actions <https://github.com/jupyterhub/the-littlest-jupyterhub/actions>`_
for each PR and merge, making sure we don't have broken tests
for too long.
The integration tests are in the ``integration-tests`` directory
in the git repository. ``py.test`` is used to write the integration
tests. Each file should contain tests that can be run in any order
against the same installation of TLJH.
Running integration tests locally
---------------------------------
You need ``docker`` installed and callable by the user running
the integration tests without needing sudo.
You can then run the tests with:
.. code-block:: bash
.github/integration-test.py run-test <name-of-run> <test-file-names>
- ``<name-of-run>`` is an identifier for the tests - you can choose anything you want
- ``<test-file-names>>`` is list of test files (under ``integration-tests``) that should be run in one go.
For example, to run all the basic tests, you would write:
.. code-block:: bash
.github/integration-test.py run-test basic-tests \
test_hub.py \
test_proxy.py \
test_install.py \
test_extensions.py
This will run the tests in the three files against the same installation
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``
parameter:
.. code-block:: bash
.github/integration-test.py run-test <name-of-run> <test-file-names> \
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"

View File

@@ -0,0 +1,100 @@
(howto-admin-admin-users)=
# Add / Remove admin users
Admin users in TLJH have the following powers:
1. Full root access to the server with passwordless `sudo`.
This lets them do literally whatever they want in the server
2. Access servers / home directories of all other users
3. Install new packages for everyone with `conda`, `pip` or `apt`
4. Change configuration of TLJH
This is a lot of power, so make sure you know who you are giving it
to. Admin users should have decent passwords / secure login mechanisms,
so attackers can not easily gain control of the system.
:::{important}
You should make sure an admin user is present when you **install** TLJH
the very first time. It is recommended that you also set a password
for the admin at this step. The [`--admin`](#howto-admin-admin-users)
flag passed to the installer does this. If you had forgotten to do so, the
easiest way to fix this is to run the installer again.
:::
## Adding admin users from the JupyterHub interface
There are two primary user interfaces for doing work on your JupyterHub. By
default, this is the Notebook Interface, and will be used in this section.
If you are using JupyterLab, you can access the Notebook Interface by replacing
`/lab` with `/tree` in your URL.
1. First, navigate to the Jupyter Notebook interface home page. You can do this
by going to the URL `<my-hub-url>/user/<my-username>/tree`.
2. Open the **Control Panel** by clicking the control panel button on the top
right of your JupyterHub.
```{image} ../../images/control-panel-button.png
:alt: Control panel button in notebook, top right
```
3. In the control panel, open the **Admin** link in the top left.
```{image} ../../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
```
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
4. Click the **Add Users** button.
```{image} ../../images/admin/add-users-button.png
:alt: Add Users button in the admin page
```
A **Add Users** dialog box opens up.
5. Type the names of users you want to add to this JupyterHub in the dialog box,
one per line. **Make sure to tick the Admin checkbox**.
```{image} ../../images/admin/add-users-dialog.png
:alt: Adding users with add users dialog
```
6. Click the **Add Users** button in the dialog box. Your users are now added
to the JupyterHub with administrator privileges!
## Adding admin users from the command line
Sometimes it is easier to add or remove admin users from the command line (for
example, if you forgot to add an admin user when first setting up your JupyterHub).
### Adding new admin users
New admin users can be added by executing the following commands on an
admin terminal:
```bash
sudo tljh-config add-item users.admin <username>
sudo tljh-config reload
```
If the user is already using the JupyterHub, they might have to stop and
start their server from the control panel to gain new powers.
### Removing admin users
You can remove an existing admin user by executing the following commands in
an admin terminal:
```bash
sudo tljh-config remove-item users.admin <username>
sudo tljh-config reload
```
If the user is already using the JupyterHub, they will continue to have
some of their admin powers until their server is stopped. Another admin
can force their server to stop by clicking 'Stop Server' in the admin
panel.

View File

@@ -1,102 +0,0 @@
.. _howto/admin/admin-users:
========================
Add / Remove admin users
========================
Admin users in TLJH have the following powers:
#. Full root access to the server with passwordless ``sudo``.
This lets them do literally whatever they want in the server
#. Access servers / home directories of all other users
#. Install new packages for everyone with ``conda``, ``pip`` or ``apt``
#. Change configuration of TLJH
This is a lot of power, so make sure you know who you are giving it
to. Admin users should have decent passwords / secure login mechanisms,
so attackers can not easily gain control of the system.
.. important::
You should make sure an admin user is present when you **install** TLJH
the very first time. It is recommended that you also set a password
for the admin at this step. The :ref:`--admin <topic/customizing-installer/admin>`
flag passed to the installer does this. If you had forgotten to do so, the
easiest way to fix this is to run the installer again.
Adding admin users from the JupyterHub interface
================================================
There are two primary user interfaces for doing work on your JupyterHub. By
default, this is the Notebook Interface, and will be used in this section.
If you are using JupyterLab, you can access the Notebook Interface by replacing
``/lab`` with ``/tree`` in your URL.
#. First, navigate to the Jupyter Notebook interface home page. You can do this
by going to the URL ``<my-hub-url>/user/<my-username>/tree``.
#. Open the **Control Panel** by clicking the control panel button on the top
right of your JupyterHub.
.. image:: ../../images/control-panel-button.png
:alt: Control panel button in notebook, top right
#. In the control panel, open the **Admin** link in the top left.
.. image:: ../../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
#. Click the **Add Users** button.
.. image:: ../../images/admin/add-users-button.png
:alt: Add Users button in the admin page
A **Add Users** dialog box opens up.
#. Type the names of users you want to add to this JupyterHub in the dialog box,
one per line. **Make sure to tick the Admin checkbox**.
.. image:: ../../images/admin/add-users-dialog.png
:alt: Adding users with add users dialog
#. Click the **Add Users** button in the dialog box. Your users are now added
to the JupyterHub with administrator privileges!
Adding admin users from the command line
========================================
Sometimes it is easier to add or remove admin users from the command line (for
example, if you forgot to add an admin user when first setting up your JupyterHub).
Adding new admin users
----------------------
New admin users can be added by executing the following commands on an
admin terminal:
.. code-block:: bash
sudo tljh-config add-item users.admin <username>
sudo tljh-config reload
If the user is already using the JupyterHub, they might have to stop and
start their server from the control panel to gain new powers.
Removing admin users
--------------------
You can remove an existing admin user by executing the following commands in
an admin terminal:
.. code-block:: bash
sudo tljh-config remove-item users.admin <username>
sudo tljh-config reload
If the user is already using the JupyterHub, they will continue to have
some of their admin powers until their server is stopped. Another admin
can force their server to stop by clicking 'Stop Server' in the admin
panel.

View File

@@ -0,0 +1,56 @@
(howto-admin-extensions)=
# Enabling Jupyter Notebook extensions
Jupyter contributed notebook
[extensions](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/index.html) are
community-contributed and maintained plug-ins to the Jupyter notebook. These extensions
serve many purposes, from [pedagogical tools](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/codefolding/readme.html)
to tools for [converting](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/latex_envs/README.html)
and [editing](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/spellchecker/README.html)
notebooks.
Extensions are often added and enabled through the graphical user interface of the notebook.
However, this interface only makes the extension available to the user, not all users on a
hub. Instead, to make contributed extensions available to your users, you will use the command
line. This can be completed using the terminal in the JupyterHub (or via SSH-ing into your
VM and using this terminal).
(tljh-extension-cli)=
## Enabling extensions via the command line
1. There are [multiple ways](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html)
to install contributed extensions. For this example, we will use `pip`.
```bash
sudo -E pip install jupyter_contrib_nbextensions
```
2. Next, add the notebook extension style files to the Jupyter configuration files.
```bash
sudo -E jupyter contrib nbextension install --sys-prefix
```
3. Then, you will enable the extensions you would like to use. The syntax for this is
`jupyter nbextension enable` followed by the path to the desired extension's main file.
For example, to enable [scratchpad](https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/scratchpad/README.html),
you would type the following:
```bash
sudo -E jupyter nbextension enable scratchpad/main --sys-prefix
```
4. When this is completed, the enabled extension should be visible in the extension list:
```bash
jupyter nbextension list
```
5. You can also verify the availability of the extension via its user interface in the notebook.
For example, spellchecker adds an ABC checkmark icon to the interface.
```{image} ../../images/admin/enable-spellcheck.png
:alt: spellcheck-interface-changes
```

View File

@@ -1,58 +0,0 @@
.. _howto/admin/extensions:
====================================
Enabling Jupyter Notebook extensions
====================================
Jupyter contributed notebook
`extensions <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/index.html>`_ are
community-contributed and maintained plug-ins to the Jupyter notebook. These extensions
serve many purposes, from `pedagogical tools <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/codefolding/readme.html>`_
to tools for `converting <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/latex_envs/README.html>`_
and `editing <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/spellchecker/README.html>`_
notebooks.
Extensions are often added and enabled through the graphical user interface of the notebook.
However, this interface only makes the extension available to the user, not all users on a
hub. Instead, to make contributed extensions available to your users, you will use the command
line. This can be completed using the terminal in the JupyterHub (or via SSH-ing into your
VM and using this terminal).
.. _tljh_extension_cli:
Enabling extensions via the command line
========================================
#. There are `multiple ways <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html>`_
to install contributed extensions. For this example, we will use ``pip``.
.. code-block:: bash
sudo -E pip install jupyter_contrib_nbextensions
#. Next, add the notebook extension style files to the Jupyter configuration files.
.. code-block:: bash
sudo -E jupyter contrib nbextension install --sys-prefix
#. Then, you will enable the extensions you would like to use. The syntax for this is
``jupyter nbextension enable`` followed by the path to the desired extension's main file.
For example, to enable `scratchpad <https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/scratchpad/README.html>`_,
you would type the following:
.. code-block:: bash
sudo -E jupyter nbextension enable scratchpad/main --sys-prefix
#. When this is completed, the enabled extension should be visible in the extension list:
.. code-block:: bash
jupyter nbextension list
#. You can also verify the availability of the extension via its user interface in the notebook.
For example, spellchecker adds an ABC checkmark icon to the interface.
.. image:: ../../images/admin/enable-spellcheck.png
:alt: spellcheck-interface-changes

121
docs/howto/admin/https.md Normal file
View File

@@ -0,0 +1,121 @@
(howto-admin-https)=
# Enable HTTPS
Every JupyterHub deployment should enable HTTPS!
HTTPS encrypts traffic so that usernames, passwords and your data are
communicated securely. sensitive bits of information are communicated
securely. The Littlest JupyterHub supports automatically configuring HTTPS
via [Let's Encrypt](https://letsencrypt.org), or setting it up
[manually](#howto-admin-https-manual) with your own TLS key and
certificate. Unless you have a strong reason to use the manual method,
you should use the [Let's Encrypt](#howto-admin-https-letsencrypt)
method.
:::{note}
You _must_ have a domain name set up to point to the IP address on
which TLJH is accessible before you can set up HTTPS.
To do that, you would have to log in to the website of your registrar
and go to the DNS records section. The interface will look like something
similar to this:
```{image} ../../images/dns.png
:alt: Adding an entry to the DNS records
```
:::
(howto-admin-https-letsencrypt)=
## Automatic HTTPS with Let's Encrypt
:::{note}
If the machine you are running on is not reachable from the internet -
for example, if it is a machine internal to your organization that
is cut off from the internet - you can not use this method. Please
set up a DNS entry and HTTPS [manually](#howto-admin-https-manual).
:::
To enable HTTPS via letsencrypt:
```
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 yourhub.yourdomain.edu
```
where `you@example.com` is your email address and `yourhub.yourdomain.edu`
is the domain where your hub will be running.
Once you have loaded this, your config should look like:
```
sudo tljh-config show
```
```yaml
https:
enabled: true
letsencrypt:
email: you@example.com
domains:
- yourhub.yourdomain.edu
```
Finally, you can reload the proxy to load the new configuration:
```
sudo tljh-config reload proxy
```
At this point, the proxy should negotiate with Let's Encrypt to set up a
trusted HTTPS certificate for you. It may take a moment for the proxy to
negotiate with Let's Encrypt to get your certificates, after which you can
access your Hub securely at <https://yourhub.yourdomain.edu>.
These certificates are valid for 3 months. The proxy will automatically
renew them for you before they expire.
(howto-admin-https-manual)=
## Manual HTTPS with existing key and certificate
You may already have an SSL key and certificate.
If so, you can tell your deployment to use these files:
```
sudo tljh-config set https.enabled true
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 add-item https.tls.domains yourhub.yourdomain.edu
```
Once you have loaded this, your config should look like:
```
sudo tljh-config show
```
```yaml
https:
enabled: true
tls:
key: /etc/mycerts/mydomain.key
cert: /etc/mycerts/mydomain.cert
domains:
- yourhub.yourdomain.edu
```
Finally, you can reload the proxy to load the new configuration:
```
sudo tljh-config reload proxy
```
and now access your Hub securely at <https://yourhub.yourdomain.edu>.
## Troubleshooting
If you're having trouble with HTTPS, looking at the [traefik proxy logs](troubleshooting-logs-traefik) might help.

View File

@@ -1,112 +0,0 @@
.. _howto/admin/https:
============
Enable HTTPS
============
Every JupyterHub deployment should enable HTTPS!
HTTPS encrypts traffic so that usernames, passwords and your data are
communicated securely. sensitive bits of information are communicated
securely. The Littlest JupyterHub supports automatically configuring HTTPS
via `Let's Encrypt <https://letsencrypt.org>`_, or setting it up
:ref:`manually <howto/admin/https/manual>` with your own TLS key and
certificate. Unless you have a strong reason to use the manual method,
you should use the :ref:`Let's Encrypt <howto/admin/https/letsencrypt>`
method.
.. note::
You *must* have a domain name set up to point to the IP address on
which TLJH is accessible before you can set up HTTPS.
To do that, you would have to log in to the website of your registrar
and go to the DNS records section. The interface will look like something
similar to this:
.. image:: ../../images/dns.png
:alt: Adding an entry to the DNS records
.. _howto/admin/https/letsencrypt:
Automatic HTTPS with Let's Encrypt
==================================
.. note::
If the machine you are running on is not reachable from the internet -
for example, if it is a machine internal to your organization that
is cut off from the internet - you can not use this method. Please
set up a DNS entry and HTTPS :ref:`manually <howto/admin/https/manual>`.
To enable HTTPS via letsencrypt::
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 yourhub.yourdomain.edu
where ``you@example.com`` is your email address and ``yourhub.yourdomain.edu``
is the domain where your hub will be running.
Once you have loaded this, your config should look like::
sudo tljh-config show
.. sourcecode:: yaml
https:
enabled: true
letsencrypt:
email: you@example.com
domains:
- yourhub.yourdomain.edu
Finally, you can reload the proxy to load the new configuration::
sudo tljh-config reload proxy
At this point, the proxy should negotiate with Let's Encrypt to set up a
trusted HTTPS certificate for you. It may take a moment for the proxy to
negotiate with Let's Encrypt to get your certificates, after which you can
access your Hub securely at https://yourhub.yourdomain.edu.
These certificates are valid for 3 months. The proxy will automatically
renew them for you before they expire.
.. _howto/admin/https/manual:
Manual HTTPS with existing key and certificate
==============================================
You may already have an SSL key and certificate.
If so, you can tell your deployment to use these files::
sudo tljh-config set https.enabled true
sudo tljh-config set https.tls.key /etc/mycerts/mydomain.key
sudo tljh-config set https.tls.cert /etc/mycerts/mydomain.cert
Once you have loaded this, your config should look like::
sudo tljh-config show
.. sourcecode:: yaml
https:
enabled: true
tls:
key: /etc/mycerts/mydomain.key
cert: /etc/mycerts/mydomain.cert
Finally, you can reload the proxy to load the new configuration::
sudo tljh-config reload proxy
and now access your Hub securely at https://yourhub.yourdomain.edu.
Troubleshooting
===============
If you're having trouble with HTTPS, looking at the :ref:`traefik
proxy logs <troubleshooting/logs/traefik>` might help.

View File

@@ -1,15 +1,14 @@
.. _howto/admin/nbresuse:
(howto-admin-nbresuse)=
=======================
Check your memory usage
=======================
# Check your memory usage
The `jupyter-resource-usage <https://github.com/jupyter-server/jupyter-resource-usage>`_ extension is part of
The [jupyter-resource-usage](https://github.com/jupyter-server/jupyter-resource-usage) extension is part of
the default installation, and tells you how much memory your user is using
right now, and what the memory limit for your user is. It is shown in the
top right corner of the notebook interface. Note that this is memory usage
for everything your user is running through the Jupyter notebook interface,
not just the specific notebook it is shown on.
.. image:: ../../images/nbresuse.png
:alt: Memory limit / usage shown with jupyter-resource-usage
```{image} ../../images/nbresuse.png
:alt: Memory limit / usage shown with jupyter-resource-usage
```

View File

@@ -1,60 +1,58 @@
.. _howto/admin/resize:
(howto-admin-resize)=
=================================================
Resize the resources available to your JupyterHub
=================================================
# Resize the resources available to your JupyterHub
As you are using your JupyterHub, you may need to increase or decrease
the amount of resources allocated to your TLJH install. The kinds of resources that can be
allocated, as well as the process to do so, will depend on the provider / interface for your
VM. We recommend consulting the installation page for your provider for more information. This
page covers the steps your should take on your JupyterHub *after* you've reallocated resources on
page covers the steps your should take on your JupyterHub _after_ you've reallocated resources on
the cloud provider of your choice.
Currently there are instructions to resize your resources on the following providers:
* :ref:`Digital Ocean <howto/providers/digitalocean/resize>`.
- [Digital Ocean](howto-providers-digitalocean-resize)
Once resources have been reallocated, you must tell TLJH to make use of these resources,
and verify that the resources have become available.
Verifying a Resize
==================
## Verifying a Resize
#. Once you have resized your server, tell the JupyterHub to make use of
1. Once you have resized your server, tell the JupyterHub to make use of
these new resources. To accomplish this, follow the instructions in
:ref:`topic/tljh-config` to set new memory or CPU limits and reload the hub. This can be completed
[](/topic/tljh-config) to set new memory or CPU limits and reload the hub. This can be completed
using the terminal in the JupyterHub (or via SSH-ing into your VM and using this terminal).
#. TLJH configuration options can be verified by viewing the tljh-config output.
.. code-block:: bash
2. TLJH configuration options can be verified by viewing the tljh-config output.
```bash
sudo tljh-config show
```
Double-check that your changes are reflected in the output.
#. **To verify changes to memory**, confirm that it worked by starting
3. **To verify changes to memory**, confirm that it worked by starting
a new server (if you had one previously running, click "Control Panel -> Stop My Server" to
shut down your active server first), opening a notebook, and checking the value of the
`jupyter-resource-usage <https://github.com/jupyter-server/jupyter-resource-usage>`_ extension in the upper-right.
[jupyter-resource-usage](https://github.com/jupyter-server/jupyter-resource-usage) extension in the upper-right.
.. image:: ../../images/nbresuse.png
```{image} ../../images/nbresuse.png
:alt: jupyter-resource-usage demonstration
```
#. **To verify changes to CPU**, use the ``nproc`` from a terminal.
4. **To verify changes to CPU**, use the `nproc` from a terminal.
This command displays the number of available cores, and should be equal to the
number of cores you selected in your provider's interface.
.. code-block:: bash
```bash
nproc --all
```
#. **To verify currently-available disk space**, use the ``df`` command in a terminal. This shows
how much disk space is available. The ``-hT`` argument allows us to have this printed in a human readable
5. **To verify currently-available disk space**, use the `df` command in a terminal. This shows
how much disk space is available. The `-hT` argument allows us to have this printed in a human readable
format, and condenses the output to show one storage volume. Note that currently you cannot
change the disk space on a per-user basis.
.. code-block:: bash
```bash
df -hT /home
```

View File

@@ -1,86 +1,78 @@
.. _howto/admin/resource-estimation:
(howto-admin-resource-estimation)=
===================================
Estimate Memory / CPU / Disk needed
===================================
# Estimate Memory / CPU / Disk needed
This page helps you estimate how much Memory / CPU / Disk the server you install
The Littlest JupyterHub on should have. These are just guidelines to help
with estimation - your actual needs will vary.
Memory
======
## Memory
Memory is usually the biggest determinant of server size in most JupyterHub
installations. At minimum, your server must have at least **1GB** of RAM
for TLJH to install.
.. math::
$$
Recommended\, Memory =
(Max\, concurrent\, users \times Max\, mem\, per\, user) + 128MB
$$
Recommended\, Memory =
(Max\, concurrent\, users \times Max\, mem\, per\, user) + 128MB
The ``128MB`` is overhead for TLJH and related services. **Server Memory Recommended**
The `128MB` is overhead for TLJH and related services. **Server Memory Recommended**
is the amount of Memory (RAM) the server you acquire should have - we recommend
erring on the side of 'more Memory'. The other terms are explained below.
Maximum concurrent users
------------------------
### Maximum concurrent users
Even if your class has 100 students, most of them will not be using the JupyterHub
actively at a single given moment. At 2am on a normal night, maybe you'll have 10 students
using it. At 2am before a final, maybe you'll have 60 students using it. Maybe
you'll have a lab session with all 100 of your students using it at the same time.
The *maximum* number of users actively using the JupyterHub at any given time determines
The _maximum_ number of users actively using the JupyterHub at any given time determines
how much memory your server will need. You'll get better at estimating this number
over time. We generally recommend between 40-60% of your total class size to start with.
Maximum memory allowed per user
-------------------------------
### Maximum memory allowed per user
Depending on what kind of work your users are doing, they will use different amounts
of memory. The easiest way to determine this is to run through a typical user
workflow yourself, and measure how much memory is used. You can use :ref:`howto/admin/nbresuse`
workflow yourself, and measure how much memory is used. You can use [](/howto/admin/nbresuse)
to determine how much memory your user is using.
A good rule of thumb is to take the maximum amount of memory you used during
your session, and add 20-40% headroom for users to 'play around'. This is the
maximum amount of memory that should be given to each user.
If users use *more* than this alloted amount of memory, their notebook kernel will *restart*.
If users use _more_ than this alloted amount of memory, their notebook kernel will _restart_.
CPU
===
## CPU
CPU estimation is more forgiving than Memory estimation. If there isn't
enough CPU for your users, their computation becomes very slow - but does not
stop, unlike with RAM.
.. math::
$$
Recommended\, CPU = (Max\, concurrent\, users \times Max\, CPU\, usage\, per\, user) + 20\%
$$
Recommended\, CPU = (Max\, concurrent\, users \times Max\, CPU\, usage\, per\, user) + 20\%
The ``20%`` is overhead for TLJH and related services. This is around 20% of a
The `20%` is overhead for TLJH and related services. This is around 20% of a
single modern CPU. This, of course, is just an estimate. We recommend using
the same process used to estimate Memory required for estimating CPU required.
You cannot use jupyter-resource-usage for this, but you should carry out normal workflow and
investigate the CPU usage on the machine.
Disk space
==========
## Disk space
Unlike Memory & CPU, disk space is predicated on **total** number of users,
rather than **maximum concurrent** users.
.. math::
$$
Recommended\, Disk\, Size = (Total\, users \times Max\, disk\, usage\, per\, user) + 2GB
$$
Recommended\, Disk\, Size = (Total\, users \times Max\, disk\, usage\, per\, user) + 2GB
## Resizing your server
Resizing your server
====================
Lots of cloud providers let your dynamically resize your server if you need it
Many cloud providers let your dynamically resize your server if you need it
to be larger or smaller. Usually this requires a restart of the whole server -
active users will be logged out, but otherwise usually nothing bad happens.
See [](#howto-admin-resize) for provider-specific instructions on resizing.

View File

@@ -0,0 +1,82 @@
(howto-admin-systemd)=
# Customizing `systemd` services
By default, TLJH configures two `systemd` services to run JupyterHub and Traefik.
These services come with a default set of settings, which are specified in
[jupyterhub.service](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/systemd-units/jupyterhub.service) and
[traefik.service](https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/systemd-units/traefik.service).
They look like the following:
```bash
[Unit]
Requires=traefik.service
After=traefik.service
[Service]
User=root
Restart=always
WorkingDirectory=/opt/tljh/state
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
Environment=TLJH_INSTALL_PREFIX=/opt/tljh
ExecStart=/opt/tljh/hub/bin/python3 -m jupyterhub -f jupyterhub_config.py --upgrade-db
[Install]
WantedBy=multi-user.target
```
However in some cases, admins might want to have better control on these settings.
For example when mounting shared volumes over the network using [Samba](<https://en.wikipedia.org/wiki/Samba_(software)>),
these namespacing settings might be a bit too strict and prevent users from accessing the shared volumes.
## Overriding settings with `override.conf`
To override the `jupyterhub` settings, it is possible to provide a custom `/etc/systemd/system/jupyterhub.service.d/override.conf` file.
Here is an example for the content of the file:
```bash
[Service]
PrivateTmp=no
PrivateDevices=no
ProtectKernelTunables=no
ProtectKernelModules=no
```
This example should be useful in the case of mounting volumes using Samba and sharing them with the JupyterHub users.
You might also want to provide your own options, which are listed in the
[systemd documentation](https://www.freedesktop.org/software/systemd/man/systemd.exec.html).
Then make sure to reload the daemon and the `jupyterhub` service:
```bash
sudo systemctl daemon-reload
sudo systemctl restart jupyterhub
```
Then check the status with:
```bash
sudo systemctl status jupyterhub
```
The output should look like the following:
```{image} ../../images/admin/jupyterhub-systemd-status.png
:alt: Checking the status of the JupyterHub systemd service
```
To override the `traefik` settings, create a new file under `/etc/systemd/system/traefik.service.d/override.conf`
and follow the same steps.
## References
If you would like to learn more about the `systemd` security features, check out these references:
- [List of systemd settings](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)
- [Mastering systemd: Securing and sandboxing applications and services](https://www.redhat.com/sysadmin/mastering-systemd)

View File

@@ -1,88 +0,0 @@
.. _howto/admin/systemd:
================================
Customizing ``systemd`` services
================================
By default, TLJH configures two ``systemd`` services to run JupyterHub and Traefik.
These services come with a default set of settings, which are specified in
`jupyterhub.service <https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/systemd-units/jupyterhub.service>`_ and
`traefik.service <https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/systemd-units/traefik.service>`_.
They look like the following:
.. code-block:: bash
[Unit]
Requires=traefik.service
After=traefik.service
[Service]
User=root
Restart=always
WorkingDirectory=/opt/tljh/state
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
Environment=TLJH_INSTALL_PREFIX=/opt/tljh
ExecStart=/opt/tljh/hub/bin/python3 -m jupyterhub.app -f jupyterhub_config.py --upgrade-db
[Install]
WantedBy=multi-user.target
However in some cases, admins might want to have better control on these settings.
For example when mounting shared volumes over the network using `Samba <https://en.wikipedia.org/wiki/Samba_(software)>`_,
these namespacing settings might be a bit too strict and prevent users from accessing the shared volumes.
Overriding settings with ``override.conf``
==========================================
To override the ``jupyterhub`` settings, it is possible to provide a custom ``/etc/systemd/system/jupyterhub.service.d/override.conf`` file.
Here is an example for the content of the file:
.. code-block:: bash
[Service]
PrivateTmp=no
PrivateDevices=no
ProtectKernelTunables=no
ProtectKernelModules=no
This example should be useful in the case of mounting volumes using Samba and sharing them with the JupyterHub users.
You might also want to provide your own options, which are listed in the
`systemd documentation <https://www.freedesktop.org/software/systemd/man/systemd.exec.html>`_.
Then make sure to reload the daemon and the ``jupyterhub`` service:
.. code-block:: bash
sudo systemctl daemon-reload
sudo systemctl restart jupyterhub
Then check the status with:
.. code-block:: bash
sudo systemctl status jupyterhub
The output should look like the following:
.. image:: ../../images/admin/jupyterhub-systemd-status.png
:alt: Checking the status of the JupyterHub systemd service
To override the ``traefik`` settings, create a new file under ``/etc/systemd/system/traefik.service.d/override.conf``
and follow the same steps.
References
==========
If you would like to learn more about the ``systemd`` security features, check out these references:
- `List of systemd settings <https://www.freedesktop.org/software/systemd/man/systemd.exec.html>`_
- `Mastering systemd: Securing and sandboxing applications and services <https://www.redhat.com/sysadmin/mastering-systemd>`_

View File

@@ -0,0 +1,64 @@
(howto-admin-upgrade-tljh)=
# Upgrade TLJH
A TLJH installation is supposed to be upgradable to get updates to JupyterHub
itself and its dependencies in the [hub environment](hub-environment). For
details on what is done during an upgrade, see
[](topic-installer-upgrade-actions).
## Step 1: Read the changelog
Before making an upgrade, please read the [](changelog) to become aware about
breaking changes. If there are breaking changes, you may need to update your
configuration files or take other actions as well as part of the upgrade.
Adjusting to the breaking changes isn't part of this documentation, please rely
on the TLJH changelog and the changelogs of related projects linked to from the
TLJH changelog.
## Step 2: Consider making a backup
Before making an upgrade, consider if you want to first make a backup in some
way. While upgrades between TLJH versions are tested with automation, there are
no guarantees.
This project does't yet provide documentation on how to make backups, but if
TLJH is installed on a virtual machine in a cloud, a good option is to try
create a snapshot of the associated disk. If this isn't an option, you could
consider making a backup of the files in `/opt/tljh` that contain most but not
all things during an upgrade, or perhaps only the JupyterHub database with
information about its users in `/opt/tljh/state` together with some other
details.
## Step 3: Make the upgrade
To initialize the upgrade, do the following from a terminal on the machine where
TLJH is installed.
```shell
# IMPORTANT: This should NOT be run from a JupyterHub started user server, but
# should only run from a standalone terminal session in the machine
# where TLJH has been installed.
#
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--version=latest
```
You can also upgrade to specific version by changing `--version=latest` to
`--version=1.0.0` or similar. There is no need to specify admin users etc again.
## Step 4: Verify function
After having made an upgrade its always good to verify that the JupyterHub
installation still works as expected. You may want to try logging out, logging
in, and starting a new server for example.
If you have issues consider the [](troubleshooting) documentation. If you need
help you can ask questions in [Jupyter forum], and if you think there is a bug
or documentation improvement that should be made you can open an issue or pull
request in the [TLJH GitHub project].
[jupyter forum]: https://discourse.jupyter.org/c/jupyterhub/tljh
[tljh github project]: https://github.com/jupyterhub/the-littlest-jupyterhub

View File

@@ -0,0 +1,158 @@
(howto-auth-awscognito)=
# Authenticate using AWS Cognito
```{warning}
This documentation has not been updated recently, and a major version of
OAuthenticator has been released since it was. Due to that, please only use this
_as a complement_ to the official [OAuthenticator documentation].
[OAuthenticator documentation]: https://oauthenticator.readthedocs.io/en/latest/tutorials/provider-specific-setup/providers/generic.html#setup-for-aws-cognito
Going onwards, the goal is to ensure we have good documentation in the
OAuthenticator project and reference that instead of maintaining similar
documentation in this project also.
```
The **AWS Cognito Authenticator** lets users log into your JupyterHub using
cognito user pools. To do so, you'll first need to register and configure a
cognito user pool and app, and then provide information about this
application to your `tljh` configuration.
## Create an AWS Cognito application
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:
- **App client id**: From the App client page
- **App client secret** From the App client page
- **Callback URL** This should be the domain you are hosting you server on:
```
http(s)://<my-tljh-ip-address>/hub/oauth_callback
```
- **Signout URL**: This is the landing page for a user when they are not logged on:
```
http(s)://<my-tljh-ip-address>
```
- **Auth Domain** Create an auth domain e.g. \<my_jupyter_hub>:
```
https://<<my_jupyter_hub>.auth.eu-west-1.amazoncognito.com
```
## Install and configure an AWS EC2 Instance with userdata
By adding following script to the ec2 instance user data you should be
able to configure the instance automatically, replace relevant placeholders:
```bash
#!/bin/bash
##############################################
# Ensure tljh is up to date
##############################################
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin insightadmin
##############################################
# Setup AWS Cognito OAuthenticator
##############################################
echo > /opt/tljh/config/jupyterhub_config.d/awscognito.py <<EOF
c.GenericOAuthenticator.client_id = "[your app client ID]"
c.GenericOAuthenticator.client_secret = "[your app client secret]"
c.GenericOAuthenticator.oauth_callback_url = "https://[your-jupyterhub-host]/hub/oauth_callback"
c.GenericOAuthenticator.authorize_url = "https://your-AWSCognito-domain/oauth2/authorize"
c.GenericOAuthenticator.token_url = "https://your-AWSCognito-domain/oauth2/token"
c.GenericOAuthenticator.userdata_url = "https://your-AWSCognito-domain/oauth2/userInfo"
c.GenericOAuthenticator.logout_redirect_url = "https://your-AWSCognito-domain/oauth2/logout"
# these are always the same
c.GenericOAuthenticator.login_service = "AWS Cognito"
c.GenericOAuthenticator.username_key = "username"
c.GenericOAuthenticator.userdata_method = "POST"
EOF
tljh-config set auth.type oauthenticator.generic.GenericOAuthenticator
tljh-config reload
```
## Manual configuration to use the AWS Cognito OAuthenticator
AWS Cognito is configured as a generic OAuth provider.
Using your preferred editor create the config file:
```
/opt/tljh/config/jupyterhub_config.d/awscognito.py
```
substituting the relevant variables:
```python
c.GenericOAuthenticator.client_id = "[your app ID]"
c.GenericOAuthenticator.client_secret = "[your app Password]"
c.GenericOAuthenticator.oauth_callback_url = "https://[your-jupyterhub-host]/hub/oauth_callback"
c.GenericOAuthenticator.authorize_url = "https://your-AWSCognito-domain/oauth2/authorize"
c.GenericOAuthenticator.token_url = "https://your-AWSCognito-domain/oauth2/token"
c.GenericOAuthenticator.userdata_url = "https://your-AWSCognito-domain/oauth2/userInfo"
c.GenericOAuthenticator.logout_redirect_url = "https://your-AWSCognito-domain/oauth2/logout"
# these are always the same
c.GenericOAuthenticator.login_service = "AWS Cognito"
c.GenericOAuthenticator.username_key = "username"
c.GenericOAuthenticator.userdata_method = "POST"
```
We'll use the `tljh-config` tool to configure your JupyterHub's authentication.
For more information on `tljh-config`, see [](/topic/tljh-config).
1. Tell your JupyterHub to use the GenericOAuthenticator for authentication:
```
tljh-config set auth.type oauthenticator.generic.GenericOAuthenticator
```
2. Restart your JupyterHub so that new users see these changes:
```
sudo tljh-config reload
```
## Confirm that the new authenticator works
1. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
2. Go to your JupyterHub URL.
3. You should see an AWS Cognito login button:
4. You will likely have to create a new user (sign up) and then you should be directed to the
Jupyter interface used in this JupyterHub.
5. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in [](/howto/auth/firstuse).
## Optionally using custom claims for group mapping
If you use AWS Cognito to federate with an OIDC provider and you want to
authorize your users based on e.g. their department claim, you have to make sure
that the custom claim is provided as array.
If it is not provided as array, there is an easy fix. Just add these lines to
your `awscognito.py`:
```python
def groups_key_func(auth_state):
return [auth_state['oauth_user']['custom:department']]
c.GenericOAuthenticator.manage_groups = True
c.GenericOAuthenticator.auth_state_groups_key = groups_key_func
c.GenericOAuthenticator.allowed_groups = ["AA BB CC", "AA BB DD"]
```

View File

@@ -1,122 +0,0 @@
.. _howto/auth/awscognito:
==============================
Authenticate using AWS Cognito
==============================
The **AWS Cognito Authenticator** lets users log into your JupyterHub using
cognito user pools. To do so, you'll first need to register and configure a
cognito user pool and app, and then provide information about this
application to your ``tljh`` configuration.
Create an AWS Cognito application
=========================================
#. 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:
* **App client id**: From the App client page
* **App client secret** From the App client page
* **Callback URL** This should be the domain you are hosting you server on::
http(s)://<my-tljh-ip-address>/hub/oauth_callback
* **Signout URL**: This is the landing page for a user when they are not logged on::
http(s)://<my-tljh-ip-address>
* **Auth Domain** Create an auth domain e.g. <my_jupyter_hub>::
https://<<my_jupyter_hub>.auth.eu-west-1.amazoncognito.com
Install and configure an AWS EC2 Instance with userdata
=======================================================
By adding following script to the ec2 instance user data you should be
able to configure the instance automatically, replace relevant placeholders::
#!/bin/bash
##############################################
# Ensure tljh is up to date
##############################################
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin insightadmin
##############################################
# Setup AWS Cognito OAuthenticator
##############################################
echo > /opt/tljh/config/jupyterhub_config.d/awscognito.py <<EOF
c.GenericOAuthenticator.client_id = "[your app client ID]"
c.GenericOAuthenticator.client_secret = "[your app client secret]"
c.GenericOAuthenticator.oauth_callback_url = "https://[your-jupyterhub-host]/hub/oauth_callback"
c.GenericOAuthenticator.authorize_url = "https://your-AWSCognito-domain/oauth2/authorize"
c.GenericOAuthenticator.token_url = "https://your-AWSCognito-domain/oauth2/token"
c.GenericOAuthenticator.userdata_url = "https://your-AWSCognito-domain/oauth2/userInfo"
c.GenericOAuthenticator.logout_redirect_url = "https://your-AWSCognito-domain/oauth2/logout"
# these are always the same
c.GenericOAuthenticator.login_service = "AWS Cognito"
c.GenericOAuthenticator.username_key = "username"
c.GenericOAuthenticator.userdata_method = "POST"
EOF
tljh-config set auth.type oauthenticator.generic.GenericOAuthenticator
tljh-config reload
Manual configuration to use the AWS Cognito OAuthenticator
==========================================================
AWS Cognito is configured as a generic OAuth provider.
Using your preferred editor create the config file::
/opt/tljh/config/jupyterhub_config.d/awscognito.py
substituting the relevant variables::
c.GenericOAuthenticator.client_id = "[your app ID]"
c.GenericOAuthenticator.client_secret = "[your app Password]"
c.GenericOAuthenticator.oauth_callback_url = "https://[your-jupyterhub-host]/hub/oauth_callback"
c.GenericOAuthenticator.authorize_url = "https://your-AWSCognito-domain/oauth2/authorize"
c.GenericOAuthenticator.token_url = "https://your-AWSCognito-domain/oauth2/token"
c.GenericOAuthenticator.userdata_url = "https://your-AWSCognito-domain/oauth2/userInfo"
c.GenericOAuthenticator.logout_redirect_url = "https://your-AWSCognito-domain/oauth2/logout"
# these are always the same
c.GenericOAuthenticator.login_service = "AWS Cognito"
c.GenericOAuthenticator.username_key = "username"
c.GenericOAuthenticator.userdata_method = "POST"
We'll use the ``tljh-config`` tool to configure your JupyterHub's authentication.
For more information on ``tljh-config``, see :ref:`topic/tljh-config`.
#. Tell your JupyterHub to use the GenericOAuthenticator for authentication::
tljh-config set auth.type oauthenticator.generic.GenericOAuthenticator
#. Restart your JupyterHub so that new users see these changes::
sudo tljh-config reload
Confirm that the new authenticator works
========================================
#. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
#. Go to your JupyterHub URL.
#. You should see an AWS Cognito login button:
#. You will likely have to create a new user (sign up) and then you should be directed to the
Jupyter interface used in this JupyterHub.
#. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in :ref:`howto/auth/firstuse`.

49
docs/howto/auth/dummy.md Normal file
View File

@@ -0,0 +1,49 @@
(howto-auth-dummy)=
# Authenticate _any_ user with a single shared password
```{warning}
The **Dummy Authenticator** lets _any_ user log in with the given password.
This authenticator is **extremely insecure**, so do not use it if you can
avoid it.
```
## Enabling the authenticator
1. Always use DummyAuthenticator with a password. You can communicate this
password to all your users via an out of band mechanism (like writing on
a whiteboard). Once you have selected a password, configure TLJH to use
the password by executing the following from an admin console.
```bash
sudo tljh-config set auth.DummyAuthenticator.password <password>
```
Remember to replace `<password>` with the password you choose.
2. Enable the authenticator and reload config to apply configuration:
```bash
sudo tljh-config set auth.type dummy
```
```bash
sudo tljh-config reload
```
Users who are currently logged in will continue to be logged in. When they
log out and try to log back in, they will be asked to provide a username and
password.
## Changing the password
The password used by DummyAuthenticator can be changed with the following
commands:
```bash
tljh-config set auth.DummyAuthenticator.password <new-password>
```
```bash
tljh-config reload
```

View File

@@ -1,51 +0,0 @@
.. _howto/auth/dummy:
=====================================================
Authenticate *any* user with a single shared password
=====================================================
The **Dummy Authenticator** lets *any* user log in with the given password.
This authenticator is **extremely insecure**, so do not use it if you can
avoid it.
Enabling the authenticator
==========================
1. Always use DummyAuthenticator with a password. You can communicate this
password to all your users via an out of band mechanism (like writing on
a whiteboard). Once you have selected a password, configure TLJH to use
the password by executing the following from an admin console.
.. code-block:: bash
sudo tljh-config set auth.DummyAuthenticator.password <password>
Remember to replace ``<password>`` with the password you choose.
2. Enable the authenticator and reload config to apply configuration:
.. code-block:: bash
sudo tljh-config set auth.type dummy
.. code-block:: bash
sudo tljh-config reload
Users who are currently logged in will continue to be logged in. When they
log out and try to log back in, they will be asked to provide a username and
password.
Changing the password
=====================
The password used by DummyAuthenticator can be changed with the following
commands:
.. code-block:: bash
tljh-config set auth.DummyAuthenticator.password <new-password>
.. code-block:: bash
tljh-config reload

View File

@@ -0,0 +1,91 @@
(howto-auth-firstuse)=
# Let users choose a password when they first log in
```{warning}
This documentation is not being updated regularly and may be out of date. Due to
that, please only use this _as a complement_ to the official
[FirstUseAuthenticator documentation].
[FirstUseAuthenticator documentation]: https://github.com/jupyterhub/firstuseauthenticator#readme
Going onwards, the goal is to ensure we have good documentation in the
FirstUseAuthenticator project and reference that instead of maintaining similar
documentation in this project also.
```
The **First Use Authenticator** lets users choose their own password.
Upon their first log-in attempt, whatever password they use will be stored
as their password for subsequent log in attempts. This is
the default authenticator that ships with TLJH.
## Enabling the authenticator
:::{note}
the FirstUseAuthenticator is enabled by default in TLJH.
:::
Enable the authenticator and reload config to apply the configuration:
```bash
sudo tljh-config set auth.type firstuseauthenticator.FirstUseAuthenticator
sudo tljh-config reload
```
Users who are currently logged in will continue to be logged in. When they
log out and try to log back in, they will be asked to provide a username and
password.
## Users changing their own password
Users can change their password by first logging into their account and then visiting
the url `<your_server_ip>/hub/auth/change-password`.
## Allowing anyone to log in to your JupyterHub
By default, you need to manually create user accounts before they will be able
to log in to your JupyterHub. If you wish to allow **any** user to access
the JupyterHub, run the following command.
```bash
tljh-config set auth.FirstUseAuthenticator.create_users true
tljh-config reload
```
## Resetting user password
The admin can reset user passwords by _deleting_ the user from the JupyterHub admin
page. This logs the user out, but does **not** remove any of their data or
home directories. The user can then set a new password by logging in again with
their new password.
1. As an admin user, open the **Control Panel** by clicking the control panel
button on the top right of your JupyterHub.
```{image} ../../images/control-panel-button.png
:alt: Control panel button in notebook, top right
```
2. In the control panel, open the **Admin** link in the top left.
```{image} ../../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
```
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
3. **Delete** the user whose password needs resetting. Remember this **does not**
delete their data or home directory.
```{image} ../../images/auth/firstuse/delete-user.png
:alt: Delete user button for each user
```
If there is a confirmation dialog, confirm the deletion. This will also log the
user out if they were currently running.
4. Re-create the user whose password needs resetting within that same dialog.
5. Ask the user to log in again with their new password as usual. This will be their
new password going forward.

View File

@@ -1,81 +0,0 @@
.. _howto/auth/firstuse:
==================================================
Let users choose a password when they first log in
==================================================
The **First Use Authenticator** lets users choose their own password.
Upon their first log-in attempt, whatever password they use will be stored
as their password for subsequent log in attempts. This is
the default authenticator that ships with TLJH.
Enabling the authenticator
==========================
.. note:: the FirstUseAuthenticator is enabled by default in TLJH.
#. Enable the authenticator and reload config to apply the configuration:
.. code-block:: bash
sudo tljh-config set auth.type firstuseauthenticator.FirstUseAuthenticator
sudo tljh-config reload
Users who are currently logged in will continue to be logged in. When they
log out and try to log back in, they will be asked to provide a username and
password.
Users changing their own password
=================================
Users can change their password by first logging into their account and then visiting
the url ``<your_server_ip>/hub/auth/change-password``.
Allowing anyone to log in to your JupyterHub
============================================
By default, you need to manually create user accounts before they will be able
to log in to your JupyterHub. If you wish to allow **any** user to access
the JupyterHub, run the following command.
.. code-block:: bash
tljh-config set auth.FirstUseAuthenticator.create_users true
tljh-config reload
Resetting user password
=======================
The admin can reset user passwords by *deleting* the user from the JupyterHub admin
page. This logs the user out, but does **not** remove any of their data or
home directories. The user can then set a new password by logging in again with
their new password.
#. As an admin user, open the **Control Panel** by clicking the control panel
button on the top right of your JupyterHub.
.. image:: ../../images/control-panel-button.png
:alt: Control panel button in notebook, top right
#. In the control panel, open the **Admin** link in the top left.
.. image:: ../../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
#. **Delete** the user whose password needs resetting. Remember this **does not**
delete their data or home directory.
.. image:: ../../images/auth/firstuse/delete-user.png
:alt: Delete user button for each user
If there is a confirmation dialog, confirm the deletion. This will also log the
user out if they were currently running.
#. Re-create the user whose password needs resetting within that same dialog.
#. Ask the user to log in again with their new password as usual. This will be their
new password going forward.

126
docs/howto/auth/github.md Normal file
View File

@@ -0,0 +1,126 @@
(howto-auth-github)=
# Authenticate using GitHub Usernames
```{warning}
This documentation has not been updated recently, and a major version of
OAuthenticator has been released since it was. Due to that, please only use this
_as a complement_ to the official [OAuthenticator documentation].
[OAuthenticator documentation]: https://oauthenticator.readthedocs.io/en/latest/tutorials/provider-specific-setup/providers/github.html
Going onwards, the goal is to ensure we have good documentation in the
OAuthenticator project and reference that instead of maintaining similar
documentation in this project also.
```
The **GitHub Authenticator** lets users log into your JupyterHub using their
GitHub user ID / password. To do so, you'll first need to register an
application with GitHub, and then provide information about this
application to your `tljh` configuration.
:::{note}
You'll need a GitHub account in order to complete these steps.
:::
## Step 1: Create a GitHub application
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`)
- **Homepage URL**: Use the IP address or URL of your JupyterHub. e.g. `` http(s)://<my-tljh-url>` ``.
- **Application description**: Use any description that you like.
- **Authorization callback URL**: Insert text with the following form:
```
http(s)://<my-tljh-ip-address>/hub/oauth_callback
```
- When you're done filling in the page, it should look something like this:
```{image} ../../images/auth/github/create_application.png
:alt: Create a GitHub OAuth application
```
2. Click "Register application". You'll be taken to a page with the registered application details.
3. Copy the **Client ID** and **Client Secret** from the application details
page. You will use these later to configure your JupyterHub authenticator.
```{image} ../../images/auth/github/client_id_secret.png
:alt: Your client ID and secret
```
:::{important}
If you are using a virtual machine from a cloud provider and
**stop the VM**, then when you re-start the VM, the provider will likely assign a **new public
IP address** to it. In this case, **you must update your GitHub application information**
with the new IP address.
:::
## Configure your JupyterHub to use the GitHub Oauthenticator
We'll use the `tljh-config` tool to configure your JupyterHub's authentication.
For more information on `tljh-config`, see [](/topic/tljh-config).
1. Log in as an administrator account to your JupyterHub.
2. Open a terminal window.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
3. Configure the GitHub OAuthenticator to use your client ID, client secret and callback URL with the following commands:
```
sudo tljh-config set auth.GitHubOAuthenticator.client_id '<my-tljh-client-id>'
```
```
sudo tljh-config set auth.GitHubOAuthenticator.client_secret '<my-tljh-client-secret>'
```
```
sudo tljh-config set auth.GitHubOAuthenticator.oauth_callback_url 'http(s)://<my-tljh-ip-address>/hub/oauth_callback'
```
4. Tell your JupyterHub to _use_ the GitHub OAuthenticator for authentication:
```
sudo tljh-config set auth.type github
```
5. Tell JupyterHub which users to allow, if you haven't already:
```
sudo tljh-config add-item users.allowed good-user_1
```
6. Restart your JupyterHub so that new users see these changes:
```
sudo tljh-config reload
```
## Confirm that the new authenticator works
1. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
2. Go to your JupyterHub URL.
3. You should see a GitHub login button like below:
```{image} ../../images/auth/github/login_button.png
:alt: The GitHub authenticator login button.
```
4. After you log in with your GitHub credentials, you should be directed to the
Jupyter interface used in this JupyterHub.
5. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in [](/howto/auth/firstuse).

View File

@@ -1,93 +0,0 @@
.. _howto/auth/github:
===================================
Authenticate using GitHub Usernames
===================================
The **GitHub Authenticator** lets users log into your JupyterHub using their
GitHub user ID / password. To do so, you'll first need to register an
application with GitHub, and then provide information about this
application to your ``tljh`` configuration.
.. note::
You'll need a GitHub account in order to complete these steps.
Step 1: Create a GitHub application
===================================
#. Go to the `GitHub OAuth app creation page <https://github.com/settings/applications/new>`_.
* **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>```.
* **Application description**: Use any description that you like.
* **Authorization callback URL**: Insert text with the following form::
http(s)://<my-tljh-ip-address>/hub/oauth_callback
* When you're done filling in the page, it should look something like this:
.. image:: ../../images/auth/github/create_application.png
:alt: Create a GitHub OAuth application
#. Click "Register application". You'll be taken to a page with the registered application details.
#. Copy the **Client ID** and **Client Secret** from the application details
page. You will use these later to configure your JupyterHub authenticator.
.. image:: ../../images/auth/github/client_id_secret.png
:alt: Your client ID and secret
.. important::
If you are using a virtual machine from a cloud provider and
**stop the VM**, then when you re-start the VM, the provider will likely assign a **new public
IP address** to it. In this case, **you must update your GitHub application information**
with the new IP address.
Configure your JupyterHub to use the GitHub Oauthenticator
==========================================================
We'll use the ``tljh-config`` tool to configure your JupyterHub's authentication.
For more information on ``tljh-config``, see :ref:`topic/tljh-config`.
#. Log in as an administrator account to your JupyterHub.
#. Open a terminal window.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. Configure the GitHub OAuthenticator to use your client ID, client secret and callback URL with the following commands::
sudo tljh-config set auth.GitHubOAuthenticator.client_id '<my-tljh-client-id>'
::
sudo tljh-config set auth.GitHubOAuthenticator.client_secret '<my-tljh-client-secret>'
::
sudo tljh-config set auth.GitHubOAuthenticator.oauth_callback_url 'http(s)://<my-tljh-ip-address>/hub/oauth_callback'
#. Tell your JupyterHub to *use* the GitHub OAuthenticator for authentication::
sudo tljh-config set auth.type oauthenticator.github.GitHubOAuthenticator
#. Restart your JupyterHub so that new users see these changes::
sudo tljh-config reload
Confirm that the new authenticator works
========================================
#. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
#. Go to your JupyterHub URL.
#. You should see a GitHub login button like below:
.. image:: ../../images/auth/github/login_button.png
:alt: The GitHub authenticator login button.
#. After you log in with your GitHub credentials, you should be directed to the
Jupyter interface used in this JupyterHub.
#. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in :ref:`howto/auth/firstuse`.

221
docs/howto/auth/google.md Normal file
View File

@@ -0,0 +1,221 @@
(howto-auth-google)=
# Authenticate using Google
```{warning}
This documentation has not been updated recently, and a major version of
OAuthenticator has been released since it was. Due to that, please only use this
_as a complement_ to the official [OAuthenticator documentation].
[OAuthenticator documentation]: https://oauthenticator.readthedocs.io/en/latest/tutorials/provider-specific-setup/providers/google.html
Going onwards, the goal is to ensure we have good documentation in the
OAuthenticator project and reference that instead of maintaining similar
documentation in this project also.
```
The **Google OAuthenticator** lets users log into your JupyterHub using their
Google user ID / password. To do so, you'll first need to register an
application with Google, and then provide information about this
application to your `tljh` configuration.
See [Google's documentation](https://developers.google.com/identity/protocols/OAuth2)
on how to create OAUth 2.0 client credentials.
:::{note}
You'll need a Google account in order to complete these steps.
:::
## Step 1: Create a Google project
Go to [Google Developers Console](https://console.developers.google.com)
and create a new project:
```{image} ../../images/auth/google/create_new_project.png
:alt: Create a Google project
```
## Step 2: Set up a Google OAuth client ID and secret
1. After creating and selecting the project:
- Go to the credentials menu:
```{image} ../../images/auth/google/credentials_button.png
:alt: Credentials menu
```
- Click "Create credentials" and from the dropdown menu select **"OAuth client ID"**:
```{image} ../../images/auth/google/create_credentials.png
:alt: Generate credentials
```
- You will have to fill a form with:
- **Application type**: Choose _Web application_
- **Name**: A descriptive name for your OAuth client ID (e.g. `tljh-client`)
- **Authorized JavaScript origins**: Use the IP address or URL of your JupyterHub. e.g. `http(s)://<my-tljh-url>`.
- **Authorized redirect URIs**: Insert text with the following form:
```
http(s)://<my-tljh-ip-address>/hub/oauth_callback
```
- When you're done filling in the page, it should look something like this (ideally without the red warnings):
```{image} ../../images/auth/google/create_oauth_client_id.png
:alt: Create a Google OAuth client ID
```
2. Click "Create". You'll be taken to a page with the registered application details.
3. Copy the **Client ID** and **Client Secret** from the application details
page. You will use these later to configure your JupyterHub authenticator.
```{image} ../../images/auth/google/client_id_secret.png
:alt: Your client ID and secret
```
:::{important}
If you are using a virtual machine from a cloud provider and
**stop the VM**, then when you re-start the VM, the provider will likely assign a **new public
IP address** to it. In this case, **you must update your Google application information**
with the new IP address.
:::
## Step 3: Configure your JupyterHub to use the Google OAuthenticator
### Configuration with `tljh-config`
In this section we'll use the `tljh-config` tool to configure your JupyterHub's authentication.
For more information on `tljh-config`, see [](/topic/tljh-config).
:::{important}
By default, the following allows _anyone_ with a Google account to login.
You can set specific allowed users and admins using [](#tljh-set-user-lists).
:::
1. Log in as an administrator account to your JupyterHub.
2. Open a terminal window.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
3. Configure the Google OAuthenticator to use your client ID, client secret and callback URL with the following commands:
```
sudo tljh-config set auth.GoogleOAuthenticator.client_id '<my-tljh-client-id>'
```
```
sudo tljh-config set auth.GoogleOAuthenticator.client_secret '<my-tljh-client-secret>'
```
```
sudo tljh-config set auth.GoogleOAuthenticator.oauth_callback_url 'http(s)://<my-tljh-ip-address>/hub/oauth_callback'
```
4. Tell your JupyterHub to _use_ the Google OAuthenticator for authentication:
```
sudo tljh-config set auth.type oauthenticator.google.GoogleOAuthenticator
```
5. Restart your JupyterHub so that new users see these changes:
```
sudo tljh-config reload
```
### Advanced Configuration with Google Groups
Administrative and regular users of your TLJH can also be easily managed with Google Groups.
This requires a service account and a Workspace admin account that can be impersonated by the
service account to read groups in your domain. You may need to contact your Google Workspace
administrator for help performing these steps.
1. [Create a service account](https://cloud.google.com/iam/docs/service-accounts-create).
1. [Create a service account key](https://developers.google.com/workspace/guides/create-credentials#create_credentials_for_a_service_account). Keep this key in a safe space, you will need to add it to your instance later.
1. Setup [domain-wide delegation](https://developers.google.com/workspace/guides/create-credentials#optional_set_up_domain-wide_delegation_for_a_service_account) for the service account that includes the following scopes:
```
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.group.readonly
```
1. Add the service account key to your instance and ensure it is _not_ readable by non-admin users of the hub.
:::{important}
The service account key is a secret. Anyone for whom you configure admin privileges on your TLJH instance will be able to access it.
:::
1. Log in as an administrator account to your JupyterHub.
1. Open a terminal window.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
1. Install the extra requirements within the hub environment.
```
source /opt/tljh/hub/bin/activate
pip3 install oauthenticator[googlegroups]
deactivate
```
1. Create a configuration directory `jupyterhub_config.d` within `/opt/tljh/config/`.
Any `.py` files within this directory will be sourced for configuration.
```
sudo mkdir /opt/tljh/config/jupyterhub_config.d
```
1. Configure your hub for Google Groups-based authentication by adding the following to a `.py` file within `/opt/tljh/config/jupyterhub_config.d`.
```python
from oauthenticator.google import GoogleOAuthenticator
c.JupyterHub.authenticator_class = GoogleOAuthenticator
c.GoogleOAuthenticator.google_service_account_keys = {'<my-domain.com>': '</path/to/your/service_account_key.json>'}
c.GoogleOAuthenticator.gsuite_administrator = {'<my-domain.com>': '<my-gsuite-admin>'}
c.GoogleOAuthenticator.allowed_google_groups = {'<my-domain.com>': ['example-group', 'another-example-group']}
c.GoogleOAuthenticator.admin_google_groups = {'<my-domain.com>': ['example-admin-group', 'another-example-admin-group']}
c.GoogleOAuthenticator.client_id = '<my-tljh-client-id>'
c.GoogleOAuthenticator.client_secret = '<my-tljh-client-secret>'
c.GoogleOAuthenticator.hosted_domain = '<my-domain.com>'
c.GoogleOAuthenticator.login_service = '<my-login-service>'
c.GoogleOAuthenticator.oauth_callback_url = 'http(s)://<my-tljh-ip-address>/hub/oauth_callback'
```
See the [Google OAuthenticator documentation](https://oauthenticator.readthedocs.io/en/latest/reference/api/gen/oauthenticator.google.html)
for more information on these and other configuration options.
1. Reload your configuration for the changes to take effect:
```
sudo tljh-config reload
```
## Step 4: Confirm that the new authenticator works
1. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
2. Go to your JupyterHub URL.
3. You should see a Google login button like below:
```{image} ../../images/auth/google/login_button.png
:alt: The Google authenticator login button.
```
4. After you log in with your Google credentials, you should be directed to the
Jupyter interface used in this JupyterHub.
5. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in [](/howto/auth/firstuse).

View File

@@ -1,119 +0,0 @@
.. _howto/auth/google:
=========================
Authenticate using Google
=========================
The **Google Authenticator** lets users log into your JupyterHub using their
Google user ID / password. To do so, you'll first need to register an
application with Google, and then provide information about this
application to your ``tljh`` configuration.
See `Google's documentation <https://developers.google.com/identity/protocols/OAuth2>`_
on how to create OAUth 2.0 client credentials.
.. note::
You'll need a Google account in order to complete these steps.
Step 1: Create a Google project
===============================
Go to `Google Developers Console <https://console.developers.google.com>`_
and create a new project:
.. image:: ../../images/auth/google/create_new_project.png
:alt: Create a Google project
Step 2: Set up a Google OAuth client ID and secret
==================================================
1. After creating and selecting the project:
* Go to the credentials menu:
.. image:: ../../images/auth/google/credentials_button.png
:alt: Credentials menu
* Click "Create credentials" and from the dropdown menu select **"OAuth client ID"**:
.. image:: ../../images/auth/google/create_credentials.png
:alt: Generate credentials
* You will have to fill a form with:
* **Application type**: Choose *Web application*
* **Name**: A descriptive name for your OAuth client ID (e.g. ``tljh-client``)
* **Authorized JavaScript origins**: Use the IP address or URL of your JupyterHub. e.g. ``http(s)://<my-tljh-url>``.
* **Authorized redirect URIs**: Insert text with the following form::
http(s)://<my-tljh-ip-address>/hub/oauth_callback
* When you're done filling in the page, it should look something like this (ideally without the red warnings):
.. image:: ../../images/auth/google/create_oauth_client_id.png
:alt: Create a Google OAuth client ID
2. Click "Create". You'll be taken to a page with the registered application details.
3. Copy the **Client ID** and **Client Secret** from the application details
page. You will use these later to configure your JupyterHub authenticator.
.. image:: ../../images/auth/google/client_id_secret.png
:alt: Your client ID and secret
.. important::
If you are using a virtual machine from a cloud provider and
**stop the VM**, then when you re-start the VM, the provider will likely assign a **new public
IP address** to it. In this case, **you must update your Google application information**
with the new IP address.
Configure your JupyterHub to use the Google Oauthenticator
==========================================================
We'll use the ``tljh-config`` tool to configure your JupyterHub's authentication.
For more information on ``tljh-config``, see :ref:`topic/tljh-config`.
#. Log in as an administrator account to your JupyterHub.
#. Open a terminal window.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. Configure the Google OAuthenticator to use your client ID, client secret and callback URL with the following commands::
sudo tljh-config set auth.GoogleOAuthenticator.client_id '<my-tljh-client-id>'
::
sudo tljh-config set auth.GoogleOAuthenticator.client_secret '<my-tljh-client-secret>'
::
sudo tljh-config set auth.GoogleOAuthenticator.oauth_callback_url 'http(s)://<my-tljh-ip-address>/hub/oauth_callback'
#. Tell your JupyterHub to *use* the Google OAuthenticator for authentication::
sudo tljh-config set auth.type oauthenticator.google.GoogleOAuthenticator
#. Restart your JupyterHub so that new users see these changes::
sudo tljh-config reload
Confirm that the new authenticator works
========================================
#. **Open an incognito window** in your browser (do not log out until you confirm
that the new authentication method works!)
#. Go to your JupyterHub URL.
#. You should see a Google login button like below:
.. image:: ../../images/auth/google/login_button.png
:alt: The Google authenticator login button.
#. After you log in with your Google credentials, you should be directed to the
Jupyter interface used in this JupyterHub.
#. **If this does not work** you can revert back to the default
JupyterHub authenticator by following the steps in :ref:`howto/auth/firstuse`.

View File

@@ -0,0 +1,45 @@
(howto-auth-nativeauth)=
# Let users sign up with a username and password
```{warning}
This documentation is not being updated regularly and may be out of date. Due to
that, please only use this _as a complement_ to the official
[NativeAuthenticator documentation].
[NativeAuthenticator documentation]: https://native-authenticator.readthedocs.io/en/latest/
Going onwards, the goal is to ensure we have good documentation in the
NativeAuthenticator project and reference that instead of maintaining similar
documentation in this project also.
```
The **Native Authenticator** lets users signup for creating a new username
and password.
When they signup, they won't be able to login until they are authorized by an
admin. Users that are characterized as admin have to signup as well, but they
will be authorized automatically.
## Enabling the authenticator
Enable the authenticator and reload config to apply the configuration:
```bash
sudo tljh-config set auth.type nativeauthenticator.NativeAuthenticator
sudo tljh-config reload
```
## Allowing all users to be authorized after signup
By default, all users created on signup don't have authorization to login.
If you wish to allow **any** user to access
the JupyterHub just after the signup, run the following command:
```bash
tljh-config set auth.NativeAuthenticator.open_signup true
tljh-config reload
```
## Optional features
More optional features are available on the [authenticator documentation](https://native-authenticator.readthedocs.io/en/latest/)

View File

@@ -1,40 +0,0 @@
.. _howto/auth/nativeauth:
==============================================
Let users sign up with a username and password
==============================================
The **Native Authenticator** lets users signup for creating a new username
and password.
When they signup, they won't be able to login until they are authorized by an
admin. Users that are characterized as admin have to signup as well, but they
will be authorized automatically.
Enabling the authenticator
==========================
Enable the authenticator and reload config to apply the configuration:
.. code-block:: bash
sudo tljh-config set auth.type nativeauthenticator.NativeAuthenticator
sudo tljh-config reload
Allowing all users to be authorized after signup
================================================
By default, all users created on signup don't have authorization to login.
If you wish to allow **any** user to access
the JupyterHub just after the signup, run the following command:
.. code-block:: bash
tljh-config set auth.NativeAuthenticator.open_signup true
tljh-config reload
Optional features
=================
More optional features are available on the `authenticator documentation <https://native-authenticator.readthedocs.io/en/latest/>`

View File

@@ -0,0 +1,100 @@
(howto-content-add-data)=
# Adding data to the JupyterHub
This section covers how to add data to your JupyterHub either from the internet
or from your own machine. To learn how to **share data** that is already
on your JupyterHub, see [](/howto/content/share-data).
:::{note}
When you add data using the methods on this page, you will **only add it
to your user directory**. This is not a place that is accessible to others.
For information on sharing this data with users on the JupyterHub, see
[](/howto/content/share-data).
:::
## Adding data from your local machine
The easiest way to add data to your JupyterHub is to use the "Upload" user
interface. To do so, follow these steps:
1. First, navigate to the Jupyter Notebook interface home page. You can do this
by going to the URL `<my-hub-url>/user/<my-username>/tree`.
2. Click the "Upload" button to open the file chooser window.
```{image} ../../images/content/upload-button.png
:alt: The upload button in Jupyter.
```
3. Choose the file you wish to upload. You may select multiple files if you
wish.
4. Click "Upload" for each file that you wish to upload.
```{image} ../../images/content/file-upload-buttons.png
:alt: Multiple file upload buttons.
```
5. Wait for the progress bar to finish for each file. These files will now
be on your JupyterHub, your home user's home directory.
To learn how to **share** this data with new users on the JupyterHub,
see [](/howto/content/share-data).
## Downloading data from the command line
If the data of interest is on the internet, you may also use code in order
to download it to your JupyterHub. There are several ways of doing this, so
we'll cover the simplest approach using the unix tool `wget`.
1. Log in to your JupyterHub and open a terminal window.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
2. Use `wget` to download the file to your current directory in the terminal.
```bash
wget <MY-FILE-URL>
```
### Example: Downloading the [gapminder](https://www.gapminder.org/) dataset.
In this example we'll download the [gapminder](https://www.gapminder.org/)
dataset, which contains information about country GDP and live expectancy over
time. You can download it from your browser [at this link](https://swcarpentry.github.io/python-novice-gapminder/files/python-novice-gapminder-data.zip).
1. Log in to your JupyterHub and open a terminal window.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
2. Use `wget` to download the gapminder dataset to your current directory in
the terminal.
```bash
wget https://swcarpentry.github.io/python-novice-gapminder/files/python-novice-gapminder-data.zip
```
3. This is a **zip** file, so we'll need to download a unix tool called "unzip"
in order to unzip it.
```bash
sudo apt install unzip
```
4. Finally, unzip the file:
```bash
unzip python-novice-gapminder-data.zip
```
5. Confirm that your data was unzipped. It could be in a folder called `data/`.
To learn how to **share** this data with new users on the JupyterHub,
see [](/howto/content/share-data).
% TODO: Downloading data with the "download" module in Python? https://github.com/choldgraf/download

View File

@@ -1,97 +0,0 @@
.. _howto/content/add-data:
=============================
Adding data to the JupyterHub
=============================
This section covers how to add data to your JupyterHub either from the internet
or from your own machine. To learn how to **share data** that is already
on your JupyterHub, see :ref:`howto/content/share-data`.
.. note::
When you add data using the methods on this page, you will **only add it
to your user directory**. This is not a place that is accessible to others.
For information on sharing this data with users on the JupyterHub, see
:ref:`howto/content/share-data`.
Adding data from your local machine
===================================
The easiest way to add data to your JupyterHub is to use the "Upload" user
interface. To do so, follow these steps:
#. First, navigate to the Jupyter Notebook interface home page. You can do this
by going to the URL ``<my-hub-url>/user/<my-username>/tree``.
#. Click the "Upload" button to open the file chooser window.
.. image:: ../../images/content/upload-button.png
:alt: The upload button in Jupyter.
#. Choose the file you wish to upload. You may select multiple files if you
wish.
#. Click "Upload" for each file that you wish to upload.
.. image:: ../../images/content/file-upload-buttons.png
:alt: Multiple file upload buttons.
#. Wait for the progress bar to finish for each file. These files will now
be on your JupyterHub, your home user's home directory.
To learn how to **share** this data with new users on the JupyterHub,
see :ref:`howto/content/share-data`.
Downloading data from the command line
======================================
If the data of interest is on the internet, you may also use code in order
to download it to your JupyterHub. There are several ways of doing this, so
we'll cover the simplest approach using the unix tool ``wget``.
#. Log in to your JupyterHub and open a terminal window.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. Use ``wget`` to download the file to your current directory in the terminal.
.. code-block:: bash
wget <MY-FILE-URL>
Example: Downloading the `gapminder <https://www.gapminder.org/>`_ dataset.
---------------------------------------------------------------------------
In this example we'll download the `gapminder <https://www.gapminder.org/>`_
dataset, which contains information about country GDP and live expectancy over
time. You can download it from your browser `at this link <https://swcarpentry.github.io/python-novice-gapminder/files/python-novice-gapminder-data.zip>`_.
#. Log in to your JupyterHub and open a terminal window.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. Use ``wget`` to download the gapminder dataset to your current directory in
the terminal.
.. code-block:: bash
wget https://swcarpentry.github.io/python-novice-gapminder/files/python-novice-gapminder-data.zip
#. This is a **zip** file, so we'll need to download a unix tool called "unzip"
in order to unzip it.
.. code-block:: bash
sudo apt install unzip
#. Finally, unzip the file:
.. code-block:: bash
unzip python-novice-gapminder-data.zip
#. Confirm that your data was unzipped. It could be in a folder called ``data/``.
To learn how to **share** this data with new users on the JupyterHub,
see :ref:`howto/content/share-data`.
.. TODO: Downloading data with the "download" module in Python? https://github.com/choldgraf/download

View File

@@ -1,11 +1,8 @@
.. _howto/content/nbgitpuller:
(howto-content-nbgitpuller)=
================================================
Distributing materials to users with nbgitpuller
================================================
# Distributing materials to users with nbgitpuller
Goal
====
## Goal
A very common need when using JupyterHub is to easily
distribute study materials / lab notebooks to students.
@@ -29,38 +26,34 @@ This tutorial will walk you through the process of creating a magic
nbgitpuller link that users of your JupyterHub can click to fetch the latest
version of materials from a git repo.
Pre-requisites
==============
## Pre-requisites
1. A JupyterHub set up with The Littlest JupyterHub
2. A git repository containing materials to distribute
Step 1: Generate nbgitpuller link
=================================
## Step 1: Generate nbgitpuller link
The quickest way to generate a link is to use `nbgitpuller.link
<https://jupyterhub.github.io/nbgitpuller/link.html>`_, but other options exist as described in the
`nbgitpuller project's documentation
<https://jupyterhub.github.io/nbgitpuller/use.html>`_.
The quickest way to generate a link is to use [nbgitpuller.link](https://jupyterhub.github.io/nbgitpuller/link.html), but other options exist as described in the
[nbgitpuller project's documentation](https://jupyterhub.github.io/nbgitpuller/use.html).
Step 2: Users click on the nbgitpuller link
===========================================
## Step 2: Users click on the nbgitpuller link
#. Send the link to your users in some way - email, slack, post a
shortened version (with `bit.ly <https://bit.ly>`_ maybe) on the wall, or
put it on your syllabus page (like `UC Berkeley's data8 does <http://data8.org/sp18/>`_).
1. Send the link to your users in some way - email, slack, post a
shortened version (with [bit.ly](https://bit.ly) maybe) on the wall, or
put it on your syllabus page (like [UC Berkeley's data8 does](http://data8.org/sp18/)).
Whatever works for you :)
#. When users click the link, they will be asked to log in to the hub
2. When users click the link, they will be asked to log in to the hub
if they have not already.
#. Users will see a progress bar as the git repository is fetched & any
3. Users will see a progress bar as the git repository is fetched & any
automatic merging required is performed.
.. image:: ../../images/nbgitpuller/pull-progress.png
```{image} ../../images/nbgitpuller/pull-progress.png
:alt: Progress bar with git repository being pulled
```
#. Users will now be redirected to the notebook specified in the URL!
4. Users will now be redirected to the notebook specified in the URL!
This workflow lets users land directly in the notebook you specified
without having to understand much about git or the JupyterHub interface.

View File

@@ -0,0 +1,137 @@
(howto-content-share-data)=
# Share data with your users
There are a few options for sharing data with your users, this page covers
a few useful patterns.
## Option 1: Distributing data with `nbgitpuller`
For small datasets, the simplest way to share data with your users is via
`nbgitpuller` links. In this case, users click on your link and the dataset
contained in the link's target repository is downloaded to the user's home
directory. Note that a copy of the dataset will be made for each user.
For information on creating and sharing `nbgitpuller` links, see
[](/howto/content/nbgitpuller).
## Option 2: Create a read-only shared folder for data
If your data is large or you don't want copies of it to exist, you can create
a read-only shared folder that users have access to. To do this, follow these
steps:
1. **Log** in to your JupyterHub as an **administrator user**.
2. **Create a terminal session** with your JupyterHub interface.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
3. **Create a folder** where your data will live. We recommend placing shared
data in `/srv`. The following command creates two folders (`/srv/data` and
`/srv/data/my_shared_data_folder`).
```bash
sudo mkdir -p /srv/data/my_shared_data_folder
```
4. **Download the data** into this folder. See [](/howto/content/add-data) for
details on how to do this.
5. All users now have read access to the data in this folder.
### Add a link to the shared folder in the user home directory
Optionally, you may also **create a symbolic link to the shared data folder**
that you created above in each **new user's** home directory.
To do this, you can use the server's **user skeleton directory** (`/etc/skel`).
Anything that is placed in this directory will also
show up in a new user's home directory.
To create a link to the shared folder in the user skeleton directory,
follow these steps:
1. `cd` into the skeleton directory:
```bash
cd /etc/skel
```
2. **Create a symbolic link** to the data folder
```bash
sudo ln -s /srv/data/my_shared_data_folder my_shared_data_folder
```
3. **Confirm that this worked** by logging in as a new user. You can do this
by opening a new "incognito" browser window and accessing your JupyterHub.
After you log in as a **new user**, the folder should appear in your new
user home directory.
From now on, when a new user account is created, their home directory will
have this symbolic link (and any other files in `/etc/skel`) in their home
directory. This will have **no effect on the directories of existing
users**.
## Option 3: Create a directory for users to share Notebooks and other files
You may want a place for users to share files with each other rather than
only having administrators share files with users (Option 2). In this
configuration, any user can put files into `/srv/scratch` that other users
can read. However, only the user that created the file can edit the file.
One way for users to share or "publish" Notebooks in a JupyterHub environment
is to create a shared directory. Any user can create files in the directory,
but only the creator may edit that file afterwards.
For instance, in a Hub with three users, User A develops a Notebook in their
`/home` directory. When it is ready to share, User A copies it to the
`shared` directory. At that time, User B and User C can see User A's
Notebook and run it themselves (or view it in a Dashboard layout
such as `voila` or `panel` if that is running in the Hub), but User B
and User C cannot edit the Notebook. Only User A can make changes.
1. **Log** in to your JupyterHub as an **administrator user**.
2. **Create a terminal session** with your JupyterHub interface.
```{image} ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
```
3. **Create a folder** where your data will live. We recommend placing shared
data in `/srv`. The following command creates a directory `/srv/scratch`
```bash
sudo mkdir -p /srv/scratch
```
4. **Change group ownership** of the new folder
```bash
sudo chown root:jupyterhub-users /srv/scratch
```
5. **Change default permissions to use group**. The default permissions for new
sub-directories uses the global umask (`drwxr-sr-x`), the `chmod g+s` tells
new files to use the default permissions for the group `jupyterhub-users`
(`rw-r--r--`)
```bash
sudo chmod 777 /srv/scratch
sudo chmod g+s /srv/scratch
```
6. **Create a symbolic link** to the scratch folder in users home directories
```bash
sudo ln -s /srv/scratch /etc/skel/scratch
```
:::{note}
The TLJH Plugin at <https://github.com/kafonek/tljh-shared-directory> installs `voila` and sets up the directories as specified above.
Include `--plugin git+https://github.com/kafonek/tljh-shared-directory` in your deployment startup script to install it.
:::

View File

@@ -1,139 +0,0 @@
.. _howto/content/share-data:
==========================
Share data with your users
==========================
There are a few options for sharing data with your users, this page covers
a few useful patterns.
Option 1: Distributing data with `nbgitpuller`
==============================================
For small datasets, the simplest way to share data with your users is via
``nbgitpuller`` links. In this case, users click on your link and the dataset
contained in the link's target repository is downloaded to the user's home
directory. Note that a copy of the dataset will be made for each user.
For information on creating and sharing ``nbgitpuller`` links, see
:ref:`howto/content/nbgitpuller`.
Option 2: Create a read-only shared folder for data
===================================================
If your data is large or you don't want copies of it to exist, you can create
a read-only shared folder that users have access to. To do this, follow these
steps:
#. **Log** in to your JupyterHub as an **administrator user**.
#. **Create a terminal session** with your JupyterHub interface.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. **Create a folder** where your data will live. We recommend placing shared
data in ``/srv``. The following command creates two folders (``/srv/data`` and
``/srv/data/my_shared_data_folder``).
.. code-block:: bash
sudo mkdir -p /srv/data/my_shared_data_folder
#. **Download the data** into this folder. See :ref:`howto/content/add-data` for
details on how to do this.
#. All users now have read access to the data in this folder.
Add a link to the shared folder in the user home directory
----------------------------------------------------------
Optionally, you may also **create a symbolic link to the shared data folder**
that you created above in each **new user's** home directory.
To do this, you can use the server's **user skeleton directory** (``/etc/skel``).
Anything that is placed in this directory will also
show up in a new user's home directory.
To create a link to the shared folder in the user skeleton directory,
follow these steps:
#. ``cd`` into the skeleton directory:
.. code-block:: bash
cd /etc/skel
#. **Create a symbolic link** to the data folder
.. code-block:: bash
sudo ln -s /srv/data/my_shared_data_folder my_shared_data_folder
#. **Confirm that this worked** by logging in as a new user. You can do this
by opening a new "incognito" browser window and accessing your JupyterHub.
After you log in as a **new user**, the folder should appear in your new
user home directory.
From now on, when a new user account is created, their home directory will
have this symbolic link (and any other files in ``/etc/skel``) in their home
directory. This will have **no effect on the directories of existing
users**.
Option 3: Create a directory for users to share Notebooks and other files
=========================================================================
You may want a place for users to share files with each other rather than
only having administrators share files with users (Option 2). In this
configuration, any user can put files into ``/srv/scratch`` that other users
can read. However, only the user that created the file can edit the file.
One way for users to share or "publish" Notebooks in a JupyterHub environment
is to create a shared directory. Any user can create files in the directory,
but only the creator may edit that file afterwards.
For instance, in a Hub with three users, User A develops a Notebook in their
``/home`` directory. When it is ready to share, User A copies it to the
`shared` directory. At that time, User B and User C can see User A's
Notebook and run it themselves (or view it in a Dashboard layout
such as ``voila`` or ``panel`` if that is running in the Hub), but User B
and User C cannot edit the Notebook. Only User A can make changes.
#. **Log** in to your JupyterHub as an **administrator user**.
#. **Create a terminal session** with your JupyterHub interface.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New terminal button.
#. **Create a folder** where your data will live. We recommend placing shared
data in ``/srv``. The following command creates a directory ``/srv/scratch``
.. code-block:: bash
sudo mkdir -p /srv/scratch
#. **Change group ownership** of the new folder
.. code-block:: bash
sudo chown root:jupyterhub-users /srv/scratch
#. **Change default permissions to use group**. The default permissions for new
sub-directories uses the global umask (``drwxr-sr-x``), the ``chmod g+s`` tells
new files to use the default permissions for the group ``jupyterhub-users``
(``rw-r--r--``)
.. code-block:: bash
sudo chmod 777 /srv/scratch
sudo chmod g+s /srv/scratch
#. **Create a symbolic link** to the scratch folder in users home directories
.. code-block:: bash
sudo ln -s /srv/scratch /etc/skel/scratch
.. note::
The TLJH Plugin at https://github.com/kafonek/tljh-shared-directory installs ``voila`` and sets up the directories as specified above.
Include ``--plugin git+https://github.com/kafonek/tljh-shared-directory`` in your deployment startup script to install it.

View File

@@ -1,56 +0,0 @@
.. _howto/env/notebook_interfaces:
=======================================
Change default User Interface for users
=======================================
By default, logging into TLJH puts you in the classic Jupyter Notebook interface
we all know and love. However, there are at least two other popular notebook
interfaces you can use:
1. `JupyterLab <http://jupyterlab.readthedocs.io/en/stable/>`_
2. `nteract <https://nteract.io/>`_
Both these interfaces are also shipped with tljh by default. You can try them
temporarily, or set them to be the default interface whenever you login.
Trying an alternate interface temporarily
=========================================
When you log in & start your server, by default the URL in your browser
will be something like ``/user/<username>/tree``. The ``/tree`` is what tells
the notebook server to give you the classic notebook interface.
* **For the JupyterLab interface**: change ``/tree`` to ``/lab``.
* **For the nteract interface**: change ``/tree`` to ``/nteract``
You can play around with them and see what fits your use cases best.
Changing the default user interface
===================================
You can change the default interface users get when they log in by modifying
``config.yaml`` as an admin user.
#. To launch **JupyterLab** when users log in, run the following in an admin console:
.. code-block:: yaml
sudo tljh-config set user_environment.default_app jupyterlab
#. Alternatively, to launch **nteract** when users log in, run the following in the admin console:
.. code-block:: yaml
sudo tljh-config set user_environment.default_app nteract
#. Apply the changes by restarting JupyterHub. This should not disrupt current users.
.. code-block:: yaml
sudo tljh-config reload hub
If this causes problems, check the :ref:`troubleshoot_logs_jupyterhub` for clues
on what went wrong.
Users might have to restart their servers from control panel to get the new interface.

View File

@@ -1,10 +0,0 @@
.. _howto/env/server-resources:
======================================
Configure resources available to users
======================================
To configure the resources that are available to your users (such as RAM, CPU
and Disk Space), see the section :ref:`tljh-set-user-limits`. For information
on **resizing** the environment available to users *after* you've created your
JupyterHub, see :ref:`howto/admin/resize`.

View File

@@ -1,209 +0,0 @@
.. _howto/env/user_environment:
==================================
Install conda, pip or apt packages
==================================
:abbr:`TLJH (The Littlest JupyterHub)` starts all users in the same `conda <https://conda.io/docs/>`_
environment. Packages / libraries installed in this environment are available
to all users on the JupyterHub. Users with :ref:`admin rights <howto/admin/admin-users>` can install packages
easily.
.. _howto/env/user_environment_pip:
Installing pip packages
=======================
`pip <https://pypi.org/project/pip/>`_ is the recommended tool for installing packages
in Python from the `Python Packaging Index (PyPI) <https://pypi.org/>`_. PyPI has
almost 145,000 packages in it right now, so a lot of what you need is going to be there!
1. Log in as an admin user and open a Terminal in your Jupyter Notebook.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New Terminal button under New menu
If you already have a terminal open as an admin user, that should work too!
2. Install a package!
.. code-block:: bash
sudo -E pip install numpy
This installs the ``numpy`` library from PyPI and makes it available
to all users.
.. note::
If you get an error message like ``sudo: pip: command not found``,
make sure you are not missing the ``-E`` parameter after ``sudo``.
.. _howto/env/user_environment_conda:
Installing conda packages
=========================
Conda lets you install new languages (such as new versions of python, node, R, etc)
as well as packages in those languages. For lots of scientific software, installing
with conda is often simpler & easier than installing with pip - especially if it
links to C / Fortran code.
We recommend installing packages from `conda-forge <https://conda-forge.org/>`_,
a community maintained repository of conda packages.
1. Log in as an admin user and open a Terminal in your Jupyter Notebook.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New Terminal button under New menu
If you already have a terminal open as an admin user, that should work too!
2. Install a package!
.. code-block:: bash
sudo -E conda install -c conda-forge gdal
This installs the ``gdal`` library from ``conda-forge`` and makes it available
to all users. ``gdal`` is much harder to install with pip.
.. note::
If you get an error message like ``sudo: conda: command not found``,
make sure you are not missing the ``-E`` parameter after ``sudo``.
.. _howto/env/user_environment_apt:
Installing apt packages
=======================
`apt <https://help.ubuntu.com/lts/serverguide/apt.html.en>`_ is the official package
manager for the `Ubuntu Linux distribution <https://www.ubuntu.com/>`_. You can install
utilities (such as ``vim``, ``sl``, ``htop``, etc), servers (``postgres``, ``mysql``, ``nginx``, etc)
and a lot more languages than present in ``conda`` (``haskell``, ``prolog``, ``INTERCAL``).
Some third party software (such as `RStudio <https://www.rstudio.com/products/rstudio/download/>`_)
is distributed as ``.deb`` files, which are the files ``apt`` uses to install software.
You can search for packages with `Ubuntu Package search <https://packages.ubuntu.com/>`_ -
make sure to look in the version of Ubuntu you are using!
1. Log in as an admin user and open a Terminal in your Jupyter Notebook.
.. image:: ../../images/notebook/new-terminal-button.png
:alt: New Terminal button under New menu
If you already have a terminal open as an admin user, that should work too!
2. Update list of packages available. This makes sure you get the latest version of
the packages possible from the repositories.
.. code-block:: bash
sudo apt update
3. Install the packages you want.
.. code-block:: bash
sudo apt install mysql-server git
This installs (and starts) a ``MySQL <https://www.mysql.com/>`` database server
and ``git``.
User environment location
=========================
The user environment is a conda environment set up in ``/opt/tljh/user``, with
a Python3 kernel as the default. It is readable by all users, but writeable only
by users who have root access. This makes it possible for JupyterHub admins (who have
root access with ``sudo``) to install software in the user environment easily.
Accessing user environment outside JupyterHub
=============================================
We add ``/opt/tljh/user/bin`` to the ``$PATH`` environment variable for all JupyterHub
users, so everything installed in the user environment is available to them automatically.
If you are using ``ssh`` to access your server instead, you can get access to the same
environment with:
.. code-block:: bash
export PATH=/opt/tljh/user/bin:${PATH}
Whenever you run any command now, the user environment will be searched first before
your system environment is. So if you run ``python3 <somefile>``, it'll use the ``python3``
installed in the user environment (``/opt/tljh/user/bin/python3``) rather than the ``python3``
installed in your system environment (``/usr/bin/python3``). This is usually what you want!
To make this change 'stick', you can add the line to the end of the ``.bashrc`` file in
your home directory.
When using ``sudo``, the ``PATH`` environment variable is usually reset, for security
reasons. This leads to error messages like:
.. code-block:: console
$ sudo conda install -c conda-forge gdal
sudo: conda: command not found
The most common & portable way to fix this when using ``ssh`` is:
.. code-block:: bash
sudo PATH=${PATH} conda install -c conda-forge gdal
Upgrade to a newer Python version
=================================
All new TLJH installs use miniconda 4.7.10, which comes with a Python 3.7
environment for the users. The previously TLJH installs came with miniconda 4.5.4,
which meant a Python 3.6 environment.
To upgrade the Python version of the user environment, one can:
* **Start fresh on a machine that doesn't have TLJH already installed.**
See the :ref:`installation guide <install/installing>` section about how to install TLJH.
* **Upgrade Python manually.**
Because upgrading Python for existing installs can break packages alaredy installed
under the old Python, upgrading your current TLJH installation, will NOT upgrade
the Python version of the user environment, but you may do so manually.
**Steps:**
1. Activate the user environment, if using ssh.
If the terminal was started with JupyterHub, this step can be skipped:
.. code-block:: bash
source /opt/tljh/user/bin/activate
2. Get the list of currently installed pip packages (so you can later install them under the
new Python):
.. code-block:: bash
pip freeze > pip_pkgs.txt
3. Update all conda installed packages in the environment:
.. code-block:: bash
sudo PATH=${PATH} conda update --all
4. Update Python version:
.. code-block:: bash
sudo PATH=${PATH} conda install python=3.7
5. Install the pip packages previously saved:
.. code-block:: bash
pip install -r pip_pkgs.txt

71
docs/howto/index.md Normal file
View File

@@ -0,0 +1,71 @@
# How-To Guides
How-To guides answer the question 'How do I...?' for a lot of topics.
## Content and data
```{toctree}
:caption: Content and data
:titlesonly: true
content/nbgitpuller
content/add-data
content/share-data
```
## The user environment
```{toctree}
:caption: The user environment
:titlesonly: true
user-env/user-environment
user-env/notebook-interfaces
user-env/server-resources
user-env/override-lab-settings
```
## Authentication
We have a special set of How-To Guides on using various forms of authentication
with your JupyterHub. For more information on Authentication, see
[](/topic/authenticator-configuration)
```{toctree}
:caption: Authentication
:titlesonly: true
auth/dummy
auth/github
auth/google
auth/awscognito
auth/firstuse
auth/nativeauth
```
## Administration and security
```{toctree}
:caption: Administration and security
:titlesonly: true
admin/admin-users
admin/resource-estimation
admin/resize
admin/nbresuse
admin/https
admin/enable-extensions
admin/systemd
admin/upgrade-tljh
```
## Cloud provider configuration
```{toctree}
:caption: Cloud provider configuration
:titlesonly: true
providers/digitalocean
providers/azure
providers/google
```

View File

@@ -1,68 +0,0 @@
How-To Guides
=============
How-To guides answer the question 'How do I...?' for a lot of topics.
Content and data
----------------
.. toctree::
:titlesonly:
:caption: Content and data
content/nbgitpuller
content/add-data
content/share-data
The user environment
--------------------
.. toctree::
:titlesonly:
:caption: The user environment
env/user-environment
env/notebook-interfaces
env/server-resources
Authentication
--------------
We have a special set of How-To Guides on using various forms of authentication
with your JupyterHub. For more information on Authentication, see
:ref:`topic/authenticator-configuration`
.. toctree::
:titlesonly:
auth/dummy
auth/github
auth/google
auth/awscognito
auth/firstuse
auth/nativeauth
Administration and security
---------------------------
.. toctree::
:titlesonly:
:caption: Administration and security
admin/admin-users
admin/resource-estimation
admin/resize
admin/nbresuse
admin/https
admin/enable-extensions
admin/systemd
Cloud provider configuration
----------------------------
.. toctree::
:titlesonly:
:caption: Cloud provider configuration
providers/digitalocean
providers/azure

View File

@@ -0,0 +1,38 @@
(howto-providers-azure)=
# Perform common Microsoft Azure configuration tasks
This page lists various common tasks you can perform on your
[Microsoft Azure virtual machine](https://azure.microsoft.com/services/virtual-machines/?WT.mc_id=TLJH-github-taallard).
(howto-providers-azure-resize)=
## Deleting or stopping your virtual machine
After you have finished using your TLJH you might wanto to either Stop or completely delete the Virtual Machine to avoid incurring in subsequent costs.
The difference between these two approaches is that **Stop** will keep the VM resources (e.g. storage and network) but will effectively stop any compute / runtime activities.
If you choose to delete the VM then all the resources associated with it will be wiped out.
To do either of this:
- Go to "Virtual Machines" on the left hand panel
- Click on your machine name
- Click on "Stop" to stop the machine temporarily, or "Delete" to delete it permanently.
```{image} ../../images/providers/azure/delete-vm.png
:alt: Delete vm
```
:::{note}
It is important to mention that even if you stop the machine you will still be charged for the use of the data disk.
:::
If you no longer need any of your resources you can delete the entire resource group.
- Go to "Reosurce groups" on the left hand panel
- Click on your resource group
- Click on "Delete resource group" you will then be asked to confirm the operation. This operation will take between 5 and 10 minutes.

View File

@@ -1,36 +0,0 @@
.. _howto/providers/azure:
==================================================
Perform common Microsoft Azure configuration tasks
==================================================
This page lists various common tasks you can perform on your
`Microsoft Azure virtual machine <https://azure.microsoft.com/services/virtual-machines/?WT.mc_id=TLJH-github-taallard>`_.
.. _howto/providers/azure/resize:
Deleting or stopping your virtual machine
===========================================
After you have finished using your TLJH you might wanto to either Stop or completely delete the Virtual Machine to avoid incurring in subsequent costs.
The difference between these two approaches is that **Stop** will keep the VM resources (e.g. storage and network) but will effectively stop any compute / runtime activities.
If you choose to delete the VM then all the resources associated with it will be wiped out.
To do either of this:
* Go to "Virtual Machines" on the left hand panel
* Click on your machine name
* Click on "Stop" to stop the machine temporarily, or "Delete" to delete it permanently.
.. image:: ../../images/providers/azure/delete-vm.png
:alt: Delete vm
.. note:: It is important to mention that even if you stop the machine you will still be charged for the use of the data disk.
If you no longer need any of your resources you can delete the entire resource group.
* Go to "Reosurce groups" on the left hand panel
* Click on your resource group
* Click on "Delete resource group" you will then be asked to confirm the operation. This operation will take between 5 and 10 minutes.

View File

@@ -0,0 +1,42 @@
(howto-providers-digitalocean)=
# Perform common Digital Ocean configuration tasks
This page lists various common tasks you can perform on your
Digital Ocean virtual machine.
(howto-providers-digitalocean-resize)=
## Resizing your droplet
As you use your JupyterHub, you may find that you need more memory,
disk space, or CPUs. Digital Ocean servers can be resized in the
"Resize Droplet" panel. These instructions take you through the process.
1. First, click on the name of your newly-created
Droplet to enter its configuration page.
2. Next, **turn off your Droplet**. This allows DigitalOcean to make
modifications to your VM. This will shut down your JupyterHub (temporarily).
```{image} ../../images/providers/digitalocean/power-off.png
:alt: Power off your Droplet
:width: 200px
```
3. Once your Droplet has been turned off, click "Resize",
which will take you to a menu with options to resize your VM.
```{image} ../../images/providers/digitalocean/resize-droplet.png
:alt: Resize panel of digital ocean
```
4. Decide what kinds of resources you'd like to resize, then click on a new VM
type in the list below. Finally, click "Resize". This may take a few moments!
5. Once your Droplet is resized, **turn your Droplet back on**. This makes your JupyterHub
available to the world once again. This will take a few moments to complete.
Now that you've resized your Droplet, you may want to change the resources available
to your users. Further information on making more resources available to
users and verifying resource availability can be found in [](/howto/admin/resize).

View File

@@ -1,43 +0,0 @@
.. _howto/providers/digitalocean:
================================================
Perform common Digital Ocean configuration tasks
================================================
This page lists various common tasks you can perform on your
Digital Ocean virtual machine.
.. _howto/providers/digitalocean/resize:
Resizing your droplet
=====================
As you use your JupyterHub, you may find that you need more memory,
disk space, or CPUs. Digital Ocean servers can be resized in the
"Resize Droplet" panel. These instructions take you through the process.
#. First, click on the name of your newly-created
Droplet to enter its configuration page.
#. Next, **turn off your Droplet**. This allows DigitalOcean to make
modifications to your VM. This will shut down your JupyterHub (temporarily).
.. image:: ../../images/providers/digitalocean/power-off.png
:alt: Power off your Droplet
:width: 200px
#. Once your Droplet has been turned off, click "Resize",
which will take you to a menu with options to resize your VM.
.. image:: ../../images/providers/digitalocean/resize-droplet.png
:alt: Resize panel of digital ocean
#. Decide what kinds of resources you'd like to resize, then click on a new VM
type in the list below. Finally, click "Resize". This may take a few moments!
#. Once your Droplet is resized, **turn your Droplet back on**. This makes your JupyterHub
available to the world once again. This will take a few moments to complete.
Now that you've resized your Droplet, you may want to change the resources available
to your users. Further information on making more resources available to
users and verifying resource availability can be found in :ref:`howto/admin/resize`.

View File

@@ -0,0 +1,63 @@
(howto-providers-google)=
# Perform common Google Cloud configuration tasks
This page lists various common tasks you can perform on your
Google Cloud virtual machine.
(howto-providers-google-resize-disk)=
## Increasing your boot disk size
Boot disks contain the operating system and boot loader for your TLJH instance. If you followed
the [Google Cloud TLJH installation instructions](#install-google) then you created a virtual machine
with one disk: a boot disk that will _also_ be used to hold user data in your hub. For various reasons
you may need to change your boot disk size.
Google Cloud Compute Engine supports _increasing_ (but not _decreasing_) the size of existing disks.
If you selected a boot disk with a supported version of **Ubuntu** or **Debian** as the operating
system, then your boot disk can be resized easily from the console with these steps.
:::{note}
Google Cloud resizes the root partition and file system for _boot_ disks with _public_ images
(such as the TLJH supported **Ubuntu** and **Debian** images) automatically after your increase
the size of your disk. If you have any other _non-boot_ disks attached to your instance, you
will need to perform extra steps yourself after resizing your disk. For more information on
this and other aspects of resizing persistent disks, see
[Google's documentation](https://cloud.google.com/compute/docs/disks/resize-persistent-disk).
:::
1. Go to [Google Cloud Console -> Compute Engine -> VM instances](https://console.cloud.google.com/compute/instances) and select your TLJH instance.
1. Scroll down until you find your boot disk and select it.
```{image} ../../images/providers/google/boot-disk-resize.png
:alt: Boot disk with Ubuntu jammy image
```
1. Select **Edit** in the top menu. This may require selecting the kebab menu (the 3 vertical dots).
```{image} ../../images/providers/google/boot-disk-edit-button.png
:alt: Disk edit button
```
1. Update the **Size** property and save the changes at the bottom of the page.
```{image} ../../images/providers/google/boot-disk-resize-properties.png
:alt: Boot disk size property
```
1. Reboot the VM instance by logging into your TLJH, opening the terminal, and running `sudo reboot`.
You will lose your connection to the instance while it restarts. Once it comes back up, your disk
will reflect your changes. You can verify that the automatic resize of your root partition and
file system took place by running `df -h` in the terminal, which will show the size of the disk
mounted on `/`:
```bash
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 25G 6.9G 18G 28% /
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 785M 956K 784M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda15 105M 6.1M 99M 6% /boot/efi
```

View File

@@ -0,0 +1,55 @@
(howto/user-env/notebook-interfaces)=
# Change default user interface
By default a user starting a server will see the JupyterLab interface. This can
be changed with TLJH config `user_environment.default_app` or with the
JupyterHub config
{external:py:attr}`jupyterhub.spawner.Spawner.default_url` directly.
The TLJH config supports the options `jupyterlab` and `classic`, which
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
temporarily, or set them to be the default interface whenever you login.
## Trying an alternate interface temporarily
When you log in and start your server, by default the URL in your browser will
be something like `/user/<username>/lab`. The `/lab` is what tells the jupyter
server to give you the JupyterLab user interface.
As an example, you can update the URL to not end with `/lab`, but instead end
with `/tree` to temporarily switch to the classic interface.
## Changing the default user interface using TLJH config
You can change the default url, and therefore the interface users get when they
log in by modifying TLJH config as an admin user.
1. To launch the classic notebook interface when users log in, run the
following in the admin console:
```bash
sudo tljh-config set user_environment.default_app classic
```
1. To launch JupyterLab when users log in, run the following in an admin
console:
```bash
sudo tljh-config set user_environment.default_app jupyterlab
```
1. Apply the changes by restarting JupyterHub. This should not disrupt
current users.
```bash
sudo tljh-config reload hub
```
If this causes problems, check the [logs](#troubleshoot-logs-jupyterhub) for
clues on what went wrong.
Users might have to restart their servers from control panel to get the
new interface.

View File

@@ -0,0 +1,121 @@
(topic-override-lab-settings)=
# Setting New Default JupyterLab Settings
If you or other users of your hub tend to use JupyterLab as your default notebook app,
then you may want to override some of the default settings for the users of your hub.
You can do this by creating a file `/opt/tljh/user/share/jupyter/lab/settings/overrides.json`
with the necessary settings.
This how-to guide will go through the necessary steps to set new defaults
for all users of your `TLJH` by example: setting the default theme to **JupyterLab Dark**.
## Step 1: Change your Personal Settings
The easiest way to set new default settings for all users starts with
configuring your own settings preferences to what you would like everyone else to have.
1. Make sure you are in the [JupyterLab notebook interface](#howto/user-env/notebook-interfaces),
which will look something like `http(s)://<YOUR-HUB-IP>/user/<YOUR_USERNAME/lab`.
1. Go to **Settings** in the menu bar and select **Theme -> JupyterLab Dark**.
## Step 2: Determine your Personal Settings Configuration
To set **JupyterLab Dark** as the default theme for all users, we will need to create
a `json` formatted file with the setting override. Now that you have changed your
personal setting, you can use the **JSON Settings Editor** to get the relevant
setting snippet to add to the `overrides.json` file later.
1. Go to **Settings -> Advanced Settings Editor** then select **JSON Settings Editor** on the right.
1. Scroll down and select **Theme**. You should see the `json` formatted configuration:
```json
{
// Theme
// @jupyterlab/apputils-extension:themes
// Theme manager settings.
// *************************************
// Theme CSS Overrides
// Override theme CSS variables by setting key-value pairs here
"overrides": {
"code-font-family": null,
"code-font-size": null,
"content-font-family": null,
"content-font-size1": null,
"ui-font-family": null,
"ui-font-size1": null
},
// Selected Theme
// Application-level visual styling theme
"theme": "JupyterLab Dark",
// Scrollbar Theming
// Enable/disable styling of the application scrollbars
"theme-scrollbars": false
}
```
1. Determine the setting that you want to change. In this example it's the `theme`
setting of `@jupyterlab/apputils-extension:theme` as can be seen above.
1. Build your `json` snippet. In this case, our snippet should look like this:
```json
{
"@jupyterlab/apputils-extension:themes": {
"theme": "JupyterLab Dark"
}
}
```
We only want to change the **Selected Theme**, so we don't need to include
the other theme-related settings for CSS and the scrollbar.
:::{note}
To apply overrides for more than one setting, separate each setting by commas. For example,
if you _also_ wanted to change the interval at which the notebook autosaves your content, you can use
```json
{
"@jupyterlab/apputils-extension:themes": {
"theme": "JupyterLab Dark"
},
"@jupyterlab/docmanager-extension:plugin": {
"autosaveInterval": 30
}
}
```
:::
## Step 3: Apply the Overrides to the Hub
Once you have your setting snippet created, you can add it to the `overrides.json` file
so that it gets applied to all users.
1. First, create the settings directory if it doesn't already exist:
```bash
sudo mkdir -p /opt/tljh/user/share/jupyter/lab/settings
```
1. Use `nano` to create and add content to the `overrides.json` file:
```bash
sudo nano /opt/tljh/user/share/jupyter/lab/settings/overrides.json
```
1. Copy and paste your snippet into the file and save.
1. Reload your configuration:
```bash
sudo tljh-config reload
```
The new default settings should now be set for all users in your `TLJH` using the
JupyterLab notebook interface.

View File

@@ -0,0 +1,8 @@
(howto/user-env/server-resources)=
# Configure resources available to users
To configure the resources that are available to your users (such as
RAM, CPU and Disk Space), see the section [](#tljh-set-user-limits).
For information on **resizing** the environment available to users _after_ you\'ve created
your JupyterHub, see [](#howto-admin-resize).

View File

@@ -0,0 +1,214 @@
(howto/user-env/user-environment)=
# Install conda, pip or apt packages
`TLJH (The Littlest JupyterHub)`{.interpreted-text role="abbr"} starts
all users in the same [conda](https://conda.io/docs/) environment.
Packages / libraries installed in this environment are available to all
users on the JupyterHub. Users with [admin rights](#howto-admin-admin-users)
can install packages easily.
(howto/user-env/user-environment-pip)=
## Installing pip packages
[pip](https://pypi.org/project/pip/) is the recommended tool for
installing packages in Python from the [Python Packaging Index
(PyPI)](https://pypi.org/). PyPI has almost 145,000 packages in it right
now, so a lot of what you need is going to be there!
1. Log in as an admin user and open a Terminal in your Jupyter
Notebook.
![New Terminal button under New menu](../../images/notebook/new-terminal-button.png)
If you already have a terminal open as an admin user, that should
work too!
2. Install a package!
```bash
sudo -E pip install numpy
```
This installs the `numpy` library from PyPI and makes it available
to all users.
:::{note}
If you get an error message like `sudo: pip: command not found`,
make sure you are not missing the `-E` parameter after `sudo`.
:::
(howto/user-env/user-environment-conda)=
## Installing conda packages
Conda lets you install new languages (such as new versions of python,
node, R, etc) as well as packages in those languages. For lots of
scientific software, installing with conda is often simpler & easier
than installing with pip - especially if it links to C / Fortran code.
We recommend installing packages from
[conda-forge](https://conda-forge.org/), a community maintained
repository of conda packages.
1. Log in as an admin user and open a Terminal in your Jupyter
Notebook.
![New Terminal button under New menu](../../images/notebook/new-terminal-button.png)
If you already have a terminal open as an admin user, that should
work too!
2. Install a package!
```bash
sudo -E conda install -c conda-forge gdal
```
This installs the `gdal` library from `conda-forge` and makes it
available to all users. `gdal` is much harder to install with pip.
:::{note}
If you get an error message like `sudo: conda: command not found`,
make sure you are not missing the `-E` parameter after `sudo`.
:::
(howto/user-env/user-environment-apt)=
## Installing apt packages
[apt](https://help.ubuntu.com/lts/serverguide/apt.html.en) is the
official package manager for the [Ubuntu Linux
distribution](https://www.ubuntu.com/). You can install utilities (such
as `vim`, `sl`, `htop`, etc), servers (`postgres`, `mysql`, `nginx`,
etc) and a lot more languages than present in `conda` (`haskell`,
`prolog`, `INTERCAL`). Some third party software (such as
[RStudio](https://www.rstudio.com/products/rstudio/download/)) is
distributed as `.deb` files, which are the files `apt` uses to install
software.
You can search for packages with [Ubuntu Package
search](https://packages.ubuntu.com/) - make sure to look in the version
of Ubuntu you are using!
1. Log in as an admin user and open a Terminal in your Jupyter
Notebook.
![New Terminal button under New menu](../../images/notebook/new-terminal-button.png)
If you already have a terminal open as an admin user, that should
work too!
2. Update list of packages available. This makes sure you get the
latest version of the packages possible from the repositories.
```bash
sudo apt update
```
3. Install the packages you want.
```bash
sudo apt install mysql-server git
```
This installs (and starts) a [MySQL](https://www.mysql.com/)
database server and `git`.
## User environment location
The user environment is a conda environment set up in `/opt/tljh/user`,
with a `python3` kernel as the default. It is readable by all users, but
writeable only by users who have root access. This makes it possible for
JupyterHub admins (who have root access with `sudo`) to install software
in the user environment easily.
## Accessing user environment outside JupyterHub
We add `/opt/tljh/user/bin` to the `$PATH` environment variable for all
JupyterHub users, so everything installed in the user environment is
available to them automatically. If you are using `ssh` to access your
server instead, you can get access to the same environment with:
```bash
export PATH=/opt/tljh/user/bin:${PATH}
```
Whenever you run any command now, the user environment will be searched
first before your system environment is. So if you run
`python3 <somefile>`, it\'ll use the `python3` installed in the user
environment (`/opt/tljh/user/bin/python3`) rather than the `python3`
installed in your system environment (`/usr/bin/python3`). This is
usually what you want!
To make this change \'stick\', you can add the line to the end of the
`.bashrc` file in your home directory.
When using `sudo`, the `$PATH` environment variable is usually reset, for
security reasons. This leads to error messages like:
```bash
sudo conda install -c conda-forge gdal
sudo: conda: command not found
```
The most common & portable way to fix this when using `ssh` is:
```bash
sudo PATH=${PATH} conda install -c conda-forge gdal
```
## Upgrade to a newer Python version
All new TLJH installs use miniconda 4.7.10, which comes with a Python
3.7 environment for the users. The previously TLJH installs came with
miniconda 4.5.4, which meant a Python 3.6 environment.
To upgrade the Python version of the user environment, one can:
- **Start fresh on a machine that doesn\'t have TLJH already
installed.**
See the [](#install-installing) section about how to install TLJH.
- **Upgrade Python manually.**
Because upgrading Python for existing installs can break packages
already installed under the old Python, upgrading your current TLJH
installation, will NOT upgrade the Python version of the user
environment, but you may do so manually.
**Steps:**
1. Activate the user environment, if using ssh. If the terminal was
started with JupyterHub, this step can be skipped:
```bash
source /opt/tljh/user/bin/activate
```
2. Get the list of currently installed pip packages (so you can
later install them under the new Python):
```bash
pip freeze > pip_pkgs.txt
```
3. Update all conda installed packages in the environment:
```bash
sudo PATH=${PATH} conda update --all
```
4. Update Python version:
```bash
sudo PATH=${PATH} conda install python=3.7
```
5. Install the pip packages previously saved:
```bash
pip install -r pip_pkgs.txt
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

85
docs/index.md Normal file
View File

@@ -0,0 +1,85 @@
# The Littlest JupyterHub
A simple [JupyterHub](https://github.com/jupyterhub/jupyterhub) distribution for
a small (0-100) number of users on a single server. We recommend reading
[](/topic/whentouse) to determine if this is the right tool for you.
## Installation
The Littlest JupyterHub (TLJH) can run on any server that is running **Debian 11** or **Ubuntu 20.04** or **22.04** on an amd64 or arm64 CPU architecture.
We aim to support 'stable' and Long-Term Support (LTS) versions.
Newer versions are likely to work with little or no adjustment, but these are not officially supported or tested.
Earlier versions of Ubuntu and Debian are not supported, nor are other Linux distributions.
We have a bunch of tutorials to get you started.
- 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
servers.
```{toctree}
:maxdepth: 2
:titlesonly: true
install/index
```
Once you are ready to run your server for real,
it's a good idea to proceed directly to {doc}`howto/admin/https`.
## How-To Guides
How-To guides answer the question 'How do I...?' for a lot of topics.
```{toctree}
:maxdepth: 2
howto/index
```
## Topic Guides
Topic guides provide in-depth explanations of specific topics.
```{toctree}
:maxdepth: 2
:titlesonly: true
topic/index
```
## Reference
The reference documentation is meant to provide narrowly scoped technical
descriptions that other documentation can link to for details.
```{toctree}
:maxdepth: 2
:titlesonly: true
reference/index
```
## Troubleshooting
In time, all systems have issues that need to be debugged. Troubleshooting
guides help you find what is broken & hopefully fix it.
```{toctree}
:maxdepth: 2
:titlesonly: true
troubleshooting/index
```
## Contributing
We want you to contribute to TLJH in the ways that are most useful
and exciting to you. This section contains documentation helpful
to people contributing in various ways.
```{toctree}
:maxdepth: 2
:titlesonly: true
contributing/index
```

View File

@@ -1,81 +0,0 @@
=======================
The Littlest JupyterHub
=======================
A simple `JupyterHub <https://github.com/jupyterhub/jupyterhub>`_ distribution for
a small (0-100) number of users on a single server. We recommend reading
:ref:`topic/whentouse` to determine if this is the right tool for you.
Development Status
==================
This project is currently in **beta** state. Folks have been using installations
of TLJH for more than a year now to great success. While we try hard not to, we
might still make breaking changes that have no clear upgrade pathway.
Installation
============
The Littlest JupyterHub (TLJH) can run on any server that is running **Ubuntu 18.04** or **Ubuntu 20.04** on a amd64 or arm64 CPU architecture. Earlier versions of Ubuntu are not supported.
We have a bunch of tutorials to get you started.
- 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
servers.
.. toctree::
:titlesonly:
:maxdepth: 2
install/index
Once you are ready to run your server for real,
it's a good idea to proceed directly to :doc:`howto/admin/https`.
How-To Guides
=============
How-To guides answer the question 'How do I...?' for a lot of topics.
.. toctree::
:maxdepth: 2
howto/index
Topic Guides
============
Topic guides provide in-depth explanations of specific topics.
.. toctree::
:titlesonly:
:maxdepth: 2
topic/index
Troubleshooting
===============
In time, all systems have issues that need to be debugged. Troubleshooting
guides help you find what is broken & hopefully fix it.
.. toctree::
:titlesonly:
:maxdepth: 2
troubleshooting/index
Contributing
============
We want you to contribute to TLJH in the ways that are most useful
and exciting to you. This section contains documentation helpful
to people contributing in various ways.
.. toctree::
:titlesonly:
:maxdepth: 2
contributing/index

View File

@@ -0,0 +1,30 @@
The **User Environment** is a conda environment that is shared by all users
in the JupyterHub. Libraries installed in this environment are immediately
available to all users. Admin users can install packages in this environment
with `sudo -E`.
1. Log in as an admin user and open a Terminal in your Jupyter Notebook.
```{image} ../images/notebook/new-terminal-button.png
:alt: New Terminal button under New menu
```
2. Install [gdal](https://anaconda.org/conda-forge/gdal) from [conda-forge](https://conda-forge.org/).
```bash
sudo -E conda install -c conda-forge gdal
```
The `sudo -E` is very important!
3. Install [there](https://pypi.org/project/there) with `pip`
```bash
sudo -E pip install there
```
The packages `gdal` and `there` are now available to all users in JupyterHub.
If a user already had a python notebook running, they have to restart their notebook's
kernel to make the new libraries available.
See [](#howto/user-env/user-environment) for more information.

42
docs/install/add-users.md Normal file
View File

@@ -0,0 +1,42 @@
Most administration & configuration of the JupyterHub can be done from the
web UI directly. Let's add a few users who can log in!
1. In the File menu select the entry for the **Hub Control Panel**.
```{image} ../images/control-panel-menu.png
:alt: Hub Control panel entry in lab File menu
```
2. In the control panel, open the **Admin** link in the top left.
```{image} ../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
```
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
3. Click the **Add Users** button.
```{image} ../images/admin/add-users-button.png
:alt: Add Users button in the admin page
```
A **Add Users** dialog box opens up.
4. Type the names of users you want to add to this JupyterHub in the dialog box,
one per line.
```{image} ../images/admin/add-users-dialog.png
:alt: Adding users with add users dialog
```
You can tick the **Admin** checkbox if you want to give admin rights to all
these users too.
5. Click the **Add Users** button in the dialog box. Your users are now added
to the JupyterHub! When they log in for the first time, they can set their
password - and use it to log in again in the future.
Congratulations, you now have a multi user JupyterHub that you can add arbitrary
users to!

View File

@@ -1,30 +0,0 @@
The **User Environment** is a conda environment that is shared by all users
in the JupyterHub. Libraries installed in this environment are immediately
available to all users. Admin users can install packages in this environment
with ``sudo -E``.
#. Log in as an admin user and open a Terminal in your Jupyter Notebook.
.. image:: ../images/notebook/new-terminal-button.png
:alt: New Terminal button under New menu
#. Install `gdal <https://anaconda.org/conda-forge/gdal>`_ from `conda-forge <https://conda-forge.org/>`_.
.. code-block:: bash
sudo -E conda install -c conda-forge gdal
The ``sudo -E`` is very important!
#. Install `there <https://pypi.org/project/there>`_ with ``pip``
.. code-block:: bash
sudo -E pip install there
The packages ``gdal`` and ``there`` are now available to all users in JupyterHub.
If a user already had a python notebook running, they have to restart their notebook's
kernel to make the new libraries available.
See :ref:`howto/env/user_environment` for more information.

View File

@@ -1,39 +0,0 @@
Most administration & configuration of the JupyterHub can be done from the
web UI directly. Let's add a few users who can log in!
#. Open the **Control Panel** by clicking the control panel button on the top
right of your JupyterHub.
.. image:: ../images/control-panel-button.png
:alt: Control panel button in notebook, top right
#. In the control panel, open the **Admin** link in the top left.
.. image:: ../images/admin/admin-access-button.png
:alt: Admin button in control panel, top left
This opens up the JupyterHub admin page, where you can add / delete users,
start / stop peoples' servers and see who is online.
#. Click the **Add Users** button.
.. image:: ../images/admin/add-users-button.png
:alt: Add Users button in the admin page
A **Add Users** dialog box opens up.
#. Type the names of users you want to add to this JupyterHub in the dialog box,
one per line.
.. image:: ../images/admin/add-users-dialog.png
:alt: Adding users with add users dialog
You can tick the **Admin** checkbox if you want to give admin rights to all
these users too.
#. Click the **Add Users** button in the dialog box. Your users are now added
to the JupyterHub! When they log in for the first time, they can set their
password - and use it to log in again in the future.
Congratulations, you now have a multi user JupyterHub that you can add arbitrary
users to!

279
docs/install/amazon.md Normal file
View File

@@ -0,0 +1,279 @@
(install-amazon)=
# Installing on Amazon Web Services
## Goal
To have a JupyterHub with admin users and a user environment with conda / pip packages.
## Prerequisites
1. An Amazon Web Services account.
If asked to choose a default region, choose the one closest to the majority
of your users.
## Step 1: Installing The Littlest JupyterHub
Let's create the server on which we can run JupyterHub.
1. Go to [Amazon Web Services](https://aws.amazon.com/) and click the gold
button 'Sign In to the Console' in the upper right. Log in with your Amazon Web
Services account.
If you need to adjust your region from your default, there is a drop-down
menu between your name and the **Support** menu on the far right of the dark
navigation bar across the top of the window. Adjust the region to match the
closest one to the majority of your users.
2. On the screen listing all the available services, pick **EC2** under **Compute**
on the left side at the top of the first column.
```{image} ../images/providers/amazon/compute_services.png
:alt: Select EC2
```
This will take you to the **EC2 Management Console**.
3. From the navigation menu listing on the far left side of the **EC2 Management
Console**, choose **Instances** under the light gray **INSTANCES** sub-heading.
```{image} ../images/providers/amazon/instances_from_console.png
:alt: Select Instances from console
```
4. In the main window of the **EC2 Management Console**, towards the top left,
click on the bright blue **Launch Instance** button.
```{image} ../images/providers/amazon/launch_instance_button.png
:alt: Click launch instance
```
This will start the 'launch instance wizard' process. This lets you customize
the kind of server you want, the resources it will have and its name.
5. On the page **Step 1: Choose an Amazon Machine Image (AMI)** you are going
to pick the base image your remote server will have. The view will
default to the 'Quick-start' tab selected and just a few down the page, select
**Ubuntu Server 22.04 LTS (HVM), SSD Volume Type - ami-XXXXXXXXXXXXXXXXX**,
leaving `64-bit (x86)` toggled.
```{image} ../images/providers/amazon/select_ubuntu_18.png
:alt: Click Ubuntu server 22.04
```
The `ami` alpha-numeric at the end references the specific Amazon machine
image, ignore this as Amazon updates them routinely. The
**Ubuntu Server 22.04 LTS (HVM)** is the important part.
6. After selecting the AMI, you'll be at **Step 2: Choose an Instance Type**.
There will be a long listing of the types and numbers of CPUs that Amazon
offers. Select the one you want and then select the button
`Next: Configure Instance Details` in the lower right corner.
Check out our guide on How To [](/howto/admin/resource-estimation) to help pick
how much Memory / CPU your server needs.
We recommend you use a server with at least 2GB of RAM, such as a **t3.small**.
However, if you need to minimise costs you can use a server with **1GB** RAM such as a **t2.micro**, but performance will be limited.
You may wish to consult the listing [here](https://www.ec2instances.info/)
because it shows cost per hour. The **On Demand** price is the pertinent cost.
`GPU graphics` and `GPU compute` products are also available around half way down the page
7. Under **Step 3: Configure Instance Details**, scroll to the bottom of the page
and toggle the arrow next to **Advanced Details**. Scroll down to 'User data'. Copy
the text below, and paste it into the **User data** 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
configure it. **Remember to add your username**!
```bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
```{image} ../images/providers/amazon/script_in_user_data.png
:alt: Install JupyterHub with the script in the User data textbox
```
:::{note}
See [](/topic/installer-actions) for a detailed description and
[](/topic/customizing-installer) for other options that can be used.
:::
8. Under **Step 4: Add Storage**, you can change the **size** and **type of your
disk by adjusting the value in \*\*Size (GiB)** and selecting **Volume Type**.
```{image} ../images/providers/amazon/change_size_type.png
:alt: Selecting disk size and type
```
Check out [](/howto/admin/resource-estimation) to help pick
how much Disk space your server needs.
Hover over the encircled `i` next to **Volume Type** for an explanation of
each. Leaving the default as is is fine. `General Purpose SSD (gp2)` is
recommended for most workloads. With `Provisioned IOPS SSD (io1)` being the
highest-performance SSD volume. Magnetic (standard) is a previous generation
volume and not suited for a hub for multi-users.
When finished, click **Next: Add Tags** in the bottom right corner.
9. Under **Step 5: Add Tags**, click **Add Tag** and enter **Name** under the
**Key** field. In the **Value** field in the **Name** row, give your new
server a memorable name that identifies what purpose this JupyterHub will be
used for.
```{image} ../images/providers/amazon/name_hub.png
:alt: Use tags to name the hub.
```
10. Under **Step 6: Configure Security Group**, you'll set the firewall rules
that control the traffic for your instance. Specifically you'll want to add
rules to allow both **HTTP Traffic** and **HTTPS Traffic**. For
advanced troubleshooting, it will be helpful to set rules so you can use
SSH to connect (port 22).
If you have never used your Amazon account before, you'll have to select
**Create a new security group**. You should give it a distinctive name
under **Security group name**
such as `ssh_web` for future reference. If you already have a security group,
you can select it and adjust it to have the rules you need, if you prefer.
The rules will default to include `SSH`. Leave that there, and then click on
the **Add Rule** button. Under **Type** for the new rule, change the field
to **HTTP**. The other boxes will get filled in appropritely. Again, click on
the **Add Rule** button. This time under **Type** for the new rule, change
the field to **HTTPS**.
The warning is there to remind you this opens things up to some degree but
this is necessary in order to let your users connect. However, this warning
is a good reminder that you should monitor your server to insure it is
available for users who may need it.
```{image} ../images/providers/amazon/set_security_groups.png
:alt: Allow HTTP & HTTPS traffic to your server
```
11. When the security rules are set, click on the blue button in the bottom
right **Review and Launch**. This will give you a chance to review things
because very soon you'll be launching and start paying for any resources you
use.
Note that you'll see two HTTP listings and two HTTPS listings under
**Security Groups** even though you only made one for each. This is normal &
necessary to match both IPv4 & IPv6 types of IP addresses.
When you are happy, press the blue **Launch** button in the bottom right
corner to nearly conclude your journey through the instance launch wizard.
```{image} ../images/providers/amazon/finally_launch.png
:alt: Launch your server
```
12. In the dialog box that pops up as the last step before launching is
triggered, you need to choose what to do about an identifying key pair and
acknowledge your choice in order to proceed. If you already have a key pair you
can select to associate it with this instance, otherwise you need to
**Create a new key pair**. Choosing to `Proceed without a key pair` is not
recommended as you'll have no way to access your server via SSH if anything
goes wrong with the Jupyterhub and have no way to recover files via download.
Download and keep the key pair file unless you are associating one you already
have.
```{image} ../images/providers/amazon/create_key_pair.png
:alt: Associate key pair
```
13. With the key pair associated, click the **Launch instances** button to
start creating the server that'll run TLJH.
```{image} ../images/providers/amazon/launch_now.png
:alt: Trigger actual launch
```
14. Following the launch initiation, you'll be taken to a **Launch Status**
notification screen. You can see more information about the details if you
click on the alphanumeric link to the launching instance following the text,
"`The following instance launches have been initiated:`".
```{image} ../images/providers/amazon/launch_status_screen.png
:alt: Launch status notice
```
15. That link will take you back to the **EC2 Management Console** with settings
that will limit the view in the console to just that instance. (Delete the
filter in the search bar if you want to see any other instances you may
have.) At first the server will be starting up, and then when the
**Instance state** is green the server is running.
```{image} ../images/providers/amazon/running_server.png
:alt: Server is running.
```
If you already have instances running in your account, the screen will look
different if you disable that filter. But you want to pay attention to the
row with the name of the server you made.
16. In a few seconds your server will be created, and you can see the
**Public IP** used to access it in the panel at the bottom of the console.
If it isn't displayed, click on the row for that instance in the console. It
will look like a pattern similar to **12.30.230.127**.
```{image} ../images/providers/amazon/public_ip.png
:alt: public IP
```
17. The Littlest JupyterHub is now installing in the background on your new
server. It takes around 10 minutes for this installation to complete.
18. Check if the installation is complete by copying the **Public IP**
of your server, and trying to access it from within a browser. If it has been
10 minutes, paste the public IP into the URL bar of your browser and hit
return to try to connect.
Accessing the JupyterHub will fail until the installation is complete,
so be patient. The next step below this one shows the login window you are
expecting to see when trying the URL and things work.
While waiting until the appropriate time to try, another way to check if
things are churning away, is to open the **System Log**. To do this, go to
the **EC2 Management Console** & highlight the instance by clicking on that
row and then right-click **Monitor and troubleshoot** > **Get system log**.
19. When the Jupyterhub creation process finishes and the hub is ready to show
the login, the **System Log** should look similar to the image below. Scroll to
the bottom of your output from the previous step.
Note the line **Starting TLJH installer**, you may also see **Started jupyterhub.service**
```{image} ../images/providers/amazon/completed_system_log.png
:alt: Completed system log
```
20. When the installation is complete, it should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
21. Login using the **admin user name** you used in step 7, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
22. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,269 +0,0 @@
.. _install/amazon:
=================================
Installing on Amazon Web Services
=================================
Goal
====
To have a JupyterHub with admin users and a user environment with conda / pip packages.
Prerequisites
=============
#. An Amazon Web Services account.
If asked to choose a default region, choose the one closest to the majority
of your users.
Step 1: Installing The Littlest JupyterHub
==========================================
Let's create the server on which we can run JupyterHub.
#. Go to `Amazon Web Services <https://aws.amazon.com/>`_ and click the gold
button 'Sign In to the Console' in the upper right. Log in with your Amazon Web
Services account.
If you need to adjust your region from your default, there is a drop-down
menu between your name and the **Support** menu on the far right of the dark
navigation bar across the top of the window. Adjust the region to match the
closest one to the majority of your users.
#. On the screen listing all the available services, pick **EC2** under **Compute**
on the left side at the top of the first column.
.. image:: ../images/providers/amazon/compute_services.png
:alt: Select EC2
This will take you to the **EC2 Management Console**.
#. From the navigation menu listing on the far left side of the **EC2 Management
Console**, choose **Instances** under the light gray **INSTANCES** sub-heading.
.. image:: ../images/providers/amazon/instances_from_console.png
:alt: Select Instances from console
#. In the main window of the **EC2 Management Console**, towards the top left,
click on the bright blue **Launch Instance** button.
.. image:: ../images/providers/amazon/launch_instance_button.png
:alt: Click launch instance
This will start the 'launch instance wizard' process. This lets you customize
the kind of server you want, the resources it will have and its name.
#. On the page **Step 1: Choose an Amazon Machine Image (AMI)** you are going
to pick the base image your remote server will have. The view will
default to the 'Quick-start' tab selected and just a few down the page, select
**Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-XXXXXXXXXXXXXXXXX**,
leaving `64-bit (x86)` toggled.
.. image:: ../images/providers/amazon/select_ubuntu_18.png
:alt: Click Ubuntu server 18.04
The `ami` alpha-numeric at the end references the specific Amazon machine
image, ignore this as Amazon updates them routinely. The
**Ubuntu Server 18.04 LTS (HVM)** is the important part.
#. After selecting the AMI, you'll be at **Step 2: Choose an Instance Type**.
There will be a long listing of the types and numbers of CPUs that Amazon
offers. Select the one you want and then select the button
`Next: Configure Instance Details` in the lower right corner.
Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick
how much Memory / CPU your server needs.
We recommend you use a server with at least 2GB of RAM, such as a **t3.small**.
However, if you need to minimise costs you can use a server with **1GB** RAM such as a **t2.micro**, but performance will be limited.
You may wish to consult the listing `here <https://www.ec2instances.info/>`_
because it shows cost per hour. The **On Demand** price is the pertinent cost.
``GPU graphics`` and ``GPU compute`` products are also available around half way down the page
#. Under **Step 3: Configure Instance Details**, scroll to the bottom of the page
and toggle the arrow next to **Advanced Details**. Scroll down to 'User data'. Copy
the text below, and paste it into the **User data** 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
configure it. **Remember to add your username**!
.. code-block:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
.. image:: ../images/providers/amazon/script_in_user_data.png
:alt: Install JupyterHub with the script in the User data textbox
.. note::
See :ref:`topic/installer-actions` for a detailed description and
:ref:`topic/customizing-installer` for other options that can be used.
#. Under **Step 4: Add Storage**, you can change the **size** and **type of your
disk by adjusting the value in **Size (GiB)** and selecting **Volume Type**.
.. image:: ../images/providers/amazon/change_size_type.png
:alt: Selecting disk size and type
Check out :ref:`howto/admin/resource-estimation` to help pick
how much Disk space your server needs.
Hover over the encircled `i` next to **Volume Type** for an explanation of
each. Leaving the default as is is fine. `General Purpose SSD (gp2)` is
recommended for most workloads. With `Provisioned IOPS SSD (io1)` being the
highest-performance SSD volume. Magnetic (standard) is a previous generation
volume and not suited for a hub for multi-users.
When finished, click **Next: Add Tags** in the bottom right corner.
#. Under **Step 5: Add Tags**, click **Add Tag** and enter **Name** under the
**Key** field. In the **Value** field in the **Name** row, give your new
server a memorable name that identifies what purpose this JupyterHub will be
used for.
.. image:: ../images/providers/amazon/name_hub.png
:alt: Use tags to name the hub.
#. Under **Step 6: Configure Security Group**, you'll set the firewall rules
that control the traffic for your instance. Specifically you'll want to add
rules to allow both **HTTP Traffic** and **HTTPS Traffic**. For
advanced troubleshooting, it will be helpful to set rules so you can use
SSH to connect (port 22).
If you have never used your Amazon account before, you'll have to select
**Create a new security group**. You should give it a disitnguishing name
under **Security group name**
such as `ssh_web` for future reference. If you have, one from before you can
select it and adjust it to have the rules you need, if you prefer.
The rules will default to include `SSH`. Leave that there, and then click on
the **Add Rule** button. Under **Type** for the new rule, change the field
to **HTTP**. The other boxes will get filled in appropritely. Again, click on
the **Add Rule** button. This time under **Type** for the new rule, change
the field to **HTTPS**.
The warning is there to remind you this opens things up to some degree but
this is necessary in order to let your users connect. However, this warning
is a good reminder that you should monitor your server to insure it is
available for users who may need it.
.. image:: ../images/providers/amazon/set_security_groups.png
:alt: Allow HTTP & HTTPS traffic to your server
#. When the security rules are set, click on the blue button in the bottom
right **Review and Launch**. This will give you a chance to review things
because very soon you'll be launching and start paying for any resources you
use.
Note that you'll see two HTTP listings and two HTTPS listings under
**Security Groups** even though you only made one for each. This is normal &
necessary to match both IPv4 & IPv6 types of IP addresses.
When you are happy, press the blue **Launch** button in the bottom right
corner to nearly conclude your journey through the instance launch wizard.
.. image:: ../images/providers/amazon/finally_launch.png
:alt: Launch your server
#. In the dialog box that pops up as the last step before launching is
triggered, you need to choose what to do about an identifying key pair and
acknowledge your choice in order to proceed. If you already have a key pair you
can select to associate it with this instance, otherwise you need to
**Create a new key pair**. Choosing to `Proceed without a key pair` is not
recommended as you'll have no way to access your server via SSH if anything
goes wrong with the Jupyterhub and have no way to recover files via download.
Download and keep the key pair file unless you are associating one you already
have.
.. image:: ../images/providers/amazon/create_key_pair.png
:alt: Associate key pair
#. With the key pair associated, click the **Launch instances** button to
start creating the server that'll run TLJH.
.. image:: ../images/providers/amazon/launch_now.png
:alt: Trigger actual launch
#. Following the launch initiation, you'll be taken to a **Launch Status**
notification screen. You can see more information about the details if you
click on the alphanumeric link to the launching instance following the text,
"`The following instance launches have been initiated:`".
.. image:: ../images/providers/amazon/launch_status_screen.png
:alt: Launch status notice
#. That link will take you back to the **EC2 Management Console** with settings
that will limit the view in the console to just that instance. (Delete the
filter in the search bar if you want to see any other instances you may
have.) At first the server will be starting up, and then when the
**Instance state** is green the server is running.
.. image:: ../images/providers/amazon/running_server.png
:alt: Server is running.
If you already have instances running in your account, the screen will look
different if you disable that filter. But you want to pay attention to the
row with the name of the server you made.
#. In a few seconds your server will be created, and you can see the
**Public IP** used to access it in the panel at the bottom of the console.
If it isn't displayed, click on the row for that instance in the console. It
will look like a pattern similar to **12.30.230.127**.
.. image:: ../images/providers/amazon/public_ip.png
:alt: public IP
#. The Littlest JupyterHub is now installing in the background on your new
server. It takes around 10 minutes for this installation to complete.
#. Check if the installation is complete by copying the **Public IP**
of your server, and trying to access it from within a browser. If it has been
10 minutes, paste the public IP into the URL bar of your browser and hit
return to try to connect.
Accessing the JupyterHub will fail until the installation is complete,
so be patient. The next step below this one shows the login window you are
expecting to see when trying the URL and things work.
While waiting until the appropriate time to try, another way to check if
things are churning away, is to open the **System Log**. To do this, go to
the **EC2 Management Console** & highlight the instance by clicking on that
row and then right-click **Monitor and troubleshoot** > **Get system log**.
#. When the Jupyterhub creation process finishes and the hub is ready to show
the login, the **System Log** should look similar to the image below. Scroll to
the bottom of your output from the previous step.
Note the line **Starting TLJH installer**, you may also see **Started jupyterhub.service**
.. image:: ../images/providers/amazon/completed_system_log.png
:alt: Completed system log
#. When the installation is complete, it should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 7, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

226
docs/install/azure.md Normal file
View File

@@ -0,0 +1,226 @@
(install-azure)=
# Installing on Azure
## Goal
By the end of this tutorial, you should have a JupyterHub with some admin
users and a user environment with packages you want to be installed running on
[Microsoft Azure](https://azure.microsoft.com).
This tutorial leads you step-by-step for you to manually deploy your own JupyterHub on Azure cloud.
:::{note}
✨ The `Deploy to Azure button` project allows you to deploy your own JupyterHub with minimal manual configuration steps. The deploy to Azure button allows you to have a vanilla configuration in just one-click and by assigning some variables.
Check it out at [https://github.com/trallard/TLJH-azure-button](https://github.com/trallard/TLJH-azure-button).
:::
## Prerequisites
- A Microsoft Azure account.
- To get started you can get a free account which includes 150 dollars worth of Azure credits ([get a free account here](https://azure.microsoft.com/en-us/free//?wt.mc_id=TLJH-github-taallard))
These instructions cover how to set up a Virtual Machine
on Microsoft Azure. For subsequent information about creating
your JupyterHub and configuring it, see [The Littlest JupyterHub guide](https://the-littlest-jupyterhub.readthedocs.io/en/latest/).
## Step 1: Installing The Littlest JupyterHub
We start by creating the Virtual Machine in which we can run TLJH (The Littlest JupyterHub).
1. Go to [Azure portal](https://portal.azure.com/) and login with your Azure account.
2. Expand the left-hand panel by clicking on the ">>" button on the top left corner of your dashboard. Find the Virtual Machines tab and click on it.
```{image} ../images/providers/azure/azure-vms.png
:alt: Virtual machines on Azure portal
```
3. Click **+ add** to create a new Virtual Machine
```{image} ../images/providers/azure/add-vm.png
:alt: Add a new virtual machine
```
4. Select **Create VM from Marketplace** in the next screen.
A new screen with all the options for Virtual Machines in Azure will displayed.
```{image} ../images/providers/azure/create-vm.png
:alt: Create VM from the marketplace
```
5. **Choose an Ubuntu server for your VM**:
- Click `Ubuntu Server 22.04 LTS.`
- Make sure `Resource Manager` is selected in the next screen and click **Create**
```{image} ../images/providers/azure/ubuntu-vm.png
:alt: Ubuntu VM
```
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.
- **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.
:::{note}
If you have never created a Resource Group, click on **Create new**
:::
```{image} ../images/providers/azure/new-rg.png
:alt: Create a new resource group
```
- **Name**. Use a descriptive name for your virtual machine (note that you cannot use spaces or special characters).
- **Region**. Choose a location near where you expect your users to be located.
- **Availability options**. Choose "No infrastructure redundancy required".
- **Image**. Make sure "Ubuntu Server 22.04 LTS" is selected (from the previous step).
- **Authentication type**. Change authentication type to "password".
- **Username**. Choose a memorable username, this will be your "root" user, and you'll need it later on.
- **Password**. Type in a password, this will be used later for admin access so make sure it is something memorable.
```{image} ../images/providers/azure/password-vm.png
:alt: Add password to VM
```
- **Login with Azure Active Directory**. Choose "Off" (usually the default)
- **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.
- 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)
```{image} ../images/providers/azure/size-vm.png
:alt: Choose vm size
```
:::{note}
For more information about estimating memory, CPU and disk needs check [The memory section in the TLJH documentation](https://tljh.jupyter.org/en/latest/howto/admin/resource-estimation.html)
:::
- 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):
- **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.
- Click "Next".
```{image} ../images/providers/azure/create-disk.png
:alt: Create and attach disk
```
```{image} ../images/providers/azure/disk-vm.png
:alt: Choose a disk size
```
9. Networking
- **Virtual network**. 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.
- **Network Security Group**. Choose "Basic"
- **Public inbound ports**. Check **HTTP**, **HTTPS**, and **SSH**.
```{image} ../images/providers/azure/networking-vm.png
:alt: Choose networking ports
```
10. Management
- Monitoring
- **Boot diagnostics**. Choose "On".
- **OS guest diagnostics**. Choose "Off".
- **Diagnostics storage account**. Leave as the default.
- Auto-Shutdown
- **Enable auto-shutdown**. Choose "Off".
- Backup
- **Backup**. Choose "Off".
- System assigned managed identity. Select "Off".
```{image} ../images/providers/azure/backup-vm.png
:alt: Choose VM Backup
```
11. Advanced settings
- **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.
Copy the code snippet below:
```bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
where the `admin-user-name` is the root username you chose for your Virtual Machine.
```{image} ../images/providers/azure/cloudinit-vm.png
:alt: Install TLJH
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
12. Check the summary and confirm the creation of your Virtual Machine.
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.
- After completion, you should see a similar screen to the one below:
```{image} ../images/providers/azure/deployed-vm.png
:alt: Deployed VM
```
14. Note that the Littlest JupyterHub should be installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
15. Click on the **Go to resource button**
```{image} ../images/providers/azure/goto-vm.png
:alt: Go to VM
```
16. Check if the installation is completed by **copying** the **Public IP address** of your virtual machine, and trying to access it with a browser.
```{image} ../images/providers/azure/ip-vm.png
:alt: Public IP address
```
Note that accessing the JupyterHub will fail until the installation is complete, so be patient.
17. When the installation is complete, it should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
18. Login using the **admin user name** you used in step 6, and a password. Use a strong password & note it down somewhere, since this will be the password for the admin user account from now on.
19. Congratulations, you have a running working JupyterHub! 🎉
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,192 +0,0 @@
.. _install/azure:
====================
Installing on Azure
====================
Goal
====
By the end of this tutorial, you should have a JupyterHub with some admin
users and a user environment with packages you want to be installed running on
`Microsoft Azure <https://azure.microsoft.com>`_.
This tutorial leads you step-by-step for you to manually deploy your own JupyterHub on Azure cloud.
.. note:: ✨ The ``Deploy to Azure button`` project allows you to deploy your own JupyterHub with minimal manual configuration steps. The deploy to Azure button allows you to have a vanilla configuration in just one-click and by assigning some variables.
Check it out at `https://github.com/trallard/TLJH-azure-button <https://github.com/trallard/TLJH-azure-button>`_.
Prerequisites
==============
* A Microsoft Azure account.
* To get started you can get a free account which includes 150 dollars worth of Azure credits (`get a free account here <https://azure.microsoft.com/en-us/free//?wt.mc_id=TLJH-github-taallard>`_)
These instructions cover how to set up a Virtual Machine
on Microsoft Azure. For subsequent information about creating
your JupyterHub and configuring it, see `The Littlest JupyterHub guide <https://the-littlest-jupyterhub.readthedocs.io/en/latest/>`_.
Step 1: Installing The Littlest JupyterHub
==========================================
We start by creating the Virtual Machine in which we can run TLJH (The Littlest JupyterHub).
#. Go to `Azure portal <https://portal.azure.com/>`_ and login with your Azure account.
#. Expand the left-hand panel by clicking on the ">>" button on the top left corner of your dashboard. Find the Virtual Machines tab and click on it.
.. image:: ../images/providers/azure/azure-vms.png
:alt: Virtual machines on Azure portal
#. Click **+ add** to create a new Virtual Machine
.. image:: ../images/providers/azure/add-vm.png
:alt: Add a new virtual machine
#. Select **Create VM from Marketplace** in the next screen.
A new screen with all the options for Virtual Machines in Azure will displayed.
.. image:: ../images/providers/azure/create-vm.png
:alt: Create VM from the marketplace
#. **Choose an Ubuntu server for your VM**:
* Click `Ubuntu Server 18.04 LTS.`
* Make sure `Resource Manager` is selected in the next screen and click **Create**
.. image:: ../images/providers/azure/ubuntu-vm.png
:alt: Ubuntu VM
#. 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.
* **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.
.. note:: If you have never created a Resource Group, click on **Create new**
.. image:: ../images/providers/azure/new-rg.png
:alt: Create a new resource group
* **Name**. Use a descriptive name for your virtual machine (note that you cannot use spaces or special characters).
* **Region**. Choose a location near where you expect your users to be located.
* **Availability options**. Choose "No infrastructure redundancy required".
* **Image**. Make sure "Ubuntu Server 18.04 LTS" is selected (from the previous step).
* **Authentication type**. Change authentication type to "password".
* **Username**. Choose a memorable username, this will be your "root" user, and you'll need it later on.
* **Password**. Type in a password, this will be used later for admin access so make sure it is something memorable.
.. image:: ../images/providers/azure/password-vm.png
:alt: Add password to VM
* **Login with Azure Active Directory**. Choose "Off" (usually the default)
* **Inbound port rules**. Leave the defaults for now, and we will update these later on in the Network configuration step.
#. 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.
* Click on **Change size** (see image below)
.. image:: ../images/providers/azure/size-vm.png
:alt: Choose vm size
.. note:: For more information about estimating memory, CPU and disk needs check `The memory section in the TLJH documentation <https://tljh.jupyter.org/en/latest/howto/admin/resource-estimation.html>`_
* 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>`_).
#. 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.
* **Data disk**. Click on create and attach a new disk. Select an appropriate type and size and click ok.
* Click "Next".
.. image:: ../images/providers/azure/create-disk.png
:alt: Create and attach disk
.. image:: ../images/providers/azure/disk-vm.png
:alt: Choose a disk size
#. Networking
* **Virtual network**. 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.
* **Network Security Group**. Choose "Basic"
* **Public inbound ports**. Check **HTTP**, **HTTPS**, and **SSH**.
.. image:: ../images/providers/azure/networking-vm.png
:alt: Choose networking ports
#. Management
* Monitoring
* **Boot diagnostics**. Choose "On".
* **OS guest diagnostics**. Choose "Off".
* **Diagnostics storage account**. Leave as the default.
* Auto-Shutdown
* **Enable auto-shutdown**. Choose "Off".
* Backup
* **Backup**. Choose "Off".
* System assigned managed identity Select "Off"
.. image:: ../images/providers/azure/backup-vm.png
:alt: Choose VM Backup
#. Advanced settings
* **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.
Copy the code snippet below:
.. code:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
where the ``username`` is the root username you chose for your Virtual Machine.
.. image:: ../images/providers/azure/cloudinit-vm.png
:alt: Install TLJH
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
#. Check the summary and confirm the creation of your Virtual Machine.
#. Check that the creation of your Virtual Machine worked.
* 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:
.. image:: ../images/providers/azure/deployed-vm.png
:alt: Deployed VM
#. Note that the Littlest JupyterHub should be installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
#. Click on the **Go to resource button**
.. image:: ../images/providers/azure/goto-vm.png
:alt: Go to VM
#. Check if the installation is completed by **copying** the **Public IP address** of your virtual machine, and trying to access it with a browser.
.. image:: ../images/providers/azure/ip-vm.png
:alt: Public IP address
Note that accessing the JupyterHub will fail until the installation is complete, so be patient.
#. When the installation is complete, it should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 6, and a password. Use a strong password & note it down somewhere, since this will be the password for the admin user account from now on.
#. Congratulations, you have a running working JupyterHub! 🎉
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

View File

@@ -0,0 +1,95 @@
(install-custom)=
# Installing on your own server
Follow this guide if your cloud provider doesn't have a direct tutorial, or
you are setting this up on a bare metal server.
:::{warning}
Do **not** install TLJH directly on your laptop or personal computer!
It will most likely open up exploitable security holes when run directly
on your personal computer.
:::
:::{note}
Running TLJH _inside_ a docker container is not supported, since we depend
on systemd. If you want to run TLJH locally for development, see
[](/contributing/dev-setup).
:::
## Goal
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
a server you have access to.
## Pre-requisites
1. Some familiarity with the command line.
2. A server running Ubuntu 20.04+ where you have root access (Ubuntu 22.04 LTS recommended).
3. At least **1GB** of RAM on your server.
4. Ability to `ssh` into the server & run commands from the prompt.
5. An **IP address** where the server can be reached from the browsers of your target audience.
If you run into issues, look at the specific [troubleshooting guide](/troubleshooting/providers/custom)
for custom server installations.
## Step 1: Installing The Littlest JupyterHub
1. Using a terminal program, SSH into your server. This should give you a prompt where you can
type commands.
2. Make sure you have `python3`, `python3-dev`, `curl` and `git` installed.
```
sudo apt install python3 python3-dev git curl
```
3. Copy the text below, and paste it into the terminal. 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. **Remember to add your username**!
```bash
curl -L https://tljh.jupyter.org/bootstrap.py | sudo -E python3 - --admin <admin-user-name>
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
4. Press `Enter` to start the installation process. This will take 5-10 minutes,
and will say `Done!` when the installation process is complete.
5. Copy the **Public IP** of your server, and try accessing `http://<public-ip>` from
your browser. If everything went well, this should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
6. Login using the **admin user name** you used in step 3. You can choose any
password that you wish. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
7. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```
## Step 4: Setup HTTPS
Once you are ready to run your server for real, and have a domain, it's a good
idea to proceed directly to [](/howto/admin/https).

View File

@@ -1,99 +0,0 @@
.. _install/custom:
=============================
Installing on your own server
=============================
Follow this guide if your cloud provider doesn't have a direct tutorial, or
you are setting this up on a bare metal server.
.. warning::
Do **not** install TLJH directly on your laptop or personal computer!
It will most likely open up exploitable security holes when run directly
on your personal computer.
.. note::
Running TLJH *inside* a docker container is not supported, since we depend
on systemd. If you want to run TLJH locally for development, see
:ref:`contributing/dev-setup`.
Goal
====
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
a server you have access to.
Pre-requisites
==============
#. Some familiarity with the command line.
#. A server running Ubuntu 18.04 where you have root access.
#. At least **1GB** of RAM on your server.
#. Ability to ``ssh`` into the server & run commands from the prompt.
#. An **IP address** where the server can be reached from the browsers of your target audience.
If you run into issues, look at the specific :ref:`troubleshooting guide <troubleshooting/providers/custom>`
for custom server installations.
Step 1: Installing The Littlest JupyterHub
==========================================
#. Using a terminal program, SSH into your server. This should give you a prompt where you can
type commands.
#. Make sure you have ``python3``, ``python3-dev``, ``curl`` and ``git`` installed.
.. code::
sudo apt install python3 python3-dev git curl
#. Copy the text below, and paste it into the terminal. 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. **Remember to add your username**!
.. code-block:: bash
curl -L https://tljh.jupyter.org/bootstrap.py | sudo -E python3 - --admin <admin-user-name>
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
#. Press ``Enter`` to start the installation process. This will take 5-10 minutes,
and will say ``Done!`` when the installation process is complete.
#. Copy the **Public IP** of your server, and try accessing ``http://<public-ip>`` from
your browser. If everything went well, this should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 3. You can choose any
password that you wish. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt
Step 4: Setup HTTPS
===================
Once you are ready to run your server for real, and have a domain, it's a good
idea to proceed directly to :ref:`howto/admin/https`.

View File

@@ -0,0 +1,123 @@
(insatll-digitalocean)=
# Installing on Digital Ocean
## Goal
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
[DigitalOcean](https://digitalocean.com).
## Pre-requisites
1. A DigitalOcean account with a payment method attached.
## Step 1: Installing The Littlest JupyterHub
Let's create the server on which we can run JupyterHub.
1. Log in to [DigitalOcean](https://digitalocean.com). You might need to
attach a credit card or other payment method to your account before you
can proceed with the tutorial.
2. Click the **Create** button on the top right, and select **Droplets** from
the dropdown menu. DigitalOcean calls servers **droplets**.
```{image} ../images/providers/digitalocean/create-menu.png
:alt: Dropdown menu on clicking 'create' in top right corner
```
This takes you to a page titled **Create Droplets** that lets you configure
your server.
3. Under **Choose an image**, select **22.04 x64** under **Ubuntu**.
```{image} ../images/providers/digitalocean/select-image.png
:alt: Select 22.04 x64 image under Ubuntu
```
4. Under **Choose a size**, select the size of the server you want. The default
(4GB RAM, 2CPUs, 24 USD / month) is not a bad start. You can resize your server
later if you need.
Check out our guide on How To [](/howto/admin/resource-estimation) to help pick
how much Memory, CPU & disk space your server needs.
5. Open the **Advanced Options**, and check the box for **Add Initialization scripts**.
```{image} ../images/providers/digitalocean/additional-options.png
:alt: Turn on User Data in advanced options
```
This opens up a textbox where you can enter a script that will be run
when the server is created. We will use this to set up The Littlest JupyterHub
on this server.
6. Copy the text below, and paste it into the user data 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
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
7. Under the **Finalize and create** section, enter a `hostname` that descriptively
identifies this server for you.
```{image} ../images/providers/digitalocean/hostname.png
:alt: Select suitable hostname for your server
```
8. Click the **Create** button! You will be taken to a different screen,
where you can see progress of your server being created.
```{image} ../images/providers/digitalocean/server-create-wait.png
:alt: Server being created
```
9. In a few seconds your server will be created, and you can see the **public IP**
used to access it.
```{image} ../images/providers/digitalocean/server-create-done.png
:alt: Server finished creating, public IP available
```
10. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
11. Check if the installation is complete by copying the **public ip**
of your server, and trying to access it with a browser. This will fail until
the installation is complete, so be patient.
12. When the installation is complete, it should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
13. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
14. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,119 +0,0 @@
.. _insatll/digitalocean:
===========================
Installing on Digital Ocean
===========================
Goal
====
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
`DigitalOcean <https://digitalocean.com>`_.
Pre-requisites
==============
#. A DigitalOcean account with a payment method attached.
Step 1: Installing The Littlest JupyterHub
==========================================
Let's create the server on which we can run JupyterHub.
#. Log in to `DigitalOcean <https://digitalocean.com>`_. You might need to
attach a credit card or other payment method to your account before you
can proceed with the tutorial.
#. Click the **Create** button on the top right, and select **Droplets** from
the dropdown menu. DigitalOcean calls servers **droplets**.
.. image:: ../images/providers/digitalocean/create-menu.png
:alt: Dropdown menu on clicking 'create' in top right corner
This takes you to a page titled **Create Droplets** that lets you configure
your server.
#. Under **Choose an image**, select **18.04 x64** under **Ubuntu**.
.. image:: ../images/providers/digitalocean/select-image.png
:alt: Select 18.04 x64 image under Ubuntu
#. Under **Choose a size**, select the size of the server you want. The default
(4GB RAM, 2CPUs, 20 USD / month) is not a bad start. You can resize your server
later if you need.
Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick
how much Memory, CPU & disk space your server needs.
#. Scroll down to **Select additional options**, and select **User data**.
.. image:: ../images/providers/digitalocean/additional-options.png
:alt: Turn on User Data in additional options
This opens up a textbox where you can enter a script that will be run
when the server is created. We will use this to set up The Littlest JupyterHub
on this server.
#. Copy the text below, and paste it into the user data 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**!
.. code-block:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
#. Under the **Finalize and create** section, enter a ``hostname`` that descriptively
identifies this server for you.
.. image:: ../images/providers/digitalocean/hostname.png
:alt: Select suitable hostname for your server
#. Click the **Create** button! You will be taken to a different screen,
where you can see progress of your server being created.
.. image:: ../images/providers/digitalocean/server-create-wait.png
:alt: Server being created
#. In a few seconds your server will be created, and you can see the **public IP**
used to access it.
.. image:: ../images/providers/digitalocean/server-create-done.png
:alt: Server finished creating, public IP available
#. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
#. Check if the installation is complete by copying the **public ip**
of your server, and trying to access it with a browser. This will fail until
the installation is complete, so be patient.
#. When the installation is complete, it should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

219
docs/install/google.md Normal file
View File

@@ -0,0 +1,219 @@
(install-google)=
# Installing on Google Cloud
## Goal
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
[Google Cloud](https://cloud.google.com/).
## Prerequisites
1. A Google Cloud account. You might use the free credits for trying it out!
## Step 1: Installing The Littlest JupyterHub
Let's create the server on which we can run JupyterHub.
1. Log in to [Google Cloud Console](https://console.cloud.google.com) with
your Google Account.
2. Open the navigation menu by clicking the button with three lines on the top
left corner of the page.
```{image} ../images/providers/google/left-menu-button.png
:alt: Button to open the menu
```
This opens a menu with all the cloud products Google Cloud offers.
3. Under **Compute Engine**, select **VM Instances**.
```{image} ../images/providers/google/vm-instances-menu.png
:alt: Navigation Menu -> Compute Engine -> VM Instances
```
4. If you are using Google Cloud for the first time, you might have to
enable billing. Google will present a screen asking you to enable billing
to proceed. Click the **Enable Billing** button and follow any prompts
that appear.
```{image} ../images/providers/google/enable-billing.png
:alt: Enable billing if needed.
```
It might take a few minutes for your account to be set up.
5. Once Compute Engine is ready, click the **Create** button to start
creating the server that'll run TLJH.
```{image} ../images/providers/google/create-vm-first.png
:alt: Create VM page when using it for the first time.
```
If you already have VMs running in your project, the screen will look
different. But you can find the **Create** button still!
6. This shows you a page titled **Create an instance**. This lets you customize
the kind of server you want, the resources it will have & what it'll be called.
7. Under **Name**, give it a memorable name that identifies what purpose this
JupyterHub will be used for.
8. **Region** specifies the physical location where this server will be hosted.
Generally, pick something close to where most of your users are. Note that
it might increase the cost of your server in some cases!
9. For **Zone**, pick any of the options. Leaving the default as is is fine.
10. Under **Machine** type, select the amount of CPU / RAM / GPU you want for your
server. You need at least **1GB** of RAM.
You can select a preset combination in the default **basic view**.
```{image} ../images/providers/google/machine-type-basic.png
:alt: Select a preset VM type
```
If you want to add **GPUs**, you should click the **Customize** button &
use the **Advanced View**. You need to request [a quota increase](https://cloud.google.com/compute/quotas#gpus)
before you can use GPUs.
```{image} ../images/providers/google/machine-type-advanced.png
:alt: Select a customized VM size
```
Check out our guide on How To [](/howto/admin/resource-estimation) to help pick
how much Memory / CPU your server needs.
11. Under **Boot Disk**, click the **Change** button. This lets us change the
operating system and the size of your disk.
```{image} ../images/providers/google/boot-disk-button.png
:alt: Changing Boot Disk & disk size
```
This should open a **Boot disk** popup.
12. Select **Ubuntu 22.04 LTS** from the list of operating system images.
```{image} ../images/providers/google/boot-disk-ubuntu.png
:alt: Selecting Ubuntu 22.04 for OS
```
13. You can also change the **type** and **size** of your disk at the bottom
of this popup.
```{image} ../images/providers/google/boot-disk-size.png
:alt: Selecting Boot disk type & size
```
**Standard persistent disk** type gives you a slower but cheaper disk, similar
to a hard drive. **SSD persistent disk** gives you a faster but more expensive
disk, similar to an SSD.
Check out our guide on How To [](/howto/admin/resource-estimation) to help pick
how much Disk space your server needs.
14. Click the **Select** button to dismiss the Boot disk popup and go back to the
Create an instance screen.
15. Under **Identity and API access**, select **No service account** for the
**Service account** field. This prevents your JupyterHub users from automatically
accessing other cloud services, increasing security.
```{image} ../images/providers/google/no-service-account.png
:alt: Disable service accounts for the server
```
16. Under **Firewall**, check both **Allow HTTP Traffic** and **Allow HTTPS Traffic**
checkboxes.
```{image} ../images/providers/google/firewall.png
:alt: Allow HTTP & HTTPS traffic to your server
```
17. Click the **Management, disks, networking, SSH keys** link to expand more
options.
```{image} ../images/providers/google/management-button.png
:alt: Expand management options by clicking link.
```
This displays a lot of advanced options, but we'll be only using one of them.
18. Copy the text below, and paste it into the **Startup script** 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
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
```{image} ../images/providers/google/startup-script.png
:alt: Install JupyterHub with the Startup script textbox
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
19. Click the **Create** button at the bottom to start your server!
```{image} ../images/providers/google/create-vm-button.png
:alt: Launch an Instance / Advanced Options dialog box
```
20. We'll be sent to the **VM instances** page, where we can see that our server
is being created.
```{image} ../images/providers/google/vm-creating.png
:alt: Spinner with vm creating
```
21. In a few seconds your server will be created, and you can see the **External IP**
used to access it.
```{image} ../images/providers/google/vm-created.png
:alt: VM created, external IP available
```
22. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
23. Check if the installation is complete by **copying** the **External IP**
of your server, and trying to access it with a browser. Do **not click** on the
IP - this will open the link with HTTPS, and will not work.
Accessing the JupyterHub will also fail until the installation is complete,
so be patient.
24. When the installation is complete, it should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
25. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
26. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,205 +0,0 @@
.. _install/google:
==========================
Installing on Google Cloud
==========================
Goal
====
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
`Google Cloud <https://cloud.google.com/>`_.
Prerequisites
=============
#. A Google Cloud account. You might use the free credits for trying it out!
Step 1: Installing The Littlest JupyterHub
==========================================
Let's create the server on which we can run JupyterHub.
#. Log in to `Google Cloud Console <https://console.cloud.google.com>`_ with
your Google Account.
#. Open the navigation menu by clicking the button with three lines on the top
left corner of the page.
.. image:: ../images/providers/google/left-menu-button.png
:alt: Button to open the menu
This opens a menu with all the cloud products Google Cloud offers.
#. Under **Compute Engine**, select **VM Instances**.
.. image:: ../images/providers/google/vm-instances-menu.png
:alt: Navigation Menu -> Compute Engine -> VM Instances
#. If you are using Google Cloud for the first time, you might have to
enable billing. Google will present a screen asking you to enable billing
to proceed. Click the **Enable Billing** button and follow any prompts
that appear.
.. image:: ../images/providers/google/enable-billing.png
:alt: Enable billing if needed.
It might take a few minutes for your account to be set up.
#. Once Compute Engine is ready, click the **Create** button to start
creating the server that'll run TLJH.
.. image:: ../images/providers/google/create-vm-first.png
:alt: Create VM page when using it for the first time.
If you already have VMs running in your project, the screen will look
different. But you can find the **Create** button still!
#. This shows you a page titled **Create an instance**. This lets you customize
the kind of server you want, the resources it will have & what it'll be called.
#. Under **Name**, give it a memorable name that identifies what purpose this
JupyterHub will be used for.
#. **Region** specifies the physical location where this server will be hosted.
Generally, pick something close to where most of your users are. Note that
it might increase the cost of your server in some cases!
#. For **Zone**, pick any of the options. Leaving the default as is is fine.
#. Under **Machine** type, select the amount of CPU / RAM / GPU you want for your
server. You need at least **1GB** of RAM.
You can select a preset combination in the default **basic view**.
.. image:: ../images/providers/google/machine-type-basic.png
:alt: Select a preset VM type
If you want to add **GPUs**, you should click the **Customize** button &
use the **Advanced View**. You need to request `a quota increase <https://cloud.google.com/compute/quotas#gpus>`_
before you can use GPUs.
.. image:: ../images/providers/google/machine-type-advanced.png
:alt: Select a customized VM size
Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick
how much Memory / CPU your server needs.
#. Under **Boot Disk**, click the **Change** button. This lets us change the
operating system and the size of your disk.
.. image:: ../images/providers/google/boot-disk-button.png
:alt: Changing Boot Disk & disk size
This should open a **Boot disk** popup.
#. Select **Ubuntu 18.04 LTS** from the list of operating system images.
.. image:: ../images/providers/google/boot-disk-ubuntu.png
:alt: Selecting Ubuntu 18.04 for OS
#. You can also change the **type** and **size** of your disk at the bottom
of this popup.
.. image:: ../images/providers/google/boot-disk-size.png
:alt: Selecting Boot disk type & size
**Standard persistent disk** type gives you a slower but cheaper disk, similar
to a hard drive. **SSD persistent disk** gives you a faster but more expensive
disk, similar to an SSD.
Check out our guide on How To :ref:`howto/admin/resource-estimation` to help pick
how much Disk space your server needs.
#. Click the **Select** button to dismiss the Boot disk popup and go back to the
Create an instance screen.
#. Under **Identity and API access**, select **No service account** for the
**Service account** field. This prevents your JupyterHub users from automatically
accessing other cloud services, increasing security.
.. image:: ../images/providers/google/no-service-account.png
:alt: Disable service accounts for the server
#. Under **Firewall**, check both **Allow HTTP Traffic** and **Allow HTTPS Traffic**
checkboxes.
.. image:: ../images/providers/google/firewall.png
:alt: Allow HTTP & HTTPS traffic to your server
#. Click the **Management, disks, networking, SSH keys** link to expand more
options.
.. image:: ../images/providers/google/management-button.png
:alt: Expand management options by clicking link.
This displays a lot of advanced options, but we'll be only using one of them.
#. Copy the text below, and paste it into the **Startup script** 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**!
.. code-block:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
.. image:: ../images/providers/google/startup-script.png
:alt: Install JupyterHub with the Startup script textbox
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
#. Click the **Create** button at the bottom to start your server!
.. image:: ../images/providers/google/create-vm-button.png
:alt: Launch an Instance / Advanced Options dialog box
#. We'll be sent to the **VM instances** page, where we can see that our server
is being created.
.. image:: ../images/providers/google/vm-creating.png
:alt: Spinner with vm creating
#. In a few seconds your server will be created, and you can see the **External IP**
used to access it.
.. image:: ../images/providers/google/vm-created.png
:alt: VM created, external IP available
#. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
#. Check if the installation is complete by **copying** the **External IP**
of your server, and trying to access it with a browser. Do **not click** on the
IP - this will open the link with HTTPS, and will not work.
Accessing the JupyterHub will also fail until the installation is complete,
so be patient.
#. When the installation is complete, it should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

23
docs/install/index.md Normal file
View File

@@ -0,0 +1,23 @@
(install-installing)=
# Installing
The Littlest JupyterHub (TLJH) can run on any server that is running **Debian 11** or **Ubuntu 20.04** or **22.04** on a amd64 or arm64 CPU architecture.
Earlier versions of Ubuntu and Debian are not supported, nor are other Linux distributions.
We have a bunch of tutorials to get you started.
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
servers.
```{toctree}
:titlesonly: true
digitalocean
ovh
jetstream
google
amazon
azure
custom-server
```

View File

@@ -1,24 +0,0 @@
.. _install/installing:
==========
Installing
==========
The Littlest JupyterHub (TLJH) can run on any server that is running at least
**Ubuntu 18.04**. Earlier versions of Ubuntu are not supported.
We have a bunch of tutorials to get you started.
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
servers.
.. toctree::
:titlesonly:
digitalocean
ovh
jetstream
google
amazon
azure
custom-server

152
docs/install/jetstream.md Normal file
View File

@@ -0,0 +1,152 @@
(install-jetstream)=
# Installing on Jetstream
## Goal
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
[Jetstream](https://jetstream-cloud.org/).
## Prerequisites
1. A Jetstream account with an XSEDE allocation; for more information,
see the [Jetstream Allocations help page](http://wiki.jetstream-cloud.org/Jetstream+Allocations).
## Step 1: Installing The Littlest JupyterHub
Let's create the server on which we can run JupyterHub.
1. Log in to [the Jetstream portal](https://use.jetstream-cloud.org/). You need an allocation
to launch instances.
2. Select the **Launch New Instance** option to get going.
```{image} ../images/providers/jetstream/launch-instance-first-button.png
:alt: Launch new instance button with description.
```
This takes you to a page with a list of base images you can choose for your
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
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
9. Under **Execution Strategy Type**, select **Run script on first boot**.
10. Under **Deployment Type**, select **Wait for script to complete**.
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
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
:alt: Instances dashboard showing deployment in progress.
```
15. It will take about ten minutes for your server to come up. The status will
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
browser. It should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
17. Login using the **admin user name** you used in step 8, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
18. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,145 +0,0 @@
.. _install/jetstream:
=======================
Installing on Jetstream
=======================
Goal
====
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
`Jetstream <https://jetstream-cloud.org/>`_.
Prerequisites
=============
#. A Jetstream account with an XSEDE allocation; for more information,
see the `Jetstream Allocations help page <http://wiki.jetstream-cloud.org/Jetstream+Allocations>`_.
Step 1: Installing The Littlest JupyterHub
==========================================
Let's create the server on which we can run JupyterHub.
#. Log in to `the Jetstream portal <https://use.jetstream-cloud.org/>`_. You need an allocation
to launch instances.
#. Select the **Launch New Instance** option to get going.
.. image:: ../images/providers/jetstream/launch-instance-first-button.png
:alt: Launch new instance button with description.
This takes you to a page with a list of base images you can choose for your
server.
#. Under **Image Search**, search for **Ubuntu 18.04**, and select the
**Ubuntu 18.04 Devel and Docker** image.
.. image:: ../images/providers/jetstream/select-image.png
:alt: Select Ubuntu 18.04 x64 image from image list
#. 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
#. 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
#. Give your server a descriptive **Instance Name**.
#. 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 :ref:`howto/admin/resource-estimation` to help pick
how much Memory, CPU & disk space your server needs.
#. If you have multiple allocations, make sure you are 'charging' this server
to the correct allocation.
#. 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.
#. 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
#. 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**!
.. code-block:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
#. Under **Execution Strategy Type**, select **Run script on first boot**.
#. Under **Deployment Type**, select **Wait for script to complete**.
#. Click the **Save and Add Script** button on the bottom right. This should hide
the dialog box.
#. 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.
#. 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
#. You'll now be shown a dashboard with all your servers and their states. The
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
:alt: Instances dashboard showing deployment in progress.
#. It will take about ten minutes for your server to come up. The status will
say **Active** and the progress bar will be a solid green. At this point,
your JupyterHub is ready for use!
#. Copy the **IP Address** of your server, and try accessing it from a web
browser. It should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 8, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

133
docs/install/ovh.md Normal file
View File

@@ -0,0 +1,133 @@
(install-ovh)=
# Installing on OVH
## Goal
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
[OVH](https://www.ovh.com).
## Pre-requisites
1. An OVH account.
## Step 1: Installing The Littlest JupyterHub
Let's create the server on which we can run JupyterHub.
1. Log in to the [OVH Control Panel](https://www.ovh.com/auth/).
2. Click the **Public Cloud** button in the navigation bar.
```{image} ../images/providers/ovh/public-cloud.png
:alt: Public Cloud entry in the navigation bar
```
3. If you don't have an OVH Stack, you can create one by clicking on the following button:
```{image} ../images/providers/ovh/create-ovh-stack.png
:alt: Button to create an OVH stack
```
4. Select a name for the project:
```{image} ../images/providers/ovh/project-name.png
:alt: Select a name for the project
```
5. If you don't have a payment method yet, select one and click on "Create my project":
```{image} ../images/providers/ovh/payment.png
:alt: Select a payment method
```
6. Using the **Public Cloud interface**, click on **Create an instance**:
```{image} ../images/providers/ovh/create-instance.png
:alt: Create a new instance
```
7. **Select a model** for the instance. A good start is the **S1-4** model under **Shared resources** which comes with 4GB RAM, 1 vCores and 20GB SSD.
8. **Select a region**.
9. Select **Ubuntu 22.04** as the image:
```{image} ../images/providers/ovh/distribution.png
:alt: Select Ubuntu 22.04 as the image
```
10. OVH requires setting an SSH key to be able to connect to the instance.
You can create a new SSH by following
[these instructions](https://help.github.com/en/enterprise/2.16/user/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).
Be sure to copy the content of the `~/.ssh/id_rsa.pub` file, which corresponds to the **public part** of the SSH key.
11. Select **Configure your instance**, and select a name for the instance.
Under **Post-installation script**, copy the text below and paste it in the 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
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
```
:::{note}
See [](/topic/installer-actions) if you want to understand exactly what the installer is doing.
[](/topic/customizing-installer) documents other options that can be passed to the installer.
:::
```{image} ../images/providers/ovh/configuration.png
:alt: Add post-installation script
```
12. Select a billing period: monthly or hourly.
13. Click the **Create an instance** button! You will be taken to a different screen,
where you can see progress of your server being created.
```{image} ../images/providers/ovh/create-instance.png
:alt: Select suitable hostname for your server
```
14. In a few seconds your server will be created, and you can see the **public IP**
used to access it.
```{image} ../images/providers/ovh/public-ip.png
:alt: Server finished creating, public IP available
```
15. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
16. Check if the installation is complete by copying the **public ip**
of your server, and trying to access it with a browser. This will fail until
the installation is complete, so be patient.
17. When the installation is complete, it should give you a JupyterHub login page.
```{image} ../images/first-login.png
:alt: JupyterHub log-in page
```
18. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
19. Congratulations, you have a running working JupyterHub!
## Step 2: Adding more users
```{include} add-users.md
```
## Step 3: Install conda / pip packages for all users
```{include} add-packages.md
```

View File

@@ -1,127 +0,0 @@
.. _install/ovh:
=================
Installing on OVH
=================
Goal
====
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
`OVH <https://www.ovh.com>`_.
Pre-requisites
==============
#. An OVH account.
Step 1: Installing The Littlest JupyterHub
==========================================
Let's create the server on which we can run JupyterHub.
#. Log in to the `OVH Control Panel <https://www.ovh.com/auth/>`_.
#. Click the **Public Cloud** button in the navigation bar.
.. image:: ../images/providers/ovh/public-cloud.png
:alt: Public Cloud entry in the navigation bar
#. If you don't have an OVH Stack, you can create one by clicking on the following button:
.. image:: ../images/providers/ovh/create-ovh-stack.png
:alt: Button to create an OVH stack
#. Select a name for the project:
.. image:: ../images/providers/ovh/project-name.png
:alt: Select a name for the project
#. If you don't have a payment method yet, select one and click on "Create my project":
.. image:: ../images/providers/ovh/payment.png
:alt: Select a payment method
#. Using the **Public Cloud interface**, click on **Create an instance**:
.. image:: ../images/providers/ovh/create-instance.png
:alt: Create a new instance
#. **Select a model** for the instance. A good start is the **S1-4** model under **Shared resources** which comes with 4GB RAM, 1 vCores and 20GB SSD.
#. **Select a region**.
#. Select **Ubuntu 18.04** as the image:
.. image:: ../images/providers/ovh/distribution.png
:alt: Select Ubuntu 18.04 as the image
#. OVH requires setting an SSH key to be able to connect to the instance.
You can create a new SSH by following
`these instructions <https://help.github.com/en/enterprise/2.16/user/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent>`_.
Be sure to copy the content of the ``~/.ssh/id_rsa.pub`` file, which corresponds to the **public part** of the SSH key.
#. Select **Configure your instance**, and select a name for the instance.
Under **Post-installation script**, copy the text below and paste it in the 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**!
.. code-block:: bash
#!/bin/bash
curl -L https://tljh.jupyter.org/bootstrap.py \
| sudo python3 - \
--admin <admin-user-name>
.. note::
See :ref:`topic/installer-actions` if you want to understand exactly what the installer is doing.
:ref:`topic/customizing-installer` documents other options that can be passed to the installer.
.. image:: ../images/providers/ovh/configuration.png
:alt: Add post-installation script
#. Select a billing period: monthly or hourly.
#. Click the **Create an instance** button! You will be taken to a different screen,
where you can see progress of your server being created.
.. image:: ../images/providers/ovh/create-instance.png
:alt: Select suitable hostname for your server
#. In a few seconds your server will be created, and you can see the **public IP**
used to access it.
.. image:: ../images/providers/ovh/public-ip.png
:alt: Server finished creating, public IP available
#. The Littlest JupyterHub is now installing in the background on your new server.
It takes around 5-10 minutes for this installation to complete.
#. Check if the installation is complete by copying the **public ip**
of your server, and trying to access it with a browser. This will fail until
the installation is complete, so be patient.
#. When the installation is complete, it should give you a JupyterHub login page.
.. image:: ../images/first-login.png
:alt: JupyterHub log-in page
#. Login using the **admin user name** you used in step 6, and a password. Use a
strong password & note it down somewhere, since this will be the password for
the admin user account from now on.
#. Congratulations, you have a running working JupyterHub!
Step 2: Adding more users
==========================
.. include:: add_users.txt
Step 3: Install conda / pip packages for all users
==================================================
.. include:: add_packages.txt

View File

@@ -1,8 +1,288 @@
# 0.2.0 - 2023-02-27
(changelog)=
# Changelog
## 2.0
### 2.0.0 - 2024-10-21
This release bundles with the latest available software from the JupyterHub
ecosystem.
For instructions on how to make an upgrade, see [](howto-admin-upgrade-tljh).
#### Breaking changes
- JupyterHub 4.\* has been upgraded to >=5.2.0,<6
- Refer to the [JupyterHub changelog] for details and pay attention to the
changelog entry for JupyterHub version 5.0.0.
- OAuthenticator 16.0.4 has been upgraded to >=17.1.0,<18
- If you are using an OAuthenticator based authenticator class
(GitHubOAuthenticator, GoogleOAuthenticator, ...), refer to the
[OAuthenticator changelog] for details and pay attention to the changelog
entry for OAuthenticator version 17.0.0.
- LDAPAuthenticator 1.3.2 has been upgraded to >=2.0.0,<3
- If you are using this authenticator class, refer to the [LDAPAuthenticator
changelog] for details and pay attention to the changelog entry for
LDAPAuthenticator version 2.0.0.
- The configured JupyterHub Proxy class `traefik-proxy` and the `traefik` server
controlled by JupyterHub via the proxy class has been upgraded to a new major
version, but no breaking change are expected to be noticed for users.
[oauthenticator changelog]: https://oauthenticator.readthedocs.io/en/latest/reference/changelog.html
[ldapauthenticator changelog]: https://github.com/jupyterhub/ldapauthenticator/blob/HEAD/CHANGELOG.md
#### Notable dependencies updated
A TLJH installation provides a Python environment where the software for
JupyterHub itself runs - _the hub environment_, and a Python environment where
the software of users runs - _the user environment_.
If you are installing TLJH for the first time, the user environment will be
setup initially with Python 3.12 and some other packages described in
[tljh/requirements-user-env-extras.txt].
If you are upgrading to this version of TLJH, the bare minimum is changed in the
user environment. The hub environment's dependencies are on the other hand
always upgraded to the latest version within the specified version range defined
in [tljh/requirements-hub-env.txt] and seen below.
[tljh/requirements-user-env-extras.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/2.0.0/tljh/requirements-user-env-extras.txt
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/2.0.0/tljh/requirements-hub-env.txt
The changes in the respective environments between TLJH version 1.0.0 and 2.0.0
are summarized below.
| Dependency changes in the _hub environment_ | Version in 1.0.0 | Version in 2.0.0 | Changelog link | Note |
| ------------------------------------------------------------------------------ | ---------------- | ---------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | >=4.0.2,<5 | >=5.2.0,<6 | [Changelog](https://jupyterhub.readthedocs.io/en/stable/reference/changelog.html) | Running in the `jupyterhub` systemd service |
| [traefik](https://github.com/traefik/traefik) | 2.10.1 | 3.1.4 | [Changelog](https://github.com/traefik/traefik/blob/master/CHANGELOG.md) | Running in the `traefik` systemd service |
| [traefik-proxy](https://github.com/jupyterhub/traefik-proxy) | >=1.1.0,<2 | 2.\* | [Changelog](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/changelog.html) | Run by jupyterhub, controls `traefik` |
| [systemdspawner](https://github.com/jupyterhub/systemdspawner) | >=1.0.1,<2 | >=1.0.2,<2 | [Changelog](https://github.com/jupyterhub/systemdspawner/blob/master/CHANGELOG.md) | Run by jupyterhub, controls user servers via systemd |
| [jupyterhub-idle-culler](https://github.com/jupyterhub/jupyterhub-idle-culler) | >=1.2.1,<2 | >=1.4.0,<2 | [Changelog](https://github.com/jupyterhub/jupyterhub-idle-culler/blob/main/CHANGELOG.md) | Run by jupyterhub, stops inactivate servers etc. |
| [firstuseauthenticator](https://github.com/jupyterhub/firstuseauthenticator) | >=1.0.0,<2 | 1.1.0,<2 | [Changelog](https://oauthenticator.readthedocs.io/en/latest/reference/changelog.html) | An optional way to authenticate users |
| [tmpauthenticator](https://github.com/jupyterhub/tmpauthenticator) | >=1.0.0,<2 | 1.0.0,<2 | [Changelog](https://github.com/jupyterhub/tmpauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [nativeauthenticator](https://github.com/jupyterhub/nativeauthenticator) | >=1.2.0,<2 | >=1.3.0,<2 | [Changelog](https://github.com/jupyterhub/nativeauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [oauthenticator](https://github.com/jupyterhub/oauthenticator) | >=16.0.4,<17 | >=17.1.0,<18 | [Changelog](https://oauthenticator.readthedocs.io/en/latest/reference/changelog.html) | An optional way to authenticate users |
| [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) | >=1.3.2,<2 | ==2.0.0 | [Changelog](https://github.com/jupyterhub/ldapauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [pip](https://github.com/pypa/pip) | >=23.1.2 | >=23.1.2 | [Changelog](https://pip.pypa.io/en/stable/news/) | - |
| Dependency changes in the _user environment_ | Version in 1.0.0 | Version in upgrade to 2.0.0 | Version in fresh install of 2.0.0 | Changelog link | Note |
| -------------------------------------------------------- | ---------------- | --------------------------- | --------------------------------- | --------------------------------------------------------------------------------- | ------------------------ |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | >=4.0.2,<5 | >=5.2.0,<6 | >=5.2.0,<6 | [Changelog](https://jupyterhub.readthedocs.io/en/stable/reference/changelog.html) | Always upgraded. |
| [pip](https://github.com/pypa/pip) | >=23.1.2 | >=23.1.2 | >=24.2 | [Changelog](https://pip.pypa.io/en/stable/news/) | Only upgraded if needed. |
| [conda](https://docs.conda.io/projects/conda/en/stable/) | >=4.10.0 | >=4.10.0 | ==24.7.1 | [Changelog](https://docs.conda.io/projects/conda/en/stable/release-notes.html) | Only upgraded if needed. |
| [mamba](https://mamba.readthedocs.io/en/latest/) | >=0.16.0 | >=0.16.0 | ==1.5.9 | [Changelog](https://github.com/mamba-org/mamba/blob/main/CHANGELOG.md) | Only upgraded if needed. |
#### New features added
- jupyterhub 5 [#989](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/989) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- Validate tljh specific config [#962](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/962) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Add the ability to define conda channels in plugins via `tljh_extra_user_conda_channels` [#942](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/942) ([@yuvipanda](https://github.com/yuvipanda), [@consideRatio](https://github.com/consideRatio))
#### Bugs fixed
- hub env: avoid installing pycurl using wheel with an issue [#1006](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1006) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- fix `-m` invocation of jupyterhub [#988](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/988) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- Re-install conda/mamba for every tljh upgrade (doesn't imply upgrade) [#968](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/968) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Add missing oauthenticator dependency for AzureADOAuthenticator [#959](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/959) ([@consideRatio](https://github.com/consideRatio))
#### Maintenance and upkeep improvements
- Update jupyterhub pinning to >=5.2.0,<6 from ==5.1.0 [#1008](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1008) ([@consideRatio](https://github.com/consideRatio))
- hub env: pin to jupyterhub 5.1.0 [#1007](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1007) ([@consideRatio](https://github.com/consideRatio))
- hub env: bump to ldapauthenticator 2.0.0 and other lower bounds [#1004](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1004) ([@consideRatio](https://github.com/consideRatio))
- Bump the requirements-user-env-extras.txt lower version bounds [#1002](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1002) ([@consideRatio](https://github.com/consideRatio))
- Update traefik from 2.10.1 to 3.1.4 [#1001](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1001) ([@consideRatio](https://github.com/consideRatio))
- Update to install miniforge 24.7.1-2 from 24.7.1-0 [#999](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/999) ([@consideRatio](https://github.com/consideRatio))
- Drop ubuntu 20.04, require py39, traefik-proxy v2, and ldapauthenticator v2 [#998](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/998) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- consolidate lock file handling [#994](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/994) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@jrdnbradford](https://github.com/jrdnbradford))
- update oauthenticator to 17 [#992](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/992) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- Update base user environment to miniforge 24.7.1-0 (Python 3.12) [#990](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/990) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- Add TLJH config lockfile [#976](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/976) ([@jrdnbradford](https://github.com/jrdnbradford), [@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- tests: fix to catch test failure earlier when they really happen [#975](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/975) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
#### Documentation improvements
- Remove mention about beta state [#1009](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1009) ([@consideRatio](https://github.com/consideRatio))
- Added missing details on how to add custom domain from manual HTTPS configuration [#983](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/983) ([@josedaudi](https://github.com/josedaudi), [@yuvipanda](https://github.com/yuvipanda))
- Reword documentation sentence [#970](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/970) ([@davidalber](https://github.com/davidalber), [@consideRatio](https://github.com/consideRatio))
- Fix typo and replace word [#969](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/969) ([@davidalber](https://github.com/davidalber), [@consideRatio](https://github.com/consideRatio))
- Fix URL syntax in nativeauth.md [#949](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/949) ([@pdebuyl](https://github.com/pdebuyl), [@minrk](https://github.com/minrk))
- adapt install documentation for new /lab default interface [#935](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/935) ([@schwebke](https://github.com/schwebke), [@minrk](https://github.com/minrk))
#### Continuous integration improvements
- Test upgrade from 1.\* [#1003](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/1003) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- ci: cache pip only when no container is used [#997](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/997) ([@consideRatio](https://github.com/consideRatio))
- ci: run unit tests in ubuntu-24.04 github actions environment as well [#993](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/993) ([@consideRatio](https://github.com/consideRatio))
- ci: add tests for debian 12 and ubuntu 24.04 [#967](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/967) ([@consideRatio](https://github.com/consideRatio))
- build(deps): bump actions/cache from 3 to 4 [#961](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/961) ([@consideRatio](https://github.com/consideRatio))
- build(deps): bump codecov/codecov-action from 3 to 4 [#960](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/960) ([@consideRatio](https://github.com/consideRatio))
- build(deps): bump actions/setup-python from 4 to 5 [#958](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/958) ([@consideRatio](https://github.com/consideRatio))
- build(deps): bump actions/checkout from 3 to 4 [#943](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/943) ([@consideRatio](https://github.com/consideRatio))
## Contributors to this release
The following people contributed discussions, new ideas, code and documentation contributions, and review.
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
([GitHub contributors page for this release](https://github.com/jupyterhub/the-littlest-jupyterhub/graphs/contributors?from=2023-08-11&to=2024-10-21&type=c))
@consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AconsideRatio+updated%3A2023-08-11..2024-10-21&type=Issues)) | @davidalber ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Adavidalber+updated%3A2023-08-11..2024-10-21&type=Issues)) | @josedaudi ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajosedaudi+updated%3A2023-08-11..2024-10-21&type=Issues)) | @jrdnbradford ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajrdnbradford+updated%3A2023-08-11..2024-10-21&type=Issues)) | @kiliansinger ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Akiliansinger+updated%3A2023-08-11..2024-10-21&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Amanics+updated%3A2023-08-11..2024-10-21&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aminrk+updated%3A2023-08-11..2024-10-21&type=Issues)) | @MridulS ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AMridulS+updated%3A2023-08-11..2024-10-21&type=Issues)) | @pdebuyl ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Apdebuyl+updated%3A2023-08-11..2024-10-21&type=Issues)) | @schwebke ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aschwebke+updated%3A2023-08-11..2024-10-21&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ayuvipanda+updated%3A2023-08-11..2024-10-21&type=Issues))
## 1.0
### 1.0.0 - 2023-08-11
This release bundles with the latest available software from the JupyterHub
ecosystem.
The TLJH project now has tests to verify upgrades of installations between
releases and procedures with automation to make releases. Going onwards, TLJH
installations of version 0.2.0 and later are meant to be easy to upgrade.
For instructions on how to make an upgrade, see [](howto-admin-upgrade-tljh).
#### Breaking changes
- JupyterHub 1.\* has been upgraded to >=4.0.2,<5
- This upgrade requires user servers to be restarted if they were running
during the upgrade.
- Refer to the [JupyterHub changelog] for details where you pay attention to
the entries for JupyterHub version 2.0.0, 3.0.0, and 4.0.0.
- Several JupyterHub Authenticators has been upgraded a major version, inspect
the changelog for the authenticator class your installation makes use of. For
links to the changelogs, see the section below.
- The configured JupyterHub Proxy class `traefik-proxy` and the `traefik` server
controlled by JupyterHub via the proxy class has been upgraded to a new major
version, but no breaking change are expected to be noticed for users of this
distribution.
- The configured JupyterHub Spawner class `jupyterhub-systemdspawner` has been
upgraded to a new major version, but no breaking change are expected to be
noticed for users of this distribution.
- User servers now launch into `/lab` by default, to revert this a JupyterHub
admin user can do `sudo tljh-config set user_environment.default_app classic`
or set the JupyterHub config `c.Spawner.default_url` directly.
[jupyterhub changelog]: https://jupyterhub.readthedocs.io/en/stable/changelog.html
#### Notable dependencies updated
A TLJH installation provides a Python environment where the software for
JupyterHub itself runs - _the hub environment_, and a Python environment where the
software of users runs - _the user environment_.
If you are installing TLJH for the first time, the user environment will be
setup initially with Python 3.10 and some other packages described in
[tljh/requirements-user-env-extras.txt].
If you are upgrading to this version of TLJH, the bare minimum is changed in the
user environment. The hub environment's dependencies are on the other hand
always upgraded to the latest version within the specified version range defined
in [tljh/requirements-hub-env.txt] and seen below.
[tljh/requirements-user-env-extras.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/1.0.0/tljh/requirements-user-env-extras.txt
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/1.0.0/tljh/requirements-hub-env.txt
The changes in the respective environments between TLJH version 0.2.0 and 1.0.0
are summarized below.
| Dependency changes in the _hub environment_ | Version in 0.2.0 | Version in 1.0.0 | Changelog link | Note |
| ------------------------------------------------------------------------------ | ---------------- | ---------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | 1.\* | >=4.0.2,<5 | [Changelog](https://jupyterhub.readthedocs.io/en/stable/reference/changelog.html) | Running in the `jupyterhub` systemd service |
| [traefik](https://github.com/traefik/traefik) | 1.7.33 | 2.10.1 | [Changelog](https://github.com/traefik/traefik/blob/master/CHANGELOG.md) | Running in the `traefik` systemd service |
| [traefik-proxy](https://github.com/jupyterhub/traefik-proxy) | 0.3.\* | >=1.1.0,<2 | [Changelog](https://jupyterhub-traefik-proxy.readthedocs.io/en/latest/changelog.html) | Run by jupyterhub, controls `traefik` |
| [systemdspawner](https://github.com/jupyterhub/systemdspawner) | 0.16.\* | >=1.0.1,<2 | [Changelog](https://github.com/jupyterhub/systemdspawner/blob/master/CHANGELOG.md) | Run by jupyterhub, controls user servers via systemd |
| [jupyterhub-idle-culler](https://github.com/jupyterhub/jupyterhub-idle-culler) | 1.\* | >=1.2.1,<2 | [Changelog](https://github.com/jupyterhub/jupyterhub-idle-culler/blob/main/CHANGELOG.md) | Run by jupyterhub, stops inactivate servers etc. |
| [firstuseauthenticator](https://github.com/jupyterhub/firstuseauthenticator) | 1.\* | >=1.0.0,<2 | [Changelog](https://oauthenticator.readthedocs.io/en/latest/reference/changelog.html) | An optional way to authenticate users |
| [tmpauthenticator](https://github.com/jupyterhub/tmpauthenticator) | 0.6.\* | >=1.0.0,<2 | [Changelog](https://github.com/jupyterhub/tmpauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [nativeauthenticator](https://github.com/jupyterhub/nativeauthenticator) | 1.\* | >=1.2.0,<2 | [Changelog](https://github.com/jupyterhub/nativeauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [oauthenticator](https://github.com/jupyterhub/oauthenticator) | 14.\* | >=16.0.4,<17 | [Changelog](https://oauthenticator.readthedocs.io/en/latest/reference/changelog.html) | An optional way to authenticate users |
| [ldapauthenticator](https://github.com/jupyterhub/ldapauthenticator) | 1.\* | >=1.3.2,<2 | [Changelog](https://github.com/jupyterhub/ldapauthenticator/blob/HEAD/CHANGELOG.md) | An optional way to authenticate users |
| [pip](https://github.com/pypa/pip) | 21.3.\* | >=23.1.2 | [Changelog](https://pip.pypa.io/en/stable/news/) | - |
| Dependency changes in the _user environment_ | Version in 0.2.0 | Version in 1.0.0 | Changelog link | Note |
| -------------------------------------------------------- | ---------------- | ---------------- | --------------------------------------------------------------------------------- | ------------------------ |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | 1.\* | >=4.0.2,<5 | [Changelog](https://jupyterhub.readthedocs.io/en/stable/reference/changelog.html) | Always upgraded. |
| [pip](https://github.com/pypa/pip) | \* | >=23.1.2 | [Changelog](https://pip.pypa.io/en/stable/news/) | Only upgraded if needed. |
| [conda](https://docs.conda.io/projects/conda/en/stable/) | 0.16.0 | >=0.16.0 | [Changelog](https://docs.conda.io/projects/conda/en/stable/release-notes.html) | Only upgraded if needed. |
| [mamba](https://mamba.readthedocs.io/en/latest/) | 4.10.3 | >=4.10.0 | [Changelog](https://github.com/mamba-org/mamba/blob/main/CHANGELOG.md) | Only upgraded if needed. |
#### New features added
- Add http[s].address config to control where traefik listens [#905](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/905) ([@nsurleraux-railnova](https://github.com/nsurleraux-railnova), [@minrk](https://github.com/minrk))
- Add support for debian >=10 to bootstrap.py [#800](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/800) ([@jochym](https://github.com/jochym), [@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics), [@yuvipanda](https://github.com/yuvipanda))
#### Enhancements made
- added `remove_named_servers` setting for jupyterhub-idle-culler [#881](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/881) ([@consideRatio](https://github.com/consideRatio))
- Traefik v2, TraefikProxy v1 [#861](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/861) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@MridulS](https://github.com/MridulS))
#### Maintenance and upkeep improvements
- Update Notebook, JupyterLab, Jupyter Resource Usage [#928](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/928) ([@jtpio](https://github.com/jtpio), [@consideRatio](https://github.com/consideRatio))
- Launch into `/lab` by default by changing TLJH config's default value [#775](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/775) ([@raybellwaves](https://github.com/raybellwaves), [@consideRatio](https://github.com/consideRatio), [@GeorgianaElena](https://github.com/GeorgianaElena), [@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- breaking: update oauthenticator from 15.1.0 to >=16.0.2,<17, make tljh auth docs link out [#924](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/924) ([@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- test refactor: add comment about python/conda/mamba [#921](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/921) ([@consideRatio](https://github.com/consideRatio))
- --force-reinstall old conda to ensure it's working before we try to install conda packages [#920](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/920) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- test refactor: put bootstrap tests in an isolated job, save ~3 min in each of the integration test jobs [#919](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/919) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- maint: refactor tests, fix upgrade tests (now correctly failing) [#916](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/916) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Update systemdspawner from version 0.17.\* to >=1.0.1,<2 [#915](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/915) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- Fix recently introduced failure to upper bound systemdspawner [#914](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/914) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Stop bundling jupyterhub-configurator which has been disabled by default [#912](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/912) ([@consideRatio](https://github.com/consideRatio), [@GeorgianaElena](https://github.com/GeorgianaElena), [@yuvipanda](https://github.com/yuvipanda))
- Update nativeauthenticator, tmpauthenticator, and jupyterhub-configurator [#900](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/900) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- ensure hub env is on $PATH in jupyterhub service [#895](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/895) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics))
- pre-commit: add isort and autoflake [#893](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/893) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Upgrade pip in hub env from 21.3 to to 23.1 when bootstrap script runs [#892](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/892) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- pre-commit.ci configured to update pre-commit hooks on a monthly basis [#891](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/891) ([@consideRatio](https://github.com/consideRatio))
- Only upgrade jupyterhub in user env when upgrading tljh, ensure pip>=23.1.2 in user env [#890](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/890) ([@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
- add integration test for hub version [#886](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/886) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- update: jupyterhub 4 [#880](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/880) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- maint: add upgrade test from main branch, latest release, and 0.2.0 [#876](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/876) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- dependabot: monthly updates of github actions [#871](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/871) ([@consideRatio](https://github.com/consideRatio))
- maint: remove deprecated nteract-on-jupyter [#869](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/869) ([@consideRatio](https://github.com/consideRatio), [@yuvipanda](https://github.com/yuvipanda))
- avoid registering duplicate log handlers [#862](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/862) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio))
- bump version to 1.0.0.dev0 [#859](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/859) ([@minrk](https://github.com/minrk), [@manics](https://github.com/manics))
- Update base user environment to mambaforge 23.1.0-1 (Python 3.10) [#858](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/858) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics))
- require ubuntu 20.04, test on debian 11, require Python 3.8 [#856](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/856) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@manics](https://github.com/manics))
- update: jupyterhub 3, oauthenticator 15, systemdspawner 0.17 (user env: ipywidgets 8) [#842](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/842) ([@yuvipanda](https://github.com/yuvipanda), [@manics](https://github.com/manics), [@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Release 0.2.0 (JupyterHub 1.\*) [#838](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/838) ([@manics](https://github.com/manics), [@minrk](https://github.com/minrk))
#### Documentation improvements
- docs: add docs about environments and upgrades [#932](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/932) ([@consideRatio](https://github.com/consideRatio), [@minrk](https://github.com/minrk))
- Add `JupyterLab` setting overrides docs [#922](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/922) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio))
- Quote `pwd` to prevent error if dir has spaces [#917](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/917) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio))
- Google Cloud troubleshooting and configuration updates [#906](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/906) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio))
- Add user env doc files [#902](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/902) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio))
- Update Google auth docs [#898](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/898) ([@jrdnbradford](https://github.com/jrdnbradford), [@consideRatio](https://github.com/consideRatio))
- docs: disable navigation with arrow keys [#896](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/896) ([@MridulS](https://github.com/MridulS), [@consideRatio](https://github.com/consideRatio))
- docs(awscognito): add custom claims example [#887](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/887) ([@consideRatio](https://github.com/consideRatio))
- Docs: Update DigitalOcean install instructions with new screenshot for "user data" [#883](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/883) ([@audiodude](https://github.com/audiodude), [@consideRatio](https://github.com/consideRatio))
- Typo : username -> admin-user-name [#879](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/879) ([@Rom1deTroyes](https://github.com/Rom1deTroyes), [@consideRatio](https://github.com/consideRatio))
- docs: fix readme badge for tests [#878](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/878) ([@consideRatio](https://github.com/consideRatio))
- docs: fix remaining issues following rst to myst transition [#870](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/870) ([@consideRatio](https://github.com/consideRatio))
- docs: transition from rst to myst markdown using rst2myst [#863](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/863) ([@minrk](https://github.com/minrk), [@consideRatio](https://github.com/consideRatio), [@jrdnbradford](https://github.com/jrdnbradford))
- Typo in user-environment.rst [#849](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/849) ([@jawiv](https://github.com/jawiv), [@minrk](https://github.com/minrk))
- Recommend Ubuntu 22.04 in docs [#843](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/843) ([@adonm](https://github.com/adonm), [@consideRatio](https://github.com/consideRatio))
#### Contributors to this release
The following people contributed discussions, new ideas, code and documentation contributions, and review.
See [our definition of contributors](https://github-activity.readthedocs.io/en/latest/#how-does-this-tool-define-contributions-in-the-reports).
([GitHub contributors page for this release](https://github.com/jupyterhub/the-littlest-jupyterhub/graphs/contributors?from=2023-02-27&to=2023-08-11&type=c))
@adonm ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aadonm+updated%3A2023-02-27..2023-08-11&type=Issues)) | @audiodude ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aaudiodude+updated%3A2023-02-27..2023-08-11&type=Issues)) | @choldgraf ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Acholdgraf+updated%3A2023-02-27..2023-08-11&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AconsideRatio+updated%3A2023-02-27..2023-08-11&type=Issues)) | @eingemaischt ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aeingemaischt+updated%3A2023-02-27..2023-08-11&type=Issues)) | @GeorgianaElena ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AGeorgianaElena+updated%3A2023-02-27..2023-08-11&type=Issues)) | @Hannnsen ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AHannnsen+updated%3A2023-02-27..2023-08-11&type=Issues)) | @jawiv ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajawiv+updated%3A2023-02-27..2023-08-11&type=Issues)) | @jochym ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajochym+updated%3A2023-02-27..2023-08-11&type=Issues)) | @jrdnbradford ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajrdnbradford+updated%3A2023-02-27..2023-08-11&type=Issues)) | @jtpio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajtpio+updated%3A2023-02-27..2023-08-11&type=Issues)) | @kevmk04 ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Akevmk04+updated%3A2023-02-27..2023-08-11&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Amanics+updated%3A2023-02-27..2023-08-11&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aminrk+updated%3A2023-02-27..2023-08-11&type=Issues)) | @MridulS ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AMridulS+updated%3A2023-02-27..2023-08-11&type=Issues)) | @nsurleraux-railnova ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ansurleraux-railnova+updated%3A2023-02-27..2023-08-11&type=Issues)) | @raybellwaves ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Araybellwaves+updated%3A2023-02-27..2023-08-11&type=Issues)) | @Rom1deTroyes ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3ARom1deTroyes+updated%3A2023-02-27..2023-08-11&type=Issues)) | @wjcapehart ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Awjcapehart+updated%3A2023-02-27..2023-08-11&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ayuvipanda+updated%3A2023-02-27..2023-08-11&type=Issues))
## 0.2.0
### 0.2.0 - 2023-02-27
([full changelog](https://github.com/jupyterhub/the-littlest-jupyterhub/compare/4a74ad17a1a19f6378efe12a01ba634ed90f1e03...0.2.0))
## Merged PRs
#### Merged PRs
- Fix broken CI [#851](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/851) ([@pnasrat](https://github.com/pnasrat))
- Ensure SQLAlchemy 1.x used for hub [#848](https://github.com/jupyterhub/the-littlest-jupyterhub/pull/848) ([@pnasrat](https://github.com/pnasrat))

10
docs/reference/index.md Normal file
View File

@@ -0,0 +1,10 @@
# Reference
The reference documentation is meant to provide narrowly scoped technical
descriptions that other documentation can link to for details.
```{toctree}
:titlesonly: true
changelog
```

View File

@@ -1,3 +1,4 @@
myst-parser>=0.19
pydata-sphinx-theme
# Sphix 6.0.0 breaks pydata-sphinx-theme
# See pydata/pydata-sphinx-theme#1094

View File

@@ -0,0 +1,89 @@
(topic-authenticator-configuration)=
# Configuring JupyterHub authenticators
Any [JupyterHub authenticator](https://github.com/jupyterhub/jupyterhub/wiki/Authenticators)
can be used with TLJH. A number of them ship by default with TLJH:
1. [OAuthenticator](https://github.com/jupyterhub/oauthenticator) - Google, GitHub, CILogon,
GitLab, Globus, Mediawiki, auth0, generic OpenID connect (for KeyCloak, etc) and other
OAuth based authentication methods.
2. [LDAPAuthenticator](https://github.com/jupyterhub/ldapauthenticator) - LDAP & Active Directory.
3. [DummyAuthenticator](https://github.com/yuvipanda/jupyterhub-dummy-authenticator) - Any username,
one shared password. A [how-to guide on using DummyAuthenticator](howto-auth-dummy) is also
available.
4. [FirstUseAuthenticator](https://github.com/yuvipanda/jupyterhub-firstuseauthenticator) - Users set
their password when they log in for the first time. Default authenticator used in TLJH.
5. [TmpAuthenticator](https://github.com/jupyterhub/tmpauthenticator) - Opens the JupyterHub to the
world, makes a new user every time someone logs in.
6. [NativeAuthenticator](https://native-authenticator.readthedocs.io/en/latest/) - Allow users to signup, add password security verification and block users after failed attempts oflogin.
We try to have specific how-to guides & tutorials for common authenticators. Since we can not cover
everything, this guide shows you how to use any authenticator you want with JupyterHub by following
the authenticator's documentation.
## Setting authenticator properties
JupyterHub authenticators are customized by setting _traitlet properties_. In the authenticator's
documentation, you will find these are usually represented as:
```python
c.<AuthenticatorName>.<property-name> = <some-value>
```
You can set these with `tljh-config` with:
```bash
sudo tljh-config set auth.<AuthenticatorName>.<property-name> <some-value>
```
### Example
[LDAPAuthenticator's documentation](https://github.com/jupyterhub/ldapauthenticator#required-configuration)
lists the various configuration options you can set for LDAPAuthenticator.
When the documentation asks you to set `LDAPAuthenticator.server_address`
to some value, you can do that with the following command:
```bash
sudo tljh-config set auth.LDAPAuthenticator.server_address 'my-ldap-server'
```
Most authenticators require you set multiple configuration options before you can
enable them. Read the authenticator's documentation carefully for more information.
## Enabling the authenticator
Once you have configured the authenticator as you want, you should then
enable it. Usually, the documentation for the authenticator would ask you to add
something like the following to your `jupyterhub_config.py` to enable it:
```python
c.JupyterHub.authenticator_class = 'fully-qualified-authenticator-name'
```
You can accomplish the same with `tljh-config`:
```bash
sudo tljh-config set auth.type <fully-qualified-authenticator-name>
```
Once enabled, you need to reload JupyterHub for the config to take effect.
```bash
sudo tljh-config reload
```
Try logging in a separate incognito window to check if your configuration works. This
lets you preserve your terminal in case there were errors. If there are
errors, [](/troubleshooting/logs) should help you debug them.
### Example
From the [documentation](https://github.com/jupyterhub/ldapauthenticator#usage) for
LDAPAuthenticator, we see that the fully qualified name is `ldapauthenticator.LDAPAuthenticator`.
Assuming you have already configured it, the following commands enable LDAPAuthenticator.
```bash
sudo tljh-config set auth.type ldapauthenticator.LDAPAuthenticator
sudo tljh-config reload
```

View File

@@ -1,95 +0,0 @@
.. _topic/authenticator-configuration:
=====================================
Configuring JupyterHub authenticators
=====================================
Any `JupyterHub authenticator <https://github.com/jupyterhub/jupyterhub/wiki/Authenticators>`_
can be used with TLJH. A number of them ship by default with TLJH:
#. `OAuthenticator <https://github.com/jupyterhub/oauthenticator>`_ - Google, GitHub, CILogon,
GitLab, Globus, Mediawiki, auth0, generic OpenID connect (for KeyCloak, etc) and other
OAuth based authentication methods.
#. `LDAPAuthenticator <https://github.com/jupyterhub/ldapauthenticator>`_ - LDAP & Active Directory.
#. `DummyAuthenticator <https://github.com/yuvipanda/jupyterhub-dummy-authenticator>`_ - Any username,
one shared password. A :ref:`how-to guide on using DummyAuthenticator <howto/auth/dummy>` is also
available.
#. `FirstUseAuthenticator <https://github.com/yuvipanda/jupyterhub-firstuseauthenticator>`_ - Users set
their password when they log in for the first time. Default authenticator used in TLJH.
#. `TmpAuthenticator <https://github.com/jupyterhub/tmpauthenticator>`_ - Opens the JupyterHub to the
world, makes a new user every time someone logs in.
#. `NativeAuthenticator <https://native-authenticator.readthedocs.io/en/latest/>`_ - Allow users to signup, add password security verification and block users after failed attempts oflogin.
We try to have specific how-to guides & tutorials for common authenticators. Since we can not cover
everything, this guide shows you how to use any authenticator you want with JupyterHub by following
the authenticator's documentation.
Setting authenticator properties
================================
JupyterHub authenticators are customized by setting *traitlet properties*. In the authenticator's
documentation, you will find these are usually represented as:
.. code-block:: python
c.<AuthenticatorName>.<property-name> = <some-value>
You can set these with ``tljh-config`` with:
.. code-block:: bash
sudo tljh-config set auth.<AuthenticatorName>.<property-name> <some-value>
Example
-------
`LDAPAuthenticator's documentation <https://github.com/jupyterhub/ldapauthenticator#required-configuration>`_
lists the various configuration options you can set for LDAPAuthenticator.
When the documentation asks you to set ``LDAPAuthenticator.server_address``
to some value, you can do that with the following command:
.. code-block:: bash
sudo tljh-config set auth.LDAPAuthenticator.server_address 'my-ldap-server'
Most authenticators require you set multiple configuration options before you can
enable them. Read the authenticator's documentation carefully for more information.
Enabling the authenticator
==========================
Once you have configured the authenticator as you want, you should then
enable it. Usually, the documentation for the authenticator would ask you to add
something like the following to your ``jupyterhub_config.py`` to enable it:
.. code-block:: python
c.JupyterHub.authenticator_class = 'fully-qualified-authenticator-name'
You can accomplish the same with ``tljh-config``:
.. code-block:: bash
sudo tljh-config set auth.type <fully-qualified-authenticator-name>
Once enabled, you need to reload JupyterHub for the config to take effect.
.. code-block:: bash
sudo tljh-config reload
Try logging in a separate incognito window to check if your configuration works. This
lets you preserve your terminal in case there were errors. If there are
errors, :ref:`troubleshooting/logs` should help you debug them.
Example
-------
From the `documentation <https://github.com/jupyterhub/ldapauthenticator#usage>`_ for
LDAPAuthenticator, we see that the fully qualified name is ``ldapauthenticator.LDAPAuthenticator``.
Assuming you have already configured it, the following commands enable LDAPAuthenticator.
.. code-block:: bash
sudo tljh-config set auth.type ldapauthenticator.LDAPAuthenticator
sudo tljh-config reload

Some files were not shown because too many files have changed in this diff Show More