170 Commits

Author SHA1 Message Date
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
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
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
59 changed files with 993 additions and 289 deletions

View File

@@ -10,7 +10,7 @@ GIT_REPO_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
TEST_IMAGE_NAME = "test-systemd"
@functools.lru_cache()
@functools.lru_cache
def _get_container_runtime_cli():
runtimes = ["docker", "podman"]
for runtime in runtimes:
@@ -167,15 +167,23 @@ def run_test(
command = f"python3 /srv/src/bootstrap/bootstrap.py --version={upgrade_from}"
run_command(container_name, command)
# show user environment
command = "/opt/tljh/user/bin/mamba list"
run_command(container_name, command)
command = f"python3 /srv/src/bootstrap/bootstrap.py {' '.join(installer_args)}"
run_command(container_name, command)
# 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
command = "/opt/tljh/hub/bin/python3 -m pip install -r /srv/src/integration-tests/requirements.txt"
run_command(container_name, command)
# show environment
# show hub environment
command = "/opt/tljh/hub/bin/python3 -m pip freeze"
run_command(container_name, command)

View File

@@ -36,12 +36,15 @@ jobs:
- name: "Debian 11, Py 3.9"
distro_image: "debian:11"
extra_flags: ""
- name: "Ubuntu 20.04, Py 3.8"
distro_image: "ubuntu:20.04"
- 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
@@ -51,10 +54,13 @@ jobs:
- 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: "3.10"
@@ -116,10 +122,13 @@ jobs:
distro_image: "ubuntu:22.04"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- 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,

View File

@@ -46,40 +46,29 @@ jobs:
- 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
run: |
pip install -r dev-requirements.txt
@@ -93,4 +82,4 @@ jobs:
run: pytest tests
timeout-minutes: 15
- uses: codecov/codecov-action@v3
- uses: codecov/codecov-action@v4

View File

@@ -11,18 +11,18 @@
repos:
# Autoformat: Python code, syntax patterns are modernized
- repo: https://github.com/asottile/pyupgrade
rev: v3.8.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.2.0
rev: v2.3.1
hooks:
- id: autoflake
# args ref: https://github.com/PyCQA/autoflake#advanced-usage
@@ -31,25 +31,25 @@ repos:
# Autoformat: Python code
- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
# Autoformat: Python code
- repo: https://github.com/psf/black
rev: 23.3.0
rev: 24.8.0
hooks:
- id: black
# Autoformat: markdown, yaml
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.0-alpha.9-for-vscode
rev: v4.0.0-alpha.8
hooks:
- id: prettier
# Misc...
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.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.
@@ -64,7 +64,7 @@ repos:
# Lint: Python code
- repo: https://github.com/pycqa/flake8
rev: "6.0.0"
rev: "7.1.1"
hooks:
- id: flake8

View File

@@ -9,10 +9,10 @@ This script is run as:
Constraints:
- The entire script should be compatible with Python 3.8, which is the default on
Ubuntu 20.04.
- The script should parse in Python 3.6 as we print error messages for using
Ubuntu 18.04 which comes with Python 3.6 by default.
- 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.
@@ -42,6 +42,7 @@ Command line flags, from "bootstrap.py --help":
can also pass a branch name such as 'main' or a
commit hash.
"""
import logging
import multiprocessing
import os
@@ -209,22 +210,22 @@ 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 20.04+ or Debian 11+
# Require Ubuntu 22.04+ or Debian 11+
distro = get_os_release_variable("ID")
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 distro == "ubuntu" and _parse_version(version) < (20, 4):
print("The Littlest JupyterHub requires Ubuntu 20.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.8+
if sys.version_info < (3, 8):
print(f"bootstrap.py must be run with at least Python 3.8, found {sys.version}")
# 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)

View File

@@ -20,6 +20,7 @@ author = "Project Jupyter Contributors"
#
extensions = [
"sphinx_copybutton",
"sphinx.ext.intersphinx",
"sphinxext.opengraph",
"sphinxext.rediraffe",
"myst_parser",
@@ -74,6 +75,32 @@ myst_enable_extensions = [
"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
#

View File

@@ -89,6 +89,7 @@ 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:
@@ -103,6 +104,8 @@ https:
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:

View File

@@ -23,7 +23,7 @@ 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
ExecStart=/opt/tljh/hub/bin/python3 -m jupyterhub -f jupyterhub_config.py --upgrade-db
[Install]
WantedBy=multi-user.target

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

@@ -149,9 +149,10 @@ If it is not provided as array, there is an easy fix. Just add these lines to
your `awscognito.py`:
```python
def claim_groups_key_func(user_data_resp_json):
return [user_data_resp_json['custom:department']]
def groups_key_func(auth_state):
return [auth_state['oauth_user']['custom:department']]
c.GenericOAuthenticator.claim_groups_key = claim_groups_key_func
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

@@ -91,10 +91,16 @@ For more information on `tljh-config`, see [](/topic/tljh-config).
4. Tell your JupyterHub to _use_ the GitHub OAuthenticator for authentication:
```
sudo tljh-config set auth.type oauthenticator.github.GitHubOAuthenticator
sudo tljh-config set auth.type github
```
5. Restart your JupyterHub so that new users see these changes:
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

View File

@@ -42,4 +42,4 @@ tljh-config reload
## Optional features
More optional features are available on the `authenticator documentation <https://native-authenticator.readthedocs.io/en/latest/>`
More optional features are available on the [authenticator documentation](https://native-authenticator.readthedocs.io/en/latest/)

View File

@@ -22,6 +22,7 @@ content/share-data
user-env/user-environment
user-env/notebook-interfaces
user-env/server-resources
user-env/override-lab-settings
```
## Authentication
@@ -55,6 +56,7 @@ admin/nbresuse
admin/https
admin/enable-extensions
admin/systemd
admin/upgrade-tljh
```
## Cloud provider configuration

View File

@@ -1,49 +1,47 @@
(howto/user-env/notebook-interfaces)=
# Change default User Interface
# Change default user interface
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:
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.
1. [JupyterLab](http://jupyterlab.readthedocs.io/en/stable/)
2. [nteract](https://nteract.io/)
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.
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.
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.
- **For the JupyterLab interface**: change `/tree` to `/lab`.
- **For the nteract interface**: change `/tree` to `/nteract`
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.
You can play around with them and see what fits your use cases best.
## Changing the default user interface using TLJH config
## Changing the default user interface
You can change the default url, and therefore the interface users get when they
log in by modifying TLJH config as an admin user.
You can change the default interface users get when they log in by
modifying `config.yaml` as an admin user.
1. To launch the classic notebook interface when users log in, run the
following in the admin console:
1. To launch **JupyterLab** when users log in, run the following in an
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
```
2. Alternatively, to launch **nteract** when users log in, run the
following in the admin console:
```bash
sudo tljh-config set user_environment.default_app nteract
```
3. Apply the changes by restarting JupyterHub. This should not disrupt
1. Apply the changes by restarting JupyterHub. This should not disrupt
current users.
```bash

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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,11 +1,10 @@
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. Open the **Control Panel** by clicking the control panel button on the top
right of your JupyterHub.
1. In the File menu select the entry for the **Hub Control Panel**.
```{image} ../images/control-panel-button.png
:alt: Control panel button in notebook, top right
```{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.

View File

@@ -139,10 +139,10 @@ Let's create the server on which we can run JupyterHub.
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
**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 have, one from before you can
select it and adjust it to have the rules you need, if you prefer.
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

View File

@@ -1,24 +1,133 @@
(changelog)=
# Changelog
## 2.0
### 2.0.0b1 - 2024-09-30
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.1.0,<6
- Refer to the [JupyterHub changelog] for details and pay attention to the
entries for JupyterHub version 5.0.0.
- OAuthenticator 16.0.4 has been upgraded to >=17.0.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 entries for
JupyterHub 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 entries 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.0b1/tljh/requirements-user-env-extras.txt
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/2.0.0b1/tljh/requirements-hub-env.txt
The changes in the respective environments between TLJH version 1.0.0 and 2.0.0b1
are summarized below.
| Dependency changes in the _hub environment_ | Version in 1.0.0 | Version in 2.0.0b1 | Changelog link | Note |
| ------------------------------------------------------------------------------ | ---------------- | ------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | >=4.0.2,<5 | >=5.1.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.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.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.0.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.0b2 | [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.0b1 | Version in fresh install of 2.0.0b1 | Changelog link | Note |
| -------------------------------------------------------- | ---------------- | ----------------------------- | ----------------------------------- | --------------------------------------------------------------------------------- | ------------------------ |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | >=4.0.2,<5 | >=5.1.0,<6 | >=5.1.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
- 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
- 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
- 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
- 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-09-30&type=c))
@consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AconsideRatio+updated%3A2023-08-11..2024-09-30&type=Issues)) | @davidalber ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Adavidalber+updated%3A2023-08-11..2024-09-30&type=Issues)) | @josedaudi ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajosedaudi+updated%3A2023-08-11..2024-09-30&type=Issues)) | @jrdnbradford ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajrdnbradford+updated%3A2023-08-11..2024-09-30&type=Issues)) | @kiliansinger ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Akiliansinger+updated%3A2023-08-11..2024-09-30&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Amanics+updated%3A2023-08-11..2024-09-30&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aminrk+updated%3A2023-08-11..2024-09-30&type=Issues)) | @MridulS ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AMridulS+updated%3A2023-08-11..2024-09-30&type=Issues)) | @pdebuyl ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Apdebuyl+updated%3A2023-08-11..2024-09-30&type=Issues)) | @schwebke ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aschwebke+updated%3A2023-08-11..2024-09-30&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ayuvipanda+updated%3A2023-08-11..2024-09-30&type=Issues))
## 1.0
### 1.0.0b1 - 2023-07-07
````{warning}
This is a beta release.
To upgrade to it, after having read the breaking changes below, you can do the
following from a terminal on a machine TLJH is installed.
```shell
# This should NOT be run from a JupyterHub started user server, but should
# 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=1.0.0b1
```
````
### 1.0.0 - 2023-08-11
This release bundles with the latest available software from the JupyterHub
ecosystem.
@@ -27,9 +136,11 @@ 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.1,<5
- 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
@@ -44,6 +155,9 @@ installations of version 0.2.0 and later are meant to be easy to upgrade.
- 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
@@ -62,29 +176,29 @@ 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.0b1/tljh/requirements-user-env-extras.txt
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/1.0.0b1/tljh/requirements-hub-env.txt
[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.0b1 are summarized below.
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.0b1 | Changelog link | Note |
| ------------------------------------------------------------------------------ | ---------------- | ------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [jupyterhub](https://github.com/jupyterhub/jupyterhub) | 1.\* | >=4.0.1,<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.2,<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 _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.1,<5 | [Changelog](https://jupyterhub.readthedocs.io/en/stable/reference/changelog.html) | Always upgraded. |
| [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. |
@@ -101,6 +215,8 @@ The changes in the respective environments between TLJH version 0.2.0 and
#### 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))
@@ -129,6 +245,8 @@ The changes in the respective environments between TLJH version 0.2.0 and
#### 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))
@@ -148,9 +266,9 @@ The changes in the respective environments between TLJH version 0.2.0 and
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-06-09&type=c))
([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-06-09&type=Issues)) | @audiodude ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aaudiodude+updated%3A2023-02-27..2023-06-09&type=Issues)) | @consideRatio ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AconsideRatio+updated%3A2023-02-27..2023-06-09&type=Issues)) | @eingemaischt ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aeingemaischt+updated%3A2023-02-27..2023-06-09&type=Issues)) | @GeorgianaElena ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AGeorgianaElena+updated%3A2023-02-27..2023-06-09&type=Issues)) | @Hannnsen ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AHannnsen+updated%3A2023-02-27..2023-06-09&type=Issues)) | @jawiv ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajawiv+updated%3A2023-02-27..2023-06-09&type=Issues)) | @jochym ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajochym+updated%3A2023-02-27..2023-06-09&type=Issues)) | @jrdnbradford ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ajrdnbradford+updated%3A2023-02-27..2023-06-09&type=Issues)) | @manics ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Amanics+updated%3A2023-02-27..2023-06-09&type=Issues)) | @minrk ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Aminrk+updated%3A2023-02-27..2023-06-09&type=Issues)) | @MridulS ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3AMridulS+updated%3A2023-02-27..2023-06-09&type=Issues)) | @nsurleraux-railnova ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ansurleraux-railnova+updated%3A2023-02-27..2023-06-09&type=Issues)) | @Rom1deTroyes ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3ARom1deTroyes+updated%3A2023-02-27..2023-06-09&type=Issues)) | @wjcapehart ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Awjcapehart+updated%3A2023-02-27..2023-06-09&type=Issues)) | @yuvipanda ([activity](https://github.com/search?q=repo%3Ajupyterhub%2Fthe-littlest-jupyterhub+involves%3Ayuvipanda+updated%3A2023-02-27..2023-06-09&type=Issues))
@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

View File

@@ -8,9 +8,11 @@ Topic guides provide in-depth explanations of specific topics.
whentouse
requirements
three-environments
security
customizing-installer
installer-actions
installer-upgrade-actions
tljh-config
authenticator-configuration
escape-hatch

View File

@@ -26,7 +26,7 @@ sudo rm -rf /opt/tljh/hub
## User environment
By default, a `mambaforge` conda environment is installed in `/opt/tljh/user`. This contains
By default, a `miniforge` conda environment is installed in `/opt/tljh/user`. This contains
the notebook interface used to launch all users, and the various packages available to all
users. The environment is owned by the `root` user. JupyterHub admins may use
to `sudo -E conda install` or `sudo -E pip install` packages into this environment.

View File

@@ -0,0 +1,30 @@
(topic-installer-upgrade-actions)=
# What is done during an upgrade of TLJH?
Once TLJH has been installed, it should be possible to upgrade the installation.
This documentation is meant to capture the changes made during an upgrade.
```{versionchanged} 1.0.0
Ensuring upgrades work has only been done since 1.0.0 upgrading from version
0.2.0.
```
## Changes to the system environment
The [system environment](system-environment) is not meant to be influenced
unless explicitly mentioned in the changelog, typically only during major
version upgrades.
## Changes to the hub environment
The [hub environment](hub-environment) gets several packages upgraded based on
version ranges specified in [tljh/requirements-hub-env.txt].
## Changes to the user environment
The [user environment](user-environment) gets is `jupyterhub` package upgraded,
but no other packages gets upgraded unless explicitly mentioned in the
changelog, typically only during major version upgrades.
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/requirements-hub-env.txt

View File

@@ -0,0 +1,76 @@
(topic-three-environments)=
# The system, hub, and user environments
TLJH's documentation mentions the _system environment_, the _hub environment_,
and the _user environment_. This section will introduce what is meant with that
and clarify the distinctions between the environments.
(system-environment)=
## The system environment
When this documentation mentions the _system environment_, it refers to the
Linux environment with its installed `apt` packages, users in `/etc/passwd`,
etc.
A part of the system environment is a Python environment setup via the `apt`
package `python` installed by default in Linux distributions supported by TLJH.
To be specific, we can refer to this as the _system's Python environment_.
If you would do `sudo python3 -m pip install <something>` you would end up
installing something in the system's Python environment, and that would not be
available in the hub environment or the user environment.
The system's Python environment is only used by TLJH to run the `bootstrap.py`
script downloaded as part of installing or upgrading TLJH. This script is also
responsible for setting up the hub environment.
(hub-environment)=
## The hub environment
The _hub environment_ is a [virtual Python environment] setup in `/opt/tljh/hub`
by the `bootstrap.py` script using the system's Python environment during TLJH
installation.
The hub environment has Python packages installed in it related to running
JupyterHub itself such as an JupyterHub authenticator package, but it doesn't
include packages to start user servers like JupyterLab.
When TLJH is installed/upgraded, the packages listed in
[tljh/requirements-hub-env.txt] are installed/upgraded in this environment.
If you would do `sudo /opt/tljh/hub/bin/python3 -m pip install <something>` you
would end up installing something in the hub environment, and that would not be
available in the system's Python environment or the user environment.
[virtual Python environment]: https://docs.python.org/3/library/venv.html
[tljh/requirements-hub-env.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/requirements-hub-env.txt
(user-environment)=
## The user environment
The _user environment_ is a Python environment setup in `/opt/tljh/user` by the
TLJH installer during TLJH installation. The user environment is not a virtual
environment because an entirely separate installation of Python has been made
for it.
The user environment has packages installed in it related to running individual
jupyter servers, such as `jupyterlab`.
When TLJH is _installed_, the packages listed in
[tljh/requirements-user-env.txt] are installed in this environment. When TLJH is
_upgraded_ though, as little as possible is done to this environment. Typically
only `jupyterhub` is upgraded to match the version in the hub environment. If
upgrading to a new major version of TLJH, then something small may be done
besides this, and then it should be described the changelog.
If you would do `sudo /opt/tljh/user/bin/python3 -m pip install <something>`, or
from a user server's terminal do `sudo -E pip install <something>` you would end
up installing something in the user environment, and that would not be available
in the system's Python environment or the hub environment.
[tljh/requirements-user-env-extras.txt]: https://github.com/jupyterhub/the-littlest-jupyterhub/blob/HEAD/tljh/requirements-user-env-extras.txt

View File

@@ -1,3 +1,5 @@
(troubleshooting)=
# Troubleshooting
In time, all systems have issues that need to be debugged. Troubleshooting

View File

@@ -1,5 +1,5 @@
# Systemd inside a Docker container, for CI only
ARG BASE_IMAGE=ubuntu:20.04
ARG BASE_IMAGE=ubuntu:22.04
FROM $BASE_IMAGE
# DEBIAN_FRONTEND is set to avoid being asked for input and hang during build:
@@ -29,8 +29,8 @@ RUN systemctl set-default multi-user.target
STOPSIGNAL SIGRTMIN+3
# Uncomment these lines for a development install
#ENV TLJH_BOOTSTRAP_DEV=yes
#ENV TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
#ENV PATH=/opt/tljh/hub/bin:${PATH}
# ENV TLJH_BOOTSTRAP_DEV=yes
# ENV TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
# ENV PATH=/opt/tljh/hub/bin:${PATH}
CMD ["/bin/bash", "-c", "exec /lib/systemd/systemd --log-target=journal 3>&1"]

View File

@@ -1,17 +1,25 @@
"""
Simplest plugin that exercises all the hooks defined in tljh/hooks.py.
"""
from tljh.hooks import hookimpl
@hookimpl
def tljh_extra_user_conda_packages():
return ["tqdm"]
# tqdm installs from the conda-forge channel (https://conda-forge.org/packages/)
# csvtk installs from the bioconda channel (https://bioconda.github.io/conda-package_index.html)
return ["tqdm", "csvtk"]
@hookimpl
def tljh_extra_user_conda_channels():
return ["conda-forge", "bioconda"]
@hookimpl
def tljh_extra_user_pip_packages():
return ["django"]
return ["simplejson"]
@hookimpl

View File

@@ -9,6 +9,7 @@ FIXME: The last test stands out and could be part of the other tests, and the
first two could be more like unit tests. Ideally, this file is
significantly reduced.
"""
import concurrent.futures
import os
import subprocess
@@ -84,9 +85,9 @@ def test_ubuntu_too_old():
"""
Error with a useful message when running in older Ubuntu
"""
output = _run_bootstrap_in_container("ubuntu:18.04", False)
output = _run_bootstrap_in_container("ubuntu:20.04", False)
_stop_container()
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 20.04 or higher\n"
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 22.04 or higher\n"
assert output.returncode == 1

View File

@@ -1,3 +1,4 @@
import re
import subprocess
@@ -7,13 +8,13 @@ def test_serverextensions():
"""
# jupyter-serverextension writes to stdout and stderr weirdly
proc = subprocess.run(
["/opt/tljh/user/bin/jupyter-serverextension", "list", "--sys-prefix"],
["/opt/tljh/user/bin/jupyter-server", "extension", "list", "--sys-prefix"],
stderr=subprocess.PIPE,
)
extensions = [
"jupyterlab 3.",
"nbgitpuller 1.",
"jupyterlab",
"nbgitpuller",
"jupyter_resource_usage",
]
@@ -21,27 +22,25 @@ def test_serverextensions():
assert e in proc.stderr.decode()
def test_nbextensions():
def test_labextensions():
"""
Validate nbextensions we want are installed & enabled
Validate JupyterLab extensions we want are installed & enabled
"""
# jupyter-nbextension writes to stdout and stderr weirdly
# jupyter-labextension writes to stdout and stderr weirdly
proc = subprocess.run(
["/opt/tljh/user/bin/jupyter-nbextension", "list", "--sys-prefix"],
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
["/opt/tljh/user/bin/jupyter-labextension", "list"],
capture_output=True,
)
extensions = [
"jupyter_resource_usage/main",
# This is what ipywidgets nbextension is called
"jupyter-js-widgets/extension",
"@jupyter-server/resource-usage",
# This is what ipywidgets lab extension is called
"@jupyter-widgets/jupyterlab-manager",
]
for e in extensions:
assert f"{e} \x1b[32m enabled \x1b[0m" in proc.stdout.decode()
# Ensure we have 'OK' messages in our stdout, to make sure everything is importable
assert proc.stderr.decode() == " - Validating: \x1b[32mOK\x1b[0m\n" * len(
extensions
)
# jupyter labextension lists outputs to stderr
out = proc.stderr.decode()
enabled_ok_pattern = re.compile(rf"{e}.*enabled.*OK")
matches = enabled_ok_pattern.search(out)
assert matches is not None

View File

@@ -33,7 +33,7 @@ def test_hub_version():
r = requests.get(HUB_URL + "/hub/api")
r.raise_for_status()
info = r.json()
assert V("4") <= V(info["version"]) <= V("5")
assert V("5.1") <= V(info["version"]) <= V("6")
async def test_user_code_execute():
@@ -59,9 +59,9 @@ async def test_user_code_execute():
async with User(username, HUB_URL, partial(login_dummy, password="")) as u:
assert await u.login()
await u.ensure_server_simulate(timeout=60, spawn_refresh_time=5)
await u.start_kernel()
await u.assert_code_output("5 * 4", "20", 5, 5)
assert await u.ensure_server_simulate(timeout=60, spawn_refresh_time=5)
assert await u.start_kernel()
assert await u.assert_code_output("5 * 4", "20", 5, 5)
async def test_user_server_started_with_custom_base_url():

View File

@@ -1,4 +1,5 @@
"""tests for the proxy"""
import os
import shutil
import ssl

View File

@@ -2,6 +2,7 @@
Test the plugin in integration-tests/plugins/simplest that makes use of all tljh
recognized plugin hooks that are defined in tljh/hooks.py.
"""
import os
import subprocess
@@ -19,13 +20,24 @@ def test_tljh_extra_user_conda_packages():
def test_tljh_extra_user_pip_packages():
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/python3", "-c", "import django"])
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/python3", "-c", "import simplejson"])
def test_tljh_extra_hub_pip_packages():
subprocess.check_call([f"{HUB_ENV_PREFIX}/bin/python3", "-c", "import there"])
def test_conda_packages():
"""
Test extra user conda packages are installed from multiple channels.
- tqdm installs from the conda-forge channel (https://conda-forge.org/packages/)
- csvtk installs from the bioconda channel (https://bioconda.github.io/conda-package_index.html)
"""
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/python3", "-c", "import tqdm"])
subprocess.check_call([f"{USER_ENV_PREFIX}/bin/csvtk", "cat", "--help"])
def test_tljh_extra_apt_packages():
assert os.path.exists("/usr/games/sl")

View File

@@ -25,12 +25,10 @@ profile = "black"
# target-version should be all supported versions, see
# https://github.com/psf/black/issues/751#issuecomment-473066811
target_version = [
"py36",
"py37",
"py38",
"py39",
"py310",
"py311",
"py312",
]
@@ -67,7 +65,7 @@ omit = [
github_url = "https://github.com/jupyterhub/the-littlest-jupyterhub"
[tool.tbump.version]
current = "1.0.0b1"
current = "2.0.0b1"
regex = '''
(?P<major>\d+)
\.

View File

@@ -2,7 +2,7 @@ from setuptools import find_packages, setup
setup(
name="the-littlest-jupyterhub",
version="1.0.0b1",
version="2.0.0b1",
description="A small JupyterHub distribution",
url="https://github.com/jupyterhub/the-littlest-jupyterhub",
author="Jupyter Development Team",
@@ -10,14 +10,16 @@ setup(
license="3 Clause BSD",
packages=find_packages(),
include_package_data=True,
python_requires=">=3.9",
install_requires=[
"ruamel.yaml==0.17.*",
"ruamel.yaml==0.18.*",
"jinja2",
"pluggy==1.*",
"backoff",
"filelock",
"requests",
"bcrypt",
"jupyterhub-traefik-proxy==1.*",
"jupyterhub-traefik-proxy==2.*",
],
entry_points={
"console_scripts": [

View File

@@ -1,4 +1,5 @@
"""pytest fixtures"""
import os
import types
from importlib import reload

View File

@@ -1,6 +1,7 @@
"""
Test conda commandline wrappers
"""
import os
import subprocess
import tempfile
@@ -13,9 +14,9 @@ from tljh import conda, installer
@pytest.fixture(scope="module")
def prefix():
"""
Provide a temporary directory with a mambaforge conda environment
Provide a temporary directory with a conda environment
"""
installer_url, checksum = installer._mambaforge_url()
installer_url, checksum = installer._miniforge_url()
with tempfile.TemporaryDirectory() as tmpdir:
with conda.download_miniconda_installer(
installer_url, checksum
@@ -33,6 +34,15 @@ def test_ensure_packages(prefix):
subprocess.check_call([os.path.join(prefix, "bin", "python"), "-c", "import numpy"])
def test_ensure_channel_packages(prefix):
"""
Test installing packages in conda environment
"""
conda.ensure_conda_packages(prefix, ["csvtk"], channels=("conda-forge", "bioconda"))
# Throws an error if this fails
subprocess.check_call([os.path.join(prefix, "bin", "csvtk"), "cat", "--help"])
def test_ensure_pip_packages(prefix):
"""
Test installing pip packages in conda environment

View File

@@ -143,21 +143,24 @@ def test_remove_from_config_error():
def test_reload_hub():
with mock.patch("tljh.systemd.restart_service") as restart_service, mock.patch(
"tljh.systemd.check_service_active"
) as check_active, mock.patch("tljh.config.check_hub_ready") as check_ready:
with (
mock.patch("tljh.systemd.restart_service") as restart_service,
mock.patch("tljh.systemd.check_service_active") as check_active,
mock.patch("tljh.config.check_hub_ready") as check_ready,
):
config.reload_component("hub")
assert restart_service.called_with("jupyterhub")
assert check_active.called_with("jupyterhub")
restart_service.assert_called_with("jupyterhub")
check_active.assert_called_with("jupyterhub")
def test_reload_proxy(tljh_dir):
with mock.patch("tljh.systemd.restart_service") as restart_service, mock.patch(
"tljh.systemd.check_service_active"
) as check_active:
with (
mock.patch("tljh.systemd.restart_service") as restart_service,
mock.patch("tljh.systemd.check_service_active") as check_active,
):
config.reload_component("proxy")
assert restart_service.called_with("traefik")
assert check_active.called_with("traefik")
restart_service.assert_called_with("traefik")
check_active.assert_called_with("traefik")
assert os.path.exists(os.path.join(config.STATE_DIR, "traefik.toml"))

View File

@@ -58,18 +58,17 @@ def test_app_default():
Test default application with no config overrides.
"""
c = apply_mock_config({})
# default_url is not set, so JupyterHub will pick default.
assert "default_url" not in c.Spawner
def test_app_jupyterlab():
"""
Test setting JupyterLab as default application
"""
c = apply_mock_config({"user_environment": {"default_app": "jupyterlab"}})
assert c.Spawner.default_url == "/lab"
def test_app_classic():
"""
Test setting classic as default application
"""
c = apply_mock_config({"user_environment": {"default_app": "classic"}})
assert c.Spawner.default_url == "/tree"
def test_auth_default():
"""
Test default authentication settings with no overrides

View File

@@ -1,6 +1,7 @@
"""
Unit test functions in installer.py
"""
import json
import os
from subprocess import PIPE, run
@@ -45,12 +46,12 @@ def test_ensure_admins(tljh_dir, admins, expected_config):
def setup_conda(distro, version, prefix):
"""Install mambaforge or miniconda in a prefix"""
"""Install miniforge or miniconda in a prefix"""
if distro == "mambaforge":
installer_url, _ = installer._mambaforge_url(version)
installer_url, _ = installer._miniforge_url(version)
installer_url = installer_url.replace("Miniforge3", "Mambaforge")
elif distro == "miniforge":
installer_url, _ = installer._mambaforge_url(version)
installer_url = installer_url.replace("Mambaforge", "Miniforge3")
installer_url, _ = installer._miniforge_url(version)
elif distro == "miniconda":
arch = os.uname().machine
installer_url = (
@@ -123,9 +124,9 @@ def _specifier(version):
None,
None,
{
"python": "3.10.*",
"conda": "23.1.0",
"mamba": "1.4.1",
"python": "3.12.*",
"conda": "24.7.1",
"mamba": "1.5.9",
},
),
# previous install, 1.0

View File

@@ -1,6 +1,7 @@
"""
Unit test functions in installer.py
"""
import os
from datetime import date

View File

@@ -1,6 +1,7 @@
"""
Test functions for normalizing various kinds of values
"""
from tljh.normalize import generate_system_username

View File

@@ -1,4 +1,5 @@
"""Test traefik configuration"""
import os
import pytest

View File

@@ -1,6 +1,7 @@
"""
Test wrappers in tljw.user module
"""
import grp
import os
import os.path

View File

@@ -1,6 +1,7 @@
"""
Utilities for working with the apt package manager
"""
import os
import subprocess

View File

@@ -1,6 +1,7 @@
"""
Wrap conda commandline program
"""
import contextlib
import hashlib
import json
@@ -98,9 +99,11 @@ def install_miniconda(installer_path, prefix):
fix_permissions(prefix)
def ensure_conda_packages(prefix, packages, force_reinstall=False):
def ensure_conda_packages(
prefix, packages, channels=("conda-forge",), force_reinstall=False
):
"""
Ensure packages (from conda-forge) are installed in the conda prefix.
Ensure packages (from channels) are installed in the conda prefix.
Note that conda seem to update dependencies by default, so there is probably
no need to have a update parameter exposed for this function.
@@ -117,13 +120,14 @@ def ensure_conda_packages(prefix, packages, force_reinstall=False):
# avoids problems with RemoveError upgrading conda from old versions
cmd += ["--force-reinstall"]
for channel in channels:
cmd += ["-c", channel]
abspath = os.path.abspath(prefix)
utils.run_subprocess(
cmd
+ [
"-c",
"conda-forge", # Make customizable if we ever need to
"--prefix",
abspath,
]

View File

@@ -18,9 +18,11 @@ import re
import sys
import time
from collections.abc import Mapping, Sequence
from contextlib import contextmanager
from copy import deepcopy
import requests
from filelock import FileLock, Timeout
from .yaml import yaml
@@ -32,6 +34,22 @@ CONFIG_DIR = os.path.join(INSTALL_PREFIX, "config")
CONFIG_FILE = os.path.join(CONFIG_DIR, "config.yaml")
@contextmanager
def config_file_lock(config_path, timeout=1):
"""Context manager to acquire the config file lock"""
lock_file = f"{config_path}.lock"
try:
with FileLock(lock_file).acquire(timeout=timeout):
yield
except Timeout:
print(
f"Another instance of tljh-config holds the lock {lock_file}.",
file=sys.stderr,
)
sys.exit(1)
def set_item_in_config(config, property_path, value):
"""
Set key at property_path to value in config & return new config.
@@ -154,92 +172,102 @@ def remove_item_from_config(config, property_path, value):
return config_copy
def validate_config(config, validate):
"""
Validate changes to the config with tljh-config against the schema
"""
import jsonschema
from .config_schema import config_schema
try:
jsonschema.validate(instance=config, schema=config_schema)
except jsonschema.exceptions.ValidationError as e:
if validate:
print(
f"Config validation error: {e.message}.\n"
"You can still apply this change without validation by re-running your command with the --no-validate flag.\n"
"If you think this validation error is incorrect, please report it to https://github.com/jupyterhub/the-littlest-jupyterhub/issues.",
file=sys.stderr,
)
sys.exit(1)
def show_config(config_path):
"""
Pretty print config from given config_path
"""
try:
with open(config_path) as f:
config = yaml.load(f)
except FileNotFoundError:
config = {}
config = get_current_config(config_path)
yaml.dump(config, sys.stdout)
def set_config_value(config_path, key_path, value):
def set_config_value(config_path, key_path, value, validate=True):
"""
Set key at key_path in config_path to value
"""
# FIXME: Have a file lock here
# FIXME: Validate schema here
try:
with open(config_path) as f:
config = yaml.load(f)
except FileNotFoundError:
config = {}
with config_file_lock(config_path):
config = get_current_config(config_path)
config = set_item_in_config(config, key_path, value)
validate_config(config, validate)
config = set_item_in_config(config, key_path, value)
with open(config_path, "w") as f:
yaml.dump(config, f)
with open(config_path, "w") as f:
yaml.dump(config, f)
def unset_config_value(config_path, key_path):
def unset_config_value(config_path, key_path, validate=True):
"""
Unset key at key_path in config_path
"""
# FIXME: Have a file lock here
# FIXME: Validate schema here
try:
with open(config_path) as f:
config = yaml.load(f)
except FileNotFoundError:
config = {}
with config_file_lock(config_path):
config = get_current_config(config_path)
config = unset_item_from_config(config, key_path)
validate_config(config, validate)
config = unset_item_from_config(config, key_path)
with open(config_path, "w") as f:
yaml.dump(config, f)
with open(config_path, "w") as f:
yaml.dump(config, f)
def add_config_value(config_path, key_path, value):
def add_config_value(config_path, key_path, value, validate=True):
"""
Add value to list at key_path
"""
# FIXME: Have a file lock here
# FIXME: Validate schema here
try:
with open(config_path) as f:
config = yaml.load(f)
except FileNotFoundError:
config = {}
with config_file_lock(config_path):
config = get_current_config(config_path)
config = add_item_to_config(config, key_path, value)
validate_config(config, validate)
config = add_item_to_config(config, key_path, value)
with open(config_path, "w") as f:
yaml.dump(config, f)
with open(config_path, "w") as f:
yaml.dump(config, f)
def remove_config_value(config_path, key_path, value):
def remove_config_value(config_path, key_path, value, validate=True):
"""
Remove value from list at key_path
"""
# FIXME: Have a file lock here
# FIXME: Validate schema here
with config_file_lock(config_path):
config = get_current_config(config_path)
config = remove_item_from_config(config, key_path, value)
validate_config(config, validate)
with open(config_path, "w") as f:
yaml.dump(config, f)
def get_current_config(config_path):
"""
Retrieve the current config at config_path
"""
try:
with open(config_path) as f:
config = yaml.load(f)
return yaml.load(f)
except FileNotFoundError:
config = {}
config = remove_item_from_config(config, key_path, value)
with open(config_path, "w") as f:
yaml.dump(config, f)
return {}
def check_hub_ready():
"""
Checks that hub is running.
"""
from .configurer import load_config
base_url = load_config()["base_url"]
@@ -336,6 +364,18 @@ def main(argv=None):
argparser.add_argument(
"--config-path", default=CONFIG_FILE, help="Path to TLJH config.yaml file"
)
argparser.add_argument(
"--validate", action="store_true", help="Validate the TLJH config"
)
argparser.add_argument(
"--no-validate",
dest="validate",
action="store_false",
help="Do not validate the TLJH config",
)
argparser.set_defaults(validate=True)
subparsers = argparser.add_subparsers(dest="action")
show_parser = subparsers.add_parser("show", help="Show current configuration")
@@ -383,13 +423,19 @@ def main(argv=None):
if args.action == "show":
show_config(args.config_path)
elif args.action == "set":
set_config_value(args.config_path, args.key_path, parse_value(args.value))
set_config_value(
args.config_path, args.key_path, parse_value(args.value), args.validate
)
elif args.action == "unset":
unset_config_value(args.config_path, args.key_path)
unset_config_value(args.config_path, args.key_path, args.validate)
elif args.action == "add-item":
add_config_value(args.config_path, args.key_path, parse_value(args.value))
add_config_value(
args.config_path, args.key_path, parse_value(args.value), args.validate
)
elif args.action == "remove-item":
remove_config_value(args.config_path, args.key_path, parse_value(args.value))
remove_config_value(
args.config_path, args.key_path, parse_value(args.value), args.validate
)
elif args.action == "reload":
reload_component(args.component)
else:

117
tljh/config_schema.py Normal file
View File

@@ -0,0 +1,117 @@
"""
The schema against which the TLJH config file can be validated.
Validation occurs when changing values with tljh-config.
"""
config_schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Littlest JupyterHub YAML config file",
"definitions": {
"BaseURL": {
"type": "string",
},
"Users": {
"type": "object",
"additionalProperties": False,
"properties": {
"extra_user_groups": {"type": "object", "items": {"type": "string"}},
"allowed": {"type": "array", "items": {"type": "string"}},
"banned": {"type": "array", "items": {"type": "string"}},
"admin": {"type": "array", "items": {"type": "string"}},
},
},
"Services": {
"type": "object",
"properties": {
"cull": {
"type": "object",
"additionalProperties": False,
"properties": {
"enabled": {"type": "boolean"},
"timeout": {"type": "integer"},
"every": {"type": "integer"},
"concurrency": {"type": "integer"},
"users": {"type": "boolean"},
"max_age": {"type": "integer"},
"remove_named_servers": {"type": "boolean"},
},
}
},
},
"HTTP": {
"type": "object",
"additionalProperties": False,
"properties": {
"address": {"type": "string", "format": "ipv4"},
"port": {"type": "integer"},
},
},
"HTTPS": {
"type": "object",
"additionalProperties": False,
"properties": {
"enabled": {"type": "boolean"},
"address": {"type": "string", "format": "ipv4"},
"port": {"type": "integer"},
"tls": {"$ref": "#/definitions/TLS"},
"letsencrypt": {"$ref": "#/definitions/LetsEncrypt"},
},
},
"LetsEncrypt": {
"type": "object",
"additionalProperties": False,
"properties": {
"email": {"type": "string", "format": "email"},
"domains": {
"type": "array",
"items": {"type": "string", "format": "hostname"},
},
"staging": {"type": "boolean"},
},
},
"TLS": {
"type": "object",
"additionalProperties": False,
"properties": {"key": {"type": "string"}, "cert": {"type": "string"}},
},
"Limits": {
"description": "User CPU and memory limits.",
"type": "object",
"additionalProperties": False,
"properties": {"memory": {"type": "string"}, "cpu": {"type": "integer"}},
},
"UserEnvironment": {
"type": "object",
"additionalProperties": False,
"properties": {
"default_app": {
"type": "string",
"enum": ["jupyterlab", "classic"],
"default": "jupyterlab",
}
},
},
"TraefikAPI": {
"type": "object",
"additionalProperties": False,
"properties": {
"ip": {"type": "string", "format": "ipv4"},
"port": {"type": "integer"},
"username": {"type": "string"},
"password": {"type": "string"},
},
},
},
"properties": {
"additionalProperties": False,
"base_url": {"$ref": "#/definitions/BaseURL"},
"user_environment": {"$ref": "#/definitions/UserEnvironment"},
"users": {"$ref": "#/definitions/Users"},
"limits": {"$ref": "#/definitions/Limits"},
"https": {"$ref": "#/definitions/HTTPS"},
"http": {"$ref": "#/definitions/HTTP"},
"traefik_api": {"$ref": "#/definitions/TraefikAPI"},
"services": {"$ref": "#/definitions/Services"},
},
}

View File

@@ -52,7 +52,7 @@ default = {
"password": "",
},
"user_environment": {
"default_app": "classic",
"default_app": "jupyterlab",
},
"services": {
"cull": {
@@ -199,6 +199,14 @@ def update_userlists(c, config):
"""
users = config["users"]
if (
not users["allowed"]
and config["auth"]["type"] == default["auth"]["type"]
and "allow_all" not in c.FirstUseAuthenticator
):
# _default_ authenticator, enable allow_all if no users specified
c.FirstUseAuthenticator.allow_all = True
c.Authenticator.allowed_users = set(users["allowed"])
c.Authenticator.blocked_users = set(users["banned"])
c.Authenticator.admin_users = set(users["admin"])
@@ -231,6 +239,8 @@ def update_user_environment(c, config):
# Set default application users are launched into
if user_env["default_app"] == "jupyterlab":
c.Spawner.default_url = "/lab"
elif user_env["default_app"] == "classic":
c.Spawner.default_url = "/tree"
def update_user_account_config(c, config):

View File

@@ -1,6 +1,7 @@
"""
Hook specifications that pluggy plugins can override
"""
import pluggy
hookspec = pluggy.HookspecMarker("tljh")
@@ -14,6 +15,13 @@ def tljh_extra_user_conda_packages():
"""
@hookspec
def tljh_extra_user_conda_channels():
"""
Return a list of conda channels to be used during user environment installation.
"""
@hookspec
def tljh_extra_user_pip_packages():
"""

View File

@@ -115,7 +115,6 @@ def ensure_jupyterhub_package(prefix):
os.path.join(HERE, "requirements-hub-env.txt"),
upgrade=True,
)
traefik.ensure_traefik_binary(prefix)
def ensure_usergroups():
@@ -136,13 +135,13 @@ def ensure_usergroups():
f.write("Defaults exempt_group = jupyterhub-admins\n")
# Install mambaforge using an installer from
# Install miniforge using an installer from
# https://github.com/conda-forge/miniforge/releases
MAMBAFORGE_VERSION = "23.1.0-1"
MINIFORGE_VERSION = "24.7.1-2"
# sha256 checksums
MAMBAFORGE_CHECKSUMS = {
"aarch64": "d9d89c9e349369702171008d9ee7c5ce80ed420e5af60bd150a3db4bf674443a",
"x86_64": "cfb16c47dc2d115c8b114280aa605e322173f029fdb847a45348bf4bd23c62ab",
MINIFORGE_CHECKSUMS = {
"aarch64": "7bf60bce50f57af7ea4500b45eeb401d9350011ab34c9c45f736647d8dba9021",
"x86_64": "636f7faca2d51ee42b4640ce160c751a46d57621ef4bf14378704c87c5db4fe3",
}
# minimum versions of packages
@@ -156,22 +155,22 @@ MINIMUM_VERSIONS = {
}
def _mambaforge_url(version=MAMBAFORGE_VERSION, arch=None):
"""Return (URL, checksum) for mambaforge download for a given version and arch
def _miniforge_url(version=MINIFORGE_VERSION, arch=None):
"""Return (URL, checksum) for miniforge download for a given version and arch
Default values provided for both version and arch
"""
if arch is None:
arch = os.uname().machine
installer_url = "https://github.com/conda-forge/miniforge/releases/download/{v}/Mambaforge-{v}-Linux-{arch}.sh".format(
installer_url = "https://github.com/conda-forge/miniforge/releases/download/{v}/Miniforge3-{v}-Linux-{arch}.sh".format(
v=version,
arch=arch,
)
# Check system architecture, set appropriate installer checksum
checksum = MAMBAFORGE_CHECKSUMS.get(arch)
checksum = MINIFORGE_CHECKSUMS.get(arch)
if not checksum:
raise ValueError(
f"Unsupported architecture: {arch}. TLJH only supports {','.join(MAMBAFORGE_CHECKSUMS.keys())}"
f"Unsupported architecture: {arch}. TLJH only supports {','.join(MINIFORGE_CHECKSUMS.keys())}"
)
return installer_url, checksum
@@ -198,7 +197,7 @@ def ensure_user_environment(user_requirements_txt_file):
raise OSError(msg)
logger.info("Downloading & setting up user environment...")
installer_url, installer_sha256 = _mambaforge_url()
installer_url, installer_sha256 = _miniforge_url()
with conda.download_miniconda_installer(
installer_url, installer_sha256
) as installer_path:
@@ -242,11 +241,10 @@ def ensure_user_environment(user_requirements_txt_file):
)
to_upgrade.append(pkg)
# force reinstall conda/mamba to ensure a basically consistent env
# avoids issues with RemoveError: 'requests' is a dependency of conda
# only do this for 'old' conda versions known to have a problem
# we don't know how old, but we know 4.10 is affected and 23.1 is not
if not is_fresh_install and V(package_versions.get("conda", "0")) < V("23.1"):
# force reinstall conda/mamba to ensure conda doesn't raise error
# "RemoveError: 'requests' is a dependency of conda" later on when
# conda/mamba is used to install/upgrade something
if not is_fresh_install:
# force-reinstall doesn't upgrade packages
# it reinstalls them in-place
# only reinstall packages already present
@@ -450,13 +448,18 @@ def run_plugin_actions(plugin_manager):
# Install conda packages
conda_packages = list(set(itertools.chain(*hook.tljh_extra_user_conda_packages())))
conda_channels = list(itertools.chain(*hook.tljh_extra_user_conda_channels()))
if len(conda_channels) == 0:
conda_channels = ("conda-forge",)
if conda_packages:
logger.info(
"Installing {} user conda packages collected from plugins: {}".format(
len(conda_packages), " ".join(conda_packages)
)
)
conda.ensure_conda_packages(USER_ENV_PREFIX, conda_packages)
conda.ensure_conda_packages(
USER_ENV_PREFIX, conda_packages, channels=conda_channels
)
# Install pip packages
user_pip_packages = list(set(itertools.chain(*hook.tljh_extra_user_pip_packages())))
@@ -532,6 +535,7 @@ def main():
logger.info("Setting up JupyterHub...")
ensure_jupyterhub_package(HUB_ENV_PREFIX)
traefik.ensure_traefik_binary(HUB_ENV_PREFIX)
# Stop the http server with the progress page before traefik starts
if args.progress_page_server_pid:

View File

@@ -1,4 +1,5 @@
"""Setup tljh logging"""
import logging
import os

View File

@@ -1,6 +1,7 @@
"""
Functions to normalize various inputs
"""
import hashlib

View File

@@ -8,14 +8,14 @@
# If a dependency is bumped to a new major version, we should make a major
# version release of tljh.
#
jupyterhub>=4.0.1,<5
jupyterhub>=5.1.0,<6
jupyterhub-systemdspawner>=1.0.1,<2
jupyterhub-firstuseauthenticator>=1.0.0,<2
jupyterhub-nativeauthenticator>=1.2.0,<2
jupyterhub-ldapauthenticator>=1.3.2,<2
jupyterhub-firstuseauthenticator>=1.1.0,<2
jupyterhub-nativeauthenticator>=1.3.0,<2
jupyterhub-ldapauthenticator==2.0.0b2 # FIXME: update to >=2.0.0,<3
jupyterhub-tmpauthenticator>=1.0.0,<2
oauthenticator>=16.0.2,<17
jupyterhub-idle-culler>=1.2.1,<2
oauthenticator>=17,<18
jupyterhub-idle-culler>=1.4.0,<2
# pycurl is installed to improve reliability and performance for when JupyterHub
# makes web requests. JupyterHub will use tornado's CurlAsyncHTTPClient when
@@ -25,4 +25,4 @@ jupyterhub-idle-culler>=1.2.1,<2
# ref: https://www.tornadoweb.org/en/stable/httpclient.html#module-tornado.simple_httpclient
# ref: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/289
#
pycurl>=7.45.2,<8
pycurl>=7.45.3,<8

View File

@@ -8,11 +8,20 @@
# the requirements-txt-fixer pre-commit hook that sorted them and made
# our integration tests fail.
#
notebook==6.*
jupyterlab==3.*
# ref: https://github.com/jupyter/notebook
notebook>=7.2.2,<8
# ref: https://github.com/jupyterlab/jupyterlab
jupyterlab>=4.2.5,<5
# nbgitpuller for easily pulling in Git repositories
nbgitpuller==1.*
# ref: https://github.com/jupyterhub/nbgitpuller
nbgitpuller>=1.2.1,<2
# jupyter-resource-usage to show people how much RAM they are using
jupyter-resource-usage==0.7.*
# ref: https://github.com/jupyter-server/jupyter-resource-usage
jupyter-resource-usage>=1.1.0,<2
# Most people consider ipywidgets to be part of the core notebook experience
ipywidgets==8.*
# ref: https://github.com/jupyter-widgets/ipywidgets
ipywidgets>=8.1.5,<9

View File

@@ -18,7 +18,7 @@ Environment=TLJH_INSTALL_PREFIX={install_prefix}
Environment=PATH={install_prefix}/hub/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Run upgrade-db before starting, in case Hub version has changed
# This is a no-op when no db exists or no upgrades are needed
ExecStart={python_interpreter_path} -m jupyterhub.app -f {jupyterhub_config_path} --upgrade-db
ExecStart={python_interpreter_path} -m jupyterhub -f {jupyterhub_config_path} --upgrade-db
[Install]
# Start service when system boots

View File

@@ -3,6 +3,7 @@ Wraps systemctl to install, uninstall, start & stop systemd services.
If we use a debian package instead, we can get rid of all this code.
"""
import os
import subprocess

View File

@@ -1,4 +1,5 @@
"""Traefik installation and setup"""
import hashlib
import io
import logging
@@ -28,13 +29,13 @@ else:
plat = None
# Traefik releases: https://github.com/traefik/traefik/releases
traefik_version = "2.10.1"
traefik_version = "3.1.4"
# record sha256 hashes for supported platforms here
# checksums are published in the checksums.txt of each release
checksums = {
"linux_amd64": "8d9bce0e6a5bf40b5399dbb1d5e3e5c57b9f9f04dd56a2dd57cb0713130bc824",
"linux_arm64": "260a574105e44901f8c9c562055936d81fbd9c96a21daaa575502dc69bfe390a",
"linux_amd64": "eb7227b1b235195355904839c514a9ed6a0aecdcf5dab02ad48db21b05c5e700",
"linux_arm64": "e5d970a7f11267b70a8e308cb80f859bba4f420f24789f7393fdf3f4cd031631",
}
_tljh_path = Path(__file__).parent.resolve()
@@ -90,7 +91,10 @@ def check_traefik_version(traefik_bin):
@backoff.on_exception(backoff.expo, Exception, max_tries=2, giveup=fatal_error)
def ensure_traefik_binary(prefix):
"""Download and install the traefik binary to a location identified by a prefix path such as '/opt/tljh/hub/'"""
"""
Ensure that a traefik binary of a hardcoded version is made available at a
prefix path such as '/opt/tljh/hub/'.
"""
if plat is None:
raise OSError(
f"Error. Platform: {os.uname().sysname} / {machine} Not supported."

View File

@@ -3,6 +3,7 @@ User management for tljh.
Supports minimal user & group management
"""
import grp
import pwd
import subprocess

View File

@@ -1,6 +1,7 @@
"""
Miscellaneous functions useful in at least two places unrelated to each other
"""
import logging
import re
import subprocess

View File

@@ -3,6 +3,7 @@
ensures the same yaml settings for reading/writing
throughout tljh
"""
from ruamel.yaml import YAML
from ruamel.yaml.composer import Composer