at 22.05-pre 3.6 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 cfg = config.services.klipper; 5 format = pkgs.formats.ini { 6 # https://github.com/NixOS/nixpkgs/pull/121613#issuecomment-885241996 7 listToValue = l: 8 if builtins.length l == 1 then generators.mkValueStringDefault {} (head l) 9 else lib.concatMapStrings (s: "\n ${generators.mkValueStringDefault {} s}") l; 10 mkKeyValue = generators.mkKeyValueDefault {} ":"; 11 }; 12in 13{ 14 ##### interface 15 options = { 16 services.klipper = { 17 enable = mkEnableOption "Klipper, the 3D printer firmware"; 18 19 package = mkOption { 20 type = types.package; 21 default = pkgs.klipper; 22 defaultText = literalExpression "pkgs.klipper"; 23 description = "The Klipper package."; 24 }; 25 26 inputTTY = mkOption { 27 type = types.path; 28 default = "/run/klipper/tty"; 29 description = "Path of the virtual printer symlink to create."; 30 }; 31 32 apiSocket = mkOption { 33 type = types.nullOr types.path; 34 default = "/run/klipper/api"; 35 description = "Path of the API socket to create."; 36 }; 37 38 octoprintIntegration = mkOption { 39 type = types.bool; 40 default = false; 41 description = "Allows Octoprint to control Klipper."; 42 }; 43 44 user = mkOption { 45 type = types.nullOr types.str; 46 default = null; 47 description = '' 48 User account under which Klipper runs. 49 50 If null is specified (default), a temporary user will be created by systemd. 51 ''; 52 }; 53 54 group = mkOption { 55 type = types.nullOr types.str; 56 default = null; 57 description = '' 58 Group account under which Klipper runs. 59 60 If null is specified (default), a temporary user will be created by systemd. 61 ''; 62 }; 63 64 settings = mkOption { 65 type = format.type; 66 default = { }; 67 description = '' 68 Configuration for Klipper. See the <link xlink:href="https://www.klipper3d.org/Overview.html#configuration-and-tuning-guides">documentation</link> 69 for supported values. 70 ''; 71 }; 72 }; 73 }; 74 75 ##### implementation 76 config = mkIf cfg.enable { 77 assertions = [ 78 { 79 assertion = cfg.octoprintIntegration -> config.services.octoprint.enable; 80 message = "Option klipper.octoprintIntegration requires Octoprint to be enabled on this system. Please enable services.octoprint to use it."; 81 } 82 { 83 assertion = cfg.user != null -> cfg.group != null; 84 message = "Option klipper.group is not set when a user is specified."; 85 } 86 ]; 87 88 environment.etc."klipper.cfg".source = format.generate "klipper.cfg" cfg.settings; 89 90 services.klipper = mkIf cfg.octoprintIntegration { 91 user = config.services.octoprint.user; 92 group = config.services.octoprint.group; 93 }; 94 95 systemd.services.klipper = let 96 klippyArgs = "--input-tty=${cfg.inputTTY}" 97 + optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}"; 98 in { 99 description = "Klipper 3D Printer Firmware"; 100 wantedBy = [ "multi-user.target" ]; 101 after = [ "network.target" ]; 102 103 serviceConfig = { 104 ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} /etc/klipper.cfg"; 105 RuntimeDirectory = "klipper"; 106 SupplementaryGroups = [ "dialout" ]; 107 WorkingDirectory = "${cfg.package}/lib"; 108 } // (if cfg.user != null then { 109 Group = cfg.group; 110 User = cfg.user; 111 } else { 112 DynamicUser = true; 113 User = "klipper"; 114 }); 115 }; 116 }; 117}