From 129bbf2f8ed5cdf4c6d89afc34e042b85b94dc8f Mon Sep 17 00:00:00 2001 From: zimward Date: Thu, 30 Apr 2026 18:07:40 +0200 Subject: [PATCH] autopush-rs: add modular service --- nixos/tests/all-tests.nix | 1 + nixos/tests/autopush-rs.nix | 60 ++++++++++++ pkgs/by-name/au/autopush-rs/package.nix | 16 +++ .../au/autopush-rs/service-autoconnect.nix | 96 ++++++++++++++++++ .../au/autopush-rs/service-autoendpoint.nix | 98 +++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 nixos/tests/autopush-rs.nix create mode 100644 pkgs/by-name/au/autopush-rs/service-autoconnect.nix create mode 100644 pkgs/by-name/au/autopush-rs/service-autoendpoint.nix diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 56c496713f21..bdf99f3a51f9 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -245,6 +245,7 @@ in authelia = runTest ./authelia.nix; auto-cpufreq = runTest ./auto-cpufreq.nix; autobrr = runTest ./autobrr.nix; + autopush-rs = runTest ./autopush-rs.nix; autosuspend = runTest ./autosuspend.nix; avahi = runTest { imports = [ ./avahi.nix ]; diff --git a/nixos/tests/autopush-rs.nix b/nixos/tests/autopush-rs.nix new file mode 100644 index 000000000000..e1075bd3d17f --- /dev/null +++ b/nixos/tests/autopush-rs.nix @@ -0,0 +1,60 @@ +{ lib, ... }: +{ + _class = "nixosTest"; + name = "autopush-rs"; + + nodes = { + machine = + { pkgs, config, ... }: + { + environment.systemPackages = [ + pkgs.curl + ]; + + services.redis.servers.autopush-rs = { + enable = true; + port = 6000; + }; + system.services.autopush-autoconnect = { + imports = [ + pkgs.autopush-rs.services.autoconnect + ]; + autoconnect.settings = { + #do not use this key in production!!! + crypto_key = "[fZQX8jgdESUYFTYfWw3Dv5RRMuwYJPPaaPcbUgHM69Q=]"; + db_dsn = "redis://localhost:${toString config.services.redis.servers.autopush-rs.port}"; + port = 8000; + }; + }; + system.services.autopush-autoendpoint = { + imports = [ + pkgs.autopush-rs.services.autoendpoint + ]; + autoendpoint.settings = { + #do not use this key in production!!! + crypto_key = "[fZQX8jgdESUYFTYfWw3Dv5RRMuwYJPPaaPcbUgHM69Q=]"; + db_dsn = "redis://localhost:${toString config.services.redis.servers.autopush-rs.port}"; + port = 8080; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 8080 + 8000 + ]; + }; + }; + + testScript = '' + start_all() + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("autopush-autoconnect.service") + machine.wait_for_unit("autopush-autoendpoint.service") + machine.wait_for_open_port(8080) + machine.wait_for_open_port(8000) + machine.succeed("curl -s -f http://localhost:8080/health") + machine.succeed("curl -s -f http://localhost:8000/health") + ''; + + meta.maintainers = with lib.maintainers; [ zimward ]; +} diff --git a/pkgs/by-name/au/autopush-rs/package.nix b/pkgs/by-name/au/autopush-rs/package.nix index 9865718a041b..08c946b5d6a4 100644 --- a/pkgs/by-name/au/autopush-rs/package.nix +++ b/pkgs/by-name/au/autopush-rs/package.nix @@ -1,5 +1,7 @@ { lib, + pkgs, + nixosTests, fetchFromGitHub, rustPlatform, stdenv, @@ -99,6 +101,20 @@ rustPlatform.buildRustPackage (finalAttrs: { ''; passthru = { + tests = nixosTests.autopush-rs; + services.autoconnect = { + imports = [ + (lib.modules.importApply ./service-autoconnect.nix { inherit pkgs; }) + ]; + package = finalAttrs.finalPackage.out; + }; + services.autoendpoint = { + imports = [ + (lib.modules.importApply ./service-autoendpoint.nix { inherit pkgs; }) + ]; + package = finalAttrs.finalPackage.out; + }; + updateScript = nix-update-script { }; }; diff --git a/pkgs/by-name/au/autopush-rs/service-autoconnect.nix b/pkgs/by-name/au/autopush-rs/service-autoconnect.nix new file mode 100644 index 000000000000..eca44eee4b87 --- /dev/null +++ b/pkgs/by-name/au/autopush-rs/service-autoconnect.nix @@ -0,0 +1,96 @@ +#v Non-module dependencies (`importApply`) +{ pkgs }: + +# Service module +{ + lib, + options, + config, + ... +}: +let + cfg = config.autoconnect; + tomlFmt = pkgs.formats.toml { }; +in +{ + _class = "service"; + options = { + package = lib.mkPackageOption pkgs "autopush-rs.out" { }; + autoconnect.settings = lib.mkOption { + type = lib.types.submodule { + freeformType = tomlFmt.type; + options = { + db_dsn = lib.mkOption { + description = "Endpoint of the database server."; + type = lib.types.str; + default = ""; + example = lib.literalExpression "redis+socket://${config.services.redis.servers.autopush-rs.unixSocket}"; + }; + }; + }; + default = { }; + description = ""; + }; + }; + config = + let + configFile = tomlFmt.generate "autoconnect.toml" cfg.settings; + in + { + process.argv = [ + "${config.package}/bin/autoconnect" + "-c" + (toString configFile) + ]; + } + // lib.optionalAttrs (options ? systemd) { + systemd.service = { + after = [ "network.target" ]; + wants = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Restart = "on-failure"; + + #hardening + MemoryDenyWriteExecute = true; + StateDirectoryMode = 0700; + UMask = 077; + DynamicUser = true; + PrivateUsers = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectSystem = "full"; + ProtectHome = true; + NoNewPrivileges = true; + RuntimeDirectoryMode = 755; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictNamespaces = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + SystemCallArchitectures = "native"; + + ProtectProc = "invisible"; + ProcSubset = "pid"; + + SystemCallFilter = [ + "~@clock" + "~@cpu-emulation" + "~@debug" + "~@module" + "~@mount" + "~@obsolete" + "~@raw-io" + "~@reboot" + "~@swap" + ]; + }; + }; + }; +} diff --git a/pkgs/by-name/au/autopush-rs/service-autoendpoint.nix b/pkgs/by-name/au/autopush-rs/service-autoendpoint.nix new file mode 100644 index 000000000000..d4c87dff54a7 --- /dev/null +++ b/pkgs/by-name/au/autopush-rs/service-autoendpoint.nix @@ -0,0 +1,98 @@ +# Non-module dependencies (`importApply`) +{ pkgs }: + +# Service module +{ + lib, + config, + options, + ... +}: +let + cfg = config.autoendpoint; + tomlFmt = pkgs.formats.toml { }; +in +{ + _class = "service"; + options = { + package = lib.mkPackageOption pkgs "autopush-rs.out" { }; + autoendpoint = { + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = tomlFmt.type; + options = { + db_dsn = lib.mkOption { + description = "Endpoint of the database server."; + type = lib.types.str; + default = ""; + example = lib.literalExpression "redis+socket://${config.services.redis.servers.autopush-rs.unixSocket}"; + }; + }; + }; + default = { }; + description = ""; + }; + }; + }; + config = + let + configFile = tomlFmt.generate "autoendpoint.toml" cfg.settings; + in + { + process.argv = [ + "${config.package}/bin/autoendpoint" + "-c" + (toString configFile) + ]; + } + // lib.optionalAttrs (options ? systemd) { + systemd.service = { + after = [ "network.target" ]; + wants = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Restart = "on-failure"; + + #hardening + MemoryDenyWriteExecute = true; + StateDirectoryMode = 0700; + UMask = 077; + DynamicUser = true; + PrivateUsers = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectSystem = "full"; + ProtectHome = true; + NoNewPrivileges = true; + RuntimeDirectoryMode = 755; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictNamespaces = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + SystemCallArchitectures = "native"; + + ProtectProc = "invisible"; + ProcSubset = "pid"; + + SystemCallFilter = [ + "~@clock" + "~@cpu-emulation" + "~@debug" + "~@module" + "~@mount" + "~@obsolete" + "~@raw-io" + "~@reboot" + "~@swap" + ]; + }; + }; + }; +}