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