1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.influxdb;
7
8 influxdbConfig = pkgs.writeText "config.toml" ''
9 bind-address = "${cfg.bindAddress}"
10
11 [logging]
12 level = "info"
13 file = "stdout"
14
15 [admin]
16 port = ${toString cfg.adminPort}
17 assets = "${pkgs.influxdb}/share/influxdb/admin"
18
19 [api]
20 port = ${toString cfg.apiPort}
21 ${cfg.apiExtraConfig}
22
23 [input_plugins]
24 ${cfg.inputPluginsConfig}
25
26 [raft]
27 dir = "${cfg.dataDir}/raft"
28 ${cfg.raftConfig}
29
30 [storage]
31 dir = "${cfg.dataDir}/db"
32 ${cfg.storageConfig}
33
34 [cluster]
35 ${cfg.clusterConfig}
36
37 [sharding]
38 ${cfg.shardingConfig}
39
40 [wal]
41 dir = "${cfg.dataDir}/wal"
42 ${cfg.walConfig}
43
44 ${cfg.extraConfig}
45 '';
46in
47{
48
49 ###### interface
50
51 options = {
52
53 services.influxdb = {
54
55 enable = mkOption {
56 default = false;
57 description = "Whether to enable the influxdb server";
58 type = types.bool;
59 };
60
61 package = mkOption {
62 default = pkgs.influxdb;
63 description = "Which influxdb derivation to use";
64 type = types.package;
65 };
66
67 user = mkOption {
68 default = "influxdb";
69 description = "User account under which influxdb runs";
70 type = types.string;
71 };
72
73 group = mkOption {
74 default = "influxdb";
75 description = "Group under which influxdb runs";
76 type = types.string;
77 };
78
79 dataDir = mkOption {
80 default = "/var/db/influxdb";
81 description = "Data directory for influxd data files.";
82 type = types.path;
83 };
84
85 bindAddress = mkOption {
86 default = "127.0.0.1";
87 description = "Address where influxdb listens";
88 type = types.str;
89 };
90
91 adminPort = mkOption {
92 default = 8083;
93 description = "The port where influxdb admin listens";
94 type = types.int;
95 };
96
97 apiPort = mkOption {
98 default = 8086;
99 description = "The port where influxdb api listens";
100 type = types.int;
101 };
102
103 apiExtraConfig = mkOption {
104 default = ''
105 read-timeout = "5s"
106 '';
107 description = "Extra influxdb api configuration";
108 example = ''
109 ssl-port = 8084
110 ssl-cert = /path/to/cert.pem
111 read-timeout = "5s"
112 '';
113 type = types.lines;
114 };
115
116 inputPluginsConfig = mkOption {
117 default = "";
118 description = "Configuration of influxdb extra plugins";
119 example = ''
120 [input_plugins.graphite]
121 enabled = true
122 port = 2003
123 database = "graphite"
124 '';
125 };
126
127 raftConfig = mkOption {
128 default = ''
129 port = 8090
130 '';
131 description = "Influxdb raft configuration";
132 type = types.lines;
133 };
134
135 storageConfig = mkOption {
136 default = ''
137 write-buffer-size = 10000
138 '';
139 description = "Influxdb raft configuration";
140 type = types.lines;
141 };
142
143 clusterConfig = mkOption {
144 default = ''
145 protobuf_port = 8099
146 protobuf_timeout = "2s"
147 protobuf_heartbeat = "200ms"
148 protobuf_min_backoff = "1s"
149 protobuf_max_backoff = "10s"
150
151 write-buffer-size = 10000
152 max-response-buffer-size = 100
153
154 concurrent-shard-query-limit = 10
155 '';
156 description = "Influxdb cluster configuration";
157 type = types.lines;
158 };
159
160 leveldbConfig = mkOption {
161 default = ''
162 max-open-files = 40
163 lru-cache-size = "200m"
164 max-open-shards = 0
165 point-batch-size = 100
166 write-batch-size = 5000000
167 '';
168 description = "Influxdb leveldb configuration";
169 type = types.lines;
170 };
171
172 shardingConfig = mkOption {
173 default = ''
174 replication-factor = 1
175
176 [sharding.short-term]
177 duration = "7d"
178 split = 1
179
180 [sharding.long-term]
181 duration = "30d"
182 split = 1
183 '';
184 description = "Influxdb sharding configuration";
185 type = types.lines;
186 };
187
188 walConfig = mkOption {
189 default = ''
190 flush-after = 1000
191 bookmark-after = 1000
192 index-after = 1000
193 requests-per-logfile = 10000
194 '';
195 description = "Influxdb write-ahead log configuration";
196 type = types.lines;
197 };
198
199 extraConfig = mkOption {
200 default = "";
201 description = "Extra configuration options for influxdb";
202 type = types.string;
203 };
204 };
205
206 };
207
208
209 ###### implementation
210
211 config = mkIf config.services.influxdb.enable {
212
213 systemd.services.influxdb = {
214 description = "InfluxDB Server";
215 wantedBy = [ "multi-user.target" ];
216 after = [ "network-interfaces.target" ];
217 serviceConfig = {
218 ExecStart = ''${cfg.package}/bin/influxdb -config "${influxdbConfig}"'';
219 User = "${cfg.user}";
220 Group = "${cfg.group}";
221 PermissionsStartOnly = true;
222 };
223 preStart = ''
224 mkdir -m 0770 -p ${cfg.dataDir}
225 if [ "$(id -u)" = 0 ]; then chown -R ${cfg.user}:${cfg.group} ${cfg.dataDir}; fi
226 '';
227 postStart = mkBefore ''
228 until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.bindAddress}:${toString cfg.apiPort}/'; do
229 sleep 1;
230 done
231 '';
232 };
233
234 users.extraUsers = optional (cfg.user == "influxdb") {
235 name = "influxdb";
236 uid = config.ids.uids.influxdb;
237 description = "Influxdb daemon user";
238 };
239
240 users.extraGroups = optional (cfg.group == "influxdb") {
241 name = "influxdb";
242 gid = config.ids.gids.influxdb;
243 };
244 };
245
246}