Skip to content

Commit 9aa5b3b

Browse files
committed
hydra-builder: move operational settings from CLI flags to a TOML config file
The builder took every tuning knob as a `--flag`, so the NixOS and Darwin modules reconstructed a dozen-argument `ExecStart` and each setting existed twice: once as a module option, once as a CLI flag. The queue runner already solved this with a `--config-path` TOML file; the builder now follows the same shape. `config.rs` splits into three concerns: - `Args` (the clap entry point) carries only `--config-path`, which is meta-config locating the file, plus a flattened `Cli`. - `Cli` keeps the connection/security options that don't belong in a world-readable config file: gateway endpoint, mTLS cert paths, auth token. - `AppConfig` (serde, `camelCase`, `deny_unknown_fields`) holds the operational settings, each defaulting to the old clap default, so a missing file behaves exactly as before. `systems` and `supportedFeatures` stay `Option`: absent means "read from `nix show-config`", an explicit `[]` means "advertise none" — the modules type them as `nullOr (listOf ...)` so that distinction survives into the generated TOML. It was unclear how to take advantage of this `None` for `Some([])` distinction before --- certainly the old NixOS module was not doing it. The modules now generate `/etc/hydra/builder.toml` with `pkgs.formats.toml` and pass only the connection/security flags. This also drops the old `--use-substitutes` always-on bug: the modules guarded it with `useSubstitutes != null`, always true for a non-null bool, so the option never actually took effect.
1 parent f69a55c commit 9aa5b3b

7 files changed

Lines changed: 315 additions & 267 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

darwin-modules/builder-module.nix

Lines changed: 84 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
let
88
cfg = config.services.hydra-queue-builder-dev;
99
user = config.users.users.hydra-queue-builder;
10+
11+
format = pkgs.formats.toml { };
1012
in
1113
{
1214
options = {
@@ -18,85 +20,93 @@ in
1820
type = lib.types.singleLineStr;
1921
};
2022

21-
pingInterval = lib.mkOption {
22-
description = "Interval in which pings are send to the runner";
23-
type = lib.types.ints.positive;
24-
default = 10;
25-
};
23+
settings = lib.mkOption {
24+
description = "Builder settings written to the TOML config file";
25+
type = lib.types.submodule {
26+
options = {
27+
pingInterval = lib.mkOption {
28+
description = "Interval in which pings are send to the runner";
29+
type = lib.types.ints.positive;
30+
default = 10;
31+
};
2632

27-
speedFactor = lib.mkOption {
28-
description = "Additional Speed factor for this machine";
29-
type = lib.types.oneOf [
30-
lib.types.ints.positive
31-
lib.types.float
32-
];
33-
default = 1;
34-
};
33+
speedFactor = lib.mkOption {
34+
description = "Additional Speed factor for this machine";
35+
type = lib.types.oneOf [
36+
lib.types.ints.positive
37+
lib.types.float
38+
];
39+
default = 1;
40+
};
3541

36-
maxJobs = lib.mkOption {
37-
description = "Maximum allowed of jobs. This only is used if the queue runner uses this metrics for determining free machines.";
38-
type = lib.types.ints.positive;
39-
default = 4;
40-
};
42+
maxJobs = lib.mkOption {
43+
description = "Maximum allowed of jobs. This only is used if the queue runner uses this metrics for determining free machines.";
44+
type = lib.types.ints.positive;
45+
default = 4;
46+
};
4147

42-
buildDirAvailThreshold = lib.mkOption {
43-
description = "Threshold in percent for nix build dir before jobs are no longer scheduled on the machine";
44-
type = lib.types.float;
45-
default = 10.0;
46-
};
48+
buildDirAvailThreshold = lib.mkOption {
49+
description = "Threshold in percent for nix build dir before jobs are no longer scheduled on the machine";
50+
type = lib.types.float;
51+
default = 10.0;
52+
};
4753

48-
storeAvailThreshold = lib.mkOption {
49-
description = "Threshold in percent for /nix/store before jobs are no longer scheduled on the machine";
50-
type = lib.types.float;
51-
default = 10.0;
52-
};
54+
storeAvailThreshold = lib.mkOption {
55+
description = "Threshold in percent for /nix/store before jobs are no longer scheduled on the machine";
56+
type = lib.types.float;
57+
default = 10.0;
58+
};
5359

54-
load1Threshold = lib.mkOption {
55-
description = "Maximum Load1 threshold before we stop scheduling jobs on that node. Only used if PSI is not available.";
56-
type = lib.types.float;
57-
default = 8.0;
58-
};
60+
load1Threshold = lib.mkOption {
61+
description = "Maximum Load1 threshold before we stop scheduling jobs on that node. Only used if PSI is not available.";
62+
type = lib.types.float;
63+
default = 8.0;
64+
};
5965

60-
cpuPsiThreshold = lib.mkOption {
61-
description = "Maximum CPU PSI in the last 10s before we stop scheduling jobs on that node";
62-
type = lib.types.float;
63-
default = 75.0;
64-
};
66+
cpuPsiThreshold = lib.mkOption {
67+
description = "Maximum CPU PSI in the last 10s before we stop scheduling jobs on that node";
68+
type = lib.types.float;
69+
default = 75.0;
70+
};
6571

66-
memPsiThreshold = lib.mkOption {
67-
description = "Maximum Memory PSI in the last 10s before we stop scheduling jobs on that node";
68-
type = lib.types.float;
69-
default = 80.0;
70-
};
72+
memPsiThreshold = lib.mkOption {
73+
description = "Maximum Memory PSI in the last 10s before we stop scheduling jobs on that node";
74+
type = lib.types.float;
75+
default = 80.0;
76+
};
7177

72-
ioPsiThreshold = lib.mkOption {
73-
description = "Maximum IO PSI in the last 10s before we stop scheduling jobs on that node. If null then this pressure check is disabled.";
74-
type = lib.types.nullOr lib.types.float;
75-
default = null;
76-
};
78+
ioPsiThreshold = lib.mkOption {
79+
description = "Maximum IO PSI in the last 10s before we stop scheduling jobs on that node. If null then this pressure check is disabled.";
80+
type = lib.types.nullOr lib.types.float;
81+
default = null;
82+
};
7783

78-
systems = lib.mkOption {
79-
description = "List of supported systems. If none are passed, system and extra-platforms are read from nix.";
80-
type = lib.types.listOf lib.types.singleLineStr;
81-
default = [ ];
82-
};
84+
systems = lib.mkOption {
85+
description = "List of supported systems. If null, system and extra-platforms are read from nix; an empty list means none.";
86+
type = lib.types.nullOr (lib.types.listOf lib.types.singleLineStr);
87+
default = null;
88+
};
8389

84-
supportedFeatures = lib.mkOption {
85-
description = "Pass supported features to the builder. If none are passed, system features will be used.";
86-
type = lib.types.listOf lib.types.singleLineStr;
87-
default = [ ];
88-
};
90+
supportedFeatures = lib.mkOption {
91+
description = "Supported features for the builder. If null, system features are read from nix; an empty list means none.";
92+
type = lib.types.nullOr (lib.types.listOf lib.types.singleLineStr);
93+
default = null;
94+
};
8995

90-
mandatoryFeatures = lib.mkOption {
91-
description = "Pass mandatory features to the builder.";
92-
type = lib.types.listOf lib.types.singleLineStr;
93-
default = [ ];
94-
};
96+
mandatoryFeatures = lib.mkOption {
97+
description = "Mandatory features for the builder.";
98+
type = lib.types.listOf lib.types.singleLineStr;
99+
default = [ ];
100+
};
95101

96-
useSubstitutes = lib.mkOption {
97-
description = "Use substitution for paths";
98-
type = lib.types.bool;
99-
default = true;
102+
useSubstitutes = lib.mkOption {
103+
description = "Use substitution for paths";
104+
type = lib.types.bool;
105+
default = true;
106+
};
107+
};
108+
};
109+
default = { };
100110
};
101111

102112
authorizationFile = lib.mkOption {
@@ -154,41 +164,8 @@ in
154164
"${cfg.package}/bin/hydra-builder"
155165
"--gateway-endpoint"
156166
cfg.queueRunnerAddr
157-
"--ping-interval"
158-
cfg.pingInterval
159-
"--speed-factor"
160-
cfg.speedFactor
161-
"--max-jobs"
162-
cfg.maxJobs
163-
"--build-dir-avail-threshold"
164-
cfg.buildDirAvailThreshold
165-
"--store-avail-threshold"
166-
cfg.storeAvailThreshold
167-
"--load1-threshold"
168-
cfg.load1Threshold
169-
"--cpu-psi-threshold"
170-
cfg.cpuPsiThreshold
171-
"--mem-psi-threshold"
172-
cfg.memPsiThreshold
173-
]
174-
++ lib.optionals (cfg.ioPsiThreshold != null) [
175-
"--io-psi-threshold"
176-
cfg.ioPsiThreshold
177-
]
178-
++ (builtins.concatMap (v: [
179-
"--systems"
180-
v
181-
]) cfg.systems)
182-
++ (builtins.concatMap (v: [
183-
"--supported-features"
184-
v
185-
]) cfg.supportedFeatures)
186-
++ (builtins.concatMap (v: [
187-
"--mandatory-features"
188-
v
189-
]) cfg.mandatoryFeatures)
190-
++ lib.optionals (cfg.useSubstitutes != null) [
191-
"--use-substitutes"
167+
"--config-path"
168+
"/etc/hydra/builder.toml"
192169
]
193170
++ lib.optionals (cfg.authorizationFile != null) [
194171
"--authorization-file"
@@ -227,6 +204,11 @@ in
227204
WorkingDirectory = user.home;
228205
};
229206
};
207+
208+
environment.etc."hydra/builder.toml".source = format.generate "builder.toml" (
209+
lib.filterAttrsRecursive (_: v: v != null) cfg.settings
210+
);
211+
230212
users = {
231213
users.hydra-queue-builder = {
232214
uid = lib.mkDefault 535;

0 commit comments

Comments
 (0)