summaryrefslogtreecommitdiffstats
path: root/nixos
diff options
context:
space:
mode:
authorBernardo Meurer <bernardo@meurer.org>2022-03-23 10:33:10 -0700
committerGitHub <noreply@github.com>2022-03-23 10:33:10 -0700
commit25d1efa97e4a5c02769825ac47a371854cee73e0 (patch)
tree237fbaa38b25da63a284f90f301b5fbc46a3e1ad /nixos
parent3bcfdb0e15c3a7f1959bd05b04fa8b292b010662 (diff)
parentb1431381d0f43804dc340cd891679345a2fe7a3e (diff)
Merge pull request #165386 from zhaofengli/moonraker-2022-03-10
moonraker: unstable-2021-12-05 -> unstable-2022-03-10
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/misc/moonraker.nix40
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/moonraker.nix45
3 files changed, 86 insertions, 0 deletions
diff --git a/nixos/modules/services/misc/moonraker.nix b/nixos/modules/services/misc/moonraker.nix
index ae57aaa6d479..b75227effa04 100644
--- a/nixos/modules/services/misc/moonraker.nix
+++ b/nixos/modules/services/misc/moonraker.nix
@@ -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;
+ }
+ });
+ '';
};
}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index b6311f856fa8..8d54f78a9481 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -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 {};
diff --git a/nixos/tests/moonraker.nix b/nixos/tests/moonraker.nix
new file mode 100644
index 000000000000..b0a93a4a608b
--- /dev/null
+++ b/nixos/tests/moonraker.nix
@@ -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)
+ '';
+})