at 25.11-pre 4.5 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.traccar; 9 stateDirectory = "/var/lib/traccar"; 10 configFilePath = "${stateDirectory}/config.xml"; 11 expandCamelCase = lib.replaceStrings lib.upperChars (map (s: ".${s}") lib.lowerChars); 12 mkConfigEntry = key: value: "<entry key='${expandCamelCase key}'>${value}</entry>"; 13 mkConfig = 14 configurationOptions: 15 pkgs.writeText "traccar.xml" '' 16 <?xml version='1.0' encoding='UTF-8'?> 17 <!DOCTYPE properties SYSTEM 'http://java.sun.com/dtd/properties.dtd'> 18 <properties> 19 ${builtins.concatStringsSep "\n" (lib.mapAttrsToList mkConfigEntry configurationOptions)} 20 </properties> 21 ''; 22 23 defaultConfig = { 24 databaseDriver = "org.h2.Driver"; 25 databasePassword = ""; 26 databaseUrl = "jdbc:h2:${stateDirectory}/traccar"; 27 databaseUser = "sa"; 28 loggerConsole = "true"; 29 mediaPath = "${stateDirectory}/media"; 30 templatesRoot = "${stateDirectory}/templates"; 31 }; 32in 33{ 34 options.services.traccar = { 35 enable = lib.mkEnableOption "Traccar, an open source GPS tracking system"; 36 settings = lib.mkOption { 37 apply = lib.recursiveUpdate defaultConfig; 38 default = defaultConfig; 39 description = '' 40 {file}`config.xml` configuration as a Nix attribute set. 41 Attribute names are translated from camelCase to dot-separated strings. For instance: 42 {option}`mailSmtpPort = "25"` 43 would result in the following configuration property: 44 `<entry key='mail.smtp.port'>25</entry>` 45 Configuration options should match those described in 46 [Traccar - Configuration File](https://www.traccar.org/configuration-file/). 47 Secret tokens should be specified using {option}`environmentFile` 48 instead of this world-readable attribute set. 49 ''; 50 }; 51 environmentFile = lib.mkOption { 52 type = lib.types.nullOr lib.types.path; 53 default = null; 54 description = '' 55 File containing environment variables to substitute in the configuration before starting Traccar. 56 57 Can be used for storing the secrets without making them available in the world-readable Nix store. 58 59 For example, you can set {option}`services.traccar.settings.databasePassword = "$TRACCAR_DB_PASSWORD"` 60 and then specify `TRACCAR_DB_PASSWORD="<secret>"` in the environment file. 61 This value will get substituted in the configuration file. 62 ''; 63 }; 64 }; 65 66 config = 67 let 68 configuration = mkConfig cfg.settings; 69 in 70 lib.mkIf cfg.enable { 71 systemd.services.traccar = { 72 enable = true; 73 description = "Traccar"; 74 75 after = [ "network-online.target" ]; 76 wantedBy = [ "multi-user.target" ]; 77 wants = [ "network-online.target" ]; 78 79 preStart = '' 80 # Copy new templates into our state directory. 81 cp -a --update=none ${pkgs.traccar}/templates ${stateDirectory} 82 test -f '${configFilePath}' && rm -f '${configFilePath}' 83 84 # Substitute the configFile from Envvars read from EnvironmentFile 85 old_umask=$(umask) 86 umask 0177 87 ${lib.getExe pkgs.envsubst} \ 88 -i ${configuration} \ 89 -o ${configFilePath} 90 umask $old_umask 91 ''; 92 93 serviceConfig = { 94 DynamicUser = true; 95 EnvironmentFile = cfg.environmentFile; 96 ExecStart = "${lib.getExe pkgs.traccar} ${configFilePath}"; 97 LockPersonality = true; 98 NoNewPrivileges = true; 99 PrivateDevices = true; 100 PrivateTmp = true; 101 PrivateUsers = true; 102 ProtectClock = true; 103 ProtectControlGroups = true; 104 ProtectHome = true; 105 ProtectHostname = true; 106 ProtectKernelLogs = true; 107 ProtectKernelModules = true; 108 ProtectKernelTunables = true; 109 ProtectSystem = "strict"; 110 Restart = "on-failure"; 111 RestartSec = 10; 112 RestrictRealtime = true; 113 RestrictSUIDSGID = true; 114 StateDirectory = "traccar"; 115 SuccessExitStatus = 143; 116 Type = "simple"; 117 # Set the working directory to traccar's package. 118 # Traccar only searches for the DB migrations relative to it's WorkingDirectory and nothing worked to 119 # work around this. To avoid copying the migrations over to the state directory, we use the package as 120 # WorkingDirectory. 121 WorkingDirectory = "${pkgs.traccar}"; 122 }; 123 }; 124 }; 125}