Skip to content
Snippets Groups Projects
Commit 94e70faa authored by Tim Kreuzer's avatar Tim Kreuzer
Browse files

Initial commit

parents
Branches
Tags
No related merge requests found
Showing
with 319 additions and 0 deletions
# Created by https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks
# Edit at https://www.toptal.com/developers/gitignore?templates=python,jupyternotebooks
### JupyterNotebooks ###
# gitignore template for Jupyter Notebooks
# website: http://jupyter.org/
.ipynb_checkpoints
*/.ipynb_checkpoints/*
# IPython
profile_default/
ipython_config.py
# Remove previous ipynb_checkpoints
# git rm -r .ipynb_checkpoints/
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
# IPython
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# End of https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks
stages:
- pypi
workflow:
rules:
- if: $CI_COMMIT_TAG
- when: never
pypi:
stage: pypi
image:
name: python:3.11-alpine3.18
before_script:
- pip install twine build && sed -i -e "s/<version>/${CI_COMMIT_TAG}/g" ${CI_PROJECT_DIR}/setup.py
script:
- python -m build
- twine upload -u __token__ -p ${PYPI_JUPYTERJSC_TOKEN} dist/*
rules:
- if: $CI_COMMIT_TAG
repos:
- repo: https://github.com/asottile/reorder_python_imports
rev: v2.6.0
hooks:
- id: reorder-python-imports
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0
hooks:
- id: end-of-file-fixer
- id: check-json
- id: check-case-conflict
- id: check-executables-have-shebangs
version: "2"
build:
os: "ubuntu-22.04"
tools:
python: "3.10"
python:
install:
- requirements: docs/requirements.txt
LICENSE 0 → 100644
BSD 3-Clause License
Copyright (c) 2023, Forschungszentrum Juelich GmbH
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# JupyterHub OutpostSpawner
JupyterHub Spawner to run services on multiple remote resources.
This diff is collapsed.
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
File added
docs/_static/images/architecture-default.png

423 KiB

This diff is collapsed.
File added
docs/_static/images/architecture-delayed.png

462 KiB

This diff is collapsed.
File added
docs/_static/images/architecture-external.png

463 KiB

This diff is collapsed.
This diff is collapsed.
# API Endpoints
Below is an interactive view of the OutpostSpawner REST API specification.
<!-- client-rendered openapi UI copied from FastAPI -->
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css">
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4.1/swagger-ui-bundle.js"></script>
<!-- `SwaggerUIBundle` is now available on the page -->
<!-- render the ui here -->
<div id="openapi-ui"></div>
<script>
const ui = SwaggerUIBundle({
url: './_static/rest-api.yml',
dom_id: '#openapi-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
layout: "BaseLayout",
deepLinking: true,
showExtensions: true,
showCommonExtensions: true,
});
</script>
# Architecture
## Default
This is the default architecture of a single-user start. The packages between user and single-user server will be tunneled through the hub container.
<img alt="JupyterHub default architecture" src="_static/images/architecture-default.png" width="800" />
Cf. [here](https://jupyterhub.readthedocs.io/en/latest/reference/technical-overview.html#the-major-subsystems-hub-proxy-single-user-notebook-server)
### 1. Send Request
The OutpostSpawner collects all information relevant for the start of a single-user server. In general these are `name`, `environment` and selected `user_options`. Optional information like `certificates` or `trust_bundles` (in case of `internal_ssl`) are send to the JupyterHub Outpost if necessary.
### 2. Spawner.start
The JupyterHub Outpost will use the configured JupyterHub Spawner, to start the single-user server. It uses the same functions JupyterHub would use during a start process (`run_pre_spawn_hook`, `move_certs`, `start`). Events generated by `_generate_progress()` will be send to JupyterHub, so users will not miss any important information.
### 3. Send service address
JupyterHub will need the service address to create the SSH port forwarding.
### 4. Port forwarding
JupyterHub uses a random available port to forward traffic for this single-user server to the JupyterHub Outpost. It uses SSH multiplexing to reduce the number of connections. Simplified port forward command: `ssh -L 0.0.0.0:[random_port]:[service_address]:[single-user_port] jupyterhuboutpost@[outpost-ip]`.
It's also possible to define a customized port forward function (e.g. to outsource port-forwarding to an external pod).
### 5. Create service
At this step JupyterHub OutpostSpawner will create a Kubernetes Service, allowing the Configurable HTTP Proxy to communicate with the single-user server. In the default configuration the Hub pod itself is targeted by the Kubernetes service. All packages between the client and the single-user server will be forwarded through the hub container. It's also possible to alter the Kubernetes service selector, or to define a customized service creation function (e.g. to outsource port-forwarding to an external pod).
## External Tunneling
In this scenario an additional pod was created to manage the port forwarding. Single-user server are reachable, even if JupyterHub itself is currently offline.
<img alt="JupyterHub external architecture" src="_static/images/architecture-external.png" width="800" />
Cf. [here](https://jupyterhub.readthedocs.io/en/latest/reference/technical-overview.html#the-major-subsystems-hub-proxy-single-user-notebook-server)
## Delayed Tunneling
This shows a single-user start on an external system, if the service address of the single-user server is not determined during the start process. This may be the case if you have configured a Spawner, which spawns single-user server on remote Batch systems. The single-user server itself has to contact the [OutpostSpawner](https://jupyterhub-outpostspawner.readthedocs.io/en/latest/apiendpoints.html) itself, once its location is settled.
<img alt="JupyterHub delayed architecture" src="_static/images/architecture-delayed.png" width="800" />
Cf. [here](https://jupyterhub.readthedocs.io/en/latest/reference/technical-overview.html#the-major-subsystems-hub-proxy-single-user-notebook-server)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment