lol

nixos/hercules-ci-agent: sync module with upstream

+188 -176
+28 -175
nixos/modules/services/continuous-integration/hercules-ci-agent/common.nix
··· 10 10 let 11 11 inherit (lib) 12 12 filterAttrs 13 - literalMD 14 13 literalExpression 15 14 mkIf 16 15 mkOption 17 16 mkRemovedOptionModule 18 17 mkRenamedOptionModule 19 18 types 20 - ; 21 - 22 - cfg = 23 - config.services.hercules-ci-agent; 24 - 25 - format = pkgs.formats.toml { }; 26 19 27 - settingsModule = { config, ... }: { 28 - freeformType = format.type; 29 - options = { 30 - apiBaseUrl = mkOption { 31 - description = lib.mdDoc '' 32 - API base URL that the agent will connect to. 33 - 34 - When using Hercules CI Enterprise, set this to the URL where your 35 - Hercules CI server is reachable. 36 - ''; 37 - type = types.str; 38 - default = "https://hercules-ci.com"; 39 - }; 40 - baseDirectory = mkOption { 41 - type = types.path; 42 - default = "/var/lib/hercules-ci-agent"; 43 - description = lib.mdDoc '' 44 - State directory (secrets, work directory, etc) for agent 45 - ''; 46 - }; 47 - concurrentTasks = mkOption { 48 - description = lib.mdDoc '' 49 - Number of tasks to perform simultaneously. 50 - 51 - A task is a single derivation build, an evaluation or an effect run. 52 - At minimum, you need 2 concurrent tasks for `x86_64-linux` 53 - in your cluster, to allow for import from derivation. 54 - 55 - `concurrentTasks` can be around the CPU core count or lower if memory is 56 - the bottleneck. 57 - 58 - The optimal value depends on the resource consumption characteristics of your workload, 59 - including memory usage and in-task parallelism. This is typically determined empirically. 60 - 61 - When scaling, it is generally better to have a double-size machine than two machines, 62 - because each split of resources causes inefficiencies; particularly with regards 63 - to build latency because of extra downloads. 64 - ''; 65 - type = types.either types.ints.positive (types.enum [ "auto" ]); 66 - default = "auto"; 67 - }; 68 - labels = mkOption { 69 - description = lib.mdDoc '' 70 - A key-value map of user data. 20 + ; 71 21 72 - This data will be available to organization members in the dashboard and API. 22 + cfg = config.services.hercules-ci-agent; 73 23 74 - The values can be of any TOML type that corresponds to a JSON type, but arrays 75 - can not contain tables/objects due to limitations of the TOML library. Values 76 - involving arrays of non-primitive types may not be representable currently. 77 - ''; 78 - type = format.type; 79 - defaultText = literalExpression '' 80 - { 81 - agent.source = "..."; # One of "nixpkgs", "flake", "override" 82 - lib.version = "..."; 83 - pkgs.version = "..."; 84 - } 85 - ''; 86 - }; 87 - workDirectory = mkOption { 88 - description = lib.mdDoc '' 89 - The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation. 90 - ''; 91 - type = types.path; 92 - default = config.baseDirectory + "/work"; 93 - defaultText = literalExpression ''baseDirectory + "/work"''; 94 - }; 95 - staticSecretsDirectory = mkOption { 96 - description = lib.mdDoc '' 97 - This is the default directory to look for statically configured secrets like `cluster-join-token.key`. 98 - 99 - See also `clusterJoinTokenPath` and `binaryCachesPath` for fine-grained configuration. 100 - ''; 101 - type = types.path; 102 - default = config.baseDirectory + "/secrets"; 103 - defaultText = literalExpression ''baseDirectory + "/secrets"''; 104 - }; 105 - clusterJoinTokenPath = mkOption { 106 - description = lib.mdDoc '' 107 - Location of the cluster-join-token.key file. 108 - 109 - You can retrieve the contents of the file when creating a new agent via 110 - <https://hercules-ci.com/dashboard>. 111 - 112 - As this value is confidential, it should not be in the store, but 113 - installed using other means, such as agenix, NixOps 114 - `deployment.keys`, or manual installation. 115 - 116 - The contents of the file are used for authentication between the agent and the API. 117 - ''; 118 - type = types.path; 119 - default = config.staticSecretsDirectory + "/cluster-join-token.key"; 120 - defaultText = literalExpression ''staticSecretsDirectory + "/cluster-join-token.key"''; 121 - }; 122 - binaryCachesPath = mkOption { 123 - description = lib.mdDoc '' 124 - Path to a JSON file containing binary cache secret keys. 125 - 126 - As these values are confidential, they should not be in the store, but 127 - copied over using other means, such as agenix, NixOps 128 - `deployment.keys`, or manual installation. 129 - 130 - The format is described on <https://docs.hercules-ci.com/hercules-ci-agent/binary-caches-json/>. 131 - ''; 132 - type = types.path; 133 - default = config.staticSecretsDirectory + "/binary-caches.json"; 134 - defaultText = literalExpression ''staticSecretsDirectory + "/binary-caches.json"''; 135 - }; 136 - secretsJsonPath = mkOption { 137 - description = lib.mdDoc '' 138 - Path to a JSON file containing secrets for effects. 139 - 140 - As these values are confidential, they should not be in the store, but 141 - copied over using other means, such as agenix, NixOps 142 - `deployment.keys`, or manual installation. 143 - 144 - The format is described on <https://docs.hercules-ci.com/hercules-ci-agent/secrets-json/>. 145 - ''; 146 - type = types.path; 147 - default = config.staticSecretsDirectory + "/secrets.json"; 148 - defaultText = literalExpression ''staticSecretsDirectory + "/secrets.json"''; 149 - }; 150 - }; 151 - }; 152 - 153 - # TODO (roberth, >=2022) remove 154 - checkNix = 155 - if !cfg.checkNix 156 - then "" 157 - else if lib.versionAtLeast config.nix.package.version "2.3.10" 158 - then "" 159 - else 160 - pkgs.stdenv.mkDerivation { 161 - name = "hercules-ci-check-system-nix-src"; 162 - inherit (config.nix.package) src patches; 163 - dontConfigure = true; 164 - buildPhase = '' 165 - echo "Checking in-memory pathInfoCache expiry" 166 - if ! grep 'PathInfoCacheValue' src/libstore/store-api.hh >/dev/null; then 167 - cat 1>&2 <<EOF 168 - 169 - You are deploying Hercules CI Agent on a system with an incompatible 170 - nix-daemon. Please make sure nix.package is set to a Nix version of at 171 - least 2.3.10 or a master version more recent than Mar 12, 2020. 172 - EOF 173 - exit 1 174 - fi 175 - ''; 176 - installPhase = "touch $out"; 177 - }; 24 + inherit (import ./settings.nix { inherit pkgs lib; }) format settingsModule; 178 25 179 26 in 180 27 { ··· 198 45 Support is available at [help@hercules-ci.com](mailto:help@hercules-ci.com). 199 46 ''; 200 47 }; 201 - checkNix = mkOption { 202 - type = types.bool; 203 - default = true; 204 - description = lib.mdDoc '' 205 - Whether to make sure that the system's Nix (nix-daemon) is compatible. 206 - 207 - If you set this to false, please keep up with the change log. 208 - ''; 209 - }; 210 48 package = mkOption { 211 49 description = lib.mdDoc '' 212 50 Package containing the bin/hercules-ci-agent executable. ··· 235 73 tomlFile = mkOption { 236 74 type = types.path; 237 75 internal = true; 238 - defaultText = literalMD "generated `hercules-ci-agent.toml`"; 76 + defaultText = lib.literalMD "generated `hercules-ci-agent.toml`"; 239 77 description = lib.mdDoc '' 240 78 The fully assembled config file. 241 79 ''; ··· 243 81 }; 244 82 245 83 config = mkIf cfg.enable { 246 - nix.extraOptions = lib.addContextFrom checkNix '' 84 + # Make sure that nix.extraOptions does not override trusted-users 85 + assertions = [ 86 + { 87 + assertion = 88 + (cfg.settings.nixUserIsTrusted or false) -> 89 + builtins.match ".*(^|\n)[ \t]*trusted-users[ \t]*=.*" config.nix.extraOptions == null; 90 + message = '' 91 + hercules-ci-agent: Please do not set `trusted-users` in `nix.extraOptions`. 92 + 93 + The hercules-ci-agent module by default relies on `nix.settings.trusted-users` 94 + to be effectful, but a line like `trusted-users = ...` in `nix.extraOptions` 95 + will override the value set in `nix.settings.trusted-users`. 96 + 97 + Instead of setting `trusted-users` in the `nix.extraOptions` string, you should 98 + set an option with additive semantics, such as 99 + - the NixOS option `nix.settings.trusted-users`, or 100 + - the Nix option in the `extraOptions` string, `extra-trusted-users` 101 + ''; 102 + } 103 + ]; 104 + nix.extraOptions = '' 247 105 # A store path that was missing at first may well have finished building, 248 106 # even shortly after the previous lookup. This *also* applies to the daemon. 249 107 narinfo-cache-negative-ttl = 0 ··· 251 109 services.hercules-ci-agent = { 252 110 tomlFile = 253 111 format.generate "hercules-ci-agent.toml" cfg.settings; 254 - 255 - settings.labels = { 256 - agent.source = 257 - if options.services.hercules-ci-agent.package.highestPrio == (lib.modules.mkOptionDefault { }).priority 258 - then "nixpkgs" 259 - else lib.mkOptionDefault "override"; 260 - pkgs.version = pkgs.lib.version; 261 - lib.version = lib.version; 112 + settings.config._module.args = { 113 + packageOption = options.services.hercules-ci-agent.package; 114 + inherit pkgs; 262 115 }; 263 116 }; 264 117 };
+7 -1
nixos/modules/services/continuous-integration/hercules-ci-agent/default.nix
··· 36 36 Restart = "on-failure"; 37 37 RestartSec = 120; 38 38 39 - LimitSTACK = 256 * 1024 * 1024; 39 + # If a worker goes OOM, don't kill the main process. It needs to 40 + # report the failure and it's unlikely to be part of the problem. 40 41 OOMPolicy = "continue"; 42 + 43 + # Work around excessive stack use by libstdc++ regex 44 + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164 45 + # A 256 MiB stack allows between 400 KiB and 1.5 MiB file to be matched by ".*". 46 + LimitSTACK = 256 * 1024 * 1024; 41 47 }; 42 48 }; 43 49
+153
nixos/modules/services/continuous-integration/hercules-ci-agent/settings.nix
··· 1 + # Not a module 2 + { pkgs, lib }: 3 + let 4 + inherit (lib) 5 + types 6 + literalExpression 7 + mkOption 8 + ; 9 + 10 + format = pkgs.formats.toml { }; 11 + 12 + settingsModule = { config, packageOption, pkgs, ... }: { 13 + freeformType = format.type; 14 + options = { 15 + apiBaseUrl = mkOption { 16 + description = lib.mdDoc '' 17 + API base URL that the agent will connect to. 18 + 19 + When using Hercules CI Enterprise, set this to the URL where your 20 + Hercules CI server is reachable. 21 + ''; 22 + type = types.str; 23 + default = "https://hercules-ci.com"; 24 + }; 25 + baseDirectory = mkOption { 26 + type = types.path; 27 + default = "/var/lib/hercules-ci-agent"; 28 + description = lib.mdDoc '' 29 + State directory (secrets, work directory, etc) for agent 30 + ''; 31 + }; 32 + concurrentTasks = mkOption { 33 + description = lib.mdDoc '' 34 + Number of tasks to perform simultaneously. 35 + 36 + A task is a single derivation build, an evaluation or an effect run. 37 + At minimum, you need 2 concurrent tasks for `x86_64-linux` 38 + in your cluster, to allow for import from derivation. 39 + 40 + `concurrentTasks` can be around the CPU core count or lower if memory is 41 + the bottleneck. 42 + 43 + The optimal value depends on the resource consumption characteristics of your workload, 44 + including memory usage and in-task parallelism. This is typically determined empirically. 45 + 46 + When scaling, it is generally better to have a double-size machine than two machines, 47 + because each split of resources causes inefficiencies; particularly with regards 48 + to build latency because of extra downloads. 49 + ''; 50 + type = types.either types.ints.positive (types.enum [ "auto" ]); 51 + default = "auto"; 52 + defaultText = lib.literalMD '' 53 + `"auto"`, meaning equal to the number of CPU cores. 54 + ''; 55 + }; 56 + labels = mkOption { 57 + description = lib.mdDoc '' 58 + A key-value map of user data. 59 + 60 + This data will be available to organization members in the dashboard and API. 61 + 62 + The values can be of any TOML type that corresponds to a JSON type, but arrays 63 + can not contain tables/objects due to limitations of the TOML library. Values 64 + involving arrays of non-primitive types may not be representable currently. 65 + ''; 66 + type = format.type; 67 + defaultText = literalExpression '' 68 + { 69 + agent.source = "..."; # One of "nixpkgs", "flake", "override" 70 + lib.version = "..."; 71 + pkgs.version = "..."; 72 + } 73 + ''; 74 + }; 75 + workDirectory = mkOption { 76 + description = lib.mdDoc '' 77 + The directory in which temporary subdirectories are created for task state. This includes sources for Nix evaluation. 78 + ''; 79 + type = types.path; 80 + default = config.baseDirectory + "/work"; 81 + defaultText = literalExpression ''baseDirectory + "/work"''; 82 + }; 83 + staticSecretsDirectory = mkOption { 84 + description = lib.mdDoc '' 85 + This is the default directory to look for statically configured secrets like `cluster-join-token.key`. 86 + 87 + See also `clusterJoinTokenPath` and `binaryCachesPath` for fine-grained configuration. 88 + ''; 89 + type = types.path; 90 + default = config.baseDirectory + "/secrets"; 91 + defaultText = literalExpression ''baseDirectory + "/secrets"''; 92 + }; 93 + clusterJoinTokenPath = mkOption { 94 + description = lib.mdDoc '' 95 + Location of the cluster-join-token.key file. 96 + 97 + You can retrieve the contents of the file when creating a new agent via 98 + <https://hercules-ci.com/dashboard>. 99 + 100 + As this value is confidential, it should not be in the store, but 101 + installed using other means, such as agenix, NixOps 102 + `deployment.keys`, or manual installation. 103 + 104 + The contents of the file are used for authentication between the agent and the API. 105 + ''; 106 + type = types.path; 107 + default = config.staticSecretsDirectory + "/cluster-join-token.key"; 108 + defaultText = literalExpression ''staticSecretsDirectory + "/cluster-join-token.key"''; 109 + }; 110 + binaryCachesPath = mkOption { 111 + description = lib.mdDoc '' 112 + Path to a JSON file containing binary cache secret keys. 113 + 114 + As these values are confidential, they should not be in the store, but 115 + copied over using other means, such as agenix, NixOps 116 + `deployment.keys`, or manual installation. 117 + 118 + The format is described on <https://docs.hercules-ci.com/hercules-ci-agent/binary-caches-json/>. 119 + ''; 120 + type = types.path; 121 + default = config.staticSecretsDirectory + "/binary-caches.json"; 122 + defaultText = literalExpression ''staticSecretsDirectory + "/binary-caches.json"''; 123 + }; 124 + secretsJsonPath = mkOption { 125 + description = lib.mdDoc '' 126 + Path to a JSON file containing secrets for effects. 127 + 128 + As these values are confidential, they should not be in the store, but 129 + copied over using other means, such as agenix, NixOps 130 + `deployment.keys`, or manual installation. 131 + 132 + The format is described on <https://docs.hercules-ci.com/hercules-ci-agent/secrets-json/>. 133 + ''; 134 + type = types.path; 135 + default = config.staticSecretsDirectory + "/secrets.json"; 136 + defaultText = literalExpression ''staticSecretsDirectory + "/secrets.json"''; 137 + }; 138 + }; 139 + config = { 140 + labels = { 141 + agent.source = 142 + if packageOption.highestPrio == (lib.modules.mkOptionDefault { }).priority 143 + then "nixpkgs" 144 + else lib.mkOptionDefault "override"; 145 + pkgs.version = pkgs.lib.version; 146 + lib.version = lib.version; 147 + }; 148 + }; 149 + }; 150 + in 151 + { 152 + inherit format settingsModule; 153 + }