Skip to content

Commit 2b41024

Browse files
committed
nixos/forgejo.runner: add more legacy and pre-registered assertions
1 parent c4a6813 commit 2b41024

1 file changed

Lines changed: 121 additions & 51 deletions

File tree

nixos/modules/services/continuous-integration/forgejo-runner.nix

Lines changed: 121 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,48 @@ let
3636

3737
instanceLabels =
3838
instance:
39-
instance.labels
40-
++ lib.concatMap (connection: connection.labels or [ ]) (
39+
(lib.defaultTo [ ] instance.labels)
40+
++ lib.concatMap (connection: lib.defaultTo [ ] (connection.labels or [ ])) (
4141
lib.attrValues (instance.settings.server.connections or { })
4242
);
4343

4444
hasDockerScheme = labels: any (label: hasInfix ":docker:" label) labels;
4545
hasHostScheme = labels: any (label: hasSuffix ":host" label) labels;
4646

47-
wantsContainerRuntime = any (instance: hasDockerScheme (instanceLabels instance)) (
48-
lib.attrValues cfg.instances
49-
);
50-
5147
hasDocker = config.virtualisation.docker.enable;
5248
hasPodman = config.virtualisation.podman.enable;
49+
50+
labelsOption = mkOption {
51+
type = types.nullOr (types.listOf types.str);
52+
default = null;
53+
example = literalExpression ''
54+
[
55+
# provide a debian base with nodejs for actions
56+
"debian-latest:docker://node:18-bullseye"
57+
# fake the ubuntu name, because node provides no ubuntu builds
58+
"ubuntu-latest:docker://node:18-bullseye"
59+
# provide native execution on the host
60+
#"native:host"
61+
]
62+
'';
63+
description = ''
64+
Labels used to map jobs to their runtime environment. Changing these
65+
labels currently requires a new registration token.
66+
67+
Many common actions require bash, git and nodejs, as well as a filesystem
68+
that follows the filesystem hierarchy standard.
69+
'';
70+
};
71+
urlOption = mkOption {
72+
type = types.nullOr types.str;
73+
default = null;
74+
example = "https://forge.example.com";
75+
description = ''
76+
Base URL of your Forgejo instance.
77+
78+
Can also be specified in `settings.servier.connections`
79+
'';
80+
};
5381
in
5482
{
5583
meta.maintainers = teams.forgejo.members;
@@ -67,30 +95,22 @@ in
6795
{ name, ... }:
6896
{
6997
options = {
98+
labels = labelsOption;
7099
enable = mkEnableOption "Forgejo Actions Runner instance";
71100

72101
name = mkOption {
73-
type = str;
102+
type = types.str;
74103
example = literalExpression "config.networking.hostName";
75104
description = ''
76105
The name identifying the runner instance towards the Forgejo instance.
77106
'';
78107
default = name;
79108
};
80109

81-
url = mkOption {
82-
type = nullOr str;
83-
default = null;
84-
example = "https://forge.example.com";
85-
description = ''
86-
Base URL of your Forgejo instance.
87-
88-
Can also be specified in `settings.servier.connections`
89-
'';
90-
};
110+
url = urlOption;
91111

92112
registrationTokenFile = mkOption {
93-
type = nullOr (either str path);
113+
type = types.nullOr (types.either types.str types.path);
94114
default = null;
95115
description = ''
96116
Path to a file containing only the token that will be used to register
@@ -102,37 +122,19 @@ in
102122
'';
103123
};
104124

105-
credentials = lib.mkOption {
106-
type = attrsOf lib.types.path;
125+
credentials = mkOption {
126+
type = types.attrsOf types.path;
107127
default = { };
108128
example = {
109129
WORKER1_TOKEN = "/run/keys/worker1";
110130
};
111131
description = ''
112132
Environment variables with absolute paths to credentials files to load
113133
on runner startup.
114-
'';
115-
};
116134
117-
labels = mkOption {
118-
type = listOf str;
119-
default = [ ];
120-
example = literalExpression ''
121-
[
122-
# provide a debian base with nodejs for actions
123-
"debian-latest:docker://node:18-bullseye"
124-
# fake the ubuntu name, because node provides no ubuntu builds
125-
"ubuntu-latest:docker://node:18-bullseye"
126-
# provide native execution on the host
127-
#"native:host"
128-
]
129-
'';
130-
description = ''
131-
Labels used to map jobs to their runtime environment. Changing these
132-
labels currently requires a new registration token.
135+
Use with Forgejo v15+ pre-registered server connections:
133136
134-
Many common actions require bash, git and nodejs, as well as a filesystem
135-
that follows the filesystem hierarchy standard.
137+
`settings.server.connections.<connection>.token_url = "file:$CREDENTIALS_DIRECTORY/WORKER1_TOKEN"`
136138
'';
137139
};
138140

@@ -144,13 +146,56 @@ in
144146

145147
type = types.submodule {
146148
freeformType = settingsFormat.type;
149+
150+
options.server.connections = mkOption {
151+
type = types.attrsOf (
152+
types.submodule {
153+
freeformType = settingsFormat.type;
154+
options = {
155+
url = urlOption;
156+
labels = labelsOption;
157+
token_url = mkOption {
158+
type = types.either types.str types.path;
159+
description = ''
160+
Path to the Forgejo v15+ pre-registered runner token.
161+
Supports a single placeholder: `$CREDENTIALS_DIRECTORY`
162+
163+
Can be combined with `instances.<instance>.credentails`
164+
165+
<https://forgejo.org/docs/latest/admin/actions/registration/>
166+
'';
167+
};
168+
};
169+
}
170+
);
171+
default = { };
172+
description = ''
173+
Forgejo v15+ pre-registered server connections.
174+
175+
See <https://forgejo.org/docs/latest/admin/actions/registration>
176+
'';
177+
example = literalExpression ''
178+
{
179+
worker1 = {
180+
url = "https://forgejo.mine";
181+
uuid = "4708f0f2-4185-49b4-8552-bc7261ec26aa";
182+
token_url = "file:$CREDENTIALS_DIRECTORY/WORKER1_TOKEN";
183+
labels = [
184+
"debian:docker://docker.io/library/node:lts"
185+
"local/x86_64-linux:host"
186+
];
187+
};
188+
};
189+
'';
190+
};
191+
147192
};
148193

149194
default = { };
150195
};
151196

152197
hostPackages = mkOption {
153-
type = listOf package;
198+
type = types.listOf types.package;
154199
default = with pkgs; [
155200
bash
156201
coreutils
@@ -186,22 +231,47 @@ in
186231
};
187232

188233
config = mkIf (cfg.instances != { }) {
189-
assertions = [
190-
{
191-
assertion = wantsContainerRuntime -> hasDocker || hasPodman;
192-
message = "Label configuration on forgejo.runner instance requires either docker or podman.";
193-
}
194-
]
195-
++ (lib.foldlAttrs (
196-
acc: _: instance:
197-
acc
234+
assertions = lib.foldlAttrs (
235+
acc_inst: _: instance:
236+
(lib.foldlAttrs (
237+
acc_conn: name: connection:
238+
acc_conn
239+
++ [
240+
{
241+
assertion = connection.url != null;
242+
message = "forgejo.runner.instances.${instance.name}.settings.server.connections.${name} requires `url` to be set.";
243+
}
244+
{
245+
assertion = !(connection ? token);
246+
message = "forgejo.runner.instances.${instance.name}.settings.server.connections.${name}.token cannot be used, use token_url instead.";
247+
}
248+
{
249+
assertion = connection ? uuid;
250+
message = "forgejo.runner.instances.${instance.name}.settings.server.connections.${name}.uuid is required.";
251+
}
252+
]
253+
) acc_inst instance.settings.server.connections)
198254
++ [
255+
{
256+
assertion =
257+
instance.settings.server.connections != { }
258+
-> instance.registrationTokenFile == null && instance.url == null && instance.labels == null;
259+
message = "forgejo.runner.instances.${instance.name} cannot contain both url/registrationTokenFile and settings.server.connections";
260+
}
199261
{
200262
assertion = instance.registrationTokenFile != null -> instance.url != null;
201263
message = "forgejo.runner.instances.${instance.name}.registrationTokenFile requires `url` to be set.";
202264
}
265+
{
266+
assertion = instance.labels != null -> instance.registrationTokenFile != null;
267+
message = "forgejo.runner.instances.${instance.name}.labels requires `registrationTokenFile` to be set.";
268+
}
269+
{
270+
assertion = hasDockerScheme (instanceLabels instance) -> hasDocker || hasPodman;
271+
message = "forgejo.runner.instances.${instance.name} label configuration requires either docker or podman.";
272+
}
203273
]
204-
) [ ] cfg.instances);
274+
) [ ] cfg.instances;
205275

206276
systemd.services =
207277
let

0 commit comments

Comments
 (0)