Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/jupyter: migrate service to jupyter 7 setup #367106

Merged
merged 1 commit into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,8 @@

- Kanidm previously had an incorrect systemd service type, causing dependent units with an `after` and `requires` directive to start before `kanidm*` finished startup. The module has now been updated in line with upstream recommendations.

- [`services.jupyter`](#opt-services.jupyter.enable) is now compatible with `Jupyter Notebook 7`. See [the migration guide](https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html) for details.

- The kubelet configuration file can now be amended with arbitrary additional content using the `services.kubernetes.kubelet.extraConfig` option.

- The `services.seafile` module was updated to major version 11.
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2505.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@

- GOverlay has been updated to 1.2, please check the [upstream changelog](https://github.com/benjamimgois/goverlay/releases) for more details.

- [`services.jupyter`](#opt-services.jupyter.enable) is now compatible with `Jupyter Notebook 7`. See [the migration guide](https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html) for details.

- `networking.wireguard` now has an optional networkd backend. It is enabled by default when `networking.useNetworkd` is enabled, and it can be enabled alongside scripted networking with `networking.wireguard.useNetworkd`. Some `networking.wireguard` options have slightly different behavior with the networkd and script-based backends, documented in each option.

- `services.avahi.ipv6` now defaults to true.
Expand Down
74 changes: 51 additions & 23 deletions nixos/modules/services/development/jupyter/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,38 @@
config,
lib,
pkgs,
options,
...
}:
let

cfg = config.services.jupyter;

package = cfg.package;
package = pkgs.python3.withPackages (
ps:
[
cfg.package
]
++ cfg.extraPackages
);

kernels = (
pkgs.jupyter-kernel.create {
definitions = if cfg.kernels != null then cfg.kernels else pkgs.jupyter-kernel.default;
}
);

notebookConfig = pkgs.writeText "jupyter_config.py" ''
notebookConfig = pkgs.writeText "jupyter_server_config.py" ''
${cfg.notebookConfig}
JohnRTitor marked this conversation as resolved.
Show resolved Hide resolved
c.NotebookApp.password = ${cfg.password}
c.ServerApp.password = "${cfg.password}"
'';

in
{
meta.maintainers = with lib.maintainers; [ aborsu ];
meta.maintainers = with lib.maintainers; [
aborsu
b-m-f
];

options.services.jupyter = {
enable = lib.mkEnableOption "Jupyter development server";
Expand All @@ -37,18 +46,42 @@ in
'';
};

# NOTE: We don't use top-level jupyter because we don't
# want to pass in JUPYTER_PATH but use .environment instead,
# saving a rebuild.
package = lib.mkPackageOption pkgs [ "python3" "pkgs" "notebook" ] { };
b-m-f marked this conversation as resolved.
Show resolved Hide resolved
package = lib.mkPackageOption pkgs [
"python3"
"pkgs"
"jupyter"
] { };

extraPackages = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [ ];
example = lib.literalExpression ''
[
pkgs.python3.pkgs.nbconvert
pkgs.python3.pkgs.playwright
]
'';
description = ''Extra packages to be available in the jupyter runtime enviroment'';
};
extraEnvironmentVariables = lib.mkOption {
description = ''Extra enviroment variables to be set in the runtime context of jupyter notebook'';
default = { };
example = lib.literalExpression ''
{
PLAYWRIGHT_BROWSERS_PATH = "''${pkgs.playwright-driver.browsers}";
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = "true";
}
'';
inherit (options.environment.variables) type apply;
};

command = lib.mkOption {
type = lib.types.str;
default = "jupyter-notebook";
example = "jupyter-lab";
default = "jupyter notebook";
example = "jupyter lab";
description = ''
Which command the service runs. Note that not all jupyter packages
have all commands, e.g. jupyter-lab isn't present in the default package.
have all commands, e.g. `jupyter lab` isn't present in the `notebook` package.
'';
};

Expand Down Expand Up @@ -93,23 +126,17 @@ in
type = lib.types.str;
description = ''
Password to use with notebook.
Can be generated using:
In [1]: from notebook.auth import passwd
In [2]: passwd('test')
Out[2]: 'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'
NOTE: you need to keep the single quote inside the nix string.
Or you can use a python oneliner:
"open('/path/secret_file', 'r', encoding='utf8').read().strip()"
It will be interpreted at the end of the notebookConfig.
Can be generated following: https://jupyter-server.readthedocs.io/en/stable/operators/public-server.html#preparing-a-hashed-password
'';
example = "'sha1:1b961dc713fb:88483270a63e57d18d43cf337e629539de1436ba'";
example = "argon2:$argon2id$v=19$m=10240,t=10,p=8$48hF+vTUuy1LB83/GzNhUg$J1nx4jPWD7PwOJHs5OtDW8pjYK2s0c1R3rYGbSIKB54";
};

notebookConfig = lib.mkOption {
type = lib.types.lines;
default = "";
description = ''
Raw jupyter config.
Please use the password configuration option to set a password instead of passing it in here.
'';
};

Expand Down Expand Up @@ -175,7 +202,7 @@ in

environment = {
JUPYTER_PATH = toString kernels;
};
} // cfg.extraEnvironmentVariables;

serviceConfig = {
Restart = "always";
Expand All @@ -185,7 +212,8 @@ in
--ip=${cfg.ip} \
--port=${toString cfg.port} --port-retries 0 \
--notebook-dir=${cfg.notebookDir} \
--NotebookApp.config_file=${notebookConfig}
--JupyterApp.config_file=${notebookConfig}
'';
User = cfg.user;
Group = cfg.group;
Expand Down