parent
00c0d79f6e
commit
228f08035d
@ -0,0 +1,190 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
|
||||
with lib; |
||||
|
||||
let |
||||
|
||||
cfg = config.services.jupyterhub; |
||||
|
||||
kernels = (pkgs.jupyter-kernel.create { |
||||
definitions = if cfg.kernels != null |
||||
then cfg.kernels |
||||
else pkgs.jupyter-kernel.default; |
||||
}); |
||||
|
||||
jupyterhubConfig = pkgs.writeText "jupyterhub_config.py" '' |
||||
c.JupyterHub.bind_url = "http://${cfg.host}:${toString cfg.port}" |
||||
|
||||
c.JupyterHub.authentication_class = "${cfg.authentication}" |
||||
c.JupyterHub.spawner_class = "${cfg.spawner}" |
||||
|
||||
c.SystemdSpawner.default_url = '/lab' |
||||
c.SystemdSpawner.cmd = "${cfg.jupyterlabEnv}/bin/jupyterhub-singleuser" |
||||
c.SystemdSpawner.environment = { |
||||
'JUPYTER_PATH': '${kernels}' |
||||
} |
||||
|
||||
${cfg.extraConfig} |
||||
''; |
||||
in { |
||||
meta.maintainers = with maintainers; [ costrouc ]; |
||||
|
||||
options.services.jupyterhub = { |
||||
enable = mkEnableOption "Jupyterhub development server"; |
||||
|
||||
authentication = mkOption { |
||||
type = types.str; |
||||
default = "jupyterhub.auth.PAMAuthenticator"; |
||||
description = '' |
||||
Jupyterhub authentication to use |
||||
|
||||
There are many authenticators available including: oauth, pam, |
||||
ldap, kerberos, etc. |
||||
''; |
||||
}; |
||||
|
||||
spawner = mkOption { |
||||
type = types.str; |
||||
default = "systemdspawner.SystemdSpawner"; |
||||
description = '' |
||||
Jupyterhub spawner to use |
||||
|
||||
There are many spawners available including: local process, |
||||
systemd, docker, kubernetes, yarn, batch, etc. |
||||
''; |
||||
}; |
||||
|
||||
extraConfig = mkOption { |
||||
type = types.lines; |
||||
default = ""; |
||||
description = '' |
||||
Extra contents appended to the jupyterhub configuration |
||||
|
||||
Jupyterhub configuration is a normal python file using |
||||
Traitlets. https://jupyterhub.readthedocs.io/en/stable/getting-started/config-basics.html. The |
||||
base configuration of this module was designed to have sane |
||||
defaults for configuration but you can override anything since |
||||
this is a python file. |
||||
''; |
||||
example = literalExample '' |
||||
c.SystemdSpawner.memory = "8G" |
||||
c.SystemdSpawner.cpus = "2" |
||||
''; |
||||
}; |
||||
|
||||
jupyterhubEnv = mkOption { |
||||
type = types.package; |
||||
default = (pkgs.python3.withPackages (p: with p; [ |
||||
jupyterhub |
||||
jupyterhub-systemdspawner |
||||
])); |
||||
description = '' |
||||
Python environment to run jupyterhub |
||||
|
||||
Customizing will affect the packages available in the hub and |
||||
proxy. This will allow packages to be available for the |
||||
extraConfig that you may need. This will not normally need to |
||||
be changed. |
||||
''; |
||||
}; |
||||
|
||||
jupyterlabEnv = mkOption { |
||||
type = types.package; |
||||
default = (pkgs.python3.withPackages (p: with p; [ |
||||
jupyterhub |
||||
jupyterlab |
||||
])); |
||||
description = '' |
||||
Python environment to run jupyterlab |
||||
|
||||
Customizing will affect the packages available in the |
||||
jupyterlab server and the default kernel provided. This is the |
||||
way to customize the jupyterlab extensions and jupyter |
||||
notebook extensions. This will not normally need to |
||||
be changed. |
||||
''; |
||||
}; |
||||
|
||||
kernels = mkOption { |
||||
type = types.nullOr (types.attrsOf(types.submodule (import ../jupyter/kernel-options.nix { |
||||
inherit lib; |
||||
}))); |
||||
|
||||
default = null; |
||||
example = literalExample '' |
||||
{ |
||||
python3 = let |
||||
env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [ |
||||
ipykernel |
||||
pandas |
||||
scikitlearn |
||||
])); |
||||
in { |
||||
displayName = "Python 3 for machine learning"; |
||||
argv = [ |
||||
"''${env.interpreter}" |
||||
"-m" |
||||
"ipykernel_launcher" |
||||
"-f" |
||||
"{connection_file}" |
||||
]; |
||||
language = "python"; |
||||
logo32 = "''${env}/''${env.sitePackages}/ipykernel/resources/logo-32x32.png"; |
||||
logo64 = "''${env}/''${env.sitePackages}/ipykernel/resources/logo-64x64.png"; |
||||
}; |
||||
} |
||||
''; |
||||
description = '' |
||||
Declarative kernel config |
||||
|
||||
Kernels can be declared in any language that supports and has |
||||
the required dependencies to communicate with a jupyter server. |
||||
In python's case, it means that ipykernel package must always be |
||||
included in the list of packages of the targeted environment. |
||||
''; |
||||
}; |
||||
|
||||
port = mkOption { |
||||
type = types.port; |
||||
default = 8000; |
||||
description = '' |
||||
Port number Jupyterhub will be listening on |
||||
''; |
||||
}; |
||||
|
||||
host = mkOption { |
||||
type = types.str; |
||||
default = "0.0.0.0"; |
||||
description = '' |
||||
Bind IP JupyterHub will be listening on |
||||
''; |
||||
}; |
||||
|
||||
stateDirectory = mkOption { |
||||
type = types.str; |
||||
default = "jupyterhub"; |
||||
description = '' |
||||
Directory for jupyterhub state (token + database) |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
config = mkMerge [ |
||||
(mkIf cfg.enable { |
||||
systemd.services.jupyterhub = { |
||||
description = "Jupyterhub development server"; |
||||
|
||||
after = [ "network.target" ]; |
||||
wantedBy = [ "multi-user.target" ]; |
||||
|
||||
serviceConfig = { |
||||
Restart = "always"; |
||||
ExecStart = "${cfg.jupyterhubEnv}/bin/jupyterhub --config ${jupyterhubConfig}"; |
||||
User = "root"; |
||||
StateDirectory = cfg.stateDirectory; |
||||
WorkingDirectory = "/var/lib/${cfg.stateDirectory}"; |
||||
}; |
||||
}; |
||||
}) |
||||
]; |
||||
} |
Loading…
Reference in new issue