Merge pull request #45412 from costrouc/costrouc/minecraft-server
minecraft-server: 1.12.2 -> 1.13.2 + service refactor
This commit is contained in:
		
						commit
						2d6f84c109
					
				@ -4,8 +4,41 @@ with lib;
 | 
			
		||||
 | 
			
		||||
let
 | 
			
		||||
  cfg = config.services.minecraft-server;
 | 
			
		||||
in
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  # We don't allow eula=false anyways
 | 
			
		||||
  eulaFile = builtins.toFile "eula.txt" ''
 | 
			
		||||
    # eula.txt managed by NixOS Configuration
 | 
			
		||||
    eula=true
 | 
			
		||||
  '';
 | 
			
		||||
 | 
			
		||||
  whitelistFile = pkgs.writeText "whitelist.json"
 | 
			
		||||
    (builtins.toJSON
 | 
			
		||||
      (mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist));
 | 
			
		||||
 | 
			
		||||
  cfgToString = v: if builtins.isBool v then boolToString v else toString v;
 | 
			
		||||
 | 
			
		||||
  serverPropertiesFile = pkgs.writeText "server.properties" (''
 | 
			
		||||
    # server.properties managed by NixOS configuration
 | 
			
		||||
  '' + concatStringsSep "\n" (mapAttrsToList
 | 
			
		||||
    (n: v: "${n}=${cfgToString v}") cfg.serverProperties));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  # To be able to open the firewall, we need to read out port values in the
 | 
			
		||||
  # server properties, but fall back to the defaults when those don't exist.
 | 
			
		||||
  # These defaults are from https://minecraft.gamepedia.com/Server.properties#Java_Edition_3
 | 
			
		||||
  defaultServerPort = 25565;
 | 
			
		||||
 | 
			
		||||
  serverPort = cfg.serverProperties.server-port or defaultServerPort;
 | 
			
		||||
 | 
			
		||||
  rconPort = if cfg.serverProperties.enable-rcon or false
 | 
			
		||||
    then cfg.serverProperties."rcon.port" or 25575
 | 
			
		||||
    else null;
 | 
			
		||||
 | 
			
		||||
  queryPort = if cfg.serverProperties.enable-query or false
 | 
			
		||||
    then cfg.serverProperties."query.port" or 25565
 | 
			
		||||
    else null;
 | 
			
		||||
 | 
			
		||||
in {
 | 
			
		||||
  options = {
 | 
			
		||||
    services.minecraft-server = {
 | 
			
		||||
 | 
			
		||||
@ -13,10 +46,32 @@ in
 | 
			
		||||
        type = types.bool;
 | 
			
		||||
        default = false;
 | 
			
		||||
        description = ''
 | 
			
		||||
          If enabled, start a Minecraft Server. The listening port for
 | 
			
		||||
          the server is always <literal>25565</literal>. The server
 | 
			
		||||
          If enabled, start a Minecraft Server. The server
 | 
			
		||||
          data will be loaded from and saved to
 | 
			
		||||
          <literal>${cfg.dataDir}</literal>.
 | 
			
		||||
          <option>services.minecraft-server.dataDir</option>.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      declarative = mkOption {
 | 
			
		||||
        type = types.bool;
 | 
			
		||||
        default = false;
 | 
			
		||||
        description = ''
 | 
			
		||||
          Whether to use a declarative Minecraft server configuration.
 | 
			
		||||
          Only if set to <literal>true</literal>, the options
 | 
			
		||||
          <option>services.minecraft-server.whitelist</option> and
 | 
			
		||||
          <option>services.minecraft-server.serverProperties</option> will be
 | 
			
		||||
          applied.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      eula = mkOption {
 | 
			
		||||
        type = types.bool;
 | 
			
		||||
        default = false;
 | 
			
		||||
        description = ''
 | 
			
		||||
          Whether you agree to
 | 
			
		||||
          <link xlink:href="https://account.mojang.com/documents/minecraft_eula">
 | 
			
		||||
          Mojangs EULA</link>. This option must be set to
 | 
			
		||||
          <literal>true</literal> to run Minecraft server.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -24,7 +79,7 @@ in
 | 
			
		||||
        type = types.path;
 | 
			
		||||
        default = "/var/lib/minecraft";
 | 
			
		||||
        description = ''
 | 
			
		||||
          Directory to store minecraft database and other state/data files.
 | 
			
		||||
          Directory to store Minecraft database and other state/data files.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
@ -32,21 +87,84 @@ in
 | 
			
		||||
        type = types.bool;
 | 
			
		||||
        default = false;
 | 
			
		||||
        description = ''
 | 
			
		||||
          Whether to open ports in the firewall (if enabled) for the server.
 | 
			
		||||
          Whether to open ports in the firewall for the server.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      whitelist = mkOption {
 | 
			
		||||
        type = let
 | 
			
		||||
          minecraftUUID = types.strMatching
 | 
			
		||||
            "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" // {
 | 
			
		||||
              description = "Minecraft UUID";
 | 
			
		||||
            };
 | 
			
		||||
          in types.attrsOf minecraftUUID;
 | 
			
		||||
        default = {};
 | 
			
		||||
        description = ''
 | 
			
		||||
          Whitelisted players, only has an effect when
 | 
			
		||||
          <option>services.minecraft-server.declarative</option> is
 | 
			
		||||
          <literal>true</literal> and the whitelist is enabled
 | 
			
		||||
          via <option>services.minecraft-server.serverProperties</option> by
 | 
			
		||||
          setting <literal>white-list</literal> to <literal>true</literal>.
 | 
			
		||||
          This is a mapping from Minecraft usernames to UUIDs.
 | 
			
		||||
          You can use <link xlink:href="https://mcuuid.net/"/> to get a
 | 
			
		||||
          Minecraft UUID for a username.
 | 
			
		||||
        '';
 | 
			
		||||
        example = literalExample ''
 | 
			
		||||
          {
 | 
			
		||||
            username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
 | 
			
		||||
            username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
 | 
			
		||||
          };
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      serverProperties = mkOption {
 | 
			
		||||
        type = with types; attrsOf (either bool (either int str));
 | 
			
		||||
        default = {};
 | 
			
		||||
        example = literalExample ''
 | 
			
		||||
          {
 | 
			
		||||
            server-port = 43000;
 | 
			
		||||
            difficulty = 3;
 | 
			
		||||
            gamemode = 1;
 | 
			
		||||
            max-players = 5;
 | 
			
		||||
            motd = "NixOS Minecraft server!";
 | 
			
		||||
            white-list = true;
 | 
			
		||||
            enable-rcon = true;
 | 
			
		||||
            "rcon.password" = "hunter2";
 | 
			
		||||
          }
 | 
			
		||||
        '';
 | 
			
		||||
        description = ''
 | 
			
		||||
          Minecraft server properties for the server.properties file. Only has
 | 
			
		||||
          an effect when <option>services.minecraft-server.declarative</option>
 | 
			
		||||
          is set to <literal>true</literal>. See
 | 
			
		||||
          <link xlink:href="https://minecraft.gamepedia.com/Server.properties#Java_Edition_3"/>
 | 
			
		||||
          for documentation on these values.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      package = mkOption {
 | 
			
		||||
        type = types.package;
 | 
			
		||||
        default = pkgs.minecraft-server;
 | 
			
		||||
        defaultText = "pkgs.minecraft-server";
 | 
			
		||||
        example = literalExample "pkgs.minecraft-server_1_12_2";
 | 
			
		||||
        description = "Version of minecraft-server to run.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      jvmOpts = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = types.separatedString " ";
 | 
			
		||||
        default = "-Xmx2048M -Xms2048M";
 | 
			
		||||
        description = "JVM options for the Minecraft Service.";
 | 
			
		||||
        # Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script
 | 
			
		||||
        example = "-Xmx2048M -Xms4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
 | 
			
		||||
          + "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 "
 | 
			
		||||
          + "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
 | 
			
		||||
        description = "JVM options for the Minecraft server.";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  config = mkIf cfg.enable {
 | 
			
		||||
 | 
			
		||||
    users.users.minecraft = {
 | 
			
		||||
      description     = "Minecraft Server Service user";
 | 
			
		||||
      description     = "Minecraft server service user";
 | 
			
		||||
      home            = cfg.dataDir;
 | 
			
		||||
      createHome      = true;
 | 
			
		||||
      uid             = config.ids.uids.minecraft;
 | 
			
		||||
@ -57,17 +175,60 @@ in
 | 
			
		||||
      wantedBy      = [ "multi-user.target" ];
 | 
			
		||||
      after         = [ "network.target" ];
 | 
			
		||||
 | 
			
		||||
      serviceConfig.Restart = "always";
 | 
			
		||||
      serviceConfig.User    = "minecraft";
 | 
			
		||||
      script = ''
 | 
			
		||||
        cd ${cfg.dataDir}
 | 
			
		||||
        exec ${pkgs.minecraft-server}/bin/minecraft-server ${cfg.jvmOpts}
 | 
			
		||||
      '';
 | 
			
		||||
      serviceConfig = {
 | 
			
		||||
        ExecStart = "${cfg.package}/bin/minecraft-server ${cfg.jvmOpts}";
 | 
			
		||||
        Restart = "always";
 | 
			
		||||
        User = "minecraft";
 | 
			
		||||
        WorkingDirectory = cfg.dataDir;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      preStart = ''
 | 
			
		||||
        ln -sf ${eulaFile} eula.txt
 | 
			
		||||
      '' + (if cfg.declarative then ''
 | 
			
		||||
 | 
			
		||||
        if [ -e .declarative ]; then
 | 
			
		||||
 | 
			
		||||
          # Was declarative before, no need to back up anything
 | 
			
		||||
          ln -sf ${whitelistFile} whitelist.json
 | 
			
		||||
          cp -f ${serverPropertiesFile} server.properties
 | 
			
		||||
 | 
			
		||||
        else
 | 
			
		||||
 | 
			
		||||
          # Declarative for the first time, backup stateful files
 | 
			
		||||
          ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
 | 
			
		||||
          cp -b --suffix=.stateful ${serverPropertiesFile} 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
 | 
			
		||||
      '');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    networking.firewall = mkIf cfg.openFirewall {
 | 
			
		||||
      allowedUDPPorts = [ 25565 ];
 | 
			
		||||
      allowedTCPPorts = [ 25565 ];
 | 
			
		||||
    };
 | 
			
		||||
    networking.firewall = mkIf cfg.openFirewall (if cfg.declarative then {
 | 
			
		||||
      allowedUDPPorts = [ serverPort ];
 | 
			
		||||
      allowedTCPPorts = [ serverPort ]
 | 
			
		||||
        ++ optional (! isNull queryPort) queryPort
 | 
			
		||||
        ++ optional (! isNull rconPort) rconPort;
 | 
			
		||||
    } else {
 | 
			
		||||
      allowedUDPPorts = [ defaultServerPort ];
 | 
			
		||||
      allowedTCPPorts = [ defaultServerPort ];
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    assertions = [
 | 
			
		||||
      { assertion = cfg.eula;
 | 
			
		||||
        message = "You must agree to Mojangs EULA to run minecraft-server."
 | 
			
		||||
          + " Read https://account.mojang.com/documents/minecraft_eula and"
 | 
			
		||||
          + " set `services.minecraft-server.eula` to `true` if you agree.";
 | 
			
		||||
      }
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,37 +1,63 @@
 | 
			
		||||
{ stdenv, fetchurl, jre }:
 | 
			
		||||
 | 
			
		||||
stdenv.mkDerivation rec {
 | 
			
		||||
  name    = "minecraft-server-${version}";
 | 
			
		||||
  version = "1.13.2";
 | 
			
		||||
let
 | 
			
		||||
  common = { version, sha256, url }:
 | 
			
		||||
    stdenv.mkDerivation (rec {
 | 
			
		||||
      name = "minecraft-server-${version}";
 | 
			
		||||
      inherit version;
 | 
			
		||||
 | 
			
		||||
  src  = fetchurl {
 | 
			
		||||
    # Old url
 | 
			
		||||
    # https://s3.amazonaws.com/Minecraft.Download/versions/${version}/minecraft_server.${version}.jar
 | 
			
		||||
      src = fetchurl {
 | 
			
		||||
        inherit url sha256;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      preferLocalBuild = true;
 | 
			
		||||
 | 
			
		||||
      installPhase = ''
 | 
			
		||||
        mkdir -p $out/bin $out/lib/minecraft
 | 
			
		||||
        cp -v $src $out/lib/minecraft/server.jar
 | 
			
		||||
 | 
			
		||||
        cat > $out/bin/minecraft-server << EOF
 | 
			
		||||
        #!/bin/sh
 | 
			
		||||
        exec ${jre}/bin/java \$@ -jar $out/lib/minecraft/server.jar nogui
 | 
			
		||||
        EOF
 | 
			
		||||
 | 
			
		||||
        chmod +x $out/bin/minecraft-server
 | 
			
		||||
      '';
 | 
			
		||||
 | 
			
		||||
      phases = "installPhase";
 | 
			
		||||
 | 
			
		||||
      meta = {
 | 
			
		||||
        description = "Minecraft Server";
 | 
			
		||||
        homepage    = "https://minecraft.net";
 | 
			
		||||
        license     = stdenv.lib.licenses.unfreeRedistributable;
 | 
			
		||||
        platforms   = stdenv.lib.platforms.unix;
 | 
			
		||||
        maintainers = with stdenv.lib.maintainers; [ thoughtpolice tomberek costrouc];
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
in {
 | 
			
		||||
  minecraft-server_1_13_2 = common {
 | 
			
		||||
    version = "1.13.2";
 | 
			
		||||
    url    = "https://launcher.mojang.com/v1/objects/3737db93722a9e39eeada7c27e7aca28b144ffa7/server.jar";
 | 
			
		||||
    sha256 = "13h8dxrrgqa1g6sd7aaw26779hcsqsyjm7xm0sknifn54lnamlzz";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  preferLocalBuild = true;
 | 
			
		||||
 | 
			
		||||
  installPhase = ''
 | 
			
		||||
    mkdir -p $out/bin $out/lib/minecraft
 | 
			
		||||
    cp -v $src $out/lib/minecraft/server.jar
 | 
			
		||||
 | 
			
		||||
    cat > $out/bin/minecraft-server << EOF
 | 
			
		||||
    #!/bin/sh
 | 
			
		||||
    exec ${jre}/bin/java \$@ -jar $out/lib/minecraft/server.jar nogui
 | 
			
		||||
    EOF
 | 
			
		||||
 | 
			
		||||
    chmod +x $out/bin/minecraft-server
 | 
			
		||||
  '';
 | 
			
		||||
 | 
			
		||||
  phases = "installPhase";
 | 
			
		||||
 | 
			
		||||
  meta = {
 | 
			
		||||
    description = "Minecraft Server";
 | 
			
		||||
    homepage    = "https://minecraft.net";
 | 
			
		||||
    license     = stdenv.lib.licenses.unfreeRedistributable;
 | 
			
		||||
    platforms   = stdenv.lib.platforms.unix;
 | 
			
		||||
    maintainers = [ stdenv.lib.maintainers.thoughtpolice stdenv.lib.maintainers.tomberek ];
 | 
			
		||||
  minecraft-server_1_13_1 = common {
 | 
			
		||||
    version = "1.13.1";
 | 
			
		||||
    url = "https://launcher.mojang.com/mc/game/1.13.1/server/fe123682e9cb30031eae351764f653500b7396c9/server.jar";
 | 
			
		||||
    sha256 = "1lak29b7dm0w1cmzjn9gyix6qkszwg8xgb20hci2ki2ifrz099if";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  minecraft-server_1_13_0 = common {
 | 
			
		||||
    version = "1.13.0";
 | 
			
		||||
    url = "https://launcher.mojang.com/mc/game/1.13/server/d0caafb8438ebd206f99930cfaecfa6c9a13dca0/server.jar";
 | 
			
		||||
    sha256 = "1fahqnylxzbvc0fdsqk0x15z40mcc5b7shrckab1qcsdj0kkjvz7";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  minecraft-server_1_12_2 = common {
 | 
			
		||||
    version = "1.12.2";
 | 
			
		||||
    url = "https://s3.amazonaws.com/Minecraft.Download/versions/1.12.2/minecraft_server.1.12.2.jar";
 | 
			
		||||
    sha256 = "0zhnac6yvkdgdaag0gb0fgrkgizbwrpf7s76yqdiknfswrs947zy";
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20783,7 +20783,13 @@ in
 | 
			
		||||
 | 
			
		||||
  minecraft = callPackage ../games/minecraft { };
 | 
			
		||||
 | 
			
		||||
  minecraft-server = callPackage ../games/minecraft-server { };
 | 
			
		||||
  minecraft-server = minecraft-server_1_13_2;
 | 
			
		||||
 | 
			
		||||
  inherit (callPackages ../games/minecraft-server { })
 | 
			
		||||
    minecraft-server_1_13_2
 | 
			
		||||
    minecraft-server_1_13_1
 | 
			
		||||
    minecraft-server_1_13_0
 | 
			
		||||
    minecraft-server_1_12_2;
 | 
			
		||||
 | 
			
		||||
  moon-buggy = callPackage ../games/moon-buggy {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user