Merge pull request #165386 from zhaofengli/moonraker-2022-03-10

moonraker: unstable-2021-12-05 -> unstable-2022-03-10
This commit is contained in:
Bernardo Meurer 2022-03-23 10:33:10 -07:00 committed by GitHub
commit 25d1efa97e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 138 additions and 6 deletions

View File

@ -79,6 +79,19 @@ in {
for supported values.
'';
};
allowSystemControl = mkOption {
type = types.bool;
default = false;
description = ''
Whether to allow Moonraker to perform system-level operations.
Moonraker exposes APIs to perform system-level operations, such as
reboot, shutdown, and management of systemd units. See the
<link xlink:href="https://moonraker.readthedocs.io/en/latest/web_api/#machine-commands">documentation</link>
for details on what clients are able to do.
'';
};
};
};
@ -86,6 +99,13 @@ in {
warnings = optional (cfg.settings ? update_manager)
''Enabling update_manager is not supported on NixOS and will lead to non-removable warnings in some clients.'';
assertions = [
{
assertion = cfg.allowSystemControl -> config.security.polkit.enable;
message = "services.moonraker.allowSystemControl requires polkit to be enabled (security.polkit.enable).";
}
];
users.users = optionalAttrs (cfg.user == "moonraker") {
moonraker = {
group = cfg.group;
@ -128,11 +148,31 @@ in {
exec ${pkg}/bin/moonraker -c ${cfg.configDir}/moonraker-temp.cfg
'';
# Needs `ip` command
path = [ pkgs.iproute2 ];
serviceConfig = {
WorkingDirectory = cfg.stateDir;
Group = cfg.group;
User = cfg.user;
};
};
security.polkit.extraConfig = lib.optionalString cfg.allowSystemControl ''
// nixos/moonraker: Allow Moonraker to perform system-level operations
//
// This was enabled via services.moonraker.allowSystemControl.
polkit.addRule(function(action, subject) {
if ((action.id == "org.freedesktop.systemd1.manage-units" ||
action.id == "org.freedesktop.login1.power-off" ||
action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
action.id == "org.freedesktop.login1.reboot" ||
action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
action.id.startsWith("org.freedesktop.packagekit.")) &&
subject.user == "${cfg.user}") {
return polkit.Result.YES;
}
});
'';
};
}

View File

@ -308,6 +308,7 @@ in
molly-brown = handleTest ./molly-brown.nix {};
mongodb = handleTest ./mongodb.nix {};
moodle = handleTest ./moodle.nix {};
moonraker = handleTest ./moonraker.nix {};
morty = handleTest ./morty.nix {};
mosquitto = handleTest ./mosquitto.nix {};
moosefs = handleTest ./moosefs.nix {};

45
nixos/tests/moonraker.nix Normal file
View File

@ -0,0 +1,45 @@
import ./make-test-python.nix ({ pkgs, ...} : {
name = "moonraker";
meta = with pkgs.lib.maintainers; {
maintainers = [ zhaofengli ];
};
nodes = {
printer = { config, pkgs, ... }: {
security.polkit.enable = true;
services.moonraker = {
enable = true;
allowSystemControl = true;
settings = {
authorization = {
trusted_clients = [ "127.0.0.0/8" "::1/128" ];
};
};
};
services.klipper = {
enable = true;
user = "moonraker";
group = "moonraker";
# No mcu configured so won't even enter `ready` state
settings = {};
};
};
};
testScript = ''
printer.start()
printer.wait_for_unit("klipper.service")
printer.wait_for_unit("moonraker.service")
printer.wait_until_succeeds("curl http://localhost:7125/printer/info | grep -v 'Not Found' >&2", timeout=30)
with subtest("Check that we can perform system-level operations"):
printer.succeed("curl -X POST http://localhost:7125/machine/services/stop?service=klipper | grep ok >&2")
printer.wait_until_succeeds("systemctl --no-pager show klipper.service | grep ActiveState=inactive", timeout=10)
'';
})

View File

@ -0,0 +1,31 @@
{ lib, fetchFromGitHub, buildPythonPackage, pythonOlder, poetry-core
, pytestCheckHook, pytest-cov
, shapely }:
buildPythonPackage rec {
pname = "preprocess-cancellation";
version = "0.2.0";
disabled = pythonOlder "3.6"; # >= 3.6
format = "pyproject";
# No tests in PyPI
src = fetchFromGitHub {
owner = "kageurufu";
repo = "cancelobject-preprocessor";
rev = version;
hash = "sha256-mn3/etXA5dkL+IsyxwD4/XjU/t4/roYFVyqQxlLOoOI=";
};
nativeBuildInputs = [ poetry-core ];
propagatedBuildInputs = [ shapely ];
checkInputs = [ pytestCheckHook pytest-cov ];
meta = with lib; {
description = "Klipper GCode Preprocessor for Object Cancellation";
homepage = "https://github.com/kageurufu/cancelobject-preprocessor";
license = licenses.gpl3Only;
maintainers = with maintainers; [ zhaofengli ];
};
}

View File

@ -36,6 +36,11 @@ stdenv.mkDerivation rec {
mkdir -p $out/lib/klipper
cp -r ./* $out/lib/klipper
# Moonraker expects `config_examples` and `docs` to be available
# under `klipper_path`
cp -r $src/docs $out/lib/docs
cp -r $src/config $out/lib/config
chmod 755 $out/lib/klipper/klippy.py
runHook postInstall
'';

View File

@ -1,9 +1,9 @@
{ lib, stdenvNoCC, fetchFromGitHub, python3, makeWrapper, unstableGitUpdater }:
{ lib, stdenvNoCC, fetchFromGitHub, python3, makeWrapper, unstableGitUpdater, nixosTests }:
let
pythonEnv = python3.withPackages (packages: with packages; [
tornado
pyserial
pyserial-asyncio
pillow
lmdb
streaming-form-data
@ -12,16 +12,21 @@ let
libnacl
paho-mqtt
pycurl
zeroconf
preprocess-cancellation
jinja2
dbus-next
apprise
]);
in stdenvNoCC.mkDerivation rec {
pname = "moonraker";
version = "unstable-2021-12-05";
version = "unstable-2022-03-10";
src = fetchFromGitHub {
owner = "Arksine";
repo = "moonraker";
rev = "ac73036857cc1ca83df072dd94bf28eb9d0ed8b0";
sha256 = "Oqjt0z4grt+hdQ4t7KQSwkkCeRGoFFedJsTpMHwMm34=";
rev = "ee312ee9c6597c8d077d7c3208ccea4e696c97ca";
sha256 = "l0VOQIfKgZ/Je4z+SKhWMgYzxye8WKs9W1GkNs7kABo=";
};
nativeBuildInputs = [ makeWrapper ];
@ -34,7 +39,10 @@ in stdenvNoCC.mkDerivation rec {
--add-flags "$out/lib/moonraker/moonraker.py"
'';
passthru.updateScript = unstableGitUpdater { url = meta.homepage; };
passthru = {
updateScript = unstableGitUpdater { url = meta.homepage; };
tests.moonraker = nixosTests.moonraker;
};
meta = with lib; {
description = "API web server for Klipper";

View File

@ -6466,6 +6466,8 @@ in {
premailer = callPackage ../development/python-modules/premailer { };
preprocess-cancellation = callPackage ../development/python-modules/preprocess-cancellation { };
preshed = callPackage ../development/python-modules/preshed { };
pretend = callPackage ../development/python-modules/pretend { };