1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.influxdb;
7
8 configOptions = recursiveUpdate {
9 meta = {
10 bind-address = ":8088";
11 commit-timeout = "50ms";
12 dir = "${cfg.dataDir}/meta";
13 election-timeout = "1s";
14 heartbeat-timeout = "1s";
15 hostname = "localhost";
16 leader-lease-timeout = "500ms";
17 retention-autocreate = true;
18 };
19
20 data = {
21 dir = "${cfg.dataDir}/data";
22 wal-dir = "${cfg.dataDir}/wal";
23 max-wal-size = 104857600;
24 wal-enable-logging = true;
25 wal-flush-interval = "10m";
26 wal-partition-flush-delay = "2s";
27 };
28
29 cluster = {
30 shard-writer-timeout = "5s";
31 write-timeout = "5s";
32 };
33
34 retention = {
35 enabled = true;
36 check-interval = "30m";
37 };
38
39 http = {
40 enabled = true;
41 auth-enabled = false;
42 bind-address = ":8086";
43 https-enabled = false;
44 log-enabled = true;
45 pprof-enabled = false;
46 write-tracing = false;
47 };
48
49 monitor = {
50 store-enabled = false;
51 store-database = "_internal";
52 store-interval = "10s";
53 };
54
55 admin = {
56 enabled = true;
57 bind-address = ":8083";
58 https-enabled = false;
59 };
60
61 graphite = [{
62 enabled = false;
63 }];
64
65 udp = [{
66 enabled = false;
67 }];
68
69 collectd = [{
70 enabled = false;
71 typesdb = "${pkgs.collectd-data}/share/collectd/types.db";
72 database = "collectd_db";
73 bind-address = ":25826";
74 }];
75
76 opentsdb = [{
77 enabled = false;
78 }];
79
80 continuous_queries = {
81 enabled = true;
82 log-enabled = true;
83 recompute-previous-n = 2;
84 recompute-no-older-than = "10m";
85 compute-runs-per-interval = 10;
86 compute-no-more-than = "2m";
87 };
88
89 hinted-handoff = {
90 enabled = true;
91 dir = "${cfg.dataDir}/hh";
92 max-size = 1073741824;
93 max-age = "168h";
94 retry-rate-limit = 0;
95 retry-interval = "1s";
96 };
97 } cfg.extraConfig;
98
99 configFile = pkgs.runCommandLocal "config.toml" { } ''
100 ${pkgs.buildPackages.remarshal}/bin/remarshal -if json -of toml \
101 < ${pkgs.writeText "config.json" (builtins.toJSON configOptions)} \
102 > $out
103 '';
104in
105{
106
107 ###### interface
108
109 options = {
110
111 services.influxdb = {
112
113 enable = mkOption {
114 default = false;
115 description = lib.mdDoc "Whether to enable the influxdb server";
116 type = types.bool;
117 };
118
119 package = mkOption {
120 default = pkgs.influxdb;
121 defaultText = literalExpression "pkgs.influxdb";
122 description = lib.mdDoc "Which influxdb derivation to use";
123 type = types.package;
124 };
125
126 user = mkOption {
127 default = "influxdb";
128 description = lib.mdDoc "User account under which influxdb runs";
129 type = types.str;
130 };
131
132 group = mkOption {
133 default = "influxdb";
134 description = lib.mdDoc "Group under which influxdb runs";
135 type = types.str;
136 };
137
138 dataDir = mkOption {
139 default = "/var/db/influxdb";
140 description = lib.mdDoc "Data directory for influxd data files.";
141 type = types.path;
142 };
143
144 extraConfig = mkOption {
145 default = {};
146 description = lib.mdDoc "Extra configuration options for influxdb";
147 type = types.attrs;
148 };
149 };
150 };
151
152
153 ###### implementation
154
155 config = mkIf config.services.influxdb.enable {
156
157 systemd.tmpfiles.rules = [
158 "d '${cfg.dataDir}' 0770 ${cfg.user} ${cfg.group} - -"
159 ];
160
161 systemd.services.influxdb = {
162 description = "InfluxDB Server";
163 wantedBy = [ "multi-user.target" ];
164 after = [ "network.target" ];
165 serviceConfig = {
166 ExecStart = ''${cfg.package}/bin/influxd -config "${configFile}"'';
167 User = cfg.user;
168 Group = cfg.group;
169 };
170 postStart =
171 let
172 scheme = if configOptions.http.https-enabled then "-k https" else "http";
173 bindAddr = (ba: if hasPrefix ":" ba then "127.0.0.1${ba}" else "${ba}")(toString configOptions.http.bind-address);
174 in
175 mkBefore ''
176 until ${pkgs.curl.bin}/bin/curl -s -o /dev/null ${scheme}://${bindAddr}/ping; do
177 sleep 1;
178 done
179 '';
180 };
181
182 users.users = optionalAttrs (cfg.user == "influxdb") {
183 influxdb = {
184 uid = config.ids.uids.influxdb;
185 group = "influxdb";
186 description = "Influxdb daemon user";
187 };
188 };
189
190 users.groups = optionalAttrs (cfg.group == "influxdb") {
191 influxdb.gid = config.ids.gids.influxdb;
192 };
193 };
194
195}