Commit fdd29ae8 by Jocelyn Delalande

jupyterhub: Bring the role to a working state

parent 36017fff
WIP JupyterHUB role
===================
JupyterHub deployment to learn programming with JS
==================================================
**Work in progress, cannot be used as-is.**
- Deploy JupyterHub
- Deploy IJavasScript kernel to allow JS notebooks
- Tweak IJavaScript config to add `prompt()` and `alert()` synchronous
functions
- Set up a locale (translation)
*see also: jupyter*
## Security warning
Be conscious that JupyterHub gives a remote (unprivilleged) shell access to
logged-in users, and that this implementation is not using docker isolation.
## Performance warning
JupyterHub can be quite intensive on resources, by experience, a group of 10
people toying with a few notebooks will quickly require 2G RAM dedicated to
Jupyter. If you experience killed notebooks or notebooks refusing to start as
more users connect, you should give a look at RAM usage and consider adding
more.
Variables
---------
### Optional (interface language)
Use both or use none, note that you have to use one of
jupyter
[supported languages](https://github.com/JocelynDelalande/notebook/blob/jd-french-i18n/notebook/i18n/nbjs.json#L3-L6). Left
those settings unchanged to use plain old English.
- *jupyterhub_locale* : a unix locale (ex: `fr_FR`)
- *jupyterhub_system_locale* : a unix locale with charset indication (ex: `fr_FR.utf8`)
......@@ -3,5 +3,18 @@
# Not that it seems not required for Debian stretch
- name: Install npm deps
npm:
name: ijavascript
name: "{{ item }}"
global: yes
with_items:
- ijavascript
- fibers # for synchronous functions
- name: Install ijavascript kernel for notebooks
shell: "ijsinstall --install=global --startup-script=/opt/jupyterhub/js-startup.js"
environment:
PATH: "/opt/jupyterhub/venv/bin:{{ ansible_env.PATH }}"
- name: Deploy custom startup script (with custom sync functions for learning)
template:
src: js-startup.js
dest: /opt/jupyterhub/js-startup.js
\ No newline at end of file
# This first task is actually required by ijavascript
# to get a recent version of node (jessie-backports contains one, but with no
# npm…)
# Seems un-needed on strecth (but not tested)
- name: Install node from nodesource as ijs wont run with node 0.10x
# This first task is actually required by ijavascript to get a recent version
# of node (jessie-backports and stretch contains a recent one, but lacking npm)
#
- name: Install node from nodesource
import_tasks: nodesource.yml
- name: install apt dependencies
......@@ -35,6 +34,9 @@
become: jupyterhub
notify: restart jupyterhub
- name: install jupyter notebook (with french translation)
include: notebook.yml
- name: Install npm deps
npm:
name: configurable-http-proxy
......@@ -78,6 +80,9 @@
dest: /etc/jupyterhub/jupyterhub_config.py
notify: restart jupyterhub
- name: Install ijavascript notebook kernel
import_tasks: ijavascript.yml
- name: systemd script is in place
template:
src: jupyterhub.service.j2
......@@ -89,5 +94,3 @@
- name: jupyterhub is started
service: name=jupyterhub state=started
- name: Install ijavascript notebook kernel
import_tasks: ijavascript.yml
- name: Install jupyter notebook
pip:
# Could switch to stable release once PR is merged
# https://github.com/jupyter/notebook/pull/3888
name: "git+https://github.com/JocelynDelalande/notebook.git@jd-french-i18n#egg=notebook"
virtualenv: /opt/jupyterhub/venv
become: jupyterhub
notify: restart jupyterhub
register: updated_notebook
- name: Install pybabel
# Could drop this step once issue is fixed
# https://github.com/jupyter/notebook/issues/3102
pip:
name: babel
virtualenv: /opt/jupyterhub/venv
become: jupyterhub
when: jupyterhub_locale
- name: Install po2json
# A recent version is required for -p option
# Could drop this step once issue is fixed
# https://github.com/jupyter/notebook/issues/3102
npm:
name: po2json
global: yes
when: jupyterhub_locale
- name: Get i18n path
# Could drop this step once issue is fixed
# https://github.com/jupyter/notebook/issues/3102
command: "/opt/jupyterhub/venv/bin/python -c 'import notebook.i18n;print(notebook.i18n.__path__[0])'"
register: i18n_path
when: jupyterhub_locale
- name: Compile translations (.po → .mo)
# Could drop this step once issue is fixed
# https://github.com/jupyter/notebook/issues/3102
command: "/opt/jupyterhub/venv/bin/pybabel compile -D notebook -f -l {{ jupyterhub_locale }} -i {{ jupyterhub_locale }}/LC_MESSAGES/{{ item }}.po -o {{ jupyterhub_locale }}/LC_MESSAGES/{{ item }}.mo"
args:
chdir: "{{ i18n_path.stdout }}"
with_items:
- notebook
- nbui
when: updated_notebook.changed and jupyterhub_locale
notify: restart jupyterhub
become: jupyterhub
- name: Compile translations (.po → .json)
# Could drop this step once issue is fixed
# https://github.com/jupyter/notebook/issues/3102
command: "po2json -p -F -f jed1.x -d nbjs {{ jupyterhub_locale }}/LC_MESSAGES/nbjs.po {{ jupyterhub_locale }}/LC_MESSAGES/nbjs.json"
args:
chdir: "{{ i18n_path.stdout }}"
when: updated_notebook.changed and jupyterhub_locale
notify: restart jupyterhub
become: jupyterhub
// {{ ansible_managed }}
/*
* Custom startup script to ease programming learning with ijavascript notebooks :
*
* - Wrap every cell execution with Fiber
* - Offer the following non-standard JavaScript functions
* - alert(<msg>) : alias to console.log
* - prompt(<msg>) : browser-like, synchronous
* - afficheLigne(<nbTirets>) : draws a line on screen
*
* /!\ That startup script prevents global scope from being shared among cells /!\
*
*/
var Fiber = require('fibers');
global.alert = function (msg) {
console.log(msg);
};
/* Wrap every execution into fiber environment
*
* To allow synchronous magic happen
*/
var runInThisContext = vm.runInThisContext;
vm.runInThisContext = function(code) {
runInThisContext("Fiber(function() {" + code + "}).run();");
};
/** Synchronous sleep-like function for JavaScript
*
* Used to implement busy loops (ugly for performance, but sometimes, that is
* not what most matters).
*/
function fiberSleep(ms) {
var fiber = Fiber.current;
setTimeout(function() {
fiber.run();
}, ms);
Fiber.yield();
}
/** Synchronously prompts the user for a string
*
* Similar to the prompt() function on browsers. Returns the typed value.
*/
global.prompt = function(msg) {
var ret;
var ready = false;
$$.input({prompt: msg+ ' ', password: false}, function(err, msg) {
ret = msg;
ready = true;
$$.done();
});
while (!ready) {
fiberSleep(100);
}
return ret;
};
global.afficheLigne = function(nbTirets) {
var l = '';
for (var i=0; i < nbTirets; i++) {
l += '-';
}
alert(l);
};
......@@ -3,7 +3,7 @@
### GLOBAL ###
## Avoid listening on iternet (we have a nginx for that)
## Avoid listening on Internet (we have a nginx for that)
c.JupyterHub.ip = '127.0.0.1'
......@@ -13,14 +13,20 @@ c.JupyterHub.admin_access = True
### SPAWNER ###
## Use our in-venv sudospawner
## Specific spawner config (our in-venv sudospawner)
c.SudoSpawner.sudospawner_path = '/opt/jupyterhub/venv/bin/sudospawner'
c.SudoSpawner.debug = True
c.SudoSpawner.mem_limit = '2M'
c.Spawner.debug = True # redundant ?
# Generic spawner config
c.Spawner.mem_limit = '2M'
c.Spawner.debug = True
c.Spawner.KernelSpecManager.whitelist = {'javascript'}
c.Spawner.notebook_dir = '~/notebooks'
c.Spawner.environment = {
{% if jupyterhub_system_locale %}
'LANG': '{{ jupyterhub_system_locale }}',
{% endif %}
'NODE_PATH':'/usr/lib/node_modules',
}
### AUTH ###
## Restrict users able to log in to a unix group
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment