• Stars
    star
    188
  • Rank 205,563 (Top 5 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created about 9 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Custom Spawner for Jupyterhub to start servers in batch scheduled systems

batchspawner for Jupyterhub

GitHub Workflow Status - Test Latest PyPI version GitHub Discourse Gitter Contribute

This is a custom spawner for Jupyterhub that is designed for installations on clusters using batch scheduling software.

This began as a generalization of mkgilbert's batchspawner which in turn was inspired by Andrea Zonca's blog post where he explains his implementation for a spawner that uses SSH and Torque. His github repo is found here.

This package formerly included WrapSpawner and ProfilesSpawner, which provide mechanisms for runtime configuration of spawners. These have been split out and moved to the wrapspawner package.

Installation

  1. from root directory of this repo (where setup.py is), run pip install -e .

    If you don't actually need an editable version, you can simply run pip install batchspawner

  2. add lines in jupyterhub_config.py for the spawner you intend to use, e.g.

       c = get_config()
       c.JupyterHub.spawner_class = 'batchspawner.TorqueSpawner'
       import batchspawner    # Even though not used, needed to register batchspawner interface
  3. Depending on the spawner, additional configuration will likely be needed.

Batch Spawners

For information on the specific spawners, see SPAWNERS.md.

Overview

This file contains an abstraction layer for batch job queueing systems (BatchSpawnerBase), and implements Jupyterhub spawners for Torque, Moab, SLURM, SGE, HTCondor, LSF, and eventually others. Common attributes of batch submission / resource manager environments will include notions of:

  • queue names, resource manager addresses
  • resource limits including runtime, number of processes, memory
  • singleuser child process running on (usually remote) host not known until runtime
  • job submission and monitoring via resource manager utilities
  • remote execution via submission of templated scripts
  • job names instead of PIDs

BatchSpawnerBase provides several general mechanisms:

  • configurable traits req_foo that are exposed as {foo} in job template scripts. Templates (submit scripts in particular) may also use the full power of jinja2. Templates are automatically detected if a {{ or {% is present, otherwise str.format() used.
  • configurable command templates for submitting/querying/cancelling jobs
  • a generic concept of job-ID and ID-based job state tracking
  • overrideable hooks for subclasses to plug in logic at numerous points

Example

Every effort has been made to accommodate highly diverse systems through configuration only. This example consists of the (lightly edited) configuration used by the author to run Jupyter notebooks on an academic supercomputer cluster.

# Select the Torque backend and increase the timeout since batch jobs may take time to start
import batchspawner
c.JupyterHub.spawner_class = 'batchspawner.TorqueSpawner'
c.Spawner.http_timeout = 120

#------------------------------------------------------------------------------
# BatchSpawnerBase configuration
#    These are simply setting parameters used in the job script template below
#------------------------------------------------------------------------------
c.BatchSpawnerBase.req_nprocs = '2'
c.BatchSpawnerBase.req_queue = 'mesabi'
c.BatchSpawnerBase.req_host = 'mesabi.xyz.edu'
c.BatchSpawnerBase.req_runtime = '12:00:00'
c.BatchSpawnerBase.req_memory = '4gb'
#------------------------------------------------------------------------------
# TorqueSpawner configuration
#    The script below is nearly identical to the default template, but we needed
#    to add a line for our local environment. For most sites the default templates
#    should be a good starting point.
#------------------------------------------------------------------------------
c.TorqueSpawner.batch_script = '''#!/bin/sh
#PBS -q {queue}@{host}
#PBS -l walltime={runtime}
#PBS -l nodes=1:ppn={nprocs}
#PBS -l mem={memory}
#PBS -N jupyterhub-singleuser
#PBS -v {keepvars}
module load python3
{cmd}
'''
# For our site we need to munge the execution hostname returned by qstat
c.TorqueSpawner.state_exechost_exp = r'int-\1.mesabi.xyz.edu'

Security

Unless otherwise stated for a specific spawner, assume that spawners do evaluate shell environment for users and thus the security requirements of JupyterHub security for untrusted users are not fulfilled because some (most?) spawners do start a user shell which will execute arbitrary user environment configuration (.profile, .bashrc and the like) unless users do not have access to their own cluster user account. This is something which we are working on.

Provide different configurations of BatchSpawner

Overview

ProfilesSpawner, available as part of the wrapspawner package, allows the Jupyterhub administrator to define a set of different spawning configurations, both different spawners and different configurations of the same spawner. The user is then presented a dropdown menu for choosing the most suitable configuration for their needs.

This method provides an easy and safe way to provide different configurations of BatchSpawner to the users, see an example below.

Example

The following is based on the author's configuration (at the same site as the example above) showing how to give users access to multiple job configurations on the batch scheduled clusters, as well as an option to run a local notebook directly on the jupyterhub server.

# Same initial setup as the previous example
import batchspawner
c.JupyterHub.spawner_class = 'wrapspawner.ProfilesSpawner'
c.Spawner.http_timeout = 120
#------------------------------------------------------------------------------
# BatchSpawnerBase configuration
#   Providing default values that we may omit in the profiles
#------------------------------------------------------------------------------
c.BatchSpawnerBase.req_host = 'mesabi.xyz.edu'
c.BatchSpawnerBase.req_runtime = '12:00:00'
c.TorqueSpawner.state_exechost_exp = r'in-\1.mesabi.xyz.edu'
#------------------------------------------------------------------------------
# ProfilesSpawner configuration
#------------------------------------------------------------------------------
# List of profiles to offer for selection. Signature is:
#   List(Tuple( Unicode, Unicode, Type(Spawner), Dict ))
# corresponding to profile display name, unique key, Spawner class,
# dictionary of spawner config options.
#
# The first three values will be exposed in the input_template as {display},
# {key}, and {type}
#
c.ProfilesSpawner.profiles = [
   ( "Local server", 'local', 'jupyterhub.spawner.LocalProcessSpawner', {'ip':'0.0.0.0'} ),
   ('Mesabi - 2 cores, 4 GB, 8 hours', 'mesabi2c4g12h', 'batchspawner.TorqueSpawner',
      dict(req_nprocs='2', req_queue='mesabi', req_runtime='8:00:00', req_memory='4gb')),
   ('Mesabi - 12 cores, 128 GB, 4 hours', 'mesabi128gb', 'batchspawner.TorqueSpawner',
      dict(req_nprocs='12', req_queue='ram256g', req_runtime='4:00:00', req_memory='125gb')),
   ('Mesabi - 2 cores, 4 GB, 24 hours', 'mesabi2c4gb24h', 'batchspawner.TorqueSpawner',
      dict(req_nprocs='2', req_queue='mesabi', req_runtime='24:00:00', req_memory='4gb')),
   ('Interactive Cluster - 2 cores, 4 GB, 8 hours', 'lab', 'batchspawner.TorqueSpawner',
      dict(req_nprocs='2', req_host='labhost.xyz.edu', req_queue='lab',
          req_runtime='8:00:00', req_memory='4gb', state_exechost_exp='')),
   ]
c.ProfilesSpawner.ip = '0.0.0.0'

Debugging batchspawner

Sometimes it can be hard to debug batchspawner, but it's not really once you know how the pieces interact. Check the following places for error messages:

  • Check the JupyterHub logs for errors.

  • Check the JupyterHub logs for the batch script that got submitted and the command used to submit it. Are these correct? (Note that there are submission environment variables too, which aren't displayed.)

  • At this point, it's a matter of checking the batch system. Is the job ever scheduled? Does it run? Does it succeed? Check the batch system status and output of the job. The most comon failure patterns are a) job never starting due to bad scheduler options, b) job waiting in the queue beyond the start_timeout, causing JupyterHub to kill the job.

  • At this point the job starts. Does it fail immediately, or before Jupyter starts? Check the scheduler output files (stdout/stderr of the job), wherever it is stored. To debug the job script, you can add debugging into the batch script, such as an env or set -x.

  • At this point Jupyter itself starts - check its error messages. Is it starting with the right options? Can it communicate with the hub? At this point there usually isn't anything batchspawner-specific, with the one exception below. The error log would be in the batch script output (same file as above). There may also be clues in the JupyterHub logfile.

  • Are you running on an NFS filesystem? It's possible for Jupyter to experience issues due to varying implementations of the fcntl() system call. (See also Jupyterhub-Notes and Tips: SQLite)

Common problems:

  • Did you import batchspawner in the jupyterhub_config.py file? This is needed in order to activate the batchspawer API in JupyterHub.

Changelog

See CHANGELOG.md.

More Repositories

1

jupyterhub

Multi-user server for Jupyter notebooks
Python
7,778
star
2

binderhub

Run your code in the cloud, with technology so advanced, it feels like magic!
Python
2,557
star
3

repo2docker

Turn repositories into Jupyter-enabled Docker images
Python
1,621
star
4

zero-to-jupyterhub-k8s

Helm Chart & Documentation for deploying JupyterHub on Kubernetes
Python
1,551
star
5

the-littlest-jupyterhub

Simple JupyterHub distribution for 1-100 users on a single server
Python
1,038
star
6

jupyterhub-deploy-docker

Reference deployment of JupyterHub with docker
Python
699
star
7

kubespawner

Kubernetes spawner for JupyterHub
Python
546
star
8

dockerspawner

Spawns JupyterHub single user servers in Docker containers
Python
489
star
9

oauthenticator

OAuth + JupyterHub Authenticator = OAuthenticator
Python
413
star
10

jupyter-server-proxy

Jupyter notebook server extension to proxy web services.
Python
351
star
11

jupyterhub-deploy-teaching

Reference deployment of JupyterHub and nbgrader on a single server
Jinja
247
star
12

configurable-http-proxy

node-http-proxy plus a REST API
JavaScript
243
star
13

nbgitpuller

Jupyter server extension to sync a git repository one-way to a local path
Python
212
star
14

ldapauthenticator

LDAP Authenticator Plugin for Jupyter
Python
206
star
15

jupyterhub-tutorial

Tutorial materials for deploying JupyterHub
Shell
196
star
16

helm-chart

A store of Helm chart tarballs for deploying JupyterHub and BinderHub on a Kubernetes cluster
187
star
17

jupyterlab-hub

Deprecated: JupyterLab extension for running JupyterLab with JupyterHub
TypeScript
181
star
18

mybinder.org-user-guide

Turn a Git repo into a collection of interactive notebooks. This is Binder's user documentation repository.
Python
158
star
19

repo2docker-action

A GitHub action to build data science environment images with repo2docker and push them to registries.
Shell
142
star
20

jupyter-rsession-proxy

Jupyter extensions for running an RStudio rsession proxy
Python
119
star
21

jupyter-remote-desktop-proxy

Run a Linux Desktop on a JupyterHub
Python
113
star
22

jupyterhub-idle-culler

JupyterHub service to cull idle servers and users
Python
101
star
23

systemdspawner

Spawn JupyterHub single-user notebook servers with systemd
Python
92
star
24

jupyterhub-the-hard-way

Understanding JupyterHub by deploying it step by step
81
star
25

mybinder.org-deploy

Deployment config files for mybinder.org
Jupyter Notebook
76
star
26

nativeauthenticator

JupyterHub-native User Authenticator
Python
72
star
27

ltiauthenticator

A JupyterHub authenticator for LTI
Python
68
star
28

team-compass

A repository for team interaction, syncing, and handling meeting notes across the JupyterHub ecosystem.
Jupyter Notebook
62
star
29

wrapspawner

Mechanism for runtime configuration of spawners for JupyterHub
Python
60
star
30

hubshare

A directory sharing service for JupyterHub
Python
57
star
31

chartpress

automate building and publishing images for helm charts
Python
55
star
32

grafana-dashboards

Grafana Dashboards useful for k8s + JupyterHub
Jsonnet
55
star
33

traefik-proxy

JupyterHub proxy implementation with traefik
Jupyter Notebook
54
star
34

sudospawner

Spawn JupyterHub single-user servers with sudo
Python
50
star
35

firstuseauthenticator

JupyterHub Authenticator that lets users set passwords when they first log in
Python
48
star
36

jupyterhub-deploy-hpc

Documented examples of Jupyterhub deployment in HPC settings
Python
36
star
37

jupyterhub-example-kerberos

Example for experimenting with how JupyterHub can be configured to work with Kerberos
Python
33
star
38

outreachy

Tasks, management and documentation for Outreachy Internships in JupyterHub
Python
33
star
39

pebble-helm-chart

To deploy a server to replace Let's Encrypt in externally unreachable CI environment for testing purposes.
Shell
28
star
40

dummyauthenticator

A Dummy JupyterHub Authenticator to make testing easy
Python
28
star
41

gh-scoped-creds

Provide fine-grained push access to GitHub from a JupyterHub
Python
26
star
42

action-k3s-helm

A GitHub action to install K3S, Calico, and Helm.
25
star
43

tmpauthenticator

JupyterHub authenticator that hands out temporary accounts for everyone. For use in tmpnb.org
Python
22
star
44

yarnspawner

Spawn JupyterHub single user notebook servers in Hadoop/YARN containers.
Python
19
star
45

jupyterhub-on-hadoop

Documentation and resources for deploying JupyterHub on Hadoop
Shell
18
star
46

simpervisor

Simple Python3 Supervisor library
Python
12
star
47

kerberosauthenticator

A JupyterHub authenticator using Kerberos
Python
11
star
48

nullauthenticator

Null Authenticator for JupyterHub instances that should have no login mechanism
Python
9
star
49

binder-data

A place to store data for Binder
Jupyter Notebook
9
star
50

docker-image-cleaner

Python script to cleanup unused docker images
Python
9
star
51

action-k8s-await-workloads

A Github Action to await k8s workloads to become Ready
TypeScript
8
star
52

research-facilities

resources for developing, deploying, and using Jupyter at Research Facilities
8
star
53

simplespawner

A simple variant of LocalProcessSpawner for JupyterHub that doesn't require users exist on the system
Python
6
star
54

action-k8s-namespace-report

GitHub Action to report info and logs from the current namespace.
Shell
6
star
55

pytest-jupyterhub

Reusable pytest plugin for testing JupyterHub's components
Python
5
star
56

binder-billing

A repository to explore billing data for mybinder.org
Jupyter Notebook
3
star
57

autodoc-traits

Sphinx extension to autodocument traitlets
Python
3
star
58

action-major-minor-tag-calculator

GitHub action to calculate major and minor semver tags, e.g. for tagging containers
JavaScript
3
star
59

mybinder-tools

Some tools for munging and utilizing kubectl
Jupyter Notebook
2
star
60

jhub-proposals

Repo for collecting conference proposals, proceedings, &c.
2
star
61

design

A collection of design material for JupyterHub and related projects
2
star
62

alabaster-jupyterhub

A slight modification of the Alabaster theme for use with JupyterHub projects
CSS
2
star
63

katacoda-scenarios

https://katacoda.com/ is a playground for learning, and these are our learning scenarios
1
star
64

nbgitpuller-downloader-googledrive

Python
1
star
65

jupyterhub-python-repo-template

A template for generating Python repositories in the `jupyterhub` organization
Python
1
star
66

.github

1
star
67

nbgitpuller-downloader-plugins

jupyterhub/nbgitpuller allows for content provider plugins, this python package provides downloader plugins
Python
1
star