2020-08-06 11:52:12 +00:00
|
|
|
{ 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}"
|
|
|
|
|
2020-08-17 20:42:37 +00:00
|
|
|
c.JupyterHub.authenticator_class = "${cfg.authentication}"
|
2020-08-06 11:52:12 +00:00
|
|
|
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 = {
|
2022-08-28 19:18:44 +00:00
|
|
|
enable = mkEnableOption (lib.mdDoc "Jupyterhub development server");
|
2020-08-06 11:52:12 +00:00
|
|
|
|
|
|
|
authentication = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "jupyterhub.auth.PAMAuthenticator";
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
Jupyterhub authentication to use
|
|
|
|
|
|
|
|
There are many authenticators available including: oauth, pam,
|
|
|
|
ldap, kerberos, etc.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
spawner = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "systemdspawner.SystemdSpawner";
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
Jupyterhub spawner to use
|
|
|
|
|
|
|
|
There are many spawners available including: local process,
|
|
|
|
systemd, docker, kubernetes, yarn, batch, etc.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
extraConfig = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
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.
|
|
|
|
'';
|
2021-10-03 16:06:03 +00:00
|
|
|
example = ''
|
|
|
|
c.SystemdSpawner.mem_limit = '8G'
|
|
|
|
c.SystemdSpawner.cpu_limit = 2.0
|
2020-08-06 11:52:12 +00:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
jupyterhubEnv = mkOption {
|
|
|
|
type = types.package;
|
2021-10-03 16:06:03 +00:00
|
|
|
default = pkgs.python3.withPackages (p: with p; [
|
2020-08-06 11:52:12 +00:00
|
|
|
jupyterhub
|
|
|
|
jupyterhub-systemdspawner
|
2021-10-03 16:06:03 +00:00
|
|
|
]);
|
|
|
|
defaultText = literalExpression ''
|
|
|
|
pkgs.python3.withPackages (p: with p; [
|
|
|
|
jupyterhub
|
|
|
|
jupyterhub-systemdspawner
|
|
|
|
])
|
|
|
|
'';
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
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;
|
2021-10-03 16:06:03 +00:00
|
|
|
default = pkgs.python3.withPackages (p: with p; [
|
2020-08-06 11:52:12 +00:00
|
|
|
jupyterhub
|
|
|
|
jupyterlab
|
2021-10-03 16:06:03 +00:00
|
|
|
]);
|
|
|
|
defaultText = literalExpression ''
|
|
|
|
pkgs.python3.withPackages (p: with p; [
|
|
|
|
jupyterhub
|
|
|
|
jupyterlab
|
|
|
|
])
|
|
|
|
'';
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
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 {
|
2022-10-14 17:19:09 +00:00
|
|
|
inherit lib pkgs;
|
2020-08-06 11:52:12 +00:00
|
|
|
})));
|
|
|
|
|
|
|
|
default = null;
|
2021-10-03 16:06:03 +00:00
|
|
|
example = literalExpression ''
|
2020-08-06 11:52:12 +00:00
|
|
|
{
|
|
|
|
python3 = let
|
|
|
|
env = (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
|
|
|
|
ipykernel
|
|
|
|
pandas
|
2021-05-14 18:46:36 +00:00
|
|
|
scikit-learn
|
2020-08-06 11:52:12 +00:00
|
|
|
]));
|
|
|
|
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";
|
|
|
|
};
|
|
|
|
}
|
|
|
|
'';
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
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;
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
Port number Jupyterhub will be listening on
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
host = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "0.0.0.0";
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
Bind IP JupyterHub will be listening on
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
stateDirectory = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "jupyterhub";
|
2022-08-05 17:39:00 +00:00
|
|
|
description = lib.mdDoc ''
|
2020-08-06 11:52:12 +00:00
|
|
|
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}";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
})
|
|
|
|
];
|
|
|
|
}
|