lol

Merge pull request #14579 from elitak/factorio

factorio: 0.12.29 headless + server module

joachifm 8b3c4348 a6978ded

+188 -51
+2
nixos/modules/misc/ids.nix
··· 262 262 mfi = 238; 263 263 caddy = 239; 264 264 taskd = 240; 265 + factorio = 241; 265 266 266 267 # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! 267 268 ··· 495 496 #mfi = 238; # unused 496 497 caddy = 239; 497 498 taskd = 240; 499 + factorio = 241; 498 500 499 501 # When adding a gid, make sure it doesn't match an existing 500 502 # uid. Users and groups with the same name should have equal
+1
nixos/modules/module-list.nix
··· 158 158 ./services/desktops/gnome3/tracker.nix 159 159 ./services/desktops/profile-sync-daemon.nix 160 160 ./services/desktops/telepathy.nix 161 + ./services/games/factorio.nix 161 162 ./services/games/ghost-one.nix 162 163 ./services/games/minecraft-server.nix 163 164 ./services/games/minetest-server.nix
+102
nixos/modules/services/games/factorio.nix
··· 1 + { config, lib, pkgs, ... }: 2 + 3 + with lib; 4 + 5 + let 6 + cfg = config.services.factorio; 7 + name = "Factorio"; 8 + stateDir = "/var/lib/factorio"; 9 + configFile = pkgs.writeText "factorio.conf" '' 10 + use-system-read-write-data-directories=true 11 + [path] 12 + read-data=${pkgs.factorio-headless}/share/factorio/data 13 + write-data=${stateDir} 14 + ''; 15 + in 16 + { 17 + options = { 18 + services.factorio = { 19 + enable = mkEnableOption name; 20 + port = mkOption { 21 + type = types.int; 22 + default = 34197; 23 + description = '' 24 + The port to which the service should bind. 25 + 26 + This option will also open up the UDP port in the firewall configuration. 27 + ''; 28 + }; 29 + saveName = mkOption { 30 + type = types.string; 31 + default = "default"; 32 + description = '' 33 + The name of the savegame that will be used by the server. 34 + 35 + When not present in ${stateDir}/saves, it will be generated before starting the service. 36 + ''; 37 + }; 38 + # TODO Add more individual settings as nixos-options? 39 + # TODO XXX The server tries to copy a newly created config file over the old one 40 + # on shutdown, but fails, because it's in the nix store. When is this needed? 41 + # Can an admin set options in-game and expect to have them persisted? 42 + configFile = mkOption { 43 + type = types.path; 44 + default = configFile; 45 + defaultText = "configFile"; 46 + description = '' 47 + The server's configuration file. 48 + 49 + The default file generated by this module contains lines essential to 50 + the server's operation. Use its contents as a basis for any 51 + customizations. 52 + ''; 53 + }; 54 + }; 55 + }; 56 + 57 + config = mkIf cfg.enable { 58 + users = { 59 + users.factorio = { 60 + uid = config.ids.uids.factorio; 61 + description = "Factorio server user"; 62 + group = "factorio"; 63 + home = stateDir; 64 + createHome = true; 65 + }; 66 + 67 + groups.factorio = { 68 + gid = config.ids.gids.factorio; 69 + }; 70 + }; 71 + 72 + systemd.services.factorio = { 73 + description = "Factorio headless server"; 74 + wantedBy = [ "multi-user.target" ]; 75 + after = [ "network.target" ]; 76 + 77 + preStart = '' 78 + test -e ${stateDir}/saves/${cfg.saveName}.zip || ${pkgs.factorio-headless}/bin/factorio \ 79 + --config=${cfg.configFile} \ 80 + --create=${cfg.saveName} 81 + ''; 82 + 83 + serviceConfig = { 84 + User = "factorio"; 85 + Group = "factorio"; 86 + Restart = "always"; 87 + KillSignal = "SIGINT"; 88 + WorkingDirectory = stateDir; 89 + PrivateTmp = true; 90 + UMask = "0007"; 91 + ExecStart = toString [ 92 + "${pkgs.factorio-headless}/bin/factorio" 93 + "--config=${cfg.configFile}" 94 + "--port=${toString cfg.port}" 95 + "--start-server=${cfg.saveName}" 96 + ]; 97 + }; 98 + }; 99 + 100 + networking.firewall.allowedUDPPorts = [ cfg.port ]; 101 + }; 102 + }
+80 -50
pkgs/games/factorio/default.nix
··· 4 4 # Begin download parameters 5 5 , username ? "" 6 6 , password ? "" 7 + , releaseType 7 8 }: 8 9 10 + assert releaseType == "alpha" || releaseType == "headless"; 11 + 12 + with stdenv.lib; 9 13 let 10 - version = "0.12.28"; 14 + version = "0.12.29"; 15 + isHeadless = releaseType == "headless"; 16 + 17 + arch = if stdenv.system == "x86_64-linux" then { 18 + inUrl = "linux64"; 19 + inTar = "x64"; 20 + } else if stdenv.system == "i686-linux" then { 21 + inUrl = "linux32"; 22 + inTar = "i386"; 23 + } else abort "Unsupported platform"; 11 24 12 - fetch = callPackage ./fetch.nix { username = username; password = password; }; 13 - arch = if stdenv.system == "x86_64-linux" then "x64" 14 - else if stdenv.system == "i686-linux" then "x32" 15 - else abort "Unsupported platform"; 25 + authenticatedFetch = callPackage ./fetch.nix { inherit username password; }; 16 26 17 - variants = { 27 + fetch = rec { 28 + url = "https://www.factorio.com/get-download/${version}/${releaseType}/${arch.inUrl}"; 29 + name = "factorio_${releaseType}_${arch.inTar}-${version}.tar.gz"; # TODO take this from 302 redirection somehow? fetchurl doesn't help. 18 30 x64 = { 19 - url = "https://www.factorio.com/get-download/${version}/alpha/linux64"; 20 - sha256 = "01si5n9hb2h0c5q8k3hr3nphsakp9kki84qyp70dgddwqsn8wfjl"; 31 + headless = fetchurl { inherit name url; sha256 = "1hr5dhpfagknjjd47qw3fa3ap8ikjc9hvxavrg4mpslbr0iqww8v"; }; 32 + alpha = authenticatedFetch { inherit url; sha256 = "0vngfrjjib99k6czhg32rikfi36i3p3adx4mxc1z8bi5n70dbwqb"; }; 21 33 }; 22 - 23 - x32 = { 24 - url = "https://www.factorio.com/get-download/${version}/alpha/linux32"; 25 - sha256 = "13h013ixyhv4rpvh0jv5jry3mrwv65v57nqn16bjh3hr8ip70lkq"; 34 + i386 = { 35 + headless = abort "Factorio 32-bit headless binaries are not available for download."; 36 + alpha = authenticatedFetch { inherit url; sha256 = "10135rd9103x79i89p6fh5ssmw612012yyx3yyhb3nzl554zqzbm"; }; 26 37 }; 27 38 }; 39 + 40 + configBaseCfg = '' 41 + use-system-read-write-data-directories=false 42 + [path] 43 + read-data=$out/share/factorio/data/ 44 + ''; 45 + 46 + updateConfigSh = '' 47 + #! $SHELL 48 + if [[ -e ~/.factorio/config.cfg ]]; then 49 + # Config file exists, but may have wrong path. 50 + # Try to edit it. I'm sure this is perfectly safe and will never go wrong. 51 + sed -i 's|^read-data=.*|read-data=$out/share/factorio/data/|' ~/.factorio/config.cfg 52 + else 53 + # Config file does not exist. Phew. 54 + install -D $out/share/factorio/config-base.cfg ~/.factorio/config.cfg 55 + fi 56 + ''; 57 + 28 58 in 29 59 30 60 stdenv.mkDerivation rec { 31 - name = "factorio-${version}"; 61 + name = "factorio-${releaseType}-${version}"; 32 62 33 - src = fetch variants.${arch}; 63 + src = fetch.${arch.inTar}.${releaseType}; 34 64 35 - libPath = stdenv.lib.makeLibraryPath [ 36 - alsaLib 37 - libX11 38 - libXcursor 39 - libXinerama 40 - libXrandr 41 - libXi 42 - mesa_noglu 43 - ]; 65 + libPath = stdenv.lib.makeLibraryPath ( 66 + optionals (! isHeadless) [ 67 + alsaLib 68 + libX11 69 + libXcursor 70 + libXinerama 71 + libXrandr 72 + libXi 73 + mesa_noglu 74 + ] 75 + ); 44 76 45 77 buildInputs = [ makeWrapper ]; 46 78 79 + dontBuild = true; 80 + 81 + # TODO detangle headless/normal mode wrapping, libs, etc. test all urls 32/64/headless/gfx 47 82 installPhase = '' 48 83 mkdir -p $out/{bin,share/factorio} 49 - cp -a bin/${arch}/factorio $out/bin/factorio.${arch} 50 - cp -a doc-html data $out/share/factorio/ 51 - 52 - # Fortunately, Factorio already supports system-wide installs. 53 - # Unfortunately it's a bit inconvenient to set the paths. 54 - cat > $out/share/factorio/config-base.cfg <<EOF 55 - use-system-read-write-data-directories=false 56 - [path] 57 - read-data=$out/share/factorio/data/ 58 - EOF 59 - 60 - cat > $out/share/factorio/update-config.sh <<EOF 61 - if [[ -e ~/.factorio/config.cfg ]]; then 62 - # Config file exists, but may have wrong path. 63 - # Try to edit it. I'm sure this is perfectly safe and will never go wrong. 64 - sed -i 's|^read-data=.*|read-data=$out/share/factorio/data/|' ~/.factorio/config.cfg 65 - else 66 - # Config file does not exist. Phew. 67 - install -D $out/share/factorio/config-base.cfg ~/.factorio/config.cfg 68 - fi 69 - EOF 70 - chmod a+x $out/share/factorio/update-config.sh 71 - 84 + cp -a data $out/share/factorio 85 + cp -a bin/${arch.inTar}/factorio $out/bin/factorio 72 86 patchelf \ 73 87 --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \ 74 - $out/bin/factorio.${arch} 88 + $out/bin/factorio 75 89 76 - makeWrapper $out/bin/factorio.${arch} $out/bin/factorio \ 90 + '' + optionalString (! isHeadless) ('' 91 + mv $out/bin/factorio $out/bin/factorio.${arch.inTar} 92 + makeWrapper $out/bin/factorio.${arch.inTar} $out/bin/factorio \ 77 93 --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib:$libPath \ 78 94 --run "$out/share/factorio/update-config.sh" \ 79 95 --add-flags "-c \$HOME/.factorio/config.cfg" 80 - ''; 96 + # Fortunately, Factorio already supports system-wide installs. 97 + # Unfortunately it's a bit inconvenient to set the paths. 98 + install -m0644 <(cat << EOF 99 + '' + configBaseCfg + '' 100 + EOF 101 + ) $out/share/factorio/config-base.cfg 102 + 103 + install -m0755 <(cat << EOF 104 + '' + updateConfigSh + '' 105 + EOF 106 + ) $out/share/factorio/update-config.sh 107 + cp -a doc-html $out/share/factorio 108 + ''); 109 + 110 + preferLocalBuild = true; 81 111 82 112 meta = { 83 113 description = "A game in which you build and maintain factories"; ··· 95 125 ''; 96 126 homepage = https://www.factorio.com/; 97 127 license = stdenv.lib.licenses.unfree; 98 - maintainers = [ stdenv.lib.maintainers.Baughn ]; 128 + maintainers = with stdenv.maintainers; [ Baughn elitak ]; 99 129 platforms = [ "i686-linux" "x86_64-linux" ]; 100 130 }; 101 131 }
+3 -1
pkgs/top-level/all-packages.nix
··· 14731 14731 14732 14732 exult = callPackage ../games/exult { }; 14733 14733 14734 - factorio = callPackage ../games/factorio {}; 14734 + factorio = callPackage ../games/factorio { releaseType = "alpha"; }; 14735 + 14736 + factorio-headless = callPackage ../games/factorio { releaseType = "headless"; }; 14735 14737 14736 14738 fairymax = callPackage ../games/fairymax {}; 14737 14739