mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Merge pull request #710 from consideRatio/pr/github-ci-spacing
Revision of our GitHub Workflows and README.rst to README.md
This commit is contained in:
30
.github/integration-test.py
vendored
30
.github/integration-test.py
vendored
@@ -4,15 +4,16 @@ import subprocess
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def build_systemd_image(image_name, source_path):
|
def build_systemd_image(image_name, source_path, build_args=None):
|
||||||
"""
|
"""
|
||||||
Build docker image with systemd at source_path.
|
Build docker image with systemd at source_path.
|
||||||
|
|
||||||
Built image is tagged with image_name
|
Built image is tagged with image_name
|
||||||
"""
|
"""
|
||||||
subprocess.check_call([
|
cmd = ['docker', 'build', '-t', image_name, source_path]
|
||||||
'docker', 'build', '-t', image_name, source_path
|
if build_args:
|
||||||
])
|
cmd.extend([f"--build-arg={ba}" for ba in build_args])
|
||||||
|
subprocess.check_call(cmd)
|
||||||
|
|
||||||
|
|
||||||
def run_systemd_image(image_name, container_name, bootstrap_pip_spec):
|
def run_systemd_image(image_name, container_name, bootstrap_pip_spec):
|
||||||
@@ -94,6 +95,10 @@ def run_test(image_name, test_name, bootstrap_pip_spec, test_files, upgrade, ins
|
|||||||
copy_to_container(test_name, os.path.join(source_path, 'bootstrap/.'), '/srv/src')
|
copy_to_container(test_name, os.path.join(source_path, 'bootstrap/.'), '/srv/src')
|
||||||
copy_to_container(test_name, os.path.join(source_path, 'integration-tests/'), '/srv/src')
|
copy_to_container(test_name, os.path.join(source_path, 'integration-tests/'), '/srv/src')
|
||||||
|
|
||||||
|
# These logs can be very relevant to debug a container startup failure
|
||||||
|
print(f"--- Start of logs from the container: {test_name}")
|
||||||
|
print(subprocess.check_output(['docker', 'logs', test_name]).decode())
|
||||||
|
print(f"--- End of logs from the container: {test_name}")
|
||||||
|
|
||||||
# Install TLJH from the default branch first to test upgrades
|
# Install TLJH from the default branch first to test upgrades
|
||||||
if upgrade:
|
if upgrade:
|
||||||
@@ -115,7 +120,10 @@ def run_test(image_name, test_name, bootstrap_pip_spec, test_files, upgrade, ins
|
|||||||
)
|
)
|
||||||
run_container_command(
|
run_container_command(
|
||||||
test_name,
|
test_name,
|
||||||
'/opt/tljh/hub/bin/python3 -m pytest -v {}'.format(
|
# We abort pytest after two failures as a compromise between wanting to
|
||||||
|
# avoid a flood of logs while still understanding if multiple tests
|
||||||
|
# would fail.
|
||||||
|
'/opt/tljh/hub/bin/python3 -m pytest --verbose --maxfail=2 --color=yes --durations=10 --capture=no {}'.format(
|
||||||
' '.join([os.path.join('/srv/src/integration-tests/', f) for f in test_files])
|
' '.join([os.path.join('/srv/src/integration-tests/', f) for f in test_files])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -138,13 +146,21 @@ def main():
|
|||||||
argparser = argparse.ArgumentParser()
|
argparser = argparse.ArgumentParser()
|
||||||
subparsers = argparser.add_subparsers(dest='action')
|
subparsers = argparser.add_subparsers(dest='action')
|
||||||
|
|
||||||
subparsers.add_parser('build-image')
|
build_image_parser = subparsers.add_parser('build-image')
|
||||||
|
build_image_parser.add_argument(
|
||||||
|
"--build-arg",
|
||||||
|
action="append",
|
||||||
|
dest="build_args",
|
||||||
|
)
|
||||||
|
|
||||||
subparsers.add_parser('stop-container').add_argument(
|
subparsers.add_parser('stop-container').add_argument(
|
||||||
'container_name'
|
'container_name'
|
||||||
)
|
)
|
||||||
|
|
||||||
subparsers.add_parser('start-container').add_argument(
|
subparsers.add_parser('start-container').add_argument(
|
||||||
'container_name'
|
'container_name'
|
||||||
)
|
)
|
||||||
|
|
||||||
run_parser = subparsers.add_parser('run')
|
run_parser = subparsers.add_parser('run')
|
||||||
run_parser.add_argument('container_name')
|
run_parser.add_argument('container_name')
|
||||||
run_parser.add_argument('command')
|
run_parser.add_argument('command')
|
||||||
@@ -181,7 +197,7 @@ def main():
|
|||||||
elif args.action == 'stop-container':
|
elif args.action == 'stop-container':
|
||||||
stop_container(args.container_name)
|
stop_container(args.container_name)
|
||||||
elif args.action == 'build-image':
|
elif args.action == 'build-image':
|
||||||
build_systemd_image(image_name, 'integration-tests')
|
build_systemd_image(image_name, 'integration-tests', args.build_args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
181
.github/workflows/integration-test.yaml
vendored
181
.github/workflows/integration-test.yaml
vendored
@@ -1,41 +1,182 @@
|
|||||||
|
# This is a GitHub workflow defining a set of jobs with a set of steps.
|
||||||
|
# ref: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
|
||||||
|
#
|
||||||
|
name: Integration tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- "**.rst"
|
||||||
|
- ".github/workflows/*"
|
||||||
|
- "!.github/workflows/integration-test.yaml"
|
||||||
push:
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- "**.rst"
|
||||||
|
- ".github/workflows/*"
|
||||||
|
- "!.github/workflows/integration-test.yaml"
|
||||||
|
branches-ignore:
|
||||||
|
- "dependabot/**"
|
||||||
|
- "pre-commit-ci-update-config"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
integration-test:
|
|
||||||
runs-on: ubuntu-18.04
|
# This job is used as a workaround to a limitation when using a matrix of
|
||||||
|
# variations that a job should be executed against. The limitation is that a
|
||||||
|
# matrix once defined can't include any conditions.
|
||||||
|
#
|
||||||
|
# What this job does before our real test job with a matrix of variations run,
|
||||||
|
# is to decide on that matrix of variations a conditional logic of our choice.
|
||||||
|
#
|
||||||
|
# For more details, see this excellent stack overflow answer:
|
||||||
|
# https://stackoverflow.com/a/65434401/2220152
|
||||||
|
#
|
||||||
|
decide-on-test-jobs-to-run:
|
||||||
|
name: Decide on test jobs to run
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# Currently, this logic filters out a matrix entry equaling a specific git
|
||||||
|
# reference identified by "dont_run_on_ref".
|
||||||
|
- name: Decide on test jobs to run
|
||||||
|
id: set-matrix
|
||||||
|
run: |
|
||||||
|
matrix_post_filter=$(
|
||||||
|
echo "$matrix_include_pre_filter" \
|
||||||
|
| yq e --output-format=json '.' - \
|
||||||
|
| jq '{"include": map( . | select(.dont_run_on_ref != "${{ github.ref }}" ))}'
|
||||||
|
)
|
||||||
|
echo ::set-output name=matrix::$(echo "$matrix_post_filter")
|
||||||
|
|
||||||
|
echo "The subsequent job's matrix are:"
|
||||||
|
echo $matrix_post_filter | jq '.'
|
||||||
|
env:
|
||||||
|
matrix_include_pre_filter: |
|
||||||
|
- name: "Int. tests: Ubuntu 18.04, Py 3.6"
|
||||||
|
ubuntu_version: "18.04"
|
||||||
|
python_version: "3.6"
|
||||||
|
extra_flags: ""
|
||||||
|
- name: "Int. tests: Ubuntu 20.04, Py 3.9"
|
||||||
|
ubuntu_version: "20.04"
|
||||||
|
python_version: "3.9"
|
||||||
|
extra_flags: ""
|
||||||
|
- name: "Int. tests: Ubuntu 21.10, Py 3.9"
|
||||||
|
runs_on: "20.04"
|
||||||
|
ubuntu_version: "21.10"
|
||||||
|
python_version: "3.9"
|
||||||
|
extra_flags: ""
|
||||||
|
- name: "Int. tests: Ubuntu 20.04, Py 3.9, --upgrade"
|
||||||
|
ubuntu_version: "20.04"
|
||||||
|
python_version: "3.9"
|
||||||
|
extra_flags: --upgrade
|
||||||
|
dont_run_on_ref: refs/heads/master
|
||||||
|
|
||||||
|
integration-tests:
|
||||||
|
needs: decide-on-test-jobs-to-run
|
||||||
|
|
||||||
|
# runs-on can only be configured to the LTS releases of ubuntu (18.04,
|
||||||
|
# 20.04, ...), so if we want to test against the latest non-LTS release, we
|
||||||
|
# must compromise when configuring runs-on and configure runs-on to be the
|
||||||
|
# latest LTS release instead.
|
||||||
|
#
|
||||||
|
# This can have consequences because actions like actions/setup-python will
|
||||||
|
# mount cached installations associated with the chosen runs-on environment.
|
||||||
|
#
|
||||||
|
runs-on: ${{ format('ubuntu-{0}', matrix.runs_on || matrix.ubuntu_version) }}
|
||||||
|
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.decide-on-test-jobs-to-run.outputs.matrix) }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: 3.6
|
python-version: ${{ matrix.python_version }}
|
||||||
|
|
||||||
|
- name: Install pytest
|
||||||
|
run: python3 -m pip install pytest
|
||||||
|
|
||||||
|
# We abort pytest after two failures as a compromise between wanting to
|
||||||
|
# avoid a flood of logs while still understanding if multiple tests would
|
||||||
|
# fail.
|
||||||
|
- name: Run bootstrap tests (Runs in/Builds ubuntu:${{ matrix.ubuntu_version }} derived image)
|
||||||
|
run: |
|
||||||
|
pytest --verbose --maxfail=2 --color=yes --durations=10 --capture=no \
|
||||||
|
integration-tests/test_bootstrap.py
|
||||||
|
timeout-minutes: 15
|
||||||
|
env:
|
||||||
|
# integration-tests/test_bootstrap.py will build and start containers
|
||||||
|
# based on this environment variable. This is similar to how
|
||||||
|
# .github/integration-test.py build-image can take a --build-arg
|
||||||
|
# setting the ubuntu_version.
|
||||||
|
UBUNTU_VERSION: ${{ matrix.ubuntu_version }}
|
||||||
|
|
||||||
|
# We build a docker image from wherein we will work
|
||||||
|
- name: Build systemd image (Builds ubuntu:${{ matrix.ubuntu_version }} derived image)
|
||||||
|
run: |
|
||||||
|
.github/integration-test.py build-image \
|
||||||
|
--build-arg "ubuntu_version=${{ matrix.ubuntu_version }}"
|
||||||
|
|
||||||
|
# FIXME: Make the logic below easier to follow.
|
||||||
|
# - In short, setting BOOTSTRAP_PIP_SPEC here, specifies from what
|
||||||
|
# location the tljh python package should be installed from. In this
|
||||||
|
# GitHub Workflow's test job, we provide a remote reference to itself as
|
||||||
|
# found on GitHub - this could be the HEAD of a PR branch or the default
|
||||||
|
# branch on merge.
|
||||||
|
#
|
||||||
|
# Overview of how this logic influences the end result.
|
||||||
|
# - integration-test.yaml:
|
||||||
|
# Runs integration-test.py by passing --bootstrap-pip-spec flag with a
|
||||||
|
# reference to the pull request on GitHub.
|
||||||
|
# - integration-test.py:
|
||||||
|
# Starts a pre-build systemd container, setting the
|
||||||
|
# TLJH_BOOTSTRAP_PIP_SPEC based on its passed --bootstrap-pip-spec value.
|
||||||
|
# - systemd container:
|
||||||
|
# Runs bootstrap.py
|
||||||
|
# - bootstrap.py
|
||||||
|
# Makes use of TLJH_BOOTSTRAP_PIP_SPEC environment variable to install
|
||||||
|
# the tljh package from a given location, which could be a local git
|
||||||
|
# clone of this repo where setup.py resides, or a reference to some
|
||||||
|
# GitHub branch for example.
|
||||||
- name: Set BOOTSTRAP_PIP_SPEC value
|
- name: Set BOOTSTRAP_PIP_SPEC value
|
||||||
run: |
|
run: |
|
||||||
echo "BOOTSTRAP_PIP_SPEC=git+https://github.com/$GITHUB_REPOSITORY.git@$GITHUB_REF" >> $GITHUB_ENV
|
echo "BOOTSTRAP_PIP_SPEC=git+https://github.com/$GITHUB_REPOSITORY.git@$GITHUB_REF" >> $GITHUB_ENV
|
||||||
- name: Build systemd image
|
echo $BOOTSTRAP_PIP_SPEC
|
||||||
|
|
||||||
|
- name: Run basic tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
|
||||||
run: |
|
run: |
|
||||||
.github/integration-test.py build-image
|
.github/integration-test.py run-test basic-tests \
|
||||||
- name: Run bootstrap checks
|
|
||||||
run: |
|
|
||||||
python3 -m pip install pytest
|
|
||||||
pytest integration-tests/test_bootstrap.py -s
|
|
||||||
- name: Run basic tests
|
|
||||||
run: |
|
|
||||||
.github/integration-test.py run-test \
|
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
||||||
basic-tests test_hub.py test_proxy.py \
|
${{ matrix.extra_flags }} \
|
||||||
test_install.py test_extensions.py
|
test_hub.py \
|
||||||
- name: Run admin tests
|
test_proxy.py \
|
||||||
|
test_install.py \
|
||||||
|
test_extensions.py
|
||||||
|
timeout-minutes: 15
|
||||||
|
|
||||||
|
- name: Run admin tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
|
||||||
run: |
|
run: |
|
||||||
.github/integration-test.py run-test \
|
.github/integration-test.py run-test admin-tests \
|
||||||
--installer-args "--admin admin:admin" \
|
--installer-args "--admin admin:admin" \
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
||||||
basic-tests test_admin_installer.py \
|
${{ matrix.extra_flags }} \
|
||||||
- name: Run plugin tests
|
test_admin_installer.py
|
||||||
|
timeout-minutes: 15
|
||||||
|
|
||||||
|
- name: Run plugin tests (Runs in ubuntu:${{ matrix.ubuntu_version }} derived image)
|
||||||
run: |
|
run: |
|
||||||
.github/integration-test.py run-test \
|
.github/integration-test.py run-test plugin-tests \
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
||||||
--installer-args "--plugin /srv/src/integration-tests/plugins/simplest" \
|
--installer-args "--plugin /srv/src/integration-tests/plugins/simplest" \
|
||||||
plugins test_simplest_plugin.py \
|
${{ matrix.extra_flags }} \
|
||||||
|
test_simplest_plugin.py
|
||||||
|
timeout-minutes: 15
|
||||||
|
|||||||
96
.github/workflows/unit-test.yaml
vendored
96
.github/workflows/unit-test.yaml
vendored
@@ -1,36 +1,108 @@
|
|||||||
|
# This is a GitHub workflow defining a set of jobs with a set of steps.
|
||||||
|
# ref: https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
|
||||||
|
#
|
||||||
|
name: Unit tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- "**.rst"
|
||||||
|
- ".github/workflows/*"
|
||||||
|
- "!.github/workflows/unit-test.yaml"
|
||||||
push:
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- "docs/**"
|
||||||
|
- "**.md"
|
||||||
|
- "**.rst"
|
||||||
|
- ".github/workflows/*"
|
||||||
|
- "!.github/workflows/unit-test.yaml"
|
||||||
|
branches-ignore:
|
||||||
|
- "dependabot/**"
|
||||||
|
- "pre-commit-ci-update-config"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
unit-test:
|
unit-tests:
|
||||||
runs-on: ubuntu-18.04
|
name: ${{ matrix.name }}
|
||||||
container: ubuntu:18.04
|
|
||||||
|
# runs-on can only be configured to the LTS releases of ubuntu (18.04,
|
||||||
|
# 20.04, ...), so if we want to test against the latest non-LTS release, we
|
||||||
|
# must compromise when configuring runs-on and configure runs-on to be the
|
||||||
|
# latest LTS release instead.
|
||||||
|
#
|
||||||
|
# This can have consequences because actions like actions/setup-python will
|
||||||
|
# mount cached installations associated with the chosen runs-on environment.
|
||||||
|
#
|
||||||
|
runs-on: ${{ format('ubuntu-{0}', matrix.runs_on || matrix.ubuntu_version) }}
|
||||||
|
container: ubuntu:${{ matrix.ubuntu_version }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Unit tests: Ubuntu 18.04, Py 3.6"
|
||||||
|
ubuntu_version: "18.04"
|
||||||
|
python_version: "3.6"
|
||||||
|
- name: "Unit tests: Ubuntu 20.04, Py 3.9"
|
||||||
|
ubuntu_version: "20.04"
|
||||||
|
python_version: "3.9"
|
||||||
|
# Test against Ubuntu 21.10 fails as of 2021-10-18 fail with the error
|
||||||
|
# described in: https://github.com/jupyterhub/the-littlest-jupyterhub/issues/714#issuecomment-945154101
|
||||||
|
#
|
||||||
|
# - name: "Unit tests: Ubuntu 21.10, Py 3.9"
|
||||||
|
# runs_on: "20.04"
|
||||||
|
# ubuntu_version: "21.10"
|
||||||
|
# python_version: "3.9"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: 3.6
|
python-version: ${{ matrix.python_version }}
|
||||||
|
|
||||||
- name: Install venv, git and setup venv
|
- name: Install venv, git and setup venv
|
||||||
run: |
|
run: |
|
||||||
apt-get update --yes && apt-get install --yes python3-venv git
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get update
|
||||||
|
apt-get install --yes \
|
||||||
|
python3-venv \
|
||||||
|
git
|
||||||
|
|
||||||
python3 -m venv /srv/venv
|
python3 -m venv /srv/venv
|
||||||
echo '/srv/venv/bin' >> $GITHUB_PATH
|
echo '/srv/venv/bin' >> $GITHUB_PATH
|
||||||
- name: Cache pip deps
|
|
||||||
|
# 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@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: /srv/venv/
|
path: /srv/venv/
|
||||||
key: ${{ runner.os }}-pip-dependencies-${{ hashFiles('*setup.py', '*dev-requirements.txt') }}
|
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
|
- name: Install Python dependencies
|
||||||
|
# Keep pip version pinning in sync with the one in bootstrap.py!
|
||||||
|
# See changelog at https://pip.pypa.io/en/latest/news/#changelog
|
||||||
run: |
|
run: |
|
||||||
python3 -m pip install -U pip==20.0.*
|
python3 -m pip install -U "pip==21.3.*"
|
||||||
python3 -m pip install -r dev-requirements.txt
|
python3 -m pip install -r dev-requirements.txt
|
||||||
python3 -m pip install -e .
|
python3 -m pip install -e .
|
||||||
pip freeze
|
pip freeze
|
||||||
|
|
||||||
|
# We abort pytest after two failures as a compromise between wanting to
|
||||||
|
# avoid a flood of logs while still understanding if multiple tests would
|
||||||
|
# fail.
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: pytest --verbose --maxfail=2 --color=yes --durations=10 --cov=tljh tests/
|
||||||
pytest --cov=tljh tests/
|
timeout-minutes: 15
|
||||||
|
|
||||||
- name: Upload code coverage stats
|
- name: Upload code coverage stats
|
||||||
run: |
|
run: codecov
|
||||||
codecov
|
|
||||||
|
|||||||
42
.github/workflows/upgrade-test.yaml
vendored
42
.github/workflows/upgrade-test.yaml
vendored
@@ -1,42 +0,0 @@
|
|||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
upgrade-test:
|
|
||||||
if: ${{ github.ref != 'refs/heads/master' }}
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: 3.6
|
|
||||||
- name: Set BOOTSTRAP_PIP_SPEC value
|
|
||||||
run: |
|
|
||||||
echo "BOOTSTRAP_PIP_SPEC=git+https://github.com/$GITHUB_REPOSITORY.git@$GITHUB_REF" >> $GITHUB_ENV
|
|
||||||
echo $BOOTSTRAP_PIP_SPEC
|
|
||||||
- name: Build systemd image
|
|
||||||
run: |
|
|
||||||
.github/integration-test.py build-image
|
|
||||||
- name: Run basic tests
|
|
||||||
run: |
|
|
||||||
.github/integration-test.py run-test \
|
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
|
||||||
basic-tests test_hub.py test_proxy.py \
|
|
||||||
test_install.py test_extensions.py \
|
|
||||||
--upgrade
|
|
||||||
- name: Run admin tests
|
|
||||||
run: |
|
|
||||||
.github/integration-test.py run-test \
|
|
||||||
--installer-args "--admin admin:admin" \
|
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
|
||||||
basic-tests test_admin_installer.py \
|
|
||||||
--upgrade
|
|
||||||
- name: Run plugin tests
|
|
||||||
run: |
|
|
||||||
.github/integration-test.py run-test \
|
|
||||||
--bootstrap-pip-spec "$BOOTSTRAP_PIP_SPEC" \
|
|
||||||
--installer-args "--plugin /srv/src/integration-tests/plugins/simplest" \
|
|
||||||
plugins test_simplest_plugin.py \
|
|
||||||
--upgrade
|
|
||||||
69
README.md
Normal file
69
README.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# The Littlest JupyterHub
|
||||||
|
|
||||||
|
[](https://tljh.jupyter.org/en/latest/?badge=latest)
|
||||||
|
[](https://github.com/jupyterhub/the-littlest-jupyterhub/actions)
|
||||||
|
[](https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub)
|
||||||
|
[](https://github.com/jupyterhub/the-littlest-jupyterhub/issues)
|
||||||
|
[](https://discourse.jupyter.org/c/jupyterhub/tljh)
|
||||||
|
[](https://gitter.im/jupyterhub/jupyterhub)
|
||||||
|
[](https://tljh.jupyter.org/en/latest/contributing/index.html)
|
||||||
|
|
||||||
|
**The Littlest JupyterHub** (TLJH) distribution helps you provide Jupyter Notebooks
|
||||||
|
to 1-100 users on a single server.
|
||||||
|
|
||||||
|
The primary audience are people who do not consider themselves 'system administrators'
|
||||||
|
but would like to provide hosted Jupyter Notebooks for their students or users.
|
||||||
|
All users are provided with the same environment, and administrators
|
||||||
|
can easily install libraries into this environment without any specialized knowledge.
|
||||||
|
|
||||||
|
See the [latest documentation](https://the-littlest-jupyterhub.readthedocs.io)
|
||||||
|
for more information on using The Littlest JupyterHub.
|
||||||
|
|
||||||
|
For support questions please search or post to [our forum](https://discourse.jupyter.org/c/jupyterhub/).
|
||||||
|
|
||||||
|
See the [contributing guide](https://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/index.html)
|
||||||
|
for information on the different ways of contributing to The Littlest JupyterHub.
|
||||||
|
|
||||||
|
See [this blog post](http://words.yuvi.in/post/the-littlest-jupyterhub/) for
|
||||||
|
more information.
|
||||||
|
|
||||||
|
## Development Status
|
||||||
|
|
||||||
|
This project is currently in **beta** state. Folks have been using installations
|
||||||
|
of TLJH for more than a year now to great success. While we try hard not to, we
|
||||||
|
might still make breaking changes that have no clear upgrade pathway.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The Littlest JupyterHub (TLJH) can run on any server that is running at least
|
||||||
|
**Ubuntu 18.04**. Earlier versions of Ubuntu are not supported.
|
||||||
|
We have several tutorials to get you started.
|
||||||
|
|
||||||
|
- Tutorials to create a new server from scratch on a cloud provider & run TLJH
|
||||||
|
on it. These are **recommended** if you do not have much experience setting up
|
||||||
|
servers.
|
||||||
|
|
||||||
|
- [Digital Ocean](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/digitalocean.html)
|
||||||
|
- [OVH](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/ovh.html)
|
||||||
|
- [Google Cloud](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/google.html)
|
||||||
|
- [Jetstream](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/jetstream.html)
|
||||||
|
- [Amazon Web Services](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/amazon.html)
|
||||||
|
- [Microsoft Azure](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/azure.html)
|
||||||
|
- ... your favorite provider here, if you can contribute!
|
||||||
|
|
||||||
|
- [Tutorial to install TLJH on an already running server you have root access to](https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/custom-server.html).
|
||||||
|
You should use this if your cloud provider does not already have a direct tutorial,
|
||||||
|
or if you have experience setting up servers.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Our latest documentation is at: https://the-littlest-jupyterhub.readthedocs.io
|
||||||
|
|
||||||
|
We place a high importance on consistency, readability and completeness of
|
||||||
|
documentation. If a feature is not documented, it does not exist. If a behavior
|
||||||
|
is not documented, it is a bug! We try to treat our documentation like we treat
|
||||||
|
our code: we aim to improve it as often as possible.
|
||||||
|
|
||||||
|
If something is confusing to you in the documentation, it is a bug. We would be
|
||||||
|
happy if you could [file an issue](https://github.com/jupyterhub/the-littlest-jupyterhub/issues) about it - or
|
||||||
|
even better, [contribute a documentation fix](http://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/docs.html)!
|
||||||
81
README.rst
81
README.rst
@@ -1,81 +0,0 @@
|
|||||||
=======================
|
|
||||||
The Littlest JupyterHub
|
|
||||||
=======================
|
|
||||||
|
|
||||||
.. image:: https://circleci.com/gh/jupyterhub/the-littlest-jupyterhub.svg?style=shield
|
|
||||||
:target: https://circleci.com/gh/jupyterhub/the-littlest-jupyterhub
|
|
||||||
.. image:: https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub/branch/master/graph/badge.svg
|
|
||||||
:target: https://codecov.io/gh/jupyterhub/the-littlest-jupyterhub
|
|
||||||
.. image:: https://readthedocs.org/projects/the-littlest-jupyterhub/badge/?version=latest
|
|
||||||
:target: https://the-littlest-jupyterhub.readthedocs.io
|
|
||||||
.. image:: https://badges.gitter.im/jupyterhub/jupyterhub.svg
|
|
||||||
:target: https://gitter.im/jupyterhub/jupyterhub
|
|
||||||
.. image:: https://img.shields.io/badge/I_want_to_contribute!-grey?logo=jupyter
|
|
||||||
:target: https://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/index.html
|
|
||||||
|
|
||||||
**The Littlest JupyterHub** (TLJH) distribution helps you provide Jupyter Notebooks
|
|
||||||
to 1-100 users on a single server.
|
|
||||||
|
|
||||||
The primary audience are people who do not consider themselves 'system administrators'
|
|
||||||
but would like to provide hosted Jupyter Notebooks for their students or users.
|
|
||||||
All users are provided with the same environment, and administrators
|
|
||||||
can easily install libraries into this environment without any specialized knowledge.
|
|
||||||
|
|
||||||
See the `latest documentation <https://the-littlest-jupyterhub.readthedocs.io>`_
|
|
||||||
for more information on using The Littlest JupyterHub.
|
|
||||||
|
|
||||||
For support questions please search or post to `our forum <https://discourse.jupyter.org/c/jupyterhub/>`_.
|
|
||||||
|
|
||||||
See the `contributing guide <https://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/index.html>`_
|
|
||||||
for information on the different ways of contributing to The Littlest JupyterHub.
|
|
||||||
|
|
||||||
See `this blog post <http://words.yuvi.in/post/the-littlest-jupyterhub/>`_ for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
|
|
||||||
Development Status
|
|
||||||
==================
|
|
||||||
|
|
||||||
This project is currently in **beta** state. Folks have been using installations
|
|
||||||
of TLJH for more than a year now to great success. While we try hard not to, we
|
|
||||||
might still make breaking changes that have no clear upgrade pathway.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
The Littlest JupyterHub (TLJH) can run on any server that is running at least
|
|
||||||
**Ubuntu 18.04**. Earlier versions of Ubuntu are not supported.
|
|
||||||
We have several tutorials to get you started.
|
|
||||||
|
|
||||||
- Tutorials to create a new server from scratch on a cloud provider & run TLJH
|
|
||||||
on it. These are **recommended** if you do not have much experience setting up
|
|
||||||
servers.
|
|
||||||
|
|
||||||
- `Digital Ocean <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/digitalocean.html>`_
|
|
||||||
- `OVH <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/ovh.html>`_
|
|
||||||
- `Google Cloud <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/google.html>`_
|
|
||||||
- `Jetstream <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/jetstream.html>`_
|
|
||||||
- `Amazon Web Services <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/amazon.html>`_
|
|
||||||
- `Microsoft Azure <https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/azure.html>`_
|
|
||||||
- ... your favorite provider here, if you can contribute!
|
|
||||||
|
|
||||||
- `Tutorial to install TLJH on an already running server you have root access to
|
|
||||||
<https://the-littlest-jupyterhub.readthedocs.io/en/latest/install/custom-server.html>`_.
|
|
||||||
You should use this if your cloud provider does not already have a direct tutorial,
|
|
||||||
or if you have experience setting up servers.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
=============
|
|
||||||
|
|
||||||
Our latest documentation is at: https://the-littlest-jupyterhub.readthedocs.io
|
|
||||||
|
|
||||||
We place a high importance on consistency, readability and completeness of
|
|
||||||
documentation. If a feature is not documented, it does not exist. If a behavior
|
|
||||||
is not documented, it is a bug! We try to treat our documentation like we treat
|
|
||||||
our code: we aim to improve it as often as possible.
|
|
||||||
|
|
||||||
If something is confusing to you in the documentation, it is a bug. We would be
|
|
||||||
happy if you could `file an issue
|
|
||||||
<https://github.com/jupyterhub/the-littlest-jupyterhub/issues>`_ about it - or
|
|
||||||
even better, `contribute a documentation fix
|
|
||||||
<http://the-littlest-jupyterhub.readthedocs.io/en/latest/contributing/docs.html>`_!
|
|
||||||
@@ -311,22 +311,23 @@ def main():
|
|||||||
logger.info('Existing TLJH installation not detected, installing...')
|
logger.info('Existing TLJH installation not detected, installing...')
|
||||||
logger.info('Setting up hub environment...')
|
logger.info('Setting up hub environment...')
|
||||||
logger.info('Installing Python, venv, pip, and git via apt-get...')
|
logger.info('Installing Python, venv, pip, and git via apt-get...')
|
||||||
# Install software-properties-common, so we can get add-apt-repository
|
|
||||||
# That helps us make sure the universe repository is enabled, since
|
|
||||||
# that's where the python3-pip package lives. In some very minimal base
|
|
||||||
# VM images, it looks like the universe repository is disabled by default,
|
|
||||||
# causing bootstrapping to fail.
|
|
||||||
run_subprocess(['apt-get', 'update', '--yes'])
|
|
||||||
run_subprocess(['apt-get', 'install', '--yes', 'software-properties-common'])
|
|
||||||
run_subprocess(['add-apt-repository', 'universe'])
|
|
||||||
|
|
||||||
run_subprocess(['apt-get', 'update', '--yes'])
|
# In some very minimal base VM images, it looks like the "universe" apt
|
||||||
run_subprocess(['apt-get', 'install', '--yes',
|
# package repository is disabled by default, causing bootstrapping to
|
||||||
'python3',
|
# fail. We install the software-properties-common package so we can get
|
||||||
'python3-venv',
|
# the add-apt-repository command to make sure the universe repository is
|
||||||
'python3-pip',
|
# enabled, since that's where the python3-pip package lives.
|
||||||
'git'
|
#
|
||||||
])
|
# In Ubuntu 21.10 DEBIAN_FRONTEND has found to be needed to avoid
|
||||||
|
# getting stuck on an input prompt during apt-get install.
|
||||||
|
#
|
||||||
|
apt_get_adjusted_env = os.environ.copy()
|
||||||
|
apt_get_adjusted_env["DEBIAN_FRONTEND"] = "noninteractive"
|
||||||
|
run_subprocess(['apt-get', 'update'])
|
||||||
|
run_subprocess(['apt-get', 'install', '--yes', 'software-properties-common'], env=apt_get_adjusted_env)
|
||||||
|
run_subprocess(['add-apt-repository', 'universe', '--yes'])
|
||||||
|
run_subprocess(['apt-get', 'update'])
|
||||||
|
run_subprocess(['apt-get', 'install', '--yes', 'python3', 'python3-venv', 'python3-pip', 'git'], env=apt_get_adjusted_env)
|
||||||
|
|
||||||
logger.info('Setting up virtual environment at {}'.format(hub_prefix))
|
logger.info('Setting up virtual environment at {}'.format(hub_prefix))
|
||||||
os.makedirs(hub_prefix, exist_ok=True)
|
os.makedirs(hub_prefix, exist_ok=True)
|
||||||
@@ -334,8 +335,10 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
# Upgrade pip
|
# Upgrade pip
|
||||||
|
# Keep pip version pinning in sync with the one in unit-test.yml!
|
||||||
|
# See changelog at https://pip.pypa.io/en/latest/news/#changelog
|
||||||
logger.info('Upgrading pip...')
|
logger.info('Upgrading pip...')
|
||||||
run_subprocess([pip_bin, 'install', '--upgrade', 'pip==20.0.*'])
|
run_subprocess([pip_bin, 'install', '--upgrade', 'pip==21.3.*'])
|
||||||
|
|
||||||
|
|
||||||
# Install/upgrade TLJH installer
|
# Install/upgrade TLJH installer
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ that the various components fit together and work as they should.
|
|||||||
So we write a lot of integration tests, and put in more effort
|
So we write a lot of integration tests, and put in more effort
|
||||||
towards them than unit tests.
|
towards them than unit tests.
|
||||||
|
|
||||||
All integration tests are run on `CircleCI <https://circleci.com>`_
|
All integration tests are run in `GitHub Actions <https://github.com/jupyterhub/the-littlest-jupyterhub/actions>`_
|
||||||
for each PR and merge, making sure we don't have broken tests
|
for each PR and merge, making sure we don't have broken tests
|
||||||
for too long.
|
for too long.
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ You can then run the tests with:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
.circleci/integration-test.py run-test <name-of-run> <test-file-names>
|
.github/integration-test.py run-test <name-of-run> <test-file-names>
|
||||||
|
|
||||||
- ``<name-of-run>`` is an identifier for the tests - you can choose anything you want
|
- ``<name-of-run>`` is an identifier for the tests - you can choose anything you want
|
||||||
- ``<test-file-names>>`` is list of test files (under ``integration-tests``) that should be run in one go.
|
- ``<test-file-names>>`` is list of test files (under ``integration-tests``) that should be run in one go.
|
||||||
@@ -48,8 +48,9 @@ For example, to run all the basic tests, you would write:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
.circleci/integration-test.py run-test basic-tests \
|
.github/integration-test.py run-test basic-tests \
|
||||||
test_hub.py \
|
test_hub.py \
|
||||||
|
test_proxy.py \
|
||||||
test_install.py \
|
test_install.py \
|
||||||
test_extensions.py
|
test_extensions.py
|
||||||
|
|
||||||
@@ -61,5 +62,5 @@ parameter:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
.circleci/integration-test.py run-test <name-of-run> <test-file-names> \
|
.github/integration-test.py run-test <name-of-run> <test-file-names> \
|
||||||
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
--bootstrap-pip-spec="git+https://github.com/your-username/the-littlest-jupyterhub.git@branch-name"
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
# Systemd inside a Docker container, for CI only
|
# Systemd inside a Docker container, for CI only
|
||||||
FROM ubuntu:18.04
|
ARG ubuntu_version=20.04
|
||||||
|
FROM ubuntu:${ubuntu_version}
|
||||||
|
|
||||||
RUN apt-get update --yes
|
# DEBIAN_FRONTEND is set to avoid being asked for input and hang during build:
|
||||||
|
# https://anonoz.github.io/tech/2020/04/24/docker-build-stuck-tzdata.html
|
||||||
RUN apt-get install --yes systemd curl git sudo
|
RUN export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install --yes \
|
||||||
|
systemd \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
sudo \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Kill all the things we don't need
|
# Kill all the things we don't need
|
||||||
RUN find /etc/systemd/system \
|
RUN find /etc/systemd/system \
|
||||||
@@ -25,4 +33,4 @@ STOPSIGNAL SIGRTMIN+3
|
|||||||
#ENV TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
|
#ENV TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
|
||||||
#ENV PATH=/opt/tljh/hub/bin:${PATH}
|
#ENV PATH=/opt/tljh/hub/bin:${PATH}
|
||||||
|
|
||||||
CMD ["/bin/bash", "-c", "exec /sbin/init --log-target=journal 3>&1"]
|
CMD ["/bin/bash", "-c", "exec /lib/systemd/systemd --log-target=journal 3>&1"]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ Test running bootstrap script in different circumstances
|
|||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
from textwrap import dedent
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
@@ -39,8 +38,43 @@ def get_bootstrap_script_location(container_name, show_progress_page):
|
|||||||
subprocess.check_call(["docker", "cp", source_path, f"{container_name}:/srv/src"])
|
subprocess.check_call(["docker", "cp", source_path, f"{container_name}:/srv/src"])
|
||||||
return bootstrap_script
|
return bootstrap_script
|
||||||
|
|
||||||
|
# FIXME: Refactor this function to easier to understand using the following
|
||||||
|
# parameters
|
||||||
|
#
|
||||||
|
# - param: container_apt_packages
|
||||||
|
# - param: bootstrap_tljh_source
|
||||||
|
# - local: copies local tljh repo to container and configures bootstrap to
|
||||||
|
# install tljh from copied repo
|
||||||
|
# - github: configures bootstrap to install tljh from the official github repo
|
||||||
|
# - <pip spec>: configures bootstrap to install tljh from any given remote location
|
||||||
|
# - param: bootstrap_flags
|
||||||
|
#
|
||||||
|
# FIXME: Consider stripping logic in this file to only testing if the bootstrap
|
||||||
|
# script successfully detects the too old Ubuntu version and the lack of
|
||||||
|
# systemd. The remaining test named test_progress_page could rely on
|
||||||
|
# running against the systemd container that cab be built by
|
||||||
|
# integration-test.py.
|
||||||
|
#
|
||||||
|
def run_bootstrap_after_preparing_container(container_name, image, show_progress_page=False):
|
||||||
|
"""
|
||||||
|
1. Stops old container
|
||||||
|
2. Starts --detached container
|
||||||
|
3. Installs apt packages in container
|
||||||
|
4. Two situations
|
||||||
|
|
||||||
def run_bootstrap(container_name, image, show_progress_page=False):
|
A) limited test (--show-progress-page=false)
|
||||||
|
- Copies ./bootstrap/ folder content to container /srv/src
|
||||||
|
- Runs copied bootstrap/bootstrap.py without flags
|
||||||
|
|
||||||
|
B) full test (--show-progress-page=true)
|
||||||
|
- Copies ./ folder content to the container /srv/src
|
||||||
|
- Runs copied bootstrap/bootstrap.py with environment variables
|
||||||
|
- TLJH_BOOTSTRAP_DEV=yes
|
||||||
|
This makes --editable be used when installing the tljh package
|
||||||
|
- TLJH_BOOTSTRAP_PIP_SPEC=/srv/src
|
||||||
|
This makes us install tljh from the given location instead of from
|
||||||
|
github.com/jupyterhub/the-littlest-jupyterhub
|
||||||
|
"""
|
||||||
# stop container if it is already running
|
# stop container if it is already running
|
||||||
subprocess.run(["docker", "rm", "-f", container_name])
|
subprocess.run(["docker", "rm", "-f", container_name])
|
||||||
|
|
||||||
@@ -49,9 +83,9 @@ def run_bootstrap(container_name, image, show_progress_page=False):
|
|||||||
[
|
[
|
||||||
"docker",
|
"docker",
|
||||||
"run",
|
"run",
|
||||||
|
"--env=DEBIAN_FRONTEND=noninteractive",
|
||||||
"--detach",
|
"--detach",
|
||||||
"--name",
|
f"--name={container_name}",
|
||||||
container_name,
|
|
||||||
image,
|
image,
|
||||||
"/bin/bash",
|
"/bin/bash",
|
||||||
"-c",
|
"-c",
|
||||||
@@ -84,24 +118,17 @@ def test_ubuntu_too_old():
|
|||||||
"""
|
"""
|
||||||
Error with a useful message when running in older Ubuntu
|
Error with a useful message when running in older Ubuntu
|
||||||
"""
|
"""
|
||||||
output = run_bootstrap("old-distro-test", "ubuntu:16.04")
|
output = run_bootstrap_after_preparing_container("old-distro-test", "ubuntu:16.04")
|
||||||
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 18.04 or higher\n"
|
assert output.stdout == "The Littlest JupyterHub requires Ubuntu 18.04 or higher\n"
|
||||||
assert output.returncode == 1
|
assert output.returncode == 1
|
||||||
|
|
||||||
|
|
||||||
def test_inside_no_systemd_docker():
|
def test_inside_no_systemd_docker():
|
||||||
output = run_bootstrap("plain-docker-test", "ubuntu:18.04")
|
output = run_bootstrap_after_preparing_container(
|
||||||
assert (
|
"plain-docker-test",
|
||||||
output.stdout.strip()
|
f"ubuntu:{os.getenv('UBUNTU_VERSION', '20.04')}",
|
||||||
== dedent(
|
|
||||||
"""
|
|
||||||
Systemd is required to run TLJH
|
|
||||||
Running inside a docker container without systemd isn't supported
|
|
||||||
We recommend against running a production TLJH instance inside a docker container
|
|
||||||
For local development, see http://tljh.jupyter.org/en/latest/contributing/dev-setup.html
|
|
||||||
"""
|
|
||||||
).strip()
|
|
||||||
)
|
)
|
||||||
|
assert "Systemd is required to run TLJH" in output.stdout
|
||||||
assert output.returncode == 1
|
assert output.returncode == 1
|
||||||
|
|
||||||
|
|
||||||
@@ -133,7 +160,10 @@ def verify_progress_page(expected_status_code, timeout):
|
|||||||
def test_progress_page():
|
def test_progress_page():
|
||||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||||
installer = executor.submit(
|
installer = executor.submit(
|
||||||
run_bootstrap, "progress-page", "ubuntu:18.04", True
|
run_bootstrap_after_preparing_container,
|
||||||
|
"progress-page",
|
||||||
|
f"ubuntu:{os.getenv('UBUNTU_VERSION', '20.04')}",
|
||||||
|
True
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if progress page started
|
# Check if progress page started
|
||||||
|
|||||||
Reference in New Issue
Block a user