Files
tgstation-server/build/package/nix/tgstation-server.nix

183 lines
5.4 KiB
Nix

inputs@{
config,
lib,
systemdUtils,
nixpkgs,
pkgs,
writeShellScriptBin,
...
}:
let
pkgs-i686 = nixpkgs.legacyPackages.i686-linux;
cfg = config.services.tgstation-server;
package = import ./package.nix inputs;
stdenv32 = pkgs-i686.stdenv_32bit;
exes-rpath = pkgs-i686.lib.makeLibraryPath [
stdenv32.cc.cc.lib
];
libbyond-rpath = pkgs-i686.lib.makeLibraryPath [
pkgs-i686.curl
];
byond-patcher = pkgs-i686.writeShellScriptBin "EngineInstallComplete-050-TgsPatchELFByond.sh" ''
# If the file doesn't exist, assume OD
BYOND_BIN_PATH="''${TGS_INSTANCE_ROOT}/Byond/$1/byond/bin/"
if [[ ! -f "''${BYOND_BIN_PATH}DreamDaemon" ]] ; then
echo "DreamDaemon doesn't appear to exist. Assuming OD install"
exit
fi
BYOND_PATH=$(realpath $BYOND_BIN_PATH)
${pkgs.patchelf}/bin/patchelf --set-interpreter "$(cat ${stdenv32.cc}/nix-support/dynamic-linker)" \
--set-rpath "$BYOND_PATH:${exes-rpath}" \
$BYOND_PATH/{DreamDaemon,DreamDownload,DreamMaker}
${pkgs.patchelf}/bin/patchelf --set-rpath "${libbyond-rpath}" $BYOND_PATH/libbyond.so
'';
tgs-wrapper = pkgs.writeShellScriptBin "tgs-path-wrapper" ''
export PATH=$PATH:${cfg.extra-path}
exec ${package}/bin/tgstation-server --appsettings-base-path=/etc/tgstation-server.d --General:SetupWizardMode=Never --General:AdditionalEventScriptsDirectories:0=/etc/tgstation-server.d/EventScripts --General:AdditionalEventScriptsDirectories:1=${byond-patcher}/bin
'';
in
{
##### interface. here we define the options that users of our service can specify
options = {
# the options for our service will be located under services.foo
services.tgstation-server = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to enable tgstation-server.
'';
};
username = lib.mkOption {
type = lib.types.nonEmptyStr;
default = "tgstation-server";
description = ''
The name of the user used to execute tgstation-server.
'';
};
groupname = lib.mkOption {
type = lib.types.nonEmptyStr;
default = "tgstation-server";
description = ''
The name of group the user used to execute tgstation-server will belong to.
'';
};
home-directory = lib.mkOption {
type = lib.types.nonEmptyStr;
default = "/home/tgstation-server";
description = ''
The home directory of TGS. Should be persistent.
'';
};
production-appsettings = lib.mkOption {
type = lib.types.path;
default = '''';
description = ''
A formatted appsettings.Production.yml file.
'';
};
extra-path = lib.mkOption {
type = lib.types.str;
default = "";
description = ''
Extra PATH entries to add to the TGS process
'';
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
Environment file as defined in {manpage}`systemd.exec(5)`
'';
};
wants = lib.mkOption {
type = lib.types.listOf systemdUtils.lib.unitNameType;
default = [];
description = ''
Start the specified units when this unit is started.
'';
};
};
};
config = lib.mkIf cfg.enable {
users.groups."${cfg.groupname}" = { };
users.users."${cfg.username}" = {
isSystemUser = true;
createHome = true;
group = cfg.groupname;
home = cfg.home-directory;
};
environment.etc = {
"tgstation-server.d/appsettings.yml" = {
text = (builtins.readFile ./../../../src/Tgstation.Server.Host/appsettings.yml);
group = cfg.groupname;
mode = "0644";
};
"tgstation-server.d/appsettings.Production.yml" = {
source = cfg.production-appsettings;
group = cfg.groupname;
mode = "0640";
};
"tgstation-server.d/EventScripts/README.txt" = {
text = "TGS event scripts placed here will be executed by all online instances";
group = cfg.groupname;
mode = "0640";
};
};
systemd.services.tgstation-server = {
description = "tgstation-server";
serviceConfig = {
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
User = cfg.username;
Type = "notify-reload";
NotifyAccess = "all";
WorkingDirectory = "${package}/bin";
ExecStart = "${tgs-wrapper}/bin/tgs-path-wrapper";
Restart = "always";
KillMode = "process";
ReloadSignal = "SIGUSR2";
AmbientCapabilities = "CAP_SYS_NICE CAP_SYS_PTRACE";
WatchdogSec = "60";
WatchdogSignal = "SIGTERM";
LogsDirectory = "tgstation-server";
};
reloadTriggers = [
(lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ])
"/etc/tgstation.server.d/appsettings.Production.yml"
];
restartIfChanged = false; # So that the TGS service doesn't just get restarted whenever it's updated, and boots players
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [
"network-online.target"
"mysql.service"
"mariadb.service"
"postgresql.service"
"mssql-server.service"
];
};
};
}