git.iko.soy/typeable/nixpkgs
on master help sign in
Merge pull request #165386 from zhaofengli/moonraker-2022-03-10

moonraker: unstable-2021-12-05 -> unstable-2022-03-10

commit25d1efa97e4a5c02769825ac47a371854cee73e0 authorBernardo Meurer <bernardo@meurer.org> dateWed 23 Mar 2022, 10:33 (5 years ago) parent3bcfdb0b143138
7 files changed+138−6
nixos/modules/services/misc/moonraker.nix+40 nixos/tests/all-tests.nix+1 nixos/tests/moonraker.nix+45 pkgs/development/python-modules/preprocess-cancellation/default.nix+31 pkgs/servers/klipper/default.nix+5 pkgs/servers/moonraker/default.nix+14−6 pkgs/top-level/python-packages.nix+2
nixos/modules/services/misc/moonraker.nix+40
@@ -79,6 +79,19 @@ in {
7979 for supported values.
8080 '';
8181 };
82+
83+ allowSystemControl = mkOption {
84+ type = types.bool;
85+ default = false;
86+ description = ''
87+ Whether to allow Moonraker to perform system-level operations.
88+
89+ Moonraker exposes APIs to perform system-level operations, such as
90+ reboot, shutdown, and management of systemd units. See the
91+ <link xlink:href="https://moonraker.readthedocs.io/en/latest/web_api/#machine-commands">documentation</link>
92+ for details on what clients are able to do.
93+ '';
94+ };
8295 };
8396 };
8497
@@ -86,6 +99,13 @@ in {
8699 warnings = optional (cfg.settings ? update_manager)
87100 ''Enabling update_manager is not supported on NixOS and will lead to non-removable warnings in some clients.'';
88101
102+ assertions = [
103+ {
104+ assertion = cfg.allowSystemControl -> config.security.polkit.enable;
105+ message = "services.moonraker.allowSystemControl requires polkit to be enabled (security.polkit.enable).";
106+ }
107+ ];
108+
89109 users.users = optionalAttrs (cfg.user == "moonraker") {
90110 moonraker = {
91111 group = cfg.group;
@@ -128,11 +148,31 @@ in {
128148 exec ${pkg}/bin/moonraker -c ${cfg.configDir}/moonraker-temp.cfg
129149 '';
130150
151+ # Needs `ip` command
152+ path = [ pkgs.iproute2 ];
153+
131154 serviceConfig = {
132155 WorkingDirectory = cfg.stateDir;
133156 Group = cfg.group;
134157 User = cfg.user;
135158 };
136159 };
160+
161+ security.polkit.extraConfig = lib.optionalString cfg.allowSystemControl ''
162+ // nixos/moonraker: Allow Moonraker to perform system-level operations
163+ //
164+ // This was enabled via services.moonraker.allowSystemControl.
165+ polkit.addRule(function(action, subject) {
166+ if ((action.id == "org.freedesktop.systemd1.manage-units" ||
167+ action.id == "org.freedesktop.login1.power-off" ||
168+ action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
169+ action.id == "org.freedesktop.login1.reboot" ||
170+ action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
171+ action.id.startsWith("org.freedesktop.packagekit.")) &&
172+ subject.user == "${cfg.user}") {
173+ return polkit.Result.YES;
174+ }
175+ });
176+ '';
137177 };
138178}
nixos/tests/all-tests.nix+1
@@ -308,6 +308,7 @@ in
308308 molly-brown = handleTest ./molly-brown.nix {};
309309 mongodb = handleTest ./mongodb.nix {};
310310 moodle = handleTest ./moodle.nix {};
311+ moonraker = handleTest ./moonraker.nix {};
311312 morty = handleTest ./morty.nix {};
312313 mosquitto = handleTest ./mosquitto.nix {};
313314 moosefs = handleTest ./moosefs.nix {};
nixos/tests/moonraker.nixnew file+45
@@ -0,0 +1,45 @@
1+import ./make-test-python.nix ({ pkgs, ...} : {
2+ name = "moonraker";
3+ meta = with pkgs.lib.maintainers; {
4+ maintainers = [ zhaofengli ];
5+ };
6+
7+ nodes = {
8+ printer = { config, pkgs, ... }: {
9+ security.polkit.enable = true;
10+
11+ services.moonraker = {
12+ enable = true;
13+ allowSystemControl = true;
14+
15+ settings = {
16+ authorization = {
17+ trusted_clients = [ "127.0.0.0/8" "::1/128" ];
18+ };
19+ };
20+ };
21+
22+ services.klipper = {
23+ enable = true;
24+
25+ user = "moonraker";
26+ group = "moonraker";
27+
28+ # No mcu configured so won't even enter `ready` state
29+ settings = {};
30+ };
31+ };
32+ };
33+
34+ testScript = ''
35+ printer.start()
36+
37+ printer.wait_for_unit("klipper.service")
38+ printer.wait_for_unit("moonraker.service")
39+ printer.wait_until_succeeds("curl http://localhost:7125/printer/info | grep -v 'Not Found' >&2", timeout=30)
40+
41+ with subtest("Check that we can perform system-level operations"):
42+ printer.succeed("curl -X POST http://localhost:7125/machine/services/stop?service=klipper | grep ok >&2")
43+ printer.wait_until_succeeds("systemctl --no-pager show klipper.service | grep ActiveState=inactive", timeout=10)
44+ '';
45+})
pkgs/development/python-modules/preprocess-cancellation/default.nixnew file+31
@@ -0,0 +1,31 @@
1+{ lib, fetchFromGitHub, buildPythonPackage, pythonOlder, poetry-core
2+, pytestCheckHook, pytest-cov
3+, shapely }:
4+
5+buildPythonPackage rec {
6+ pname = "preprocess-cancellation";
7+ version = "0.2.0";
8+ disabled = pythonOlder "3.6"; # >= 3.6
9+ format = "pyproject";
10+
11+ # No tests in PyPI
12+ src = fetchFromGitHub {
13+ owner = "kageurufu";
14+ repo = "cancelobject-preprocessor";
15+ rev = version;
16+ hash = "sha256-mn3/etXA5dkL+IsyxwD4/XjU/t4/roYFVyqQxlLOoOI=";
17+ };
18+
19+ nativeBuildInputs = [ poetry-core ];
20+
21+ propagatedBuildInputs = [ shapely ];
22+
23+ checkInputs = [ pytestCheckHook pytest-cov ];
24+
25+ meta = with lib; {
26+ description = "Klipper GCode Preprocessor for Object Cancellation";
27+ homepage = "https://github.com/kageurufu/cancelobject-preprocessor";
28+ license = licenses.gpl3Only;
29+ maintainers = with maintainers; [ zhaofengli ];
30+ };
31+}
pkgs/servers/klipper/default.nix+5
@@ -36,6 +36,11 @@ stdenv.mkDerivation rec {
3636 mkdir -p $out/lib/klipper
3737 cp -r ./* $out/lib/klipper
3838
39+ # Moonraker expects `config_examples` and `docs` to be available
40+ # under `klipper_path`
41+ cp -r $src/docs $out/lib/docs
42+ cp -r $src/config $out/lib/config
43+
3944 chmod 755 $out/lib/klipper/klippy.py
4045 runHook postInstall
4146 '';
pkgs/servers/moonraker/default.nix+14−6
@@ -1,9 +1,9 @@
1−{ lib, stdenvNoCC, fetchFromGitHub, python3, makeWrapper, unstableGitUpdater }:
1+{ lib, stdenvNoCC, fetchFromGitHub, python3, makeWrapper, unstableGitUpdater, nixosTests }:
22
33let
44 pythonEnv = python3.withPackages (packages: with packages; [
55 tornado
6− pyserial
6+ pyserial-asyncio
77 pillow
88 lmdb
99 streaming-form-data
@@ -12,16 +12,21 @@ let
1212 libnacl
1313 paho-mqtt
1414 pycurl
15+ zeroconf
16+ preprocess-cancellation
17+ jinja2
18+ dbus-next
19+ apprise
1520 ]);
1621in stdenvNoCC.mkDerivation rec {
1722 pname = "moonraker";
18− version = "unstable-2021-12-05";
23+ version = "unstable-2022-03-10";
1924
2025 src = fetchFromGitHub {
2126 owner = "Arksine";
2227 repo = "moonraker";
23− rev = "ac73036857cc1ca83df072dd94bf28eb9d0ed8b0";
24− sha256 = "Oqjt0z4grt+hdQ4t7KQSwkkCeRGoFFedJsTpMHwMm34=";
28+ rev = "ee312ee9c6597c8d077d7c3208ccea4e696c97ca";
29+ sha256 = "l0VOQIfKgZ/Je4z+SKhWMgYzxye8WKs9W1GkNs7kABo=";
2530 };
2631
2732 nativeBuildInputs = [ makeWrapper ];
@@ -34,7 +39,10 @@ in stdenvNoCC.mkDerivation rec {
3439 --add-flags "$out/lib/moonraker/moonraker.py"
3540 '';
3641
37− passthru.updateScript = unstableGitUpdater { url = meta.homepage; };
42+ passthru = {
43+ updateScript = unstableGitUpdater { url = meta.homepage; };
44+ tests.moonraker = nixosTests.moonraker;
45+ };
3846
3947 meta = with lib; {
4048 description = "API web server for Klipper";
pkgs/top-level/python-packages.nix+2
@@ -6466,6 +6466,8 @@ in {
64666466
64676467 premailer = callPackage ../development/python-modules/premailer { };
64686468
6469+ preprocess-cancellation = callPackage ../development/python-modules/preprocess-cancellation { };
6470+
64696471 preshed = callPackage ../development/python-modules/preshed { };
64706472
64716473 pretend = callPackage ../development/python-modules/pretend { };