at 22.05-pre 4.1 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 pkg = pkgs.moonraker; 5 cfg = config.services.moonraker; 6 format = pkgs.formats.ini { 7 # https://github.com/NixOS/nixpkgs/pull/121613#issuecomment-885241996 8 listToValue = l: 9 if builtins.length l == 1 then generators.mkValueStringDefault {} (head l) 10 else lib.concatMapStrings (s: "\n ${generators.mkValueStringDefault {} s}") l; 11 mkKeyValue = generators.mkKeyValueDefault {} ":"; 12 }; 13in { 14 options = { 15 services.moonraker = { 16 enable = mkEnableOption "Moonraker, an API web server for Klipper"; 17 18 klipperSocket = mkOption { 19 type = types.path; 20 default = config.services.klipper.apiSocket; 21 description = "Path to Klipper's API socket."; 22 }; 23 24 stateDir = mkOption { 25 type = types.path; 26 default = "/var/lib/moonraker"; 27 description = "The directory containing the Moonraker databases."; 28 }; 29 30 configDir = mkOption { 31 type = types.path; 32 default = cfg.stateDir + "/config"; 33 description = '' 34 The directory containing client-writable configuration files. 35 36 Clients will be able to edit files in this directory via the API. This directory must be writable. 37 ''; 38 }; 39 40 user = mkOption { 41 type = types.str; 42 default = "moonraker"; 43 description = "User account under which Moonraker runs."; 44 }; 45 46 group = mkOption { 47 type = types.str; 48 default = "moonraker"; 49 description = "Group account under which Moonraker runs."; 50 }; 51 52 address = mkOption { 53 type = types.str; 54 default = "127.0.0.1"; 55 example = "0.0.0.0"; 56 description = "The IP or host to listen on."; 57 }; 58 59 port = mkOption { 60 type = types.ints.unsigned; 61 default = 7125; 62 description = "The port to listen on."; 63 }; 64 65 settings = mkOption { 66 type = format.type; 67 default = { }; 68 example = { 69 authorization = { 70 trusted_clients = [ "10.0.0.0/24" ]; 71 cors_domains = [ "https://app.fluidd.xyz" ]; 72 }; 73 }; 74 description = '' 75 Configuration for Moonraker. See the <link xlink:href="https://moonraker.readthedocs.io/en/latest/configuration/">documentation</link> 76 for supported values. 77 ''; 78 }; 79 }; 80 }; 81 82 config = mkIf cfg.enable { 83 warnings = optional (cfg.settings ? update_manager) 84 ''Enabling update_manager is not supported on NixOS and will lead to non-removable warnings in some clients.''; 85 86 users.users = optionalAttrs (cfg.user == "moonraker") { 87 moonraker = { 88 group = cfg.group; 89 uid = config.ids.uids.moonraker; 90 }; 91 }; 92 93 users.groups = optionalAttrs (cfg.group == "moonraker") { 94 moonraker.gid = config.ids.gids.moonraker; 95 }; 96 97 environment.etc."moonraker.cfg".source = let 98 forcedConfig = { 99 server = { 100 host = cfg.address; 101 port = cfg.port; 102 klippy_uds_address = cfg.klipperSocket; 103 config_path = cfg.configDir; 104 database_path = "${cfg.stateDir}/database"; 105 }; 106 }; 107 fullConfig = recursiveUpdate cfg.settings forcedConfig; 108 in format.generate "moonraker.cfg" fullConfig; 109 110 systemd.tmpfiles.rules = [ 111 "d '${cfg.stateDir}' - ${cfg.user} ${cfg.group} - -" 112 "d '${cfg.configDir}' - ${cfg.user} ${cfg.group} - -" 113 ]; 114 115 systemd.services.moonraker = { 116 description = "Moonraker, an API web server for Klipper"; 117 wantedBy = [ "multi-user.target" ]; 118 after = [ "network.target" ] 119 ++ optional config.services.klipper.enable "klipper.service"; 120 121 # Moonraker really wants its own config to be writable... 122 script = '' 123 cp /etc/moonraker.cfg ${cfg.configDir}/moonraker-temp.cfg 124 chmod u+w ${cfg.configDir}/moonraker-temp.cfg 125 exec ${pkg}/bin/moonraker -c ${cfg.configDir}/moonraker-temp.cfg 126 ''; 127 128 serviceConfig = { 129 WorkingDirectory = cfg.stateDir; 130 Group = cfg.group; 131 User = cfg.user; 132 }; 133 }; 134 }; 135}