Unverified Commit 65365bbb authored by Kevin Cox's avatar Kevin Cox Committed by GitHub
Browse files

Merge pull request #240417 from kevincox/minetest-conf

nixos.minetest-server: Add option for generating config file and ability to add extra command line flags
parents 56193604 6cb0b6a4
Loading
Loading
Loading
Loading
+63 −8
Original line number Diff line number Diff line
@@ -3,15 +3,52 @@
with lib;

let
  CONTAINS_NEWLINE_RE = ".*\n.*";
  # The following values are reserved as complete option values:
  # { - start of a group.
  # """ - start of a multi-line string.
  RESERVED_VALUE_RE = "[[:space:]]*(\"\"\"|\\{)[[:space:]]*";
  NEEDS_MULTILINE_RE = "${CONTAINS_NEWLINE_RE}|${RESERVED_VALUE_RE}";

  # There is no way to encode """ on its own line in a Minetest config.
  UNESCAPABLE_RE = ".*\n\"\"\"\n.*";

  toConfMultiline = name: value:
    assert lib.assertMsg
      ((builtins.match UNESCAPABLE_RE value) == null)
      ''""" can't be on its own line in a minetest config.'';
    "${name} = \"\"\"\n${value}\n\"\"\"\n";

  toConf = values:
    lib.concatStrings
      (lib.mapAttrsToList
        (name: value: {
          bool = "${name} = ${toString value}\n";
          int = "${name} = ${toString value}\n";
          null = "";
          set = "${name} = {\n${toConf value}}\n";
          string =
            if (builtins.match NEEDS_MULTILINE_RE value) != null
            then toConfMultiline name value
            else "${name} = ${value}\n";
        }.${builtins.typeOf value})
        values);

  cfg   = config.services.minetest-server;
  flag  = val: name: optionalString (val != null) "--${name} ${toString val} ";
  flag  = val: name: lib.optionals (val != null) ["--${name}" "${toString val}"];

  flags = [
    (flag cfg.gameId "gameid")
    (flag cfg.world "world")
    (flag cfg.configPath "config")
    (flag cfg.logPath "logfile")
    (flag cfg.port "port")
  ];
    "--server"
  ]
    ++ (
      if cfg.configPath != null
      then ["--config" cfg.configPath]
      else ["--config" (builtins.toFile "minetest.conf" (toConf cfg.config))])
    ++ (flag cfg.gameId "gameid")
    ++ (flag cfg.world "world")
    ++ (flag cfg.logPath "logfile")
    ++ (flag cfg.port "port")
    ++ cfg.extraArgs;
in
{
  options = {
@@ -55,6 +92,16 @@ in
        '';
      };

      config = mkOption {
        type = types.attrsOf types.anything;
        default = {};
        description = lib.mdDoc ''
          Settings to add to the minetest config file.

          This option is ignored if `configPath` is set.
        '';
      };

      logPath = mkOption {
        type        = types.nullOr types.path;
        default     = null;
@@ -75,6 +122,14 @@ in
          If set to null, the default 30000 will be used.
        '';
      };

      extraArgs = mkOption {
        type = types.listOf types.str;
        default = [];
        description = lib.mdDoc ''
          Additional command line flags to pass to the minetest executable.
        '';
      };
    };
  };

@@ -100,7 +155,7 @@ in
      script = ''
        cd /var/lib/minetest

        exec ${pkgs.minetest}/bin/minetest --server ${concatStrings flags}
        exec ${pkgs.minetest}/bin/minetest ${lib.escapeShellArgs flags}
      '';
    };
  };