├── etcldap.conf ├── setup-user.sh ├── docker-compose.yml ├── nsswitch.conf ├── start-notebook.sh ├── start-singleuser.sh ├── Dockerfile ├── jupyter_notebook_config.py ├── start.sh └── CactusTutorial.ipynb /etcldap.conf: -------------------------------------------------------------------------------- 1 | base dc=hub 2 | uri ldap://hub 3 | ldap_version 3 4 | rootbinddn cn=admin,dc=hub 5 | pam_password clear 6 | 7 | -------------------------------------------------------------------------------- /setup-user.sh: -------------------------------------------------------------------------------- 1 | export USER=$(python3 -c 'import pwd, os; print(pwd.getpwuid(os.getuid()).pw_name)') 2 | cp -nr /etc/skel/* $HOME/ 3 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | 5 | perimeter-workspace: 6 | build: 7 | context: . 8 | dockerfile: Dockerfile 9 | image: einsteintoolkit/et-workshop 10 | -------------------------------------------------------------------------------- /nsswitch.conf: -------------------------------------------------------------------------------- 1 | passwd: files ldap 2 | group: files ldap 3 | shadow: files ldap 4 | gshadow: files ldap 5 | hosts: files dns 6 | networks: files 7 | protocols: db files 8 | services: db files 9 | ethers: db files 10 | rpc: db files 11 | netgroup: nis 12 | -------------------------------------------------------------------------------- /start-notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Jupyter Development Team. 3 | # Distributed under the terms of the Modified BSD License. 4 | 5 | set -e 6 | 7 | #set 8 | #echo "start-notebook.sh: $@" 9 | #echo "I am: $(whoami)" 10 | export HOME=/nfs/home/$(whoami) 11 | cd 12 | echo "pwd: $(pwd)" 13 | echo "restartable: $RESTARTABLE" 14 | echo "api token: $JUPYTERHUB_API_TOKEN" 15 | echo "lab: $JUPYTER_ENABLE_LAB" 16 | 17 | mkdir -p /tmp/$(whoami)/jupyter-runtime 18 | export JUPYTER_RUNTIME_DIR=/tmp/$(whoami)/jupyter-runtime 19 | 20 | # Special setup 21 | if [ -r /usr/local/bin/setup-user.sh ]; then source /usr/local/bin/setup-user.sh; fi 22 | 23 | wrapper="" 24 | if [[ "${RESTARTABLE}" == "yes" ]]; then 25 | wrapper="run-one-constantly" 26 | fi 27 | 28 | if [[ ! -z "${JUPYTERHUB_API_TOKEN}" ]]; then 29 | # launched by JupyterHub, use single-user entrypoint 30 | exec /usr/local/bin/start-singleuser.sh "$@" 31 | elif [[ ! -z "${JUPYTER_ENABLE_LAB}" ]]; then 32 | #. /usr/local/bin/start.sh $wrapper jupyter lab "$@" 33 | $wrapper jupyter lab "$@" 34 | else 35 | #. /usr/local/bin/start.sh $wrapper jupyter notebook "$@" 36 | $wrapper jupyter notebook --allow-root "$@" 37 | fi 38 | -------------------------------------------------------------------------------- /start-singleuser.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Jupyter Development Team. 3 | # Distributed under the terms of the Modified BSD License. 4 | 5 | set -e 6 | 7 | # set default ip to 0.0.0.0 8 | if [[ "$NOTEBOOK_ARGS $@" != *"--ip="* ]]; then 9 | NOTEBOOK_ARGS="--ip=0.0.0.0 $NOTEBOOK_ARGS" 10 | fi 11 | 12 | # handle some deprecated environment variables 13 | # from DockerSpawner < 0.8. 14 | # These won't be passed from DockerSpawner 0.9, 15 | # so avoid specifying --arg=empty-string 16 | if [ ! -z "$NOTEBOOK_DIR" ]; then 17 | NOTEBOOK_ARGS="--notebook-dir='$NOTEBOOK_DIR' $NOTEBOOK_ARGS" 18 | fi 19 | if [ ! -z "$JPY_PORT" ]; then 20 | NOTEBOOK_ARGS="--port=$JPY_PORT $NOTEBOOK_ARGS" 21 | fi 22 | if [ ! -z "$JPY_USER" ]; then 23 | NOTEBOOK_ARGS="--user=$JPY_USER $NOTEBOOK_ARGS" 24 | fi 25 | if [ ! -z "$JPY_COOKIE_NAME" ]; then 26 | NOTEBOOK_ARGS="--cookie-name=$JPY_COOKIE_NAME $NOTEBOOK_ARGS" 27 | fi 28 | if [ ! -z "$JPY_BASE_URL" ]; then 29 | NOTEBOOK_ARGS="--base-url=$JPY_BASE_URL $NOTEBOOK_ARGS" 30 | fi 31 | if [ ! -z "$JPY_HUB_PREFIX" ]; then 32 | NOTEBOOK_ARGS="--hub-prefix=$JPY_HUB_PREFIX $NOTEBOOK_ARGS" 33 | fi 34 | if [ ! -z "$JPY_HUB_API_URL" ]; then 35 | NOTEBOOK_ARGS="--hub-api-url=$JPY_HUB_API_URL $NOTEBOOK_ARGS" 36 | fi 37 | if [ ! -z "$JUPYTER_ENABLE_LAB" ]; then 38 | NOTEBOOK_BIN="jupyter labhub" 39 | else 40 | NOTEBOOK_BIN="jupyterhub-singleuser" 41 | fi 42 | 43 | #. /usr/local/bin/start.sh $NOTEBOOK_BIN $NOTEBOOK_ARGS "$@" 44 | $NOTEBOOK_BIN $NOTEBOOK_ARGS "$@" 45 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # FROM ubuntu:18.04 2 | # FROM nvidia/cuda:11.5.2-devel-ubuntu20.04 3 | #FROM nvidia/cuda:11.0.3-devel-ubuntu20.04 4 | FROM einsteintoolkit/et-notebook 5 | USER root 6 | 7 | ENV DEBIAN_FRONTEND=noninteractive 8 | RUN apt update && apt -yq dist-upgrade && \ 9 | apt install -yq --no-install-recommends apt-utils && \ 10 | apt install -yq --no-install-recommends \ 11 | wget \ 12 | bzip2 \ 13 | ca-certificates \ 14 | sudo \ 15 | locales \ 16 | fonts-liberation \ 17 | run-one \ 18 | python3 python3-pip python3-dev \ 19 | openssh-client libssl-dev \ 20 | gnupg policycoreutils imagemagick curl vim \ 21 | iputils-ping git less \ 22 | patch gcc make libc6-dev \ 23 | nfs-common rpcbind libnss-ldap ldap-utils ldap-auth-config \ 24 | libpam-ldap \ 25 | libbz2-dev \ 26 | && rm -rf /var/lib/apt/lists/* 27 | 28 | # Make python3 the default 29 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 && \ 30 | update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 31 | 32 | RUN pip install --no-cache-dir setuptools && \ 33 | pip install --no-cache-dir \ 34 | oauthenticator==0.9.0 \ 35 | jupyter==1.0.0 \ 36 | jupyterhub==1.0.0 \ 37 | python-oauth2==1.1.1 \ 38 | notebook==6.0.2 \ 39 | matplotlib numpy scipy scikit-learn astropy pandas fitsio pyephem \ 40 | asdf h5py emcee corner cython 41 | 42 | # RUN wget -nv https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.2-linux-x86_64.tar.gz && \ 43 | # tar xvz -C /usr/local --strip-components 1 -f julia-1.5.2-linux-x86_64.tar.gz && \ 44 | # rm julia-1.5.2-linux-x86_64.tar.gz 45 | 46 | COPY nsswitch.conf /etc 47 | COPY etcldap.conf /etc/ldap.conf 48 | 49 | RUN echo "libpam-runtime libpam-runtime/profiles multiselect unix, ldap" | debconf-set-selections && \ 50 | dpkg-reconfigure libpam-runtime 51 | 52 | RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen 53 | 54 | ENV SHELL=/bin/bash \ 55 | LC_ALL=en_US.UTF-8 \ 56 | LANG=en_US.UTF-8 \ 57 | LANGUAGE=en_US.UTF-8 58 | 59 | EXPOSE 8888 60 | CMD ["start-notebook.sh"] 61 | 62 | # From https://github.com/jupyter/docker-stacks 63 | COPY start-notebook.sh /usr/local/bin/ 64 | COPY start-singleuser.sh /usr/local/bin/ 65 | COPY setup-user.sh /usr/local/bin/ 66 | COPY jupyter_notebook_config.py /etc/jupyter/ 67 | COPY CactusTutorial.ipynb /etck/skel/ 68 | -------------------------------------------------------------------------------- /jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Jupyter Development Team. 2 | # Distributed under the terms of the Modified BSD License. 3 | 4 | from jupyter_core.paths import jupyter_data_dir 5 | import subprocess 6 | import os 7 | import errno 8 | import stat 9 | 10 | c = get_config() 11 | c.NotebookApp.ip = '0.0.0.0' 12 | c.NotebookApp.port = 8888 13 | #c.NotebookApp.open_browser = False 14 | 15 | # Auto-shutdown -- 16 | # shutdown the server after no activity for an hour 17 | c.NotebookApp.shutdown_no_activity_timeout = 60 * 60 18 | # shutdown kernels after no activity for 20 minutes 19 | c.MappingKernelManager.cull_idle_timeout = 20 * 60 20 | # check for idle kernels every two minutes 21 | c.MappingKernelManager.cull_interval = 2 * 60 22 | 23 | 24 | # https://github.com/jupyter/notebook/issues/3130 25 | c.FileContentsManager.delete_to_trash = False 26 | 27 | # https://stackoverflow.com/questions/55245895/jupyter-notebook-ssh-tunneling-error-the-signatures-database-cannot-be-opened 28 | c.NotebookNotary.db_file = ':memory:' 29 | 30 | # Generate a self-signed certificate 31 | if 'GEN_CERT' in os.environ: 32 | dir_name = jupyter_data_dir() 33 | pem_file = os.path.join(dir_name, 'notebook.pem') 34 | try: 35 | os.makedirs(dir_name) 36 | except OSError as exc: # Python >2.5 37 | if exc.errno == errno.EEXIST and os.path.isdir(dir_name): 38 | pass 39 | else: 40 | raise 41 | 42 | # Generate an openssl.cnf file to set the distinguished name 43 | cnf_file = os.path.join(os.getenv('CONDA_DIR', '/usr/lib'), 'ssl', 'openssl.cnf') 44 | if not os.path.isfile(cnf_file): 45 | with open(cnf_file, 'w') as fh: 46 | fh.write('''\ 47 | [req] 48 | distinguished_name = req_distinguished_name 49 | [req_distinguished_name] 50 | ''') 51 | 52 | # Generate a certificate if one doesn't exist on disk 53 | subprocess.check_call(['openssl', 'req', '-new', 54 | '-newkey', 'rsa:2048', 55 | '-days', '365', 56 | '-nodes', '-x509', 57 | '-subj', '/C=XX/ST=XX/L=XX/O=generated/CN=generated', 58 | '-keyout', pem_file, 59 | '-out', pem_file]) 60 | # Restrict access to the file 61 | os.chmod(pem_file, stat.S_IRUSR | stat.S_IWUSR) 62 | c.NotebookApp.certfile = pem_file 63 | 64 | # Change default umask for all subprocesses of the notebook server if set in 65 | # the environment 66 | if 'NB_UMASK' in os.environ: 67 | os.umask(int(os.environ['NB_UMASK'], 8)) 68 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Jupyter Development Team. 3 | # Distributed under the terms of the Modified BSD License. 4 | 5 | set -e 6 | 7 | # Exec the specified command or fall back on bash 8 | if [ $# -eq 0 ]; then 9 | cmd=( "bash" ) 10 | else 11 | cmd=( "$@" ) 12 | fi 13 | 14 | run-hooks () { 15 | # Source scripts or run executable files in a directory 16 | if [[ ! -d "$1" ]] ; then 17 | return 18 | fi 19 | echo "$0: running hooks in $1" 20 | for f in "$1/"*; do 21 | case "$f" in 22 | *.sh) 23 | echo "$0: running $f" 24 | source "$f" 25 | ;; 26 | *) 27 | if [[ -x "$f" ]] ; then 28 | echo "$0: running $f" 29 | "$f" 30 | else 31 | echo "$0: ignoring $f" 32 | fi 33 | ;; 34 | esac 35 | done 36 | echo "$0: done running hooks in $1" 37 | } 38 | 39 | run-hooks /usr/local/bin/start-notebook.d 40 | 41 | # Handle special flags if we're root 42 | if [ $(id -u) == 0 ] ; then 43 | 44 | # Only attempt to change the jovyan username if it exists 45 | if id jovyan &> /dev/null ; then 46 | echo "Set username to: $NB_USER" 47 | usermod -d /home/$NB_USER -l $NB_USER jovyan 48 | fi 49 | 50 | # Handle case where provisioned storage does not have the correct permissions by default 51 | # Ex: default NFS/EFS (no auto-uid/gid) 52 | if [[ "$CHOWN_HOME" == "1" || "$CHOWN_HOME" == 'yes' ]]; then 53 | echo "Changing ownership of /home/$NB_USER to $NB_UID:$NB_GID with options '${CHOWN_HOME_OPTS}'" 54 | chown $CHOWN_HOME_OPTS $NB_UID:$NB_GID /home/$NB_USER 55 | fi 56 | if [ ! -z "$CHOWN_EXTRA" ]; then 57 | for extra_dir in $(echo $CHOWN_EXTRA | tr ',' ' '); do 58 | echo "Changing ownership of ${extra_dir} to $NB_UID:$NB_GID with options '${CHOWN_EXTRA_OPTS}'" 59 | chown $CHOWN_EXTRA_OPTS $NB_UID:$NB_GID $extra_dir 60 | done 61 | fi 62 | 63 | # handle home and working directory if the username changed 64 | if [[ "$NB_USER" != "jovyan" ]]; then 65 | # changing username, make sure homedir exists 66 | # (it could be mounted, and we shouldn't create it if it already exists) 67 | if [[ ! -e "/home/$NB_USER" ]]; then 68 | echo "Relocating home dir to /home/$NB_USER" 69 | mv /home/jovyan "/home/$NB_USER" 70 | fi 71 | # if workdir is in /home/jovyan, cd to /home/$NB_USER 72 | if [[ "$PWD/" == "/home/jovyan/"* ]]; then 73 | newcwd="/home/$NB_USER/${PWD:13}" 74 | echo "Setting CWD to $newcwd" 75 | cd "$newcwd" 76 | fi 77 | fi 78 | 79 | # Change UID of NB_USER to NB_UID if it does not match 80 | if [ "$NB_UID" != $(id -u $NB_USER) ] ; then 81 | echo "Set $NB_USER UID to: $NB_UID" 82 | usermod -u $NB_UID $NB_USER 83 | fi 84 | 85 | # Set NB_USER primary gid to NB_GID (after making the group). Set 86 | # supplementary gids to NB_GID and 100. 87 | if [ "$NB_GID" != $(id -g $NB_USER) ] ; then 88 | echo "Add $NB_USER to group: $NB_GID" 89 | groupadd -g $NB_GID -o ${NB_GROUP:-${NB_USER}} 90 | usermod -g $NB_GID -aG 100 $NB_USER 91 | fi 92 | 93 | # Enable sudo if requested 94 | if [[ "$GRANT_SUDO" == "1" || "$GRANT_SUDO" == 'yes' ]]; then 95 | echo "Granting $NB_USER sudo access and appending $CONDA_DIR/bin to sudo PATH" 96 | echo "$NB_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/notebook 97 | fi 98 | 99 | # Add $CONDA_DIR/bin to sudo secure_path 100 | sed -r "s#Defaults\s+secure_path=\"([^\"]+)\"#Defaults secure_path=\"\1:$CONDA_DIR/bin\"#" /etc/sudoers | grep secure_path > /etc/sudoers.d/path 101 | 102 | # Exec the command as NB_USER with the PATH and the rest of 103 | # the environment preserved 104 | run-hooks /usr/local/bin/before-notebook.d 105 | echo "Executing the command: ${cmd[@]}" 106 | exec sudo -E -H -u $NB_USER PATH=$PATH XDG_CACHE_HOME=/home/$NB_USER/.cache PYTHONPATH=${PYTHONPATH:-} "${cmd[@]}" 107 | else 108 | if [[ "$NB_UID" == "$(id -u jovyan)" && "$NB_GID" == "$(id -g jovyan)" ]]; then 109 | # User is not attempting to override user/group via environment 110 | # variables, but they could still have overridden the uid/gid that 111 | # container runs as. Check that the user has an entry in the passwd 112 | # file and if not add an entry. 113 | STATUS=0 && whoami &> /dev/null || STATUS=$? && true 114 | if [[ "$STATUS" != "0" ]]; then 115 | if [[ -w /etc/passwd ]]; then 116 | echo "Adding passwd file entry for $(id -u)" 117 | cat /etc/passwd | sed -e "s/^jovyan:/nayvoj:/" > /tmp/passwd 118 | echo "jovyan:x:$(id -u):$(id -g):,,,:/home/jovyan:/bin/bash" >> /tmp/passwd 119 | cat /tmp/passwd > /etc/passwd 120 | rm /tmp/passwd 121 | else 122 | echo 'Container must be run with group "root" to update passwd file' 123 | fi 124 | fi 125 | 126 | # Warn if the user isn't going to be able to write files to $HOME. 127 | if [[ ! -w /home/jovyan ]]; then 128 | echo 'Container must be run with group "users" to update files' 129 | fi 130 | else 131 | # Warn if looks like user want to override uid/gid but hasn't 132 | # run the container as root. 133 | if [[ ! -z "$NB_UID" && "$NB_UID" != "$(id -u)" ]]; then 134 | echo 'Container must be run as root to set $NB_UID' 135 | fi 136 | if [[ ! -z "$NB_GID" && "$NB_GID" != "$(id -g)" ]]; then 137 | echo 'Container must be run as root to set $NB_GID' 138 | fi 139 | fi 140 | 141 | # Warn if looks like user want to run in sudo mode but hasn't run 142 | # the container as root. 143 | if [[ "$GRANT_SUDO" == "1" || "$GRANT_SUDO" == 'yes' ]]; then 144 | echo 'Container must be run as root to grant sudo permissions' 145 | fi 146 | 147 | # Execute the command 148 | run-hooks /usr/local/bin/before-notebook.d 149 | echo "Executing the command: ${cmd[@]}" 150 | exec "${cmd[@]}" 151 | fi 152 | -------------------------------------------------------------------------------- /CactusTutorial.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
| Package | Debian /Ubuntu | fedora | centos | opensuse |
|---|---|---|---|---|
| jpeg | apt-get install -y libjpeg-turbo?-dev | dnf install -y libjpeg-turbo-devel | yum install -y libjpeg-turbo-devel | |
| curl | apt-get install -y curl | dnf install -y curl | yum install -y curl | zypper install -y curl |
| gcc | apt-get install -y gcc | dnf install -y gcc | yum install -y gcc | zypper install -y gcc |
| git | apt-get install -y git | dnf install -y git | yum install -y git | zypper install -y git |
| lapack | apt-get install -y liblapack-dev | dnf install -y lapack-devel | yum install -y lapack-devel | zypper install -y lapack-devel |
| make | apt-get install -y make | dnf install -y make | yum install -y make | zypper install -y make |
| subversion | apt-get install -y subversion | dnf install -y subversion | yum install -y subversion | zypper install -y subversion |
| g++ | apt-get install -y g++ | dnf install -y gcc-c++ | yum install -y gcc-c++ | zypper install -y gcc-c++ |
| which | dnf install -y which | yum install -y which | zypper install -y which | |
| papi | apt-get install -y libpapi-dev | dnf install -y papi-devel | yum install -y papi-devel | zypper install -y papi-devel |
| python | apt-get install -y python | dnf install -y python | yum install -y python | zypper install -y python |
| hwloc | apt-get install -y libhwloc-dev | dnf install -y hwloc-devel | yum install -y hwloc-devel | zypper install -y hwloc-devel |
| mpi | libopenmpi-dev libhdf5-openmpi-dev | openmpi-devel hdf5-openmpi-devel | openmpi-devel hdf5-openmpi-devel | zypper install -y openmpi-devel |
| ssl | apt-get install -y libssl-dev | dnf install -y openssl-devel | yum install -y openssl-devel | zypper install -y libopenssl-devel |
| libtool | dnf install -y libtool-ltdl-devel | yum install -y libtool-ltdl-devel | ||
| numa | apt-get install -y numactl | dnf install -y numactl-devel | yum install -y numactl-devel | zypper install -y libnuma-devel |
| gfortran | apt-get install -y gfortran | dnf install -y gcc-gfortran | yum install -y gcc-gfortran | zypper install -y gcc-fortran |
| xargs | dnf install -y findutils | yum install -y findutils | ||
| hdf5 | apt-get install -y libhdf5-dev | dnf install -y hdf5-devel | yum install -y hdf5-devel | zypper install -y hdf5-devel |
| fftw | apt-get install -y libfftw3-dev | dnf install -y fftw-devel | yum install -y fftw-devel | zypper install -y libfftw3-3 |
| patch | apt-get install -y patch | dnf install -y patch | yum install -y patch | zypper install -y patch |
| gsl | apt-get install -y libgsl-dev | dnf install -y gsl-devel | yum install -y gsl-devel | zypper install -y gsl-devel |
| pkg-config | apt-get install -y pkg-config | dnf install -y pkgconfig | yum install -y pkgconfig | zypper install -y pkg-config |