nixos/mchprs: init module
Co-authored-by: Ryan Lahfa <masterancpp@gmail.com>
This commit is contained in:
parent
4f822ac9fd
commit
04c830db01
3 changed files with 343 additions and 1 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
## New Services {#sec-release-23.11-new-services}
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
- [MCHPRS](https://github.com/MCHPR/MCHPRS), a multithreaded Minecraft server built for redstone. Available as [services.mchprs](#opt-services.mchprs.enable).
|
||||
|
||||
- [acme-dns](https://github.com/joohoi/acme-dns), a limited DNS server to handle ACME DNS challenges easily and securely. Available as [services.acme-dns](#opt-services.acme-dns.enable).
|
||||
|
||||
|
|
|
@ -476,6 +476,7 @@
|
|||
./services/games/deliantra-server.nix
|
||||
./services/games/factorio.nix
|
||||
./services/games/freeciv.nix
|
||||
./services/games/mchprs.nix
|
||||
./services/games/minecraft-server.nix
|
||||
./services/games/minetest-server.nix
|
||||
./services/games/openarena.nix
|
||||
|
|
341
nixos/modules/services/games/mchprs.nix
Normal file
341
nixos/modules/services/games/mchprs.nix
Normal file
|
@ -0,0 +1,341 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.mchprs;
|
||||
settingsFormat = pkgs.formats.toml { };
|
||||
|
||||
whitelistFile = pkgs.writeText "whitelist.json"
|
||||
(builtins.toJSON
|
||||
(mapAttrsToList (n: v: { name = n; uuid = v; }) cfg.whitelist.list));
|
||||
|
||||
configToml =
|
||||
(removeAttrs cfg.settings [ "address" "port" ]) //
|
||||
{
|
||||
bind_address = cfg.settings.address + ":" + toString cfg.settings.port;
|
||||
whitelist = cfg.whitelist.enable;
|
||||
};
|
||||
|
||||
configTomlFile = settingsFormat.generate "Config.toml" configToml;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.mchprs = {
|
||||
enable = mkEnableOption "MCHPRS";
|
||||
|
||||
declarativeSettings = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Whether to use a declarative configuration for MCHPRS.
|
||||
'';
|
||||
};
|
||||
|
||||
declarativeWhitelist = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Whether to use a declarative whitelist.
|
||||
The options {option}`services.mchprs.whitelist.list`
|
||||
will be applied if and only if set to `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/mchprs";
|
||||
description = mdDoc ''
|
||||
Directory to store MCHPRS database and other state/data files.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Whether to open ports in the firewall for the server.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
maxRuntime = mkOption {
|
||||
type = types.str;
|
||||
default = "infinity";
|
||||
example = "7d";
|
||||
description = mdDoc ''
|
||||
Automatically restart the server after
|
||||
{option}`services.mchprs.maxRuntime`.
|
||||
The time span format is described here:
|
||||
https://www.freedesktop.org/software/systemd/man/systemd.time.html#Parsing%20Time%20Spans.
|
||||
If `null`, then the server is not restarted automatically.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.mchprs;
|
||||
defaultText = literalExpression "pkgs.mchprs";
|
||||
description = mdDoc "Version of MCHPRS to run.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 25565;
|
||||
description = mdDoc ''
|
||||
Port for the server.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
description = mdDoc ''
|
||||
Address for the server.
|
||||
Please use enclosing square brackets when using ipv6.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
motd = mkOption {
|
||||
type = types.str;
|
||||
default = "Minecraft High Performance Redstone Server";
|
||||
description = mdDoc ''
|
||||
Message of the day.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
chat_format = mkOption {
|
||||
type = types.str;
|
||||
default = "<{username}> {message}";
|
||||
description = mdDoc ''
|
||||
How to format chat message interpolating `username`
|
||||
and `message` with curly braces.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
max_players = mkOption {
|
||||
type = types.ints.positive;
|
||||
default = 99999;
|
||||
description = mdDoc ''
|
||||
Maximum number of simultaneous players.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
view_distance = mkOption {
|
||||
type = types.ints.positive;
|
||||
default = 8;
|
||||
description = mdDoc ''
|
||||
Maximal distance (in chunks) between players and loaded chunks.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
bungeecord = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Enable compatibility with
|
||||
[BungeeCord](https://github.com/SpigotMC/BungeeCord).
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
schemati = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Mimic the verification and directory layout used by the
|
||||
Open Redstone Engineers
|
||||
[Schemati plugin](https://github.com/OpenRedstoneEngineers/Schemati).
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
block_in_hitbox = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = mdDoc ''
|
||||
Allow placing blocks inside of players
|
||||
(hitbox logic is simplified).
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
auto_redpiler = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = mdDoc ''
|
||||
Use redpiler automatically.
|
||||
Only has effect when
|
||||
{option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
|
||||
description = mdDoc ''
|
||||
Configuration for MCHPRS via `Config.toml`.
|
||||
See https://github.com/MCHPR/MCHPRS/blob/master/README.md for documentation.
|
||||
'';
|
||||
};
|
||||
|
||||
whitelist = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = mdDoc ''
|
||||
Whether or not the whitelist (in `whitelist.json`) shoud be enabled.
|
||||
Only has effect when {option}`services.mchprs.declarativeSettings` is `true`.
|
||||
'';
|
||||
};
|
||||
|
||||
list = 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 = { };
|
||||
example = literalExpression ''
|
||||
{
|
||||
username1 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
|
||||
username2 = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy";
|
||||
};
|
||||
'';
|
||||
description = mdDoc ''
|
||||
Whitelisted players, only has an effect when
|
||||
{option}`services.mchprs.declarativeWhitelist` is
|
||||
`true` and the whitelist is enabled
|
||||
via {option}`services.mchprs.whitelist.enable`.
|
||||
This is a mapping from Minecraft usernames to UUIDs.
|
||||
You can use <https://mcuuid.net/> to get a
|
||||
Minecraft UUID for a username.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.mchprs = {
|
||||
description = "MCHPRS service user";
|
||||
home = cfg.dataDir;
|
||||
createHome = true;
|
||||
isSystemUser = true;
|
||||
group = "mchprs";
|
||||
};
|
||||
users.groups.mchprs = { };
|
||||
|
||||
systemd.services.mchprs = {
|
||||
description = "MCHPRS Service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${lib.getExe cfg.package}";
|
||||
Restart = "always";
|
||||
RuntimeMaxSec = cfg.maxRuntime;
|
||||
User = "mchprs";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
UMask = "0077";
|
||||
};
|
||||
|
||||
preStart =
|
||||
(if cfg.declarativeSettings then ''
|
||||
if [ -e .declarativeSettings ]; then
|
||||
|
||||
# Settings were declarative before, no need to back up anything
|
||||
cp -f ${configTomlFile} Config.toml
|
||||
|
||||
else
|
||||
|
||||
# Declarative settings for the first time, backup stateful files
|
||||
cp -b --suffix=.stateful ${configTomlFile} Config.toml
|
||||
|
||||
echo "Autogenerated file that implies that this server configuration is managed declaratively by NixOS" \
|
||||
> .declarativeSettings
|
||||
|
||||
fi
|
||||
'' else ''
|
||||
if [ -e .declarativeSettings ]; then
|
||||
rm .declarativeSettings
|
||||
fi
|
||||
'') + (if cfg.declarativeWhitelist then ''
|
||||
if [ -e .declarativeWhitelist ]; then
|
||||
|
||||
# Whitelist was declarative before, no need to back up anything
|
||||
ln -sf ${whitelistFile} whitelist.json
|
||||
|
||||
else
|
||||
|
||||
# Declarative whitelist for the first time, backup stateful files
|
||||
ln -sb --suffix=.stateful ${whitelistFile} whitelist.json
|
||||
|
||||
echo "Autogenerated file that implies that this server's whitelist is managed declaratively by NixOS" \
|
||||
> .declarativeWhitelist
|
||||
|
||||
fi
|
||||
'' else ''
|
||||
if [ -e .declarativeWhitelist ]; then
|
||||
rm .declarativeWhitelist
|
||||
fi
|
||||
'');
|
||||
};
|
||||
|
||||
networking.firewall = mkIf (cfg.declarativeSettings && cfg.openFirewall) {
|
||||
allowedUDPPorts = [ cfg.settings.port ];
|
||||
allowedTCPPorts = [ cfg.settings.port ];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [ gdd ];
|
||||
}
|
Loading…
Reference in a new issue