at 25.11-pre 3.7 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 inherit (lib) 10 escapeShellArgs 11 mkEnableOption 12 mkIf 13 mkOption 14 types 15 ; 16 17 cfg = config.services.loki; 18 19 prettyJSON = 20 conf: 21 pkgs.runCommand "loki-config.json" { } '' 22 echo '${builtins.toJSON conf}' | ${pkgs.jq}/bin/jq 'del(._module)' > $out 23 ''; 24 25in 26{ 27 options.services.loki = { 28 enable = mkEnableOption "loki"; 29 30 user = mkOption { 31 type = types.str; 32 default = "loki"; 33 description = '' 34 User under which the Loki service runs. 35 ''; 36 }; 37 38 package = lib.mkPackageOption pkgs "grafana-loki" { }; 39 40 group = mkOption { 41 type = types.str; 42 default = "loki"; 43 description = '' 44 Group under which the Loki service runs. 45 ''; 46 }; 47 48 dataDir = mkOption { 49 type = types.path; 50 default = "/var/lib/loki"; 51 description = '' 52 Specify the directory for Loki. 53 ''; 54 }; 55 56 configuration = mkOption { 57 type = (pkgs.formats.json { }).type; 58 default = { }; 59 description = '' 60 Specify the configuration for Loki in Nix. 61 ''; 62 }; 63 64 configFile = mkOption { 65 type = types.nullOr types.path; 66 default = null; 67 description = '' 68 Specify a configuration file that Loki should use. 69 ''; 70 }; 71 72 extraFlags = mkOption { 73 type = types.listOf types.str; 74 default = [ ]; 75 example = [ "--server.http-listen-port=3101" ]; 76 description = '' 77 Specify a list of additional command line flags, 78 which get escaped and are then passed to Loki. 79 ''; 80 }; 81 }; 82 83 config = mkIf cfg.enable { 84 assertions = [ 85 { 86 assertion = ( 87 (cfg.configuration == { } -> cfg.configFile != null) 88 && (cfg.configFile != null -> cfg.configuration == { }) 89 ); 90 message = '' 91 Please specify either 92 'services.loki.configuration' or 93 'services.loki.configFile'. 94 ''; 95 } 96 ]; 97 98 environment.systemPackages = [ cfg.package ]; # logcli 99 100 users.groups.${cfg.group} = { }; 101 users.users.${cfg.user} = { 102 description = "Loki Service User"; 103 group = cfg.group; 104 home = cfg.dataDir; 105 createHome = true; 106 isSystemUser = true; 107 }; 108 109 systemd.services.loki = { 110 description = "Loki Service Daemon"; 111 wants = [ "network-online.target" ]; 112 after = [ "network-online.target" ]; 113 wantedBy = [ "multi-user.target" ]; 114 115 serviceConfig = 116 let 117 conf = 118 if cfg.configFile == null then 119 # Config validation may fail when using extraFlags = [ "-config.expand-env=true" ]. 120 # To work around this, we simply skip it when extraFlags is not empty. 121 if cfg.extraFlags == [ ] then 122 validateConfig (prettyJSON cfg.configuration) 123 else 124 prettyJSON cfg.configuration 125 else 126 cfg.configFile; 127 validateConfig = 128 file: 129 pkgs.runCommand "validate-loki-conf" 130 { 131 nativeBuildInputs = [ cfg.package ]; 132 } 133 '' 134 loki -verify-config -config.file "${file}" 135 ln -s "${file}" "$out" 136 ''; 137 in 138 { 139 ExecStart = "${cfg.package}/bin/loki --config.file=${conf} ${escapeShellArgs cfg.extraFlags}"; 140 User = cfg.user; 141 Restart = "always"; 142 PrivateTmp = true; 143 ProtectHome = true; 144 ProtectSystem = "full"; 145 DevicePolicy = "closed"; 146 NoNewPrivileges = true; 147 WorkingDirectory = cfg.dataDir; 148 }; 149 }; 150 }; 151}