|
36 | 36 |
|
37 | 37 | instanceLabels = |
38 | 38 | 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 [ ])) ( |
41 | 41 | lib.attrValues (instance.settings.server.connections or { }) |
42 | 42 | ); |
43 | 43 |
|
44 | 44 | hasDockerScheme = labels: any (label: hasInfix ":docker:" label) labels; |
45 | 45 | hasHostScheme = labels: any (label: hasSuffix ":host" label) labels; |
46 | 46 |
|
47 | | - wantsContainerRuntime = any (instance: hasDockerScheme (instanceLabels instance)) ( |
48 | | - lib.attrValues cfg.instances |
49 | | - ); |
50 | | - |
51 | 47 | hasDocker = config.virtualisation.docker.enable; |
52 | 48 | 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 | + }; |
53 | 81 | in |
54 | 82 | { |
55 | 83 | meta.maintainers = teams.forgejo.members; |
|
67 | 95 | { name, ... }: |
68 | 96 | { |
69 | 97 | options = { |
| 98 | + labels = labelsOption; |
70 | 99 | enable = mkEnableOption "Forgejo Actions Runner instance"; |
71 | 100 |
|
72 | 101 | name = mkOption { |
73 | | - type = str; |
| 102 | + type = types.str; |
74 | 103 | example = literalExpression "config.networking.hostName"; |
75 | 104 | description = '' |
76 | 105 | The name identifying the runner instance towards the Forgejo instance. |
77 | 106 | ''; |
78 | 107 | default = name; |
79 | 108 | }; |
80 | 109 |
|
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; |
91 | 111 |
|
92 | 112 | registrationTokenFile = mkOption { |
93 | | - type = nullOr (either str path); |
| 113 | + type = types.nullOr (types.either types.str types.path); |
94 | 114 | default = null; |
95 | 115 | description = '' |
96 | 116 | Path to a file containing only the token that will be used to register |
|
102 | 122 | ''; |
103 | 123 | }; |
104 | 124 |
|
105 | | - credentials = lib.mkOption { |
106 | | - type = attrsOf lib.types.path; |
| 125 | + credentials = mkOption { |
| 126 | + type = types.attrsOf types.path; |
107 | 127 | default = { }; |
108 | 128 | example = { |
109 | 129 | WORKER1_TOKEN = "/run/keys/worker1"; |
110 | 130 | }; |
111 | 131 | description = '' |
112 | 132 | Environment variables with absolute paths to credentials files to load |
113 | 133 | on runner startup. |
114 | | - ''; |
115 | | - }; |
116 | 134 |
|
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: |
133 | 136 |
|
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"` |
136 | 138 | ''; |
137 | 139 | }; |
138 | 140 |
|
|
144 | 146 |
|
145 | 147 | type = types.submodule { |
146 | 148 | 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 | + |
147 | 192 | }; |
148 | 193 |
|
149 | 194 | default = { }; |
150 | 195 | }; |
151 | 196 |
|
152 | 197 | hostPackages = mkOption { |
153 | | - type = listOf package; |
| 198 | + type = types.listOf types.package; |
154 | 199 | default = with pkgs; [ |
155 | 200 | bash |
156 | 201 | coreutils |
|
186 | 231 | }; |
187 | 232 |
|
188 | 233 | 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) |
198 | 254 | ++ [ |
| 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 | + } |
199 | 261 | { |
200 | 262 | assertion = instance.registrationTokenFile != null -> instance.url != null; |
201 | 263 | message = "forgejo.runner.instances.${instance.name}.registrationTokenFile requires `url` to be set."; |
202 | 264 | } |
| 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 | + } |
203 | 273 | ] |
204 | | - ) [ ] cfg.instances); |
| 274 | + ) [ ] cfg.instances; |
205 | 275 |
|
206 | 276 | systemd.services = |
207 | 277 | let |
|
0 commit comments