{ pkgs, lib, ... }: cfg: with lib; let eulaFile = builtins.toFile "eula.txt" '' # eula.txt managed by NixOS Configuration eula=true ''; whitelistFile = server: pkgs.writeText "whitelist.json" (builtins.toJSON (mapAttrsToList (n: v: { name = n; uuid = v; }) server.whitelist)); serverPropertiesFile = let cfgToString = v: if builtins.isBool v then boolToString v else toString v; in (server: pkgs.writeText "server.properties" ('' # server.properties managed by NixOS configuration '' + concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${cfgToString v}") server.serverProperties))); tmux = "${getBin pkgs.tmux}/bin/tmux"; stopScript = name: pkgs.writeScript "minecraft-stop" '' #!${pkgs.runtimeShell} if ! [ -d "/proc/$1" ]; then exit 0 fi ${tmux} -S ${cfg.dataDir}/${name}.sock send-keys Enter stop Enter ${getBin pkgs.coreutils}/bin/tail --pid-"$1" -f /dev/null ''; mkService = (name: inst: nameValuePair ("minecraft-server-${name}") ({ description = "Minecraft Server Service: ${name}"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { ExecStart = '' ${tmux} -S ${cfg.dataDir}/${name}.sock new \ -d ${inst.package}/bin/minecraft-server ${inst.jvmOpts} ''; ExecStop = "${stopScript name} $MAINPID"; Restart = "always"; Type = "forking"; GuessMainPIP = true; User = "minecraft"; WorkingDirectory = "${cfg.dataDir}/${name}"; }; preStart = '' ln -sf ${eulaFile} eula.txt '' + (if inst.declarative then '' if [ -e .declarative ]; then # Was declarative before, no need to back up anything ln -sf ${whitelistFile inst} whitelist.json cp -f ${serverPropertiesFile inst} server.properties else # Declarative for the first time, backup stateful files ln -sb --suffix=.stateful ${whitelistFile inst} whitelist.json cp -b --suffix=.stateful ${ serverPropertiesFile inst } server.properties # server.properties must have write permissions, because every time # the server starts it first parses the file and then regenerates it.. chmod +w server.properties echo "Autogenerated file that signifies that this server configuration is managed declaratively by NixOS" \ > .declarative fi '' else '' if [ -e .declarative ]; then rm .declarative fi ''); postStart = '' ${pkgs.coreutils}/bin/chmod 660 ${cfg.dataDir}/${name}.sock ${pkgs.coreutils}/bin/chgrp minecraft ${cfg.dataDir}/${name}.sock ''; }) ); in flip mapAttrs' cfg.servers mkService