1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.xtreemfs;
8
9 xtreemfs = pkgs.xtreemfs;
10
11 home = cfg.homeDir;
12
13 startupScript = class: configPath: pkgs.writeScript "xtreemfs-osd.sh" ''
14 #! ${pkgs.runtimeShell}
15 JAVA_HOME="${pkgs.jdk}"
16 JAVADIR="${xtreemfs}/share/java"
17 JAVA_CALL="$JAVA_HOME/bin/java -ea -cp $JAVADIR/XtreemFS.jar:$JAVADIR/BabuDB.jar:$JAVADIR/Flease.jar:$JAVADIR/protobuf-java-2.5.0.jar:$JAVADIR/Foundation.jar:$JAVADIR/jdmkrt.jar:$JAVADIR/jdmktk.jar:$JAVADIR/commons-codec-1.3.jar"
18 $JAVA_CALL ${class} ${configPath}
19 '';
20
21 dirReplicationConfig = pkgs.writeText "xtreemfs-dir-replication-plugin.properties" ''
22 babudb.repl.backupDir = ${home}/server-repl-dir
23 plugin.jar = ${xtreemfs}/share/java/BabuDB_replication_plugin.jar
24 babudb.repl.dependency.0 = ${xtreemfs}/share/java/Flease.jar
25
26 ${cfg.dir.replication.extraConfig}
27 '';
28
29 dirConfig = pkgs.writeText "xtreemfs-dir-config.properties" ''
30 uuid = ${cfg.dir.uuid}
31 listen.port = ${toString cfg.dir.port}
32 ${optionalString (cfg.dir.address != "") "listen.address = ${cfg.dir.address}"}
33 http_port = ${toString cfg.dir.httpPort}
34 babudb.baseDir = ${home}/dir/database
35 babudb.logDir = ${home}/dir/db-log
36 babudb.sync = ${if cfg.dir.replication.enable then "FDATASYNC" else cfg.dir.syncMode}
37
38 ${optionalString cfg.dir.replication.enable "babudb.plugin.0 = ${dirReplicationConfig}"}
39
40 ${cfg.dir.extraConfig}
41 '';
42
43 mrcReplicationConfig = pkgs.writeText "xtreemfs-mrc-replication-plugin.properties" ''
44 babudb.repl.backupDir = ${home}/server-repl-mrc
45 plugin.jar = ${xtreemfs}/share/java/BabuDB_replication_plugin.jar
46 babudb.repl.dependency.0 = ${xtreemfs}/share/java/Flease.jar
47
48 ${cfg.mrc.replication.extraConfig}
49 '';
50
51 mrcConfig = pkgs.writeText "xtreemfs-mrc-config.properties" ''
52 uuid = ${cfg.mrc.uuid}
53 listen.port = ${toString cfg.mrc.port}
54 ${optionalString (cfg.mrc.address != "") "listen.address = ${cfg.mrc.address}"}
55 http_port = ${toString cfg.mrc.httpPort}
56 babudb.baseDir = ${home}/mrc/database
57 babudb.logDir = ${home}/mrc/db-log
58 babudb.sync = ${if cfg.mrc.replication.enable then "FDATASYNC" else cfg.mrc.syncMode}
59
60 ${optionalString cfg.mrc.replication.enable "babudb.plugin.0 = ${mrcReplicationConfig}"}
61
62 ${cfg.mrc.extraConfig}
63 '';
64
65 osdConfig = pkgs.writeText "xtreemfs-osd-config.properties" ''
66 uuid = ${cfg.osd.uuid}
67 listen.port = ${toString cfg.osd.port}
68 ${optionalString (cfg.osd.address != "") "listen.address = ${cfg.osd.address}"}
69 http_port = ${toString cfg.osd.httpPort}
70 object_dir = ${home}/osd/
71
72 ${cfg.osd.extraConfig}
73 '';
74
75 optionalDir = optionals cfg.dir.enable ["xtreemfs-dir.service"];
76
77 systemdOptionalDependencies = {
78 after = [ "network.target" ] ++ optionalDir;
79 wantedBy = [ "multi-user.target" ] ++ optionalDir;
80 };
81
82in
83
84{
85
86 ###### interface
87
88 options = {
89
90 services.xtreemfs = {
91
92 enable = mkEnableOption "XtreemFS";
93
94 homeDir = mkOption {
95 default = "/var/lib/xtreemfs";
96 description = ''
97 XtreemFS home dir for the xtreemfs user.
98 '';
99 };
100
101 dir = {
102 enable = mkOption {
103 default = true;
104 description = ''
105 Whether to enable XtreemFS DIR service.
106 '';
107 };
108 uuid = mkOption {
109 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e40";
110 description = ''
111 Must be set to a unique identifier, preferably a UUID according to
112 RFC 4122. UUIDs can be generated with `uuidgen` command, found in
113 the `utillinux` package.
114 '';
115 };
116 port = mkOption {
117 default = 32638;
118 description = ''
119 The port to listen on for incoming connections (TCP).
120 '';
121 };
122 address = mkOption {
123 example = "127.0.0.1";
124 default = "";
125 description = ''
126 If specified, it defines the interface to listen on. If not
127 specified, the service will listen on all interfaces (any).
128 '';
129 };
130 httpPort = mkOption {
131 default = 30638;
132 description = ''
133 Specifies the listen port for the HTTP service that returns the
134 status page.
135 '';
136 };
137 syncMode = mkOption {
138 default = "FSYNC";
139 example = "FDATASYNC";
140 description = ''
141 The sync mode influences how operations are committed to the disk
142 log before the operation is acknowledged to the caller.
143
144 -ASYNC mode the writes to the disk log are buffered in memory by the operating system. This is the fastest mode but will lead to data loss in case of a crash, kernel panic or power failure.
145 -SYNC_WRITE_METADATA opens the file with O_SYNC, the system will not buffer any writes. The operation will be acknowledged when data has been safely written to disk. This mode is slow but offers maximum data safety. However, BabuDB cannot influence the disk drive caches, this depends on the OS and hard disk model.
146 -SYNC_WRITE similar to SYNC_WRITE_METADATA but opens file with O_DSYNC which means that only the data is commit to disk. This can lead to some data loss depending on the implementation of the underlying file system. Linux does not implement this mode.
147 -FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk.
148 -FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk.
149
150 For best throughput use ASYNC, for maximum data safety use FSYNC.
151
152 (If xtreemfs.dir.replication.enable is true then FDATASYNC is forced)
153 '';
154 };
155 extraConfig = mkOption {
156 type = types.lines;
157 default = "";
158 example = ''
159 # specify whether SSL is required
160 ssl.enabled = true
161 ssl.service_creds.pw = passphrase
162 ssl.service_creds.container = pkcs12
163 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/dir.p12
164 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
165 ssl.trusted_certs.pw = jks_passphrase
166 ssl.trusted_certs.container = jks
167 '';
168 description = ''
169 Configuration of XtreemFS DIR service.
170 WARNING: configuration is saved as plaintext inside nix store.
171 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
172 '';
173 };
174 replication = {
175 enable = mkEnableOption "XtreemFS DIR replication plugin";
176 extraConfig = mkOption {
177 type = types.lines;
178 example = ''
179 # participants of the replication including this replica
180 babudb.repl.participant.0 = 192.168.0.10
181 babudb.repl.participant.0.port = 35676
182 babudb.repl.participant.1 = 192.168.0.11
183 babudb.repl.participant.1.port = 35676
184 babudb.repl.participant.2 = 192.168.0.12
185 babudb.repl.participant.2.port = 35676
186
187 # number of servers that at least have to be up to date
188 # To have a fault-tolerant system, this value has to be set to the
189 # majority of nodes i.e., if you have three replicas, set this to 2
190 # Please note that a setup with two nodes provides no fault-tolerance.
191 babudb.repl.sync.n = 2
192
193 # specify whether SSL is required
194 babudb.ssl.enabled = true
195
196 babudb.ssl.protocol = tlsv12
197
198 # server credentials for SSL handshakes
199 babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
200 babudb.ssl.service_creds.pw = passphrase
201 babudb.ssl.service_creds.container = pkcs12
202
203 # trusted certificates for SSL handshakes
204 babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
205 babudb.ssl.trusted_certs.pw = jks_passphrase
206 babudb.ssl.trusted_certs.container = jks
207
208 babudb.ssl.authenticationWithoutEncryption = false
209 '';
210 description = ''
211 Configuration of XtreemFS DIR replication plugin.
212 WARNING: configuration is saved as plaintext inside nix store.
213 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
214 '';
215 };
216 };
217 };
218
219 mrc = {
220 enable = mkOption {
221 default = true;
222 description = ''
223 Whether to enable XtreemFS MRC service.
224 '';
225 };
226 uuid = mkOption {
227 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e41";
228 description = ''
229 Must be set to a unique identifier, preferably a UUID according to
230 RFC 4122. UUIDs can be generated with `uuidgen` command, found in
231 the `utillinux` package.
232 '';
233 };
234 port = mkOption {
235 default = 32636;
236 description = ''
237 The port to listen on for incoming connections (TCP).
238 '';
239 };
240 address = mkOption {
241 example = "127.0.0.1";
242 default = "";
243 description = ''
244 If specified, it defines the interface to listen on. If not
245 specified, the service will listen on all interfaces (any).
246 '';
247 };
248 httpPort = mkOption {
249 default = 30636;
250 description = ''
251 Specifies the listen port for the HTTP service that returns the
252 status page.
253 '';
254 };
255 syncMode = mkOption {
256 default = "FSYNC";
257 example = "FDATASYNC";
258 description = ''
259 The sync mode influences how operations are committed to the disk
260 log before the operation is acknowledged to the caller.
261
262 -ASYNC mode the writes to the disk log are buffered in memory by the operating system. This is the fastest mode but will lead to data loss in case of a crash, kernel panic or power failure.
263 -SYNC_WRITE_METADATA opens the file with O_SYNC, the system will not buffer any writes. The operation will be acknowledged when data has been safely written to disk. This mode is slow but offers maximum data safety. However, BabuDB cannot influence the disk drive caches, this depends on the OS and hard disk model.
264 -SYNC_WRITE similar to SYNC_WRITE_METADATA but opens file with O_DSYNC which means that only the data is commit to disk. This can lead to some data loss depending on the implementation of the underlying file system. Linux does not implement this mode.
265 -FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk.
266 -FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk.
267
268 For best throughput use ASYNC, for maximum data safety use FSYNC.
269
270 (If xtreemfs.mrc.replication.enable is true then FDATASYNC is forced)
271 '';
272 };
273 extraConfig = mkOption {
274 type = types.lines;
275 example = ''
276 osd_check_interval = 300
277 no_atime = true
278 local_clock_renewal = 0
279 remote_time_sync = 30000
280 authentication_provider = org.xtreemfs.common.auth.NullAuthProvider
281
282 # shared secret between the MRC and all OSDs
283 capability_secret = iNG8UuQJrJ6XVDTe
284
285 dir_service.host = 192.168.0.10
286 dir_service.port = 32638
287
288 # if replication is enabled
289 dir_service.1.host = 192.168.0.11
290 dir_service.1.port = 32638
291 dir_service.2.host = 192.168.0.12
292 dir_service.2.port = 32638
293
294 # specify whether SSL is required
295 ssl.enabled = true
296 ssl.protocol = tlsv12
297 ssl.service_creds.pw = passphrase
298 ssl.service_creds.container = pkcs12
299 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/mrc.p12
300 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
301 ssl.trusted_certs.pw = jks_passphrase
302 ssl.trusted_certs.container = jks
303 '';
304 description = ''
305 Configuration of XtreemFS MRC service.
306 WARNING: configuration is saved as plaintext inside nix store.
307 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
308 '';
309 };
310 replication = {
311 enable = mkEnableOption "XtreemFS MRC replication plugin";
312 extraConfig = mkOption {
313 type = types.lines;
314 example = ''
315 # participants of the replication including this replica
316 babudb.repl.participant.0 = 192.168.0.10
317 babudb.repl.participant.0.port = 35678
318 babudb.repl.participant.1 = 192.168.0.11
319 babudb.repl.participant.1.port = 35678
320 babudb.repl.participant.2 = 192.168.0.12
321 babudb.repl.participant.2.port = 35678
322
323 # number of servers that at least have to be up to date
324 # To have a fault-tolerant system, this value has to be set to the
325 # majority of nodes i.e., if you have three replicas, set this to 2
326 # Please note that a setup with two nodes provides no fault-tolerance.
327 babudb.repl.sync.n = 2
328
329 # specify whether SSL is required
330 babudb.ssl.enabled = true
331
332 babudb.ssl.protocol = tlsv12
333
334 # server credentials for SSL handshakes
335 babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
336 babudb.ssl.service_creds.pw = passphrase
337 babudb.ssl.service_creds.container = pkcs12
338
339 # trusted certificates for SSL handshakes
340 babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
341 babudb.ssl.trusted_certs.pw = jks_passphrase
342 babudb.ssl.trusted_certs.container = jks
343
344 babudb.ssl.authenticationWithoutEncryption = false
345 '';
346 description = ''
347 Configuration of XtreemFS MRC replication plugin.
348 WARNING: configuration is saved as plaintext inside nix store.
349 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
350 '';
351 };
352 };
353 };
354
355 osd = {
356 enable = mkOption {
357 default = true;
358 description = ''
359 Whether to enable XtreemFS OSD service.
360 '';
361 };
362 uuid = mkOption {
363 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e42";
364 description = ''
365 Must be set to a unique identifier, preferably a UUID according to
366 RFC 4122. UUIDs can be generated with `uuidgen` command, found in
367 the `utillinux` package.
368 '';
369 };
370 port = mkOption {
371 default = 32640;
372 description = ''
373 The port to listen on for incoming connections (TCP and UDP).
374 '';
375 };
376 address = mkOption {
377 example = "127.0.0.1";
378 default = "";
379 description = ''
380 If specified, it defines the interface to listen on. If not
381 specified, the service will listen on all interfaces (any).
382 '';
383 };
384 httpPort = mkOption {
385 default = 30640;
386 description = ''
387 Specifies the listen port for the HTTP service that returns the
388 status page.
389 '';
390 };
391 extraConfig = mkOption {
392 type = types.lines;
393 example = ''
394 local_clock_renewal = 0
395 remote_time_sync = 30000
396 report_free_space = true
397 capability_secret = iNG8UuQJrJ6XVDTe
398
399 dir_service.host = 192.168.0.10
400 dir_service.port = 32638
401
402 # if replication is used
403 dir_service.1.host = 192.168.0.11
404 dir_service.1.port = 32638
405 dir_service.2.host = 192.168.0.12
406 dir_service.2.port = 32638
407
408 # specify whether SSL is required
409 ssl.enabled = true
410 ssl.service_creds.pw = passphrase
411 ssl.service_creds.container = pkcs12
412 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12
413 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks
414 ssl.trusted_certs.pw = jks_passphrase
415 ssl.trusted_certs.container = jks
416 '';
417 description = ''
418 Configuration of XtreemFS OSD service.
419 WARNING: configuration is saved as plaintext inside nix store.
420 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html
421 '';
422 };
423 };
424 };
425
426 };
427
428
429 ###### implementation
430
431 config = lib.mkIf cfg.enable {
432
433 environment.systemPackages = [ xtreemfs ];
434
435 users.users.xtreemfs =
436 { uid = config.ids.uids.xtreemfs;
437 description = "XtreemFS user";
438 createHome = true;
439 home = home;
440 };
441
442 users.groups.xtreemfs =
443 { gid = config.ids.gids.xtreemfs;
444 };
445
446 systemd.services.xtreemfs-dir = mkIf cfg.dir.enable {
447 description = "XtreemFS-DIR Server";
448 after = [ "network.target" ];
449 wantedBy = [ "multi-user.target" ];
450 serviceConfig = {
451 User = "xtreemfs";
452 ExecStart = "${startupScript "org.xtreemfs.dir.DIR" dirConfig}";
453 };
454 };
455
456 systemd.services.xtreemfs-mrc = mkIf cfg.mrc.enable ({
457 description = "XtreemFS-MRC Server";
458 serviceConfig = {
459 User = "xtreemfs";
460 ExecStart = "${startupScript "org.xtreemfs.mrc.MRC" mrcConfig}";
461 };
462 } // systemdOptionalDependencies);
463
464 systemd.services.xtreemfs-osd = mkIf cfg.osd.enable ({
465 description = "XtreemFS-OSD Server";
466 serviceConfig = {
467 User = "xtreemfs";
468 ExecStart = "${startupScript "org.xtreemfs.osd.OSD" osdConfig}";
469 };
470 } // systemdOptionalDependencies);
471
472 };
473
474}