1/* 2 This file is for NixOS-specific options and configs. 3 4 Code that is shared with nix-darwin goes in common.nix. 5*/ 6 7{ 8 pkgs, 9 config, 10 lib, 11 ... 12}: 13let 14 inherit (lib) mkIf mkDefault; 15 16 cfg = config.services.hercules-ci-agent; 17 18 command = "${cfg.package}/bin/hercules-ci-agent --config ${cfg.tomlFile}"; 19 testCommand = "${command} --test-configuration"; 20 21in 22{ 23 imports = [ 24 ./common.nix 25 (lib.mkRenamedOptionModule 26 [ "services" "hercules-ci-agent" "user" ] 27 [ "systemd" "services" "hercules-ci-agent" "serviceConfig" "User" ] 28 ) 29 ]; 30 31 config = mkIf cfg.enable { 32 systemd.services.hercules-ci-agent = { 33 wantedBy = [ "multi-user.target" ]; 34 after = [ "network-online.target" ]; 35 wants = [ "network-online.target" ]; 36 path = [ config.nix.package ]; 37 startLimitBurst = 30 * 1000000; # practically infinite 38 serviceConfig = { 39 User = "hercules-ci-agent"; 40 ExecStart = command; 41 ExecStartPre = testCommand; 42 Restart = "on-failure"; 43 RestartSec = 120; 44 45 # If a worker goes OOM, don't kill the main process. It needs to 46 # report the failure and it's unlikely to be part of the problem. 47 OOMPolicy = "continue"; 48 49 # Work around excessive stack use by libstdc++ regex 50 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164 51 # A 256 MiB stack allows between 400 KiB and 1.5 MiB file to be matched by ".*". 52 LimitSTACK = 256 * 1024 * 1024; 53 }; 54 }; 55 56 # Changes in the secrets do not affect the unit in any way that would cause 57 # a restart, which is currently necessary to reload the secrets. 58 systemd.paths.hercules-ci-agent-restart-files = { 59 wantedBy = [ "hercules-ci-agent.service" ]; 60 pathConfig = { 61 Unit = "hercules-ci-agent-restarter.service"; 62 PathChanged = [ 63 cfg.settings.clusterJoinTokenPath 64 cfg.settings.binaryCachesPath 65 ]; 66 }; 67 }; 68 systemd.services.hercules-ci-agent-restarter = { 69 serviceConfig.Type = "oneshot"; 70 script = '' 71 # Wait a bit, with the effect of bundling up file changes into a single 72 # run of this script and hopefully a single restart. 73 sleep 10 74 if systemctl is-active --quiet hercules-ci-agent.service; then 75 if ${testCommand}; then 76 systemctl restart hercules-ci-agent.service 77 else 78 echo 1>&2 "WARNING: Not restarting agent because config is not valid at this time." 79 fi 80 else 81 echo 1>&2 "Not restarting hercules-ci-agent despite config file update, because it is not already active." 82 fi 83 ''; 84 }; 85 86 # Trusted user allows simplified configuration and better performance 87 # when operating in a cluster. 88 nix.settings.trusted-users = [ config.systemd.services.hercules-ci-agent.serviceConfig.User ]; 89 services.hercules-ci-agent = { 90 settings = { 91 nixUserIsTrusted = true; 92 labels = 93 let 94 mkIfNotNull = x: mkIf (x != null) x; 95 in 96 { 97 nixos.configurationRevision = mkIfNotNull config.system.configurationRevision; 98 nixos.release = config.system.nixos.release; 99 nixos.label = mkIfNotNull config.system.nixos.label; 100 nixos.codeName = config.system.nixos.codeName; 101 nixos.tags = config.system.nixos.tags; 102 nixos.systemName = mkIfNotNull config.system.name; 103 }; 104 }; 105 }; 106 107 users.users.hercules-ci-agent = { 108 home = cfg.settings.baseDirectory; 109 createHome = true; 110 group = "hercules-ci-agent"; 111 description = "Hercules CI Agent system user"; 112 isSystemUser = true; 113 }; 114 115 users.groups.hercules-ci-agent = { }; 116 }; 117 118 meta.maintainers = [ lib.maintainers.roberth ]; 119}