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 (lib.mdDoc "XtreemFS"); 93 94 homeDir = mkOption { 95 type = types.path; 96 default = "/var/lib/xtreemfs"; 97 description = lib.mdDoc '' 98 XtreemFS home dir for the xtreemfs user. 99 ''; 100 }; 101 102 dir = { 103 enable = mkOption { 104 type = types.bool; 105 default = true; 106 description = lib.mdDoc '' 107 Whether to enable XtreemFS DIR service. 108 ''; 109 }; 110 111 uuid = mkOption { 112 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e40"; 113 type = types.str; 114 description = lib.mdDoc '' 115 Must be set to a unique identifier, preferably a UUID according to 116 RFC 4122. UUIDs can be generated with `uuidgen` command, found in 117 the `util-linux` package. 118 ''; 119 }; 120 port = mkOption { 121 default = 32638; 122 type = types.port; 123 description = lib.mdDoc '' 124 The port to listen on for incoming connections (TCP). 125 ''; 126 }; 127 address = mkOption { 128 type = types.str; 129 example = "127.0.0.1"; 130 default = ""; 131 description = lib.mdDoc '' 132 If specified, it defines the interface to listen on. If not 133 specified, the service will listen on all interfaces (any). 134 ''; 135 }; 136 httpPort = mkOption { 137 default = 30638; 138 type = types.port; 139 description = lib.mdDoc '' 140 Specifies the listen port for the HTTP service that returns the 141 status page. 142 ''; 143 }; 144 syncMode = mkOption { 145 type = types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ]; 146 default = "FSYNC"; 147 example = "FDATASYNC"; 148 description = lib.mdDoc '' 149 The sync mode influences how operations are committed to the disk 150 log before the operation is acknowledged to the caller. 151 152 -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. 153 -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. 154 -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. 155 -FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk. 156 -FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk. 157 158 For best throughput use ASYNC, for maximum data safety use FSYNC. 159 160 (If xtreemfs.dir.replication.enable is true then FDATASYNC is forced) 161 ''; 162 }; 163 extraConfig = mkOption { 164 type = types.lines; 165 default = ""; 166 example = '' 167 # specify whether SSL is required 168 ssl.enabled = true 169 ssl.service_creds.pw = passphrase 170 ssl.service_creds.container = pkcs12 171 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/dir.p12 172 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks 173 ssl.trusted_certs.pw = jks_passphrase 174 ssl.trusted_certs.container = jks 175 ''; 176 description = lib.mdDoc '' 177 Configuration of XtreemFS DIR service. 178 WARNING: configuration is saved as plaintext inside nix store. 179 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html 180 ''; 181 }; 182 replication = { 183 enable = mkEnableOption (lib.mdDoc "XtreemFS DIR replication plugin"); 184 extraConfig = mkOption { 185 type = types.lines; 186 example = '' 187 # participants of the replication including this replica 188 babudb.repl.participant.0 = 192.168.0.10 189 babudb.repl.participant.0.port = 35676 190 babudb.repl.participant.1 = 192.168.0.11 191 babudb.repl.participant.1.port = 35676 192 babudb.repl.participant.2 = 192.168.0.12 193 babudb.repl.participant.2.port = 35676 194 195 # number of servers that at least have to be up to date 196 # To have a fault-tolerant system, this value has to be set to the 197 # majority of nodes i.e., if you have three replicas, set this to 2 198 # Please note that a setup with two nodes provides no fault-tolerance. 199 babudb.repl.sync.n = 2 200 201 # specify whether SSL is required 202 babudb.ssl.enabled = true 203 204 babudb.ssl.protocol = tlsv12 205 206 # server credentials for SSL handshakes 207 babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 208 babudb.ssl.service_creds.pw = passphrase 209 babudb.ssl.service_creds.container = pkcs12 210 211 # trusted certificates for SSL handshakes 212 babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks 213 babudb.ssl.trusted_certs.pw = jks_passphrase 214 babudb.ssl.trusted_certs.container = jks 215 216 babudb.ssl.authenticationWithoutEncryption = false 217 ''; 218 description = lib.mdDoc '' 219 Configuration of XtreemFS DIR replication plugin. 220 WARNING: configuration is saved as plaintext inside nix store. 221 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html 222 ''; 223 }; 224 }; 225 }; 226 227 mrc = { 228 enable = mkOption { 229 type = types.bool; 230 default = true; 231 description = lib.mdDoc '' 232 Whether to enable XtreemFS MRC service. 233 ''; 234 }; 235 236 uuid = mkOption { 237 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e41"; 238 type = types.str; 239 description = lib.mdDoc '' 240 Must be set to a unique identifier, preferably a UUID according to 241 RFC 4122. UUIDs can be generated with `uuidgen` command, found in 242 the `util-linux` package. 243 ''; 244 }; 245 port = mkOption { 246 default = 32636; 247 type = types.port; 248 description = lib.mdDoc '' 249 The port to listen on for incoming connections (TCP). 250 ''; 251 }; 252 address = mkOption { 253 example = "127.0.0.1"; 254 type = types.str; 255 default = ""; 256 description = lib.mdDoc '' 257 If specified, it defines the interface to listen on. If not 258 specified, the service will listen on all interfaces (any). 259 ''; 260 }; 261 httpPort = mkOption { 262 default = 30636; 263 type = types.port; 264 description = lib.mdDoc '' 265 Specifies the listen port for the HTTP service that returns the 266 status page. 267 ''; 268 }; 269 syncMode = mkOption { 270 default = "FSYNC"; 271 type = types.enum [ "ASYNC" "SYNC_WRITE_METADATA" "SYNC_WRITE" "FDATASYNC" "FSYNC" ]; 272 example = "FDATASYNC"; 273 description = lib.mdDoc '' 274 The sync mode influences how operations are committed to the disk 275 log before the operation is acknowledged to the caller. 276 277 -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. 278 -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. 279 -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. 280 -FDATASYNC is similar to SYNC_WRITE but opens the file in asynchronous mode and calls fdatasync() after writing the data to disk. 281 -FSYNC is similar to SYNC_WRITE_METADATA but opens the file in asynchronous mode and calls fsync() after writing the data to disk. 282 283 For best throughput use ASYNC, for maximum data safety use FSYNC. 284 285 (If xtreemfs.mrc.replication.enable is true then FDATASYNC is forced) 286 ''; 287 }; 288 extraConfig = mkOption { 289 type = types.lines; 290 example = '' 291 osd_check_interval = 300 292 no_atime = true 293 local_clock_renewal = 0 294 remote_time_sync = 30000 295 authentication_provider = org.xtreemfs.common.auth.NullAuthProvider 296 297 # shared secret between the MRC and all OSDs 298 capability_secret = iNG8UuQJrJ6XVDTe 299 300 dir_service.host = 192.168.0.10 301 dir_service.port = 32638 302 303 # if replication is enabled 304 dir_service.1.host = 192.168.0.11 305 dir_service.1.port = 32638 306 dir_service.2.host = 192.168.0.12 307 dir_service.2.port = 32638 308 309 # specify whether SSL is required 310 ssl.enabled = true 311 ssl.protocol = tlsv12 312 ssl.service_creds.pw = passphrase 313 ssl.service_creds.container = pkcs12 314 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/mrc.p12 315 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks 316 ssl.trusted_certs.pw = jks_passphrase 317 ssl.trusted_certs.container = jks 318 ''; 319 description = lib.mdDoc '' 320 Configuration of XtreemFS MRC service. 321 WARNING: configuration is saved as plaintext inside nix store. 322 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html 323 ''; 324 }; 325 replication = { 326 enable = mkEnableOption (lib.mdDoc "XtreemFS MRC replication plugin"); 327 extraConfig = mkOption { 328 type = types.lines; 329 example = '' 330 # participants of the replication including this replica 331 babudb.repl.participant.0 = 192.168.0.10 332 babudb.repl.participant.0.port = 35678 333 babudb.repl.participant.1 = 192.168.0.11 334 babudb.repl.participant.1.port = 35678 335 babudb.repl.participant.2 = 192.168.0.12 336 babudb.repl.participant.2.port = 35678 337 338 # number of servers that at least have to be up to date 339 # To have a fault-tolerant system, this value has to be set to the 340 # majority of nodes i.e., if you have three replicas, set this to 2 341 # Please note that a setup with two nodes provides no fault-tolerance. 342 babudb.repl.sync.n = 2 343 344 # specify whether SSL is required 345 babudb.ssl.enabled = true 346 347 babudb.ssl.protocol = tlsv12 348 349 # server credentials for SSL handshakes 350 babudb.ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 351 babudb.ssl.service_creds.pw = passphrase 352 babudb.ssl.service_creds.container = pkcs12 353 354 # trusted certificates for SSL handshakes 355 babudb.ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks 356 babudb.ssl.trusted_certs.pw = jks_passphrase 357 babudb.ssl.trusted_certs.container = jks 358 359 babudb.ssl.authenticationWithoutEncryption = false 360 ''; 361 description = lib.mdDoc '' 362 Configuration of XtreemFS MRC replication plugin. 363 WARNING: configuration is saved as plaintext inside nix store. 364 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html 365 ''; 366 }; 367 }; 368 }; 369 370 osd = { 371 enable = mkOption { 372 type = types.bool; 373 default = true; 374 description = lib.mdDoc '' 375 Whether to enable XtreemFS OSD service. 376 ''; 377 }; 378 379 uuid = mkOption { 380 example = "eacb6bab-f444-4ebf-a06a-3f72d7465e42"; 381 type = types.str; 382 description = lib.mdDoc '' 383 Must be set to a unique identifier, preferably a UUID according to 384 RFC 4122. UUIDs can be generated with `uuidgen` command, found in 385 the `util-linux` package. 386 ''; 387 }; 388 port = mkOption { 389 default = 32640; 390 type = types.port; 391 description = lib.mdDoc '' 392 The port to listen on for incoming connections (TCP and UDP). 393 ''; 394 }; 395 address = mkOption { 396 example = "127.0.0.1"; 397 type = types.str; 398 default = ""; 399 description = lib.mdDoc '' 400 If specified, it defines the interface to listen on. If not 401 specified, the service will listen on all interfaces (any). 402 ''; 403 }; 404 httpPort = mkOption { 405 default = 30640; 406 type = types.port; 407 description = lib.mdDoc '' 408 Specifies the listen port for the HTTP service that returns the 409 status page. 410 ''; 411 }; 412 extraConfig = mkOption { 413 type = types.lines; 414 example = '' 415 local_clock_renewal = 0 416 remote_time_sync = 30000 417 report_free_space = true 418 capability_secret = iNG8UuQJrJ6XVDTe 419 420 dir_service.host = 192.168.0.10 421 dir_service.port = 32638 422 423 # if replication is used 424 dir_service.1.host = 192.168.0.11 425 dir_service.1.port = 32638 426 dir_service.2.host = 192.168.0.12 427 dir_service.2.port = 32638 428 429 # specify whether SSL is required 430 ssl.enabled = true 431 ssl.service_creds.pw = passphrase 432 ssl.service_creds.container = pkcs12 433 ssl.service_creds = /etc/xos/xtreemfs/truststore/certs/osd.p12 434 ssl.trusted_certs = /etc/xos/xtreemfs/truststore/certs/trusted.jks 435 ssl.trusted_certs.pw = jks_passphrase 436 ssl.trusted_certs.container = jks 437 ''; 438 description = lib.mdDoc '' 439 Configuration of XtreemFS OSD service. 440 WARNING: configuration is saved as plaintext inside nix store. 441 For more options: http://www.xtreemfs.org/xtfs-guide-1.5.1/index.html 442 ''; 443 }; 444 }; 445 }; 446 447 }; 448 449 450 ###### implementation 451 452 config = lib.mkIf cfg.enable { 453 454 environment.systemPackages = [ xtreemfs ]; 455 456 users.users.xtreemfs = 457 { uid = config.ids.uids.xtreemfs; 458 description = "XtreemFS user"; 459 createHome = true; 460 home = home; 461 }; 462 463 users.groups.xtreemfs = 464 { gid = config.ids.gids.xtreemfs; 465 }; 466 467 systemd.services.xtreemfs-dir = mkIf cfg.dir.enable { 468 description = "XtreemFS-DIR Server"; 469 after = [ "network.target" ]; 470 wantedBy = [ "multi-user.target" ]; 471 serviceConfig = { 472 User = "xtreemfs"; 473 ExecStart = "${startupScript "org.xtreemfs.dir.DIR" dirConfig}"; 474 }; 475 }; 476 477 systemd.services.xtreemfs-mrc = mkIf cfg.mrc.enable ({ 478 description = "XtreemFS-MRC Server"; 479 serviceConfig = { 480 User = "xtreemfs"; 481 ExecStart = "${startupScript "org.xtreemfs.mrc.MRC" mrcConfig}"; 482 }; 483 } // systemdOptionalDependencies); 484 485 systemd.services.xtreemfs-osd = mkIf cfg.osd.enable ({ 486 description = "XtreemFS-OSD Server"; 487 serviceConfig = { 488 User = "xtreemfs"; 489 ExecStart = "${startupScript "org.xtreemfs.osd.OSD" osdConfig}"; 490 }; 491 } // systemdOptionalDependencies); 492 493 }; 494 495}