diff --git a/build/package/nix/ServerConsole.sha256 b/build/package/nix/ServerConsole.sha256 new file mode 100644 index 0000000000..ae3d91ae7d --- /dev/null +++ b/build/package/nix/ServerConsole.sha256 @@ -0,0 +1 @@ +sha256-mHlRHPSeZxyJPqN3KUmc0ftYNZgh81LauIu+fCSKPUI= diff --git a/build/package/nix/flake.nix b/build/package/nix/flake.nix new file mode 100644 index 0000000000..f2bf8c14a9 --- /dev/null +++ b/build/package/nix/flake.nix @@ -0,0 +1,13 @@ +{ + description = "tgstation-server"; + + inputs = {}; + + outputs = { ... }: { + nixosModules = { + default = { ... }: { + imports = [ ./tgstation-server.nix ]; + }; + }; + }; +} diff --git a/build/package/nix/package.nix b/build/package/nix/package.nix new file mode 100644 index 0000000000..1dae347413 --- /dev/null +++ b/build/package/nix/package.nix @@ -0,0 +1,121 @@ +{ + pkgs, + ... +}: + +let + inherit (pkgs) stdenv lib; + + versionParse = stdenv.mkDerivation { + pname = "tgstation-server-version-parse"; + version = "1.0.0"; + + meta = with pkgs.lib; { + description = "Version parser for tgstation-server"; + homepage = "https://github.com/tgstation/tgstation-server"; + changelog = "https://github.com/tgstation/tgstation-server/blob/gh-pages/changelog.yml"; + license = licenses.agpl3Plus; + platforms = platforms.x86_64; + }; + + nativeBuildInputs = with pkgs; [ + xmlstarlet + ]; + + src = ./../..; + + installPhase = '' + mkdir -p $out + xmlstarlet sel -N X="http://schemas.microsoft.com/developer/msbuild/2003" --template --value-of /X:Project/X:PropertyGroup/X:TgsCoreVersion ./Version.props > $out/tgs_version.txt + ''; + }; + + fixedOutput = stdenv.mkDerivation { + pname = "tgstation-server-release-server-console-zip"; + version = (builtins.readFile "${versionParse}/tgs_version.txt"); + + meta = with pkgs.lib; { + description = "Host watchdog binaries for tgstation-server"; + homepage = "https://github.com/tgstation/tgstation-server"; + changelog = "https://github.com/tgstation/tgstation-server/releases/tag/tgstation-server-v${version}"; + license = licenses.agpl3Plus; + platforms = platforms.x86_64; + }; + + nativeBuildInputs = with pkgs; [ + curl + cacert + versionParse + ]; + + src = ./.; + + buildPhase = '' + curl -L https://file.house/b2eyKOJZ7ptxwqm8O24-9A==.zip -o ServerConsole.zip + ''; + + installPhase = '' + mkdir -p $out + mv ServerConsole.zip $out/ServerConsole.zip + ''; + + outputHashAlgo = "sha256"; + outputHashMode = "recursive"; + outputHash = (builtins.readFile ./ServerConsole.sha256); + }; + rpath = lib.makeLibraryPath [ pkgs.stdenv_32bit.cc.cc.lib ]; +in +stdenv.mkDerivation { + pname = "tgstation-server"; + version = (builtins.readFile "${versionParse}/tgs_version.txt"); + + meta = with pkgs.lib; { + description = "A production scale tool for DreamMaker server management"; + homepage = "https://github.com/tgstation/tgstation-server"; + changelog = "https://github.com/tgstation/tgstation-server/releases/tag/tgstation-server-v${version}"; + license = licenses.agpl3Plus; + platforms = platforms.x86_64; + }; + + buildInputs = with pkgs; [ + dotnetCorePackages.aspnetcore_8_0 + gdb + systemd + zlib + gcc_multi + glibc + patchelf + ]; + nativeBuildInputs = with pkgs; [ + makeWrapper + unzip + fixedOutput + versionParse + ]; + + src = ./.; + + installPhase = '' + mkdir -p $out/bin + unzip "${fixedOutput}/ServerConsole.zip" -d $out/bin + rm -rf $out/bin/lib + makeWrapper ${pkgs.dotnetCorePackages.aspnetcore_8_0}/dotnet $out/bin/tgstation-server --suffix PATH : ${ + lib.makeBinPath ( + with pkgs; + [ + patchelf + dotnetCorePackages.aspnetcore_8_0 + gdb + ] + ) + } --suffix LD_LIBRARY_PATH : ${ + lib.makeLibraryPath ( + with pkgs; + [ + systemd + zlib + ] + ) + } --add-flags "$out/bin/Tgstation.Server.Host.Console.dll --bootstrap" + ''; +} diff --git a/build/package/nix/tgstation-server.nix b/build/package/nix/tgstation-server.nix new file mode 100644 index 0000000000..83076b44a2 --- /dev/null +++ b/build/package/nix/tgstation-server.nix @@ -0,0 +1,124 @@ +inputs@{ + config, + lib, + nixpkgs, + pkgs, + ... +}: + +let + pkgs-i686 = nixpkgs.legacyPackages.i686-linux; + + cfg = config.services.tgstation-server; + + package = import ./package.nix inputs; + + stdenv = pkgs-i686.stdenv_32bit; + + rpath = pkgs-i686.lib.makeLibraryPath [ + stdenv.cc.cc.lib + ]; + + byond-patcher = pkgs-i686.writeShellScriptBin "byond-patcher" '' + BYOND_PATH=$(realpath ../../Byond/$1/byond/bin/) + + patchelf --set-interpreter "$(cat ${stdenv.cc}/nix-support/dynamic-linker)" \ + --set-rpath "$BYOND_PATH:${rpath}" \ + $BYOND_PATH/{DreamDaemon,DreamDownload,DreamMaker} + ''; +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.str; + default = "tgstation-server"; + description = '' + The name of the user used to execute tgstation-server. + ''; + }; + + groupname = lib.mkOption { + type = lib.types.str; + 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.str; + default = "/home/tgstation-server"; + description = '' + The home directory of TGS. Should be persistent. + ''; + }; + + production-appsettings = lib.mkOption { + type = lib.types.lines; + default = ''''; + description = '' + The contents of appsettings.Production.yml in the /etc/tgstation-server.d directory. + ''; + }; + }; + }; + + 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 "${package}/bin/appsettings.yml"); + group = cfg.groupname; + mode = "0644"; + }; + "tgstation-server.d/appsettings.Production.yml" = { + text = cfg.production-appsettings; + group = cfg.groupname; + mode = "0640"; + }; + "tgstation-server.d/EventScripts/EngineInstallComplete-050-PatchELFByond.sh" = { + source = "${byond-patcher}/bin/byond-patcher"; + group = cfg.groupname; + mode = "755"; + }; + }; + + systemd.services.tgstation-server = { + description = "tgstation-server"; + serviceConfig = { + User = cfg.username; + Type = "notify-reload"; + NotifyAccess = "all"; + WorkingDirectory = "${package}/bin"; + ExecStart = "${package}/bin/tgstation-server --appsettings-base-path=/etc/tgstation-server.d --General:SetupWizardMode=Never --General:AdditionalEventScriptsDirectories:0=/etc/tgstation-server.d/EventScripts"; + Restart = "always"; + KillMode = "process"; + ReloadSignal = "SIGUSR2"; + AmbientCapabilities = "CAP_SYS_NICE CAP_SYS_PTRACE"; + WatchdogSec = "60"; + WatchdogSignal = "SIGTERM"; + LogsDirectory = "tgstation-server"; + }; + wantedBy = [ "multi-user.target" ]; + }; + }; +}