diff --git a/jupyter-compose/app-notebooks/Dockerfile b/jupyter-compose/app-notebooks/Dockerfile index a40f1de..9a6bbdc 100644 --- a/jupyter-compose/app-notebooks/Dockerfile +++ b/jupyter-compose/app-notebooks/Dockerfile @@ -35,8 +35,7 @@ RUN \ jupyter nbextension enable --sys-prefix --py widgetsnbextension RUN \ - jupyter labextension install @jupyterlab/hub-extension && \ - conda install jupyterhub + jupyter labextension install @jupyterlab/hub-extension # Some dummy users diff --git a/jupyter-compose/docker-compose.yml b/jupyter-compose/docker-compose.yml index 3ce3c51..eda1e73 100644 --- a/jupyter-compose/docker-compose.yml +++ b/jupyter-compose/docker-compose.yml @@ -4,12 +4,20 @@ services: image: web-jupyterhub:latest environment: - CONFIGPROXY_AUTH_TOKEN=the-sign-pointed-this-way + - ANNOUNCEMENT_JUPYTERHUB_API_TOKEN=the-hands-of-fate-have-doomed-this-man volumes: - ./config:/config + ports: + - 8081:8081 app: image: app-notebooks:latest volumes: - ./config:/config + announcement: + image: web-announcement:latest + environment: + - JUPYTERHUB_API_TOKEN=the-hands-of-fate-have-doomed-this-man + - JUPYTERHUB_API_URL=http://web:8081/hub/api proxy: image: jupyterhub/configurable-http-proxy:latest environment: diff --git a/jupyter-compose/web-announcement/Dockerfile b/jupyter-compose/web-announcement/Dockerfile new file mode 100644 index 0000000..e96f1a7 --- /dev/null +++ b/jupyter-compose/web-announcement/Dockerfile @@ -0,0 +1,14 @@ +ARG branch=unknown + +FROM registry.spin.nersc.gov/das/jupyter-base-${branch}:latest +LABEL maintainer="Rollin Thomas " + +RUN \ + pip install git+https://github.com/rcthomas/jupyterhub-announcement.git@persist-announcements + +WORKDIR /srv + +ADD docker-entrypoint.sh announcement_config.py ./ +RUN chmod +x docker-entrypoint.sh +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["python", "-m", "jupyterhub_announcement"] diff --git a/jupyter-compose/web-announcement/announcement_config.py b/jupyter-compose/web-announcement/announcement_config.py new file mode 100644 index 0000000..ba3fc72 --- /dev/null +++ b/jupyter-compose/web-announcement/announcement_config.py @@ -0,0 +1,72 @@ +# Configuration file for application. + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## The date format used by logging formatters for %(asctime)s +#c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +#c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +#c.Application.log_level = 30 +c.Application.log_level = 0 + +#------------------------------------------------------------------------------ +# AnnouncementService(Application) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## Config file to load +#c.AnnouncementService.config_file = 'announcement_config.py' + +## Fixed message to show at the top of the page. +# +# A good use for this parameter would be a link to a more general live system +# status page or MOTD. +#c.AnnouncementService.fixed_message = '' + +## Generate default config file +#c.AnnouncementService.generate_config = False + +## Logo path, can be used to override JupyterHub one +#c.AnnouncementService.logo_file = '' + +## Port this service will listen on +#c.AnnouncementService.port = 8888 + +## Announcement service prefix +#c.AnnouncementService.service_prefix = '/services/announcement/' + +## Search paths for jinja templates, coming before default ones +#c.AnnouncementService.template_paths = [] + +#------------------------------------------------------------------------------ +# AnnouncementQueue(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ + +## File path where announcements persist as JSON. +# +# For a persistent announcement queue, this parameter must be set to a non-empty +# value and correspond to a read+write-accessible path. The announcement queue +# is stored as a list of JSON objects. If this parameter is set to a non-empty +# value: +# +# * The persistence file is used to initialize the announcement queue +# at start-up. This is the only time the persistence file is read. +# * If the persistence file does not exist at start-up, it is +# created when an announcement is added to the queue. +# * The persistence file is over-written with the contents of the +# announcement queue each time a new announcement is added. +# +# If this parameter is set to an empty value (the default) then the queue is +# just empty at initialization and the queue is ephemeral; announcements will +# not be persisted on updates to the queue. +#c.AnnouncementQueue.persist_path = '' +c.AnnouncementQueue.persist_path = 'announcements.json' + diff --git a/jupyter-compose/web-announcement/build.sh b/jupyter-compose/web-announcement/build.sh new file mode 100644 index 0000000..7e48fc6 --- /dev/null +++ b/jupyter-compose/web-announcement/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +branch=$(git symbolic-ref --short HEAD) + +docker build \ + --build-arg branch=$branch \ + "$@" \ + --tag web-announcement:latest . diff --git a/jupyter-compose/web-announcement/docker-entrypoint.sh b/jupyter-compose/web-announcement/docker-entrypoint.sh new file mode 100644 index 0000000..a2c1ead --- /dev/null +++ b/jupyter-compose/web-announcement/docker-entrypoint.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# file_env VAR [DEFAULT] +# ---------------------- +# Treat the value of VAR_FILE as the path to a secrets file and initialize VAR +# with the contents of that file. From postgres docker-entrypoint.sh. + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +file_env 'JUPYTERHUB_API_TOKEN' + +exec "$@" diff --git a/jupyter-compose/web-jupyterhub/Dockerfile b/jupyter-compose/web-jupyterhub/Dockerfile index f0a3828..8f06ced 100644 --- a/jupyter-compose/web-jupyterhub/Dockerfile +++ b/jupyter-compose/web-jupyterhub/Dockerfile @@ -21,6 +21,7 @@ RUN \ WORKDIR /srv ADD docker-entrypoint.sh . ADD jupyterhub_config.py . +ADD templates templates RUN chmod +x docker-entrypoint.sh RUN echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config diff --git a/jupyter-compose/web-jupyterhub/jupyterhub_config.py b/jupyter-compose/web-jupyterhub/jupyterhub_config.py index 845229c..e931e6f 100644 --- a/jupyter-compose/web-jupyterhub/jupyterhub_config.py +++ b/jupyter-compose/web-jupyterhub/jupyterhub_config.py @@ -427,6 +427,14 @@ # } # ] #c.JupyterHub.services = [] +import os +c.JupyterHub.services = [ + { + 'name': 'announcement', + 'url': 'http://announcement:8888', + 'api_token': os.environ["ANNOUNCEMENT_JUPYTERHUB_API_TOKEN"] + } +] ## Shuts down all user servers on logout #c.JupyterHub.shutdown_on_logout = False @@ -483,6 +491,7 @@ ## Paths to search for jinja templates, before using the default templates. #c.JupyterHub.template_paths = [] +c.JupyterHub.template_paths = ["./templates"] ## Extra variables to be passed into jinja templates #c.JupyterHub.template_vars = {} diff --git a/jupyter-compose/web-jupyterhub/templates/page.html b/jupyter-compose/web-jupyterhub/templates/page.html new file mode 100644 index 0000000..4a3f7c2 --- /dev/null +++ b/jupyter-compose/web-jupyterhub/templates/page.html @@ -0,0 +1,24 @@ +{% extends "templates/page.html" %} +{% block announcement %} +
+
+{% endblock %} + +{% block script %} +{{ super() }} + +{% endblock %} diff --git a/jupyter-localhost/web-jupyterhub/Dockerfile b/jupyter-localhost/web-jupyterhub/Dockerfile index 70d822e..be79a7b 100644 --- a/jupyter-localhost/web-jupyterhub/Dockerfile +++ b/jupyter-localhost/web-jupyterhub/Dockerfile @@ -31,7 +31,11 @@ RUN \ adduser -q --gecos "" --disabled-password master && \ echo master:you-have-failed-us-torgo | chpasswd +RUN \ + pip install --no-cache-dir git+https://github.com/rcthomas/jupyterhub-announcement.git@persist-announcements + WORKDIR /srv +ADD announcement_config.py . RUN chmod +x docker-entrypoint.sh CMD ["jupyterhub", "--debug"] ENTRYPOINT ["./docker-entrypoint.sh"] diff --git a/jupyter-localhost/web-jupyterhub/announcement_config.py b/jupyter-localhost/web-jupyterhub/announcement_config.py new file mode 100644 index 0000000..f8d1250 --- /dev/null +++ b/jupyter-localhost/web-jupyterhub/announcement_config.py @@ -0,0 +1,72 @@ +# Configuration file for application. + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## The date format used by logging formatters for %(asctime)s +#c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +#c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +#c.Application.log_level = 30 +c.AnnouncementService.log_level = 0 + +#------------------------------------------------------------------------------ +# AnnouncementService(Application) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## Config file to load +#c.AnnouncementService.config_file = 'announcement_config.py' + +## Fixed message to show at the top of the page. +# +# A good use for this parameter would be a link to a more general live system +# status page or MOTD. +#c.AnnouncementService.fixed_message = '' + +## Generate default config file +#c.AnnouncementService.generate_config = False + +## Logo path, can be used to override JupyterHub one +#c.AnnouncementService.logo_file = '' + +## Port this service will listen on +#c.AnnouncementService.port = 8888 + +## Announcement service prefix +#c.AnnouncementService.service_prefix = '/services/announcement/' + +## Search paths for jinja templates, coming before default ones +#c.AnnouncementService.template_paths = [] + +#------------------------------------------------------------------------------ +# AnnouncementQueue(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ + +## File path where announcements persist as JSON. +# +# For a persistent announcement queue, this parameter must be set to a non-empty +# value and correspond to a read+write-accessible path. The announcement queue +# is stored as a list of JSON objects. If this parameter is set to a non-empty +# value: +# +# * The persistence file is used to initialize the announcement queue +# at start-up. This is the only time the persistence file is read. +# * If the persistence file does not exist at start-up, it is +# created when an announcement is added to the queue. +# * The persistence file is over-written with the contents of the +# announcement queue each time a new announcement is added. +# +# If this parameter is set to an empty value (the default) then the queue is +# just empty at initialization and the queue is ephemeral; announcements will +# not be persisted on updates to the queue. +#c.AnnouncementQueue.persist_path = '' +c.AnnouncementQueue.persist_path = 'announcements.json' + diff --git a/jupyter-localhost/web-jupyterhub/jupyterhub_config.py b/jupyter-localhost/web-jupyterhub/jupyterhub_config.py index d33bc70..def26e2 100644 --- a/jupyter-localhost/web-jupyterhub/jupyterhub_config.py +++ b/jupyter-localhost/web-jupyterhub/jupyterhub_config.py @@ -269,6 +269,15 @@ # } # ] #c.JupyterHub.services = [] +import os +c.JupyterHub.services = [ + { + 'name': 'announcement', + 'url': 'http://127.0.0.1:8888', + 'command': ["python", "-m", "jupyterhub_announcement"] +# 'api_token': os.environ["ANNOUNCEMENT_JUPYTERHUB_API_TOKEN"] + } +] ## The class to use for spawning single-user servers. # diff --git a/jupyter-nersc/app-notebooks/Dockerfile b/jupyter-nersc/app-notebooks/Dockerfile index 15982bb..d4d63aa 100644 --- a/jupyter-nersc/app-notebooks/Dockerfile +++ b/jupyter-nersc/app-notebooks/Dockerfile @@ -72,8 +72,13 @@ RUN \ RUN \ pip install --no-cache-dir ipympl && \ - jupyter nbextension enable --sys-prefix --py widgetsnbextension && \ - jupyter labextension install \ + jupyter nbextension enable --sys-prefix --py widgetsnbextension + +RUN \ + conda install --yes -c conda-forge nodejs + +RUN \ + jupyter labextension install --debug \ @jupyter-widgets/jupyterlab-manager \ jupyter-matplotlib \ @jupyterlab/toc \ diff --git a/jupyter-nersc/web-announcement/Dockerfile b/jupyter-nersc/web-announcement/Dockerfile new file mode 100644 index 0000000..e96f1a7 --- /dev/null +++ b/jupyter-nersc/web-announcement/Dockerfile @@ -0,0 +1,14 @@ +ARG branch=unknown + +FROM registry.spin.nersc.gov/das/jupyter-base-${branch}:latest +LABEL maintainer="Rollin Thomas " + +RUN \ + pip install git+https://github.com/rcthomas/jupyterhub-announcement.git@persist-announcements + +WORKDIR /srv + +ADD docker-entrypoint.sh announcement_config.py ./ +RUN chmod +x docker-entrypoint.sh +ENTRYPOINT ["./docker-entrypoint.sh"] +CMD ["python", "-m", "jupyterhub_announcement"] diff --git a/jupyter-nersc/web-announcement/announcement_config.py b/jupyter-nersc/web-announcement/announcement_config.py new file mode 100644 index 0000000..ba3fc72 --- /dev/null +++ b/jupyter-nersc/web-announcement/announcement_config.py @@ -0,0 +1,72 @@ +# Configuration file for application. + +#------------------------------------------------------------------------------ +# Application(SingletonConfigurable) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## The date format used by logging formatters for %(asctime)s +#c.Application.log_datefmt = '%Y-%m-%d %H:%M:%S' + +## The Logging format template +#c.Application.log_format = '[%(name)s]%(highlevel)s %(message)s' + +## Set the log level by value or name. +#c.Application.log_level = 30 +c.Application.log_level = 0 + +#------------------------------------------------------------------------------ +# AnnouncementService(Application) configuration +#------------------------------------------------------------------------------ + +## This is an application. + +## Config file to load +#c.AnnouncementService.config_file = 'announcement_config.py' + +## Fixed message to show at the top of the page. +# +# A good use for this parameter would be a link to a more general live system +# status page or MOTD. +#c.AnnouncementService.fixed_message = '' + +## Generate default config file +#c.AnnouncementService.generate_config = False + +## Logo path, can be used to override JupyterHub one +#c.AnnouncementService.logo_file = '' + +## Port this service will listen on +#c.AnnouncementService.port = 8888 + +## Announcement service prefix +#c.AnnouncementService.service_prefix = '/services/announcement/' + +## Search paths for jinja templates, coming before default ones +#c.AnnouncementService.template_paths = [] + +#------------------------------------------------------------------------------ +# AnnouncementQueue(LoggingConfigurable) configuration +#------------------------------------------------------------------------------ + +## File path where announcements persist as JSON. +# +# For a persistent announcement queue, this parameter must be set to a non-empty +# value and correspond to a read+write-accessible path. The announcement queue +# is stored as a list of JSON objects. If this parameter is set to a non-empty +# value: +# +# * The persistence file is used to initialize the announcement queue +# at start-up. This is the only time the persistence file is read. +# * If the persistence file does not exist at start-up, it is +# created when an announcement is added to the queue. +# * The persistence file is over-written with the contents of the +# announcement queue each time a new announcement is added. +# +# If this parameter is set to an empty value (the default) then the queue is +# just empty at initialization and the queue is ephemeral; announcements will +# not be persisted on updates to the queue. +#c.AnnouncementQueue.persist_path = '' +c.AnnouncementQueue.persist_path = 'announcements.json' + diff --git a/jupyter-nersc/web-announcement/build.sh b/jupyter-nersc/web-announcement/build.sh new file mode 100644 index 0000000..0505f8a --- /dev/null +++ b/jupyter-nersc/web-announcement/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +branch=$(git symbolic-ref --short HEAD) + +docker build \ + --build-arg branch=$branch \ + "$@" \ + --tag registry.spin.nersc.gov/das/web-announcement.jupyter-nersc-$branch:latest . diff --git a/jupyter-nersc/web-announcement/docker-entrypoint.sh b/jupyter-nersc/web-announcement/docker-entrypoint.sh new file mode 100644 index 0000000..a2c1ead --- /dev/null +++ b/jupyter-nersc/web-announcement/docker-entrypoint.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# file_env VAR [DEFAULT] +# ---------------------- +# Treat the value of VAR_FILE as the path to a secrets file and initialize VAR +# with the contents of that file. From postgres docker-entrypoint.sh. + +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + local val="$def" + if [ "${!var:-}" ]; then + val="${!var}" + elif [ "${!fileVar:-}" ]; then + val="$(< "${!fileVar}")" + fi + export "$var"="$val" + unset "$fileVar" +} + +file_env 'JUPYTERHUB_API_TOKEN' + +exec "$@" diff --git a/jupyter-nersc/web-jupyterhub/Dockerfile b/jupyter-nersc/web-jupyterhub/Dockerfile index b0a04d5..a1ca275 100644 --- a/jupyter-nersc/web-jupyterhub/Dockerfile +++ b/jupyter-nersc/web-jupyterhub/Dockerfile @@ -21,7 +21,6 @@ ADD templates templates ENV PYTHONPATH=/srv ADD nerscspawner.py . ADD nerscslurmspawner.py . -ADD announcement.py . ADD iris.py . # Hub scripts diff --git a/jupyter-nersc/web-jupyterhub/docker-entrypoint.sh b/jupyter-nersc/web-jupyterhub/docker-entrypoint.sh index b4d9189..096e023 100644 --- a/jupyter-nersc/web-jupyterhub/docker-entrypoint.sh +++ b/jupyter-nersc/web-jupyterhub/docker-entrypoint.sh @@ -28,5 +28,8 @@ file_env 'SKEY' file_env 'MODS_JUPYTERHUB_API_TOKEN' file_env 'CONFIGPROXY_AUTH_TOKEN' file_env 'JUPYTERHUB_CRYPT_KEY' +file_env 'ANNOUNCEMENT_JUPYTERHUB_API_TOKEN' + +# file_env 'NBVIEWER_JUPYTERHUB_API_TOKEN' exec "$@" diff --git a/jupyter-nersc/web-jupyterhub/jupyterhub_config.py b/jupyter-nersc/web-jupyterhub/jupyterhub_config.py index c7c2d46..92cf8fe 100644 --- a/jupyter-nersc/web-jupyterhub/jupyterhub_config.py +++ b/jupyter-nersc/web-jupyterhub/jupyterhub_config.py @@ -397,14 +397,19 @@ def comma_split(string): }, { 'name': 'announcement', - 'url': 'http://web-jupyterhub:8888', - 'command': ["python", "-m", "announcement"], + 'url': 'http://web-announcement:8888', + 'api_token': os.environ["ANNOUNCEMENT_JUPYTERHUB_API_TOKEN"] }, { 'name': 'mods', 'admin': True, 'api_token': os.environ["MODS_JUPYTERHUB_API_TOKEN"] - } + }, +# { +# 'name': 'nbviewer', +# 'url': 'http://web-nbviewer:5000', +# 'api_token': os.environ["NBVIEWER_JUPYTERHUB_API_TOKEN"] +# } ] ## The class to use for spawning single-user servers. @@ -505,7 +510,7 @@ def comma_split(string): # environment variables here. Most, including the default, do not. Consult the # documentation for your spawner to verify! #c.Spawner.args = [] -c.Spawner.args = ["--transport=ipc"] +#c.Spawner.args = ["--transport=ipc"] ## The command used for starting the single-user server. # @@ -1058,31 +1063,33 @@ def comma_split(string): "gerty-shared-node-cpu": ( "sshspawner.sshspawner.SSHSpawner", { "cmd": ["/global/common/cori/das/jupyterhub/jupyter-launcher.sh", - "/usr/common/software/python/3.7-anaconda-2019.07/bin/jupyter-labhub"], + "/global/common/cori_cle7/software/jupyter/19-09/bin/jupyter-labhub"], + "args": ["--transport=ipc"], "environment": {"OMP_NUM_THREADS" : "2"}, "remote_hosts": ["gerty.nersc.gov"], "remote_port_command": "/usr/bin/python /global/common/cori/das/jupyterhub/new-get-port.py --ip", "hub_api_url": "http://{}:8081/hub/api".format(ip), - "path": "/usr/common/software/python/3.7-anaconda-2019.07/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", + "path": "/global/common/cori_cle7/software/jupyter/19-09/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", "ssh_keyfile": '/certs/{username}.key' } ), "cori-shared-node-cpu": ( "sshspawner.sshspawner.SSHSpawner", { "cmd": ["/global/common/cori/das/jupyterhub/jupyter-launcher.sh", - "/usr/common/software/python/3.7-anaconda-2019.07/bin/jupyter-labhub"], + "/usr/common/software/jupyter/19-09/bin/jupyter-labhub"], + "args": ["--transport=ipc"], "environment": {"OMP_NUM_THREADS" : "2", "PYTHONFAULTHANDLER": "1"}, "remote_hosts": ["corijupyter.nersc.gov"], "remote_port_command": "/usr/bin/python /global/common/cori/das/jupyterhub/new-get-port.py --ip", "hub_api_url": "http://{}:8081/hub/api".format(ip), - "path": "/usr/common/software/python/3.7-anaconda-2019.07/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", + "path": "/usr/common/software/jupyter/19-09/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", "ssh_keyfile": '/certs/{username}.key' } ), "cori-exclusive-node-cpu": ( "nerscslurmspawner.NERSCExclusiveSlurmSpawner", { "cmd": ["/global/common/cori/das/jupyterhub/jupyter-launcher.sh", - "/usr/common/software/python/3.7-anaconda-2019.07/bin/jupyter-labhub"], + "/usr/common/software/jupyter/19-09/bin/jupyter-labhub"], "exec_prefix": "/usr/bin/ssh -q -o StrictHostKeyChecking=no -o preferredauthentications=publickey -l {username} -i /certs/{username}.key {remote_host}", "http_timeout": 300, "startup_poll_interval": 30.0, @@ -1090,26 +1097,28 @@ def comma_split(string): "req_homedir": "/tmp", "req_runtime": "240", "hub_api_url": "http://{}:8081/hub/api".format(ip), - "path": "/usr/common/software/python/3.7-anaconda-2019.07/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", + "path": "/usr/common/software/jupyter/19-09/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", } ), "cori-exclusive-node-gpu": ( "nerscslurmspawner.NERSCExclusiveGPUSlurmSpawner", { "cmd": ["/global/common/cori/das/jupyterhub/jupyter-launcher.sh", - "/usr/common/software/python/3.7-anaconda-2019.07/bin/jupyter-labhub"], + "/usr/common/software/jupyter/19-09/bin/jupyter-labhub"], + "args": ["--transport=ipc"], "exec_prefix": "/usr/bin/ssh -q -o StrictHostKeyChecking=no -o preferredauthentications=publickey -l {username} -i /certs/{username}.key {remote_host}", "startup_poll_interval": 30.0, "req_remote_host": "cori19-224.nersc.gov", "req_homedir": "/tmp", "req_runtime": "240", "hub_api_url": "http://{}:8081/hub/api".format(ip), - "path": "/usr/common/software/python/3.7-anaconda-2019.07/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", + "path": "/usr/common/software/jupyter/19-09/bin:/global/common/cori/das/jupyterhub:/usr/common/usg/bin:/usr/bin:/bin", } ), "spin-shared-node-cpu": ( "sshspawner.sshspawner.SSHSpawner", { "cmd": ["/global/common/cori/das/jupyterhub/jupyter-launcher.sh", "/opt/anaconda3/bin/jupyter-labhub"], + "args": ["--transport=ipc"], "environment": {"OMP_NUM_THREADS" : "2"}, "remote_hosts": ["app-notebooks"], "remote_port_command": "/opt/anaconda3/bin/python /global/common/cori/das/jupyterhub/new-get-port.py --ip", diff --git a/jupyter-nersc/web-jupyterhub/templates/page.html b/jupyter-nersc/web-jupyterhub/templates/page.html index 921f1cd..4a3f7c2 100644 --- a/jupyter-nersc/web-jupyterhub/templates/page.html +++ b/jupyter-nersc/web-jupyterhub/templates/page.html @@ -7,7 +7,7 @@ {% block script %} {{ super() }}