]> Git — Sourcephile - sourcephile-nix.git/blob - nixpkgs/patches/sourcehut.diff
nix: update nixpkgs
[sourcephile-nix.git] / nixpkgs / patches / sourcehut.diff
1 diff --git a/nixos/lib/make-options-doc/options-to-docbook.xsl b/nixos/lib/make-options-doc/options-to-docbook.xsl
2 index 18d19fddaca..304698a51ad 100644
3 --- a/nixos/lib/make-options-doc/options-to-docbook.xsl
4 +++ b/nixos/lib/make-options-doc/options-to-docbook.xsl
5 @@ -20,7 +20,7 @@
6 <title>Configuration Options</title>
7 <variablelist xml:id="configuration-variable-list">
8 <xsl:for-each select="attrs">
9 - <xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'))" />
10 + <xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '&lt;', '_'), '>', '_'), ':', '_'))" />
11 <varlistentry>
12 <term xlink:href="#{$id}">
13 <xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
14 diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix
15 index 1b9358c81a1..b6ff355f58b 100644
16 --- a/nixos/modules/services/databases/redis.nix
17 +++ b/nixos/modules/services/databases/redis.nix
18 @@ -5,17 +5,18 @@ with lib;
19 let
20 cfg = config.services.redis;
21
22 - ulimitNofile = cfg.maxclients + 32;
23 -
24 mkValueString = value:
25 if value == true then "yes"
26 else if value == false then "no"
27 else generators.mkValueStringDefault { } value;
28
29 - redisConfig = pkgs.writeText "redis.conf" (generators.toKeyValue {
30 + redisConfig = settings: pkgs.writeText "redis.conf" (generators.toKeyValue {
31 listsAsDuplicateKeys = true;
32 mkKeyValue = generators.mkKeyValueDefault { inherit mkValueString; } " ";
33 - } cfg.settings);
34 + } settings);
35 +
36 + redisName = name: "redis" + optionalString (name != "") ("-"+name);
37 + enabledServers = filterAttrs (name: conf: conf.enable) config.services.redis.servers;
38
39 in {
40 imports = [
41 @@ -25,6 +26,27 @@ in {
42 (mkRemovedOptionModule [ "services" "redis" "appendOnlyFilename" ] "This option was never used.")
43 (mkRemovedOptionModule [ "services" "redis" "pidFile" ] "This option was removed.")
44 (mkRemovedOptionModule [ "services" "redis" "extraConfig" ] "Use services.redis.settings instead.")
45 + (mkRenamedOptionModule [ "services" "redis" "enable"] [ "services" "redis" "servers" "" "enable" ])
46 + (mkRenamedOptionModule [ "services" "redis" "port"] [ "services" "redis" "servers" "" "port" ])
47 + (mkRenamedOptionModule [ "services" "redis" "openFirewall"] [ "services" "redis" "servers" "" "openFirewall" ])
48 + (mkRenamedOptionModule [ "services" "redis" "bind"] [ "services" "redis" "servers" "" "bind" ])
49 + (mkRenamedOptionModule [ "services" "redis" "unixSocket"] [ "services" "redis" "servers" "" "unixSocket" ])
50 + (mkRenamedOptionModule [ "services" "redis" "unixSocketPerm"] [ "services" "redis" "servers" "" "unixSocketPerm" ])
51 + (mkRenamedOptionModule [ "services" "redis" "logLevel"] [ "services" "redis" "servers" "" "logLevel" ])
52 + (mkRenamedOptionModule [ "services" "redis" "logfile"] [ "services" "redis" "servers" "" "logfile" ])
53 + (mkRenamedOptionModule [ "services" "redis" "syslog"] [ "services" "redis" "servers" "" "syslog" ])
54 + (mkRenamedOptionModule [ "services" "redis" "databases"] [ "services" "redis" "servers" "" "databases" ])
55 + (mkRenamedOptionModule [ "services" "redis" "maxclients"] [ "services" "redis" "servers" "" "maxclients" ])
56 + (mkRenamedOptionModule [ "services" "redis" "save"] [ "services" "redis" "servers" "" "save" ])
57 + (mkRenamedOptionModule [ "services" "redis" "slaveOf"] [ "services" "redis" "servers" "" "slaveOf" ])
58 + (mkRenamedOptionModule [ "services" "redis" "masterAuth"] [ "services" "redis" "servers" "" "masterAuth" ])
59 + (mkRenamedOptionModule [ "services" "redis" "requirePass"] [ "services" "redis" "servers" "" "requirePass" ])
60 + (mkRenamedOptionModule [ "services" "redis" "requirePassFile"] [ "services" "redis" "servers" "" "requirePassFile" ])
61 + (mkRenamedOptionModule [ "services" "redis" "appendOnly"] [ "services" "redis" "servers" "" "appendOnly" ])
62 + (mkRenamedOptionModule [ "services" "redis" "appendFsync"] [ "services" "redis" "servers" "" "appendFsync" ])
63 + (mkRenamedOptionModule [ "services" "redis" "slowLogLogSlowerThan"] [ "services" "redis" "servers" "" "slowLogLogSlowerThan" ])
64 + (mkRenamedOptionModule [ "services" "redis" "slowLogMaxLen"] [ "services" "redis" "servers" "" "slowLogMaxLen" ])
65 + (mkRenamedOptionModule [ "services" "redis" "settings"] [ "services" "redis" "servers" "" "settings" ])
66 ];
67
68 ###### interface
69 @@ -32,18 +54,6 @@ in {
70 options = {
71
72 services.redis = {
73 -
74 - enable = mkOption {
75 - type = types.bool;
76 - default = false;
77 - description = ''
78 - Whether to enable the Redis server. Note that the NixOS module for
79 - Redis disables kernel support for Transparent Huge Pages (THP),
80 - because this features causes major performance problems for Redis,
81 - e.g. (https://redis.io/topics/latency).
82 - '';
83 - };
84 -
85 package = mkOption {
86 type = types.package;
87 default = pkgs.redis;
88 @@ -51,177 +61,227 @@ in {
89 description = "Which Redis derivation to use.";
90 };
91
92 - port = mkOption {
93 - type = types.port;
94 - default = 6379;
95 - description = "The port for Redis to listen to.";
96 - };
97 + vmOverCommit = mkEnableOption ''
98 + setting of vm.overcommit_memory to 1
99 + (Suggested for Background Saving: http://redis.io/topics/faq)
100 + '';
101
102 - vmOverCommit = mkOption {
103 - type = types.bool;
104 - default = false;
105 - description = ''
106 - Set vm.overcommit_memory to 1 (Suggested for Background Saving: http://redis.io/topics/faq)
107 - '';
108 - };
109 -
110 - openFirewall = mkOption {
111 - type = types.bool;
112 - default = false;
113 - description = ''
114 - Whether to open ports in the firewall for the server.
115 - '';
116 - };
117 -
118 - bind = mkOption {
119 - type = with types; nullOr str;
120 - default = "127.0.0.1";
121 - description = ''
122 - The IP interface to bind to.
123 - <literal>null</literal> means "all interfaces".
124 - '';
125 - example = "192.0.2.1";
126 - };
127 -
128 - unixSocket = mkOption {
129 - type = with types; nullOr path;
130 - default = null;
131 - description = "The path to the socket to bind to.";
132 - example = "/run/redis/redis.sock";
133 - };
134 -
135 - unixSocketPerm = mkOption {
136 - type = types.int;
137 - default = 750;
138 - description = "Change permissions for the socket";
139 - example = 700;
140 - };
141 -
142 - logLevel = mkOption {
143 - type = types.str;
144 - default = "notice"; # debug, verbose, notice, warning
145 - example = "debug";
146 - description = "Specify the server verbosity level, options: debug, verbose, notice, warning.";
147 - };
148 -
149 - logfile = mkOption {
150 - type = types.str;
151 - default = "/dev/null";
152 - description = "Specify the log file name. Also 'stdout' can be used to force Redis to log on the standard output.";
153 - example = "/var/log/redis.log";
154 - };
155 -
156 - syslog = mkOption {
157 - type = types.bool;
158 - default = true;
159 - description = "Enable logging to the system logger.";
160 - };
161 -
162 - databases = mkOption {
163 - type = types.int;
164 - default = 16;
165 - description = "Set the number of databases.";
166 - };
167 -
168 - maxclients = mkOption {
169 - type = types.int;
170 - default = 10000;
171 - description = "Set the max number of connected clients at the same time.";
172 - };
173 -
174 - save = mkOption {
175 - type = with types; listOf (listOf int);
176 - default = [ [900 1] [300 10] [60 10000] ];
177 - description = "The schedule in which data is persisted to disk, represented as a list of lists where the first element represent the amount of seconds and the second the number of changes.";
178 - example = [ [900 1] [300 10] [60 10000] ];
179 - };
180 -
181 - slaveOf = mkOption {
182 - type = with types; nullOr (submodule ({ ... }: {
183 + servers = mkOption {
184 + type = with types; attrsOf (submodule ({config, name, ...}@args: {
185 options = {
186 - ip = mkOption {
187 - type = str;
188 - description = "IP of the Redis master";
189 - example = "192.168.1.100";
190 + enable = mkEnableOption ''
191 + Redis server.
192 +
193 + Note that the NixOS module for Redis disables kernel support
194 + for Transparent Huge Pages (THP),
195 + because this features causes major performance problems for Redis,
196 + e.g. (https://redis.io/topics/latency).
197 + '';
198 +
199 + user = mkOption {
200 + type = types.str;
201 + default = redisName name;
202 + defaultText = "\"redis\" or \"redis-\${name}\" if name != \"\"";
203 + description = "The username and groupname for redis-server.";
204 };
205
206 port = mkOption {
207 - type = port;
208 - description = "port of the Redis master";
209 + type = types.port;
210 default = 6379;
211 + description = "The port for Redis to listen to.";
212 + };
213 +
214 + openFirewall = mkOption {
215 + type = types.bool;
216 + default = false;
217 + description = ''
218 + Whether to open ports in the firewall for the server.
219 + '';
220 + };
221 +
222 + bind = mkOption {
223 + type = with types; nullOr str;
224 + default = if name == "" then "127.0.0.1" else null;
225 + defaultText = "127.0.0.1 or null if name != \"\"";
226 + description = ''
227 + The IP interface to bind to.
228 + <literal>null</literal> means "all interfaces".
229 + '';
230 + example = "192.0.2.1";
231 + };
232 +
233 + unixSocket = mkOption {
234 + type = with types; nullOr path;
235 + default = "/run/${redisName name}/redis.sock";
236 + defaultText = "\"/run/redis/redis.sock\" or \"/run/redis-\${name}/redis.sock\" if name != \"\"";
237 + description = "The path to the socket to bind to.";
238 + };
239 +
240 + unixSocketPerm = mkOption {
241 + type = types.int;
242 + default = 660;
243 + description = "Change permissions for the socket";
244 + example = 600;
245 + };
246 +
247 + logLevel = mkOption {
248 + type = types.str;
249 + default = "notice"; # debug, verbose, notice, warning
250 + example = "debug";
251 + description = "Specify the server verbosity level, options: debug, verbose, notice, warning.";
252 + };
253 +
254 + logfile = mkOption {
255 + type = types.str;
256 + default = "/dev/null";
257 + description = "Specify the log file name. Also 'stdout' can be used to force Redis to log on the standard output.";
258 + example = "/var/log/redis.log";
259 + };
260 +
261 + syslog = mkOption {
262 + type = types.bool;
263 + default = true;
264 + description = "Enable logging to the system logger.";
265 + };
266 +
267 + databases = mkOption {
268 + type = types.int;
269 + default = 16;
270 + description = "Set the number of databases.";
271 + };
272 +
273 + maxclients = mkOption {
274 + type = types.int;
275 + default = 10000;
276 + description = "Set the max number of connected clients at the same time.";
277 + };
278 +
279 + save = mkOption {
280 + type = with types; listOf (listOf int);
281 + default = [ [900 1] [300 10] [60 10000] ];
282 + description = "The schedule in which data is persisted to disk, represented as a list of lists where the first element represent the amount of seconds and the second the number of changes.";
283 + example = [ [900 1] [300 10] [60 10000] ];
284 + };
285 +
286 + slaveOf = mkOption {
287 + type = with types; nullOr (submodule ({ ... }: {
288 + options = {
289 + ip = mkOption {
290 + type = str;
291 + description = "IP of the Redis master";
292 + example = "192.168.1.100";
293 + };
294 +
295 + port = mkOption {
296 + type = port;
297 + description = "port of the Redis master";
298 + default = 6379;
299 + };
300 + };
301 + }));
302 +
303 + default = null;
304 + description = "IP and port to which this redis instance acts as a slave.";
305 + example = { ip = "192.168.1.100"; port = 6379; };
306 + };
307 +
308 + masterAuth = mkOption {
309 + type = with types; nullOr str;
310 + default = null;
311 + description = ''If the master is password protected (using the requirePass configuration)
312 + it is possible to tell the slave to authenticate before starting the replication synchronization
313 + process, otherwise the master will refuse the slave request.
314 + (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)'';
315 + };
316 +
317 + requirePass = mkOption {
318 + type = with types; nullOr str;
319 + default = null;
320 + description = ''
321 + Password for database (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE).
322 + Use requirePassFile to store it outside of the nix store in a dedicated file.
323 + '';
324 + example = "letmein!";
325 + };
326 +
327 + requirePassFile = mkOption {
328 + type = with types; nullOr path;
329 + default = null;
330 + description = "File with password for the database.";
331 + example = "/run/keys/redis-password";
332 + };
333 +
334 + appendOnly = mkOption {
335 + type = types.bool;
336 + default = false;
337 + description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence.";
338 + };
339 +
340 + appendFsync = mkOption {
341 + type = types.str;
342 + default = "everysec"; # no, always, everysec
343 + description = "How often to fsync the append-only log, options: no, always, everysec.";
344 + };
345 +
346 + slowLogLogSlowerThan = mkOption {
347 + type = types.int;
348 + default = 10000;
349 + description = "Log queries whose execution take longer than X in milliseconds.";
350 + example = 1000;
351 + };
352 +
353 + slowLogMaxLen = mkOption {
354 + type = types.int;
355 + default = 128;
356 + description = "Maximum number of items to keep in slow log.";
357 + };
358 +
359 + settings = mkOption {
360 + # TODO: this should be converted to freeformType
361 + type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
362 + default = {};
363 + description = ''
364 + Redis configuration. Refer to
365 + <link xlink:href="https://redis.io/topics/config"/>
366 + for details on supported values.
367 + '';
368 + example = literalExample ''
369 + {
370 + loadmodule = [ "/path/to/my_module.so" "/path/to/other_module.so" ];
371 + }
372 + '';
373 };
374 };
375 + config.settings = mkMerge [
376 + {
377 + port = if config.bind == null then 0 else config.port;
378 + daemonize = false;
379 + supervised = "systemd";
380 + loglevel = config.logLevel;
381 + logfile = config.logfile;
382 + syslog-enabled = config.syslog;
383 + databases = config.databases;
384 + maxclients = config.maxclients;
385 + save = map (d: "${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}") config.save;
386 + dbfilename = "dump.rdb";
387 + dir = "/var/lib/${redisName name}";
388 + appendOnly = config.appendOnly;
389 + appendfsync = config.appendFsync;
390 + slowlog-log-slower-than = config.slowLogLogSlowerThan;
391 + slowlog-max-len = config.slowLogMaxLen;
392 + }
393 + (mkIf (config.bind != null) { bind = config.bind; })
394 + (mkIf (config.unixSocket != null) {
395 + unixsocket = config.unixSocket;
396 + unixsocketperm = toString config.unixSocketPerm;
397 + })
398 + (mkIf (config.slaveOf != null) { slaveof = "${config.slaveOf.ip} ${toString config.slaveOf.port}"; })
399 + (mkIf (config.masterAuth != null) { masterauth = config.masterAuth; })
400 + (mkIf (config.requirePass != null) { requirepass = config.requirePass; })
401 + ];
402 }));
403 -
404 - default = null;
405 - description = "IP and port to which this redis instance acts as a slave.";
406 - example = { ip = "192.168.1.100"; port = 6379; };
407 - };
408 -
409 - masterAuth = mkOption {
410 - type = with types; nullOr str;
411 - default = null;
412 - description = ''If the master is password protected (using the requirePass configuration)
413 - it is possible to tell the slave to authenticate before starting the replication synchronization
414 - process, otherwise the master will refuse the slave request.
415 - (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE)'';
416 - };
417 -
418 - requirePass = mkOption {
419 - type = with types; nullOr str;
420 - default = null;
421 - description = ''
422 - Password for database (STORED PLAIN TEXT, WORLD-READABLE IN NIX STORE).
423 - Use requirePassFile to store it outside of the nix store in a dedicated file.
424 - '';
425 - example = "letmein!";
426 - };
427 -
428 - requirePassFile = mkOption {
429 - type = with types; nullOr path;
430 - default = null;
431 - description = "File with password for the database.";
432 - example = "/run/keys/redis-password";
433 - };
434 -
435 - appendOnly = mkOption {
436 - type = types.bool;
437 - default = false;
438 - description = "By default data is only periodically persisted to disk, enable this option to use an append-only file for improved persistence.";
439 - };
440 -
441 - appendFsync = mkOption {
442 - type = types.str;
443 - default = "everysec"; # no, always, everysec
444 - description = "How often to fsync the append-only log, options: no, always, everysec.";
445 - };
446 -
447 - slowLogLogSlowerThan = mkOption {
448 - type = types.int;
449 - default = 10000;
450 - description = "Log queries whose execution take longer than X in milliseconds.";
451 - example = 1000;
452 - };
453 -
454 - slowLogMaxLen = mkOption {
455 - type = types.int;
456 - default = 128;
457 - description = "Maximum number of items to keep in slow log.";
458 - };
459 -
460 - settings = mkOption {
461 - type = with types; attrsOf (oneOf [ bool int str (listOf str) ]);
462 + description = "Configuration of multiple <literal>redis-server</literal> instances.";
463 default = {};
464 - description = ''
465 - Redis configuration. Refer to
466 - <link xlink:href="https://redis.io/topics/config"/>
467 - for details on supported values.
468 - '';
469 - example = literalExample ''
470 - {
471 - loadmodule = [ "/path/to/my_module.so" "/path/to/other_module.so" ];
472 - }
473 - '';
474 };
475 };
476
477 @@ -230,78 +290,60 @@ in {
478
479 ###### implementation
480
481 - config = mkIf config.services.redis.enable {
482 - assertions = [{
483 - assertion = cfg.requirePass != null -> cfg.requirePassFile == null;
484 - message = "You can only set one services.redis.requirePass or services.redis.requirePassFile";
485 - }];
486 - boot.kernel.sysctl = (mkMerge [
487 + config = mkIf (enabledServers != {}) {
488 +
489 + assertions = attrValues (mapAttrs (name: conf: {
490 + assertion = conf.requirePass != null -> conf.requirePassFile == null;
491 + message = ''
492 + You can only set one services.redis.servers.${name}.requirePass
493 + or services.redis.servers.${name}.requirePassFile
494 + '';
495 + }) enabledServers);
496 +
497 + boot.kernel.sysctl = mkMerge [
498 { "vm.nr_hugepages" = "0"; }
499 ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } )
500 - ]);
501 + ];
502
503 - networking.firewall = mkIf cfg.openFirewall {
504 - allowedTCPPorts = [ cfg.port ];
505 - };
506 -
507 - users.users.redis = {
508 - description = "Redis database user";
509 - group = "redis";
510 - isSystemUser = true;
511 - };
512 - users.groups.redis = {};
513 + networking.firewall.allowedTCPPorts = concatMap (conf:
514 + optional conf.openFirewall conf.port
515 + ) (attrValues enabledServers);
516
517 environment.systemPackages = [ cfg.package ];
518
519 - services.redis.settings = mkMerge [
520 - {
521 - port = cfg.port;
522 - daemonize = false;
523 - supervised = "systemd";
524 - loglevel = cfg.logLevel;
525 - logfile = cfg.logfile;
526 - syslog-enabled = cfg.syslog;
527 - databases = cfg.databases;
528 - maxclients = cfg.maxclients;
529 - save = map (d: "${toString (builtins.elemAt d 0)} ${toString (builtins.elemAt d 1)}") cfg.save;
530 - dbfilename = "dump.rdb";
531 - dir = "/var/lib/redis";
532 - appendOnly = cfg.appendOnly;
533 - appendfsync = cfg.appendFsync;
534 - slowlog-log-slower-than = cfg.slowLogLogSlowerThan;
535 - slowlog-max-len = cfg.slowLogMaxLen;
536 - }
537 - (mkIf (cfg.bind != null) { bind = cfg.bind; })
538 - (mkIf (cfg.unixSocket != null) { unixsocket = cfg.unixSocket; unixsocketperm = "${toString cfg.unixSocketPerm}"; })
539 - (mkIf (cfg.slaveOf != null) { slaveof = "${cfg.slaveOf.ip} ${toString cfg.slaveOf.port}"; })
540 - (mkIf (cfg.masterAuth != null) { masterauth = cfg.masterAuth; })
541 - (mkIf (cfg.requirePass != null) { requirepass = cfg.requirePass; })
542 - ];
543 + users.users = mapAttrs' (name: conf: nameValuePair (redisName name) {
544 + description = "System user for the redis-server instance ${name}";
545 + isSystemUser = true;
546 + }) enabledServers;
547 + users.groups = mapAttrs' (name: conf: nameValuePair (redisName name) {
548 + }) enabledServers;
549
550 - systemd.services.redis = {
551 - description = "Redis Server";
552 + systemd.services = mapAttrs' (name: conf: nameValuePair (redisName name) {
553 + description = "Redis Server - ${redisName name}";
554
555 wantedBy = [ "multi-user.target" ];
556 after = [ "network.target" ];
557
558 - preStart = ''
559 - install -m 600 ${redisConfig} /run/redis/redis.conf
560 - '' + optionalString (cfg.requirePassFile != null) ''
561 - password=$(cat ${escapeShellArg cfg.requirePassFile})
562 - echo "requirePass $password" >> /run/redis/redis.conf
563 - '';
564 -
565 serviceConfig = {
566 - ExecStart = "${cfg.package}/bin/redis-server /run/redis/redis.conf";
567 + ExecStart = "${cfg.package}/bin/redis-server /run/${redisName name}/redis.conf";
568 + ExecStartPre = [("+"+pkgs.writeShellScript "${redisName name}-credentials" (''
569 + install -o '${conf.user}' -m 600 ${redisConfig conf.settings} /run/${redisName name}/redis.conf
570 + '' + optionalString (conf.requirePassFile != null) ''
571 + {
572 + printf requirePass' '
573 + cat ${escapeShellArg conf.requirePassFile}
574 + } >>/run/${redisName name}/redis.conf
575 + '')
576 + )];
577 Type = "notify";
578 # User and group
579 - User = "redis";
580 - Group = "redis";
581 + User = conf.user;
582 + Group = conf.user;
583 # Runtime directory and mode
584 - RuntimeDirectory = "redis";
585 + RuntimeDirectory = redisName name;
586 RuntimeDirectoryMode = "0750";
587 # State directory and mode
588 - StateDirectory = "redis";
589 + StateDirectory = redisName name;
590 StateDirectoryMode = "0700";
591 # Access write directories
592 UMask = "0077";
593 @@ -310,7 +352,7 @@ in {
594 # Security
595 NoNewPrivileges = true;
596 # Process Properties
597 - LimitNOFILE = "${toString ulimitNofile}";
598 + LimitNOFILE = mkDefault "${toString (conf.maxclients + 32)}";
599 # Sandboxing
600 ProtectSystem = "strict";
601 ProtectHome = true;
602 @@ -323,7 +365,9 @@ in {
603 ProtectKernelModules = true;
604 ProtectKernelTunables = true;
605 ProtectControlGroups = true;
606 - RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
607 + RestrictAddressFamilies =
608 + optionals (conf.bind != null) ["AF_INET" "AF_INET6"] ++
609 + optional (conf.unixSocket != null) "AF_UNIX";
610 RestrictNamespaces = true;
611 LockPersonality = true;
612 MemoryDenyWriteExecute = true;
613 @@ -334,6 +378,7 @@ in {
614 SystemCallArchitectures = "native";
615 SystemCallFilter = "~@cpu-emulation @debug @keyring @memlock @mount @obsolete @privileged @resources @setuid";
616 };
617 - };
618 + }) enabledServers;
619 +
620 };
621 }
622 diff --git a/nixos/modules/services/misc/sourcehut/builds.nix b/nixos/modules/services/misc/sourcehut/builds.nix
623 deleted file mode 100644
624 index e446f08284f..00000000000
625 --- a/nixos/modules/services/misc/sourcehut/builds.nix
626 +++ /dev/null
627 @@ -1,234 +0,0 @@
628 -{ config, lib, pkgs, ... }:
629 -
630 -with lib;
631 -let
632 - cfg = config.services.sourcehut;
633 - scfg = cfg.builds;
634 - rcfg = config.services.redis;
635 - iniKey = "builds.sr.ht";
636 -
637 - drv = pkgs.sourcehut.buildsrht;
638 -in
639 -{
640 - options.services.sourcehut.builds = {
641 - user = mkOption {
642 - type = types.str;
643 - default = "buildsrht";
644 - description = ''
645 - User for builds.sr.ht.
646 - '';
647 - };
648 -
649 - port = mkOption {
650 - type = types.port;
651 - default = 5002;
652 - description = ''
653 - Port on which the "builds" module should listen.
654 - '';
655 - };
656 -
657 - database = mkOption {
658 - type = types.str;
659 - default = "builds.sr.ht";
660 - description = ''
661 - PostgreSQL database name for builds.sr.ht.
662 - '';
663 - };
664 -
665 - statePath = mkOption {
666 - type = types.path;
667 - default = "${cfg.statePath}/buildsrht";
668 - description = ''
669 - State path for builds.sr.ht.
670 - '';
671 - };
672 -
673 - enableWorker = mkOption {
674 - type = types.bool;
675 - default = false;
676 - description = ''
677 - Run workers for builds.sr.ht.
678 - '';
679 - };
680 -
681 - images = mkOption {
682 - type = types.attrsOf (types.attrsOf (types.attrsOf types.package));
683 - default = { };
684 - example = lib.literalExample ''(let
685 - # Pinning unstable to allow usage with flakes and limit rebuilds.
686 - pkgs_unstable = builtins.fetchGit {
687 - url = "https://github.com/NixOS/nixpkgs";
688 - rev = "ff96a0fa5635770390b184ae74debea75c3fd534";
689 - ref = "nixos-unstable";
690 - };
691 - image_from_nixpkgs = pkgs_unstable: (import ("${pkgs.sourcehut.buildsrht}/lib/images/nixos/image.nix") {
692 - pkgs = (import pkgs_unstable {});
693 - });
694 - in
695 - {
696 - nixos.unstable.x86_64 = image_from_nixpkgs pkgs_unstable;
697 - }
698 - )'';
699 - description = ''
700 - Images for builds.sr.ht. Each package should be distro.release.arch and point to a /nix/store/package/root.img.qcow2.
701 - '';
702 - };
703 -
704 - };
705 -
706 - config = with scfg; let
707 - image_dirs = lib.lists.flatten (
708 - lib.attrsets.mapAttrsToList
709 - (distro: revs:
710 - lib.attrsets.mapAttrsToList
711 - (rev: archs:
712 - lib.attrsets.mapAttrsToList
713 - (arch: image:
714 - pkgs.runCommand "buildsrht-images" { } ''
715 - mkdir -p $out/${distro}/${rev}/${arch}
716 - ln -s ${image}/*.qcow2 $out/${distro}/${rev}/${arch}/root.img.qcow2
717 - '')
718 - archs)
719 - revs)
720 - scfg.images);
721 - image_dir_pre = pkgs.symlinkJoin {
722 - name = "builds.sr.ht-worker-images-pre";
723 - paths = image_dirs ++ [
724 - "${pkgs.sourcehut.buildsrht}/lib/images"
725 - ];
726 - };
727 - image_dir = pkgs.runCommand "builds.sr.ht-worker-images" { } ''
728 - mkdir -p $out/images
729 - cp -Lr ${image_dir_pre}/* $out/images
730 - '';
731 - in
732 - lib.mkIf (cfg.enable && elem "builds" cfg.services) {
733 - users = {
734 - users = {
735 - "${user}" = {
736 - isSystemUser = true;
737 - group = user;
738 - extraGroups = lib.optionals cfg.builds.enableWorker [ "docker" ];
739 - description = "builds.sr.ht user";
740 - };
741 - };
742 -
743 - groups = {
744 - "${user}" = { };
745 - };
746 - };
747 -
748 - services.postgresql = {
749 - authentication = ''
750 - local ${database} ${user} trust
751 - '';
752 - ensureDatabases = [ database ];
753 - ensureUsers = [
754 - {
755 - name = user;
756 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
757 - }
758 - ];
759 - };
760 -
761 - systemd = {
762 - tmpfiles.rules = [
763 - "d ${statePath} 0755 ${user} ${user} -"
764 - ] ++ (lib.optionals cfg.builds.enableWorker
765 - [ "d ${statePath}/logs 0775 ${user} ${user} - -" ]
766 - );
767 -
768 - services = {
769 - buildsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey
770 - {
771 - after = [ "postgresql.service" "network.target" ];
772 - requires = [ "postgresql.service" ];
773 - wantedBy = [ "multi-user.target" ];
774 -
775 - description = "builds.sr.ht website service";
776 -
777 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
778 -
779 - # Hack to bypass this hack: https://git.sr.ht/~sircmpwn/core.sr.ht/tree/master/item/srht-update-profiles#L6
780 - } // { preStart = " "; };
781 -
782 - buildsrht-worker = {
783 - enable = scfg.enableWorker;
784 - after = [ "postgresql.service" "network.target" ];
785 - requires = [ "postgresql.service" ];
786 - wantedBy = [ "multi-user.target" ];
787 - partOf = [ "buildsrht.service" ];
788 - description = "builds.sr.ht worker service";
789 - path = [ pkgs.openssh pkgs.docker ];
790 - preStart = let qemuPackage = pkgs.qemu_kvm;
791 - in ''
792 - if [[ "$(docker images -q qemu:latest 2> /dev/null)" == "" || "$(cat ${statePath}/docker-image-qemu 2> /dev/null || true)" != "${qemuPackage.version}" ]]; then
793 - # Create and import qemu:latest image for docker
794 - ${
795 - pkgs.dockerTools.streamLayeredImage {
796 - name = "qemu";
797 - tag = "latest";
798 - contents = [ qemuPackage ];
799 - }
800 - } | docker load
801 - # Mark down current package version
802 - printf "%s" "${qemuPackage.version}" > ${statePath}/docker-image-qemu
803 - fi
804 - '';
805 - serviceConfig = {
806 - Type = "simple";
807 - User = user;
808 - Group = "nginx";
809 - Restart = "always";
810 - };
811 - serviceConfig.ExecStart = "${pkgs.sourcehut.buildsrht}/bin/builds.sr.ht-worker";
812 - };
813 - };
814 - };
815 -
816 - services.sourcehut.settings = {
817 - # URL builds.sr.ht is being served at (protocol://domain)
818 - "builds.sr.ht".origin = mkDefault "http://builds.${cfg.originBase}";
819 - # Address and port to bind the debug server to
820 - "builds.sr.ht".debug-host = mkDefault "0.0.0.0";
821 - "builds.sr.ht".debug-port = mkDefault port;
822 - # Configures the SQLAlchemy connection string for the database.
823 - "builds.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
824 - # Set to "yes" to automatically run migrations on package upgrade.
825 - "builds.sr.ht".migrate-on-upgrade = mkDefault "yes";
826 - # builds.sr.ht's OAuth client ID and secret for meta.sr.ht
827 - # Register your client at meta.example.org/oauth
828 - "builds.sr.ht".oauth-client-id = mkDefault null;
829 - "builds.sr.ht".oauth-client-secret = mkDefault null;
830 - # The redis connection used for the celery worker
831 - "builds.sr.ht".redis = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/3";
832 - # The shell used for ssh
833 - "builds.sr.ht".shell = mkDefault "runner-shell";
834 - # Register the builds.sr.ht dispatcher
835 - "git.sr.ht::dispatch".${builtins.unsafeDiscardStringContext "${pkgs.sourcehut.buildsrht}/bin/buildsrht-keys"} = mkDefault "${user}:${user}";
836 -
837 - # Location for build logs, images, and control command
838 - } // lib.attrsets.optionalAttrs scfg.enableWorker {
839 - # Default worker stores logs that are accessible via this address:port
840 - "builds.sr.ht::worker".name = mkDefault "127.0.0.1:5020";
841 - "builds.sr.ht::worker".buildlogs = mkDefault "${scfg.statePath}/logs";
842 - "builds.sr.ht::worker".images = mkDefault "${image_dir}/images";
843 - "builds.sr.ht::worker".controlcmd = mkDefault "${image_dir}/images/control";
844 - "builds.sr.ht::worker".timeout = mkDefault "3m";
845 - };
846 -
847 - services.nginx.virtualHosts."logs.${cfg.originBase}" =
848 - if scfg.enableWorker then {
849 - listen = with builtins; let address = split ":" cfg.settings."builds.sr.ht::worker".name;
850 - in [{ addr = elemAt address 0; port = lib.toInt (elemAt address 2); }];
851 - locations."/logs".root = "${scfg.statePath}";
852 - } else { };
853 -
854 - services.nginx.virtualHosts."builds.${cfg.originBase}" = {
855 - forceSSL = true;
856 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
857 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
858 - locations."/static".root = "${pkgs.sourcehut.buildsrht}/${pkgs.sourcehut.python.sitePackages}/buildsrht";
859 - };
860 - };
861 -}
862 diff --git a/nixos/modules/services/misc/sourcehut/default.nix b/nixos/modules/services/misc/sourcehut/default.nix
863 index 9c812d6b043..6cea2ce6490 100644
864 --- a/nixos/modules/services/misc/sourcehut/default.nix
865 +++ b/nixos/modules/services/misc/sourcehut/default.nix
866 @@ -1,14 +1,90 @@
867 { config, pkgs, lib, ... }:
868 -
869 with lib;
870 let
871 + inherit (config.services) nginx postfix postgresql redis;
872 + inherit (config.users) users groups;
873 cfg = config.services.sourcehut;
874 - cfgIni = cfg.settings;
875 - settingsFormat = pkgs.formats.ini { };
876 + domain = cfg.settings."sr.ht".global-domain;
877 + settingsFormat = pkgs.formats.ini {
878 + listToValue = concatMapStringsSep "," (generators.mkValueStringDefault {});
879 + mkKeyValue = k: v:
880 + if v == null then ""
881 + else generators.mkKeyValueDefault {
882 + mkValueString = v:
883 + if v == true then "yes"
884 + else if v == false then "no"
885 + else generators.mkValueStringDefault {} v;
886 + } "=" k v;
887 + };
888 + configIniOfService = srv: settingsFormat.generate "sourcehut-${srv}-config.ini"
889 + # Each service needs access to only a subset of sections (and secrets).
890 + (filterAttrs (k: v: v != null)
891 + (mapAttrs (section: v:
892 + let srvMatch = builtins.match "^([a-z]*)\\.sr\\.ht(::.*)?$" section; in
893 + if srvMatch == null # Include sections shared by all services
894 + || head srvMatch == srv # Include sections for the service being configured
895 + then v
896 + # Enable Web links and integrations between services.
897 + else if tail srvMatch == [ null ] && elem (head srvMatch) cfg.services
898 + then {
899 + inherit (v) origin;
900 + # mansrht crashes without it
901 + oauth-client-id = v.oauth-client-id or null;
902 + }
903 + # Drop sub-sections of other services
904 + else null)
905 + (recursiveUpdate cfg.settings {
906 + # Those paths are mounted using BindPaths= or BindReadOnlyPaths=
907 + # for services needing access to them.
908 + "builds.sr.ht::worker".buildlogs = "/var/log/sourcehut/buildsrht/logs";
909 + "git.sr.ht".post-update-script = "/var/lib/sourcehut/gitsrht/bin/post-update-script";
910 + "git.sr.ht".repos = "/var/lib/sourcehut/gitsrht/repos";
911 + "hg.sr.ht".changegroup-script = "/var/lib/sourcehut/hgsrht/bin/changegroup-script";
912 + "hg.sr.ht".repos = "/var/lib/sourcehut/hgsrht/repos";
913 + # Making this a per service option despite being in a global section,
914 + # so that it uses the redis-server used by the service.
915 + "sr.ht".redis-host = cfg.${srv}.redis.host;
916 + })));
917 + commonServiceSettings = srv: {
918 + origin = mkOption {
919 + description = "URL ${srv}.sr.ht is being served at (protocol://domain)";
920 + type = types.str;
921 + default = "https://${srv}.${domain}";
922 + defaultText = "https://${srv}.example.com";
923 + };
924 + debug-host = mkOption {
925 + description = "Address to bind the debug server to.";
926 + type = with types; nullOr str;
927 + default = null;
928 + };
929 + debug-port = mkOption {
930 + description = "Port to bind the debug server to.";
931 + type = with types; nullOr str;
932 + default = null;
933 + };
934 + connection-string = mkOption {
935 + description = "SQLAlchemy connection string for the database.";
936 + type = types.str;
937 + default = "postgresql:///localhost?user=${srv}srht&host=/run/postgresql";
938 + };
939 + migrate-on-upgrade = mkEnableOption "automatic migrations on package upgrade" // { default = true; };
940 + oauth-client-id = mkOption {
941 + description = "${srv}.sr.ht's OAuth client id for meta.sr.ht.";
942 + type = types.str;
943 + };
944 + oauth-client-secret = mkOption {
945 + description = "${srv}.sr.ht's OAuth client secret for meta.sr.ht.";
946 + type = types.path;
947 + apply = s: "<" + toString s;
948 + };
949 + };
950
951 # Specialized python containing all the modules
952 python = pkgs.sourcehut.python.withPackages (ps: with ps; [
953 gunicorn
954 + eventlet
955 + # For monitoring Celery: sudo -u listssrht celery --app listssrht.process -b redis+socket:///run/redis-sourcehut/redis.sock?virtual_host=5 flower
956 + flower
957 # Sourcehut services
958 srht
959 buildsrht
960 @@ -19,69 +95,37 @@ let
961 listssrht
962 mansrht
963 metasrht
964 + # Not a python package
965 + #pagessrht
966 pastesrht
967 todosrht
968 ]);
969 + mkOptionNullOrStr = description: mkOption {
970 + inherit description;
971 + type = with types; nullOr str;
972 + default = null;
973 + };
974 in
975 {
976 - imports =
977 - [
978 - ./git.nix
979 - ./hg.nix
980 - ./hub.nix
981 - ./todo.nix
982 - ./man.nix
983 - ./meta.nix
984 - ./paste.nix
985 - ./builds.nix
986 - ./lists.nix
987 - ./dispatch.nix
988 - (mkRemovedOptionModule [ "services" "sourcehut" "nginx" "enable" ] ''
989 - The sourcehut module supports `nginx` as a local reverse-proxy by default and doesn't
990 - support other reverse-proxies officially.
991 -
992 - However it's possible to use an alternative reverse-proxy by
993 -
994 - * disabling nginx
995 - * adjusting the relevant settings for server addresses and ports directly
996 -
997 - Further details about this can be found in the `Sourcehut`-section of the NixOS-manual.
998 - '')
999 - ];
1000 -
1001 options.services.sourcehut = {
1002 - enable = mkOption {
1003 - type = types.bool;
1004 - default = false;
1005 - description = ''
1006 - Enable sourcehut - git hosting, continuous integration, mailing list, ticket tracking,
1007 - task dispatching, wiki and account management services
1008 - '';
1009 - };
1010 + enable = mkEnableOption ''
1011 + sourcehut - git hosting, continuous integration, mailing list, ticket tracking,
1012 + task dispatching, wiki and account management services
1013 + '';
1014
1015 services = mkOption {
1016 - type = types.nonEmptyListOf (types.enum [ "builds" "dispatch" "git" "hub" "hg" "lists" "man" "meta" "paste" "todo" ]);
1017 - default = [ "man" "meta" "paste" ];
1018 - example = [ "builds" "dispatch" "git" "hub" "hg" "lists" "man" "meta" "paste" "todo" ];
1019 + type = with types; listOf (enum
1020 + [ "builds" "dispatch" "git" "hg" "hub" "lists" "man" "meta" "pages" "paste" "todo" ]);
1021 + defaultText = "locally enabled services";
1022 description = ''
1023 - Services to enable on the sourcehut network.
1024 + Services that may be displayed as links in the title bar of the Web interface.
1025 '';
1026 };
1027
1028 - originBase = mkOption {
1029 + listenAddress = mkOption {
1030 type = types.str;
1031 - default = with config.networking; hostName + lib.optionalString (domain != null) ".${domain}";
1032 - description = ''
1033 - Host name used by reverse-proxy and for default settings. Will host services at git."''${originBase}". For example: git.sr.ht
1034 - '';
1035 - };
1036 -
1037 - address = mkOption {
1038 - type = types.str;
1039 - default = "127.0.0.1";
1040 - description = ''
1041 - Address to bind to.
1042 - '';
1043 + default = "localhost";
1044 + description = "Address to bind to.";
1045 };
1046
1047 python = mkOption {
1048 @@ -94,105 +138,1212 @@ in
1049 '';
1050 };
1051
1052 - statePath = mkOption {
1053 - type = types.path;
1054 - default = "/var/lib/sourcehut";
1055 - description = ''
1056 - Root state path for the sourcehut network. If left as the default value
1057 - this directory will automatically be created before the sourcehut server
1058 - starts, otherwise the sysadmin is responsible for ensuring the
1059 - directory exists with appropriate ownership and permissions.
1060 - '';
1061 + minio = {
1062 + enable = mkEnableOption ''local minio integration'';
1063 + };
1064 +
1065 + nginx = {
1066 + enable = mkEnableOption ''local nginx integration'';
1067 + virtualHost = mkOption {
1068 + type = types.attrs;
1069 + default = {};
1070 + description = "Virtual-host configuration merged with all Sourcehut's virtual-hosts.";
1071 + };
1072 + };
1073 +
1074 + postfix = {
1075 + enable = mkEnableOption ''local postfix integration'';
1076 + };
1077 +
1078 + postgresql = {
1079 + enable = mkEnableOption ''local postgresql integration'';
1080 + };
1081 +
1082 + redis = {
1083 + enable = mkEnableOption ''local redis integration in a dedicated redis-server'';
1084 };
1085
1086 settings = mkOption {
1087 type = lib.types.submodule {
1088 freeformType = settingsFormat.type;
1089 + options."sr.ht" = {
1090 + global-domain = mkOption {
1091 + description = "Global domain name.";
1092 + type = types.str;
1093 + example = "example.com";
1094 + };
1095 + environment = mkOption {
1096 + description = "Values other than \"production\" adds a banner to each page.";
1097 + type = types.enum [ "development" "production" ];
1098 + default = "development";
1099 + };
1100 + network-key = mkOption {
1101 + description = ''
1102 + An absolute file path (which should be outside the Nix-store)
1103 + to a secret key to encrypt internal messages with. Use <code>srht-keygen network</code> to
1104 + generate this key. It must be consistent between all services and nodes.
1105 + '';
1106 + type = types.path;
1107 + apply = s: "<" + toString s;
1108 + };
1109 + owner-email = mkOption {
1110 + description = "Owner's email.";
1111 + type = types.str;
1112 + default = "contact@example.com";
1113 + };
1114 + owner-name = mkOption {
1115 + description = "Owner's name.";
1116 + type = types.str;
1117 + default = "John Doe";
1118 + };
1119 + site-blurb = mkOption {
1120 + description = "Blurb for your site.";
1121 + type = types.str;
1122 + default = "the hacker's forge";
1123 + };
1124 + site-info = mkOption {
1125 + description = "The top-level info page for your site.";
1126 + type = types.str;
1127 + default = "https://sourcehut.org";
1128 + };
1129 + service-key = mkOption {
1130 + description = ''
1131 + An absolute file path (which should be outside the Nix-store)
1132 + to a key used for encrypting session cookies. Use <code>srht-keygen service</code> to
1133 + generate the service key. This must be shared between each node of the same
1134 + service (e.g. git1.sr.ht and git2.sr.ht), but different services may use
1135 + different keys. If you configure all of your services with the same
1136 + config.ini, you may use the same service-key for all of them.
1137 + '';
1138 + type = types.path;
1139 + apply = s: "<" + toString s;
1140 + };
1141 + site-name = mkOption {
1142 + description = "The name of your network of sr.ht-based sites.";
1143 + type = types.str;
1144 + default = "sourcehut";
1145 + };
1146 + source-url = mkOption {
1147 + description = "The source code for your fork of sr.ht.";
1148 + type = types.str;
1149 + default = "https://git.sr.ht/~sircmpwn/srht";
1150 + };
1151 + };
1152 + options.mail = {
1153 + smtp-host = mkOptionNullOrStr "Outgoing SMTP host.";
1154 + smtp-port = mkOption {
1155 + description = "Outgoing SMTP port.";
1156 + type = with types; nullOr port;
1157 + default = null;
1158 + };
1159 + smtp-user = mkOptionNullOrStr "Outgoing SMTP user.";
1160 + smtp-password = mkOptionNullOrStr "Outgoing SMTP password.";
1161 + smtp-from = mkOptionNullOrStr "Outgoing SMTP FROM.";
1162 + error-to = mkOptionNullOrStr "Address receiving application exceptions";
1163 + error-from = mkOptionNullOrStr "Address sending application exceptions";
1164 + pgp-privkey = mkOptionNullOrStr ''
1165 + An absolute file path (which should be outside the Nix-store)
1166 + to an OpenPGP private key.
1167 +
1168 + Your PGP key information (DO NOT mix up pub and priv here)
1169 + You must remove the password from your secret key, if present.
1170 + You can do this with <code>gpg --edit-key [key-id]</code>,
1171 + then use the <code>passwd</code> command and do not enter a new password.
1172 + '';
1173 + pgp-pubkey = mkOptionNullOrStr "OpenPGP public key.";
1174 + pgp-key-id = mkOptionNullOrStr "OpenPGP key identifier.";
1175 + };
1176 + options.objects = {
1177 + s3-upstream = mkOption {
1178 + description = "Configure the S3-compatible object storage service.";
1179 + type = with types; nullOr str;
1180 + default = null;
1181 + };
1182 + s3-access-key = mkOption {
1183 + description = "Access key to the S3-compatible object storage service";
1184 + type = with types; nullOr str;
1185 + default = null;
1186 + };
1187 + s3-secret-key = mkOption {
1188 + description = ''
1189 + An absolute file path (which should be outside the Nix-store)
1190 + to the secret key of the S3-compatible object storage service.
1191 + '';
1192 + type = with types; nullOr path;
1193 + default = null;
1194 + apply = mapNullable (s: "<" + toString s);
1195 + };
1196 + };
1197 + options.webhooks = {
1198 + private-key = mkOption {
1199 + description = ''
1200 + An absolute file path (which should be outside the Nix-store)
1201 + to a base64-encoded Ed25519 key for signing webhook payloads.
1202 + This should be consistent for all *.sr.ht sites,
1203 + as this key will be used to verify signatures
1204 + from other sites in your network.
1205 + Use the <code>srht-keygen webhook</code> command to generate a key.
1206 + '';
1207 + type = types.path;
1208 + apply = s: "<" + toString s;
1209 + };
1210 + };
1211 +
1212 + options."dispatch.sr.ht" = commonServiceSettings "dispatch" // {
1213 + };
1214 + options."dispatch.sr.ht::github" = {
1215 + oauth-client-id = mkOptionNullOrStr "OAuth client id.";
1216 + oauth-client-secret = mkOptionNullOrStr "OAuth client secret.";
1217 + };
1218 + options."dispatch.sr.ht::gitlab" = {
1219 + enabled = mkEnableOption "GitLab integration";
1220 + canonical-upstream = mkOption {
1221 + type = types.str;
1222 + description = "Canonical upstream.";
1223 + default = "gitlab.com";
1224 + };
1225 + repo-cache = mkOption {
1226 + type = types.str;
1227 + description = "Repository cache directory.";
1228 + default = "./repo-cache";
1229 + };
1230 + "gitlab.com" = mkOption {
1231 + type = with types; nullOr str;
1232 + description = "GitLab id and secret.";
1233 + default = null;
1234 + example = "GitLab:application id:secret";
1235 + };
1236 + };
1237 +
1238 + options."builds.sr.ht" = commonServiceSettings "builds" // {
1239 + allow-free = mkEnableOption "nonpaying users to submit builds";
1240 + redis = mkOption {
1241 + description = "The Redis connection used for the Celery worker.";
1242 + type = types.str;
1243 + default = "redis+socket:///run/redis-sourcehut-buildsrht/redis.sock?virtual_host=2";
1244 + };
1245 + shell = mkOption {
1246 + description = ''
1247 + Scripts used to launch on SSH connection.
1248 + <literal>/usr/bin/master-shell</literal> on master,
1249 + <literal>/usr/bin/runner-shell</literal> on runner.
1250 + If master and worker are on the same system
1251 + set to <literal>/usr/bin/runner-shell</literal>.
1252 + '';
1253 + type = types.enum ["/usr/bin/master-shell" "/usr/bin/runner-shell"];
1254 + default = "/usr/bin/master-shell";
1255 + };
1256 + };
1257 + options."builds.sr.ht::worker" = {
1258 + bind-address = mkOption {
1259 + description = ''
1260 + HTTP bind address for serving local build information/monitoring.
1261 + '';
1262 + type = types.str;
1263 + default = "localhost:8080";
1264 + };
1265 + buildlogs = mkOption {
1266 + description = "Path to write build logs.";
1267 + type = types.str;
1268 + default = "/var/log/sourcehut/buildsrht";
1269 + };
1270 + name = mkOption {
1271 + description = ''
1272 + Listening address and listening port
1273 + of the build runner (with HTTP port if not 80).
1274 + '';
1275 + type = types.str;
1276 + default = "localhost:5020";
1277 + };
1278 + timeout = mkOption {
1279 + description = ''
1280 + Max build duration.
1281 + See <link xlink:href="https://golang.org/pkg/time/#ParseDuration"/>.
1282 + '';
1283 + type = types.str;
1284 + default = "3m";
1285 + };
1286 + };
1287 +
1288 + options."git.sr.ht" = commonServiceSettings "git" // {
1289 + outgoing-domain = mkOption {
1290 + description = "Outgoing domain.";
1291 + type = types.str;
1292 + default = "https://git.localhost.localdomain";
1293 + };
1294 + post-update-script = mkOption {
1295 + description = ''
1296 + A post-update script which is installed in every git repo.
1297 + This setting is propagated to newer and existing repositories.
1298 + '';
1299 + type = types.path;
1300 + default = "${pkgs.sourcehut.gitsrht}/bin/gitsrht-update-hook";
1301 + defaultText = "\${pkgs.sourcehut.gitsrht}/bin/gitsrht-update-hook";
1302 + # Git hooks are run relative to their repository's directory,
1303 + # but gitsrht-update-hook looks up ../config.ini
1304 + apply = p: pkgs.writeShellScript "update-hook-wrapper" ''
1305 + set -e
1306 + test -e "''${PWD%/*}"/config.ini ||
1307 + ln -s /run/sourcehut/gitsrht/config.ini "''${PWD%/*}"/config.ini
1308 + exec -a "$0" '${p}' "$@"
1309 + '';
1310 + };
1311 + repos = mkOption {
1312 + description = ''
1313 + Path to git repositories on disk.
1314 + If changing the default, you must ensure that
1315 + the gitsrht's user as read and write access to it.
1316 + '';
1317 + type = types.str;
1318 + default = "/var/lib/sourcehut/gitsrht/repos";
1319 + };
1320 + webhooks = mkOption {
1321 + description = "The Redis connection used for the webhooks worker.";
1322 + type = types.str;
1323 + default = "redis+socket:///run/redis-sourcehut-gitsrht/redis.sock?virtual_host=1";
1324 + };
1325 + };
1326 + options."git.sr.ht::api" = {
1327 + internal-ipnet = mkOption {
1328 + description = ''
1329 + Set of IP subnets which are permitted to utilize internal API
1330 + authentication. This should be limited to the subnets
1331 + from which your *.sr.ht services are running.
1332 + See <xref linkend="opt-services.sourcehut.listenAddress"/>.
1333 + '';
1334 + type = with types; listOf str;
1335 + default = [ "127.0.0.0/8" "::1/128" ];
1336 + };
1337 + };
1338 +
1339 + options."hg.sr.ht" = commonServiceSettings "hg" // {
1340 + changegroup-script = mkOption {
1341 + description = ''
1342 + A changegroup script which is installed in every mercurial repo.
1343 + This setting is propagated to newer and existing repositories.
1344 + '';
1345 + type = types.str;
1346 + default = "${cfg.python}/bin/hgsrht-hook-changegroup";
1347 + defaultText = "\${cfg.python}/bin/hgsrht-hook-changegroup";
1348 + # Mercurial's changegroup hooks are run relative to their repository's directory,
1349 + # but hgsrht-hook-changegroup looks up ./config.ini
1350 + apply = p: pkgs.writeShellScript "hook-changegroup-wrapper" ''
1351 + set -e
1352 + test -e "''$PWD"/config.ini ||
1353 + ln -s /run/sourcehut/hgsrht/config.ini "''$PWD"/config.ini
1354 + exec -a "$0" '${p}' "$@"
1355 + '';
1356 + };
1357 + repos = mkOption {
1358 + description = ''
1359 + Path to mercurial repositories on disk.
1360 + If changing the default, you must ensure that
1361 + the hgsrht's user as read and write access to it.
1362 + '';
1363 + type = types.str;
1364 + default = "/var/lib/sourcehut/hgsrht/repos";
1365 + };
1366 + srhtext = mkOptionNullOrStr ''
1367 + Path to the srht mercurial extension
1368 + (defaults to where the hgsrht code is)
1369 + '';
1370 + clone_bundle_threshold = mkOption {
1371 + description = ".hg/store size (in MB) past which the nightly job generates clone bundles.";
1372 + type = types.ints.unsigned;
1373 + default = 50;
1374 + };
1375 + hg_ssh = mkOption {
1376 + description = "Path to hg-ssh (if not in $PATH).";
1377 + type = types.str;
1378 + default = "${pkgs.mercurial}/bin/hg-ssh";
1379 + defaultText = "\${pkgs.mercurial}/bin/hg-ssh";
1380 + };
1381 + webhooks = mkOption {
1382 + description = "The Redis connection used for the webhooks worker.";
1383 + type = types.str;
1384 + default = "redis+socket:///run/redis-sourcehut-hgsrht/redis.sock?virtual_host=1";
1385 + };
1386 + };
1387 +
1388 + options."hub.sr.ht" = commonServiceSettings "hub" // {
1389 + };
1390 +
1391 + options."lists.sr.ht" = commonServiceSettings "lists" // {
1392 + allow-new-lists = mkEnableOption "Allow creation of new lists.";
1393 + notify-from = mkOption {
1394 + description = "Outgoing email for notifications generated by users.";
1395 + type = types.str;
1396 + default = "lists-notify@localhost.localdomain";
1397 + };
1398 + posting-domain = mkOption {
1399 + description = "Posting domain.";
1400 + type = types.str;
1401 + default = "lists.localhost.localdomain";
1402 + };
1403 + redis = mkOption {
1404 + description = "The Redis connection used for the Celery worker.";
1405 + type = types.str;
1406 + default = "redis+socket:///run/redis-sourcehut-listssrht/redis.sock?virtual_host=2";
1407 + };
1408 + webhooks = mkOption {
1409 + description = "The Redis connection used for the webhooks worker.";
1410 + type = types.str;
1411 + default = "redis+socket:///run/redis-sourcehut-listssrht/redis.sock?virtual_host=1";
1412 + };
1413 + };
1414 + options."lists.sr.ht::worker" = {
1415 + reject-mimetypes = mkOption {
1416 + description = ''
1417 + Comma-delimited list of Content-Types to reject. Messages with Content-Types
1418 + included in this list are rejected. Multipart messages are always supported,
1419 + and each part is checked against this list.
1420 +
1421 + Uses fnmatch for wildcard expansion.
1422 + '';
1423 + type = with types; listOf str;
1424 + default = ["text/html"];
1425 + };
1426 + reject-url = mkOption {
1427 + description = "Reject URL.";
1428 + type = types.str;
1429 + default = "https://man.sr.ht/lists.sr.ht/etiquette.md";
1430 + };
1431 + sock = mkOption {
1432 + description = ''
1433 + Path for the lmtp daemon's unix socket. Direct incoming mail to this socket.
1434 + Alternatively, specify IP:PORT and an SMTP server will be run instead.
1435 + '';
1436 + type = types.str;
1437 + default = "/tmp/lists.sr.ht-lmtp.sock";
1438 + };
1439 + sock-group = mkOption {
1440 + description = ''
1441 + The lmtp daemon will make the unix socket group-read/write
1442 + for users in this group.
1443 + '';
1444 + type = types.str;
1445 + default = "postfix";
1446 + };
1447 + };
1448 +
1449 + options."man.sr.ht" = commonServiceSettings "man" // {
1450 + };
1451 +
1452 + options."meta.sr.ht" =
1453 + removeAttrs (commonServiceSettings "meta")
1454 + ["oauth-client-id" "oauth-client-secret"] // {
1455 + api-origin = mkOption {
1456 + description = "Origin URL for API, 100 more than web.";
1457 + type = types.str;
1458 + default = "http://${cfg.listenAddress}:${toString (cfg.meta.port + 100)}";
1459 + defaultText = ''http://<xref linkend="opt-services.sourcehut.listenAddress"/>:''${toString (<xref linkend="opt-services.sourcehut.meta.port"/> + 100)}'';
1460 + };
1461 + webhooks = mkOption {
1462 + description = "The Redis connection used for the webhooks worker.";
1463 + type = types.str;
1464 + default = "redis+socket:///run/redis-sourcehut-metasrht/redis.sock?virtual_host=1";
1465 + };
1466 + welcome-emails = mkEnableOption "sending stock sourcehut welcome emails after signup";
1467 + };
1468 + options."meta.sr.ht::api" = {
1469 + internal-ipnet = mkOption {
1470 + description = ''
1471 + Set of IP subnets which are permitted to utilize internal API
1472 + authentication. This should be limited to the subnets
1473 + from which your *.sr.ht services are running.
1474 + See <xref linkend="opt-services.sourcehut.listenAddress"/>.
1475 + '';
1476 + type = with types; listOf str;
1477 + default = [ "127.0.0.0/8" "::1/128" ];
1478 + };
1479 + };
1480 + options."meta.sr.ht::aliases" = mkOption {
1481 + description = "Aliases for the client IDs of commonly used OAuth clients.";
1482 + type = with types; attrsOf int;
1483 + default = {};
1484 + example = { "git.sr.ht" = 12345; };
1485 + };
1486 + options."meta.sr.ht::billing" = {
1487 + enabled = mkEnableOption "the billing system";
1488 + stripe-public-key = mkOptionNullOrStr "Public key for Stripe. Get your keys at https://dashboard.stripe.com/account/apikeys";
1489 + stripe-secret-key = mkOptionNullOrStr ''
1490 + An absolute file path (which should be outside the Nix-store)
1491 + to a secret key for Stripe. Get your keys at https://dashboard.stripe.com/account/apikeys
1492 + '' // {
1493 + apply = mapNullable (s: "<" + toString s);
1494 + };
1495 + };
1496 + options."meta.sr.ht::settings" = {
1497 + registration = mkEnableOption "public registration";
1498 + onboarding-redirect = mkOption {
1499 + description = "Where to redirect new users upon registration.";
1500 + type = types.str;
1501 + default = "https://meta.localhost.localdomain";
1502 + };
1503 + user-invites = mkOption {
1504 + description = ''
1505 + How many invites each user is issued upon registration
1506 + (only applicable if open registration is disabled).
1507 + '';
1508 + type = types.ints.unsigned;
1509 + default = 5;
1510 + };
1511 + };
1512 +
1513 + options."pages.sr.ht" = commonServiceSettings "pages" // {
1514 + gemini-certs = mkOption {
1515 + description = ''
1516 + An absolute file path (which should be outside the Nix-store)
1517 + to Gemini certificates.
1518 + '';
1519 + type = with types; nullOr path;
1520 + default = null;
1521 + };
1522 + max-site-size = mkOption {
1523 + description = "Maximum size of any given site (post-gunzip), in MiB.";
1524 + type = types.int;
1525 + default = 1024;
1526 + };
1527 + user-domain = mkOption {
1528 + description = ''
1529 + Configures the user domain, if enabled.
1530 + All users are given &lt;username&gt;.this.domain.
1531 + '';
1532 + type = with types; nullOr str;
1533 + default = null;
1534 + };
1535 + };
1536 + options."pages.sr.ht::api" = {
1537 + internal-ipnet = mkOption {
1538 + description = ''
1539 + Set of IP subnets which are permitted to utilize internal API
1540 + authentication. This should be limited to the subnets
1541 + from which your *.sr.ht services are running.
1542 + See <xref linkend="opt-services.sourcehut.listenAddress"/>.
1543 + '';
1544 + type = with types; listOf str;
1545 + default = [ "127.0.0.0/8" "::1/128" ];
1546 + };
1547 + };
1548 +
1549 + options."paste.sr.ht" = commonServiceSettings "paste" // {
1550 + };
1551 +
1552 + options."todo.sr.ht" = commonServiceSettings "todo" // {
1553 + notify-from = mkOption {
1554 + description = "Outgoing email for notifications generated by users.";
1555 + type = types.str;
1556 + default = "todo-notify@localhost.localdomain";
1557 + };
1558 + webhooks = mkOption {
1559 + description = "The Redis connection used for the webhooks worker.";
1560 + type = types.str;
1561 + default = "redis+socket:///run/redis-sourcehut-todosrht/redis.sock?virtual_host=1";
1562 + };
1563 + };
1564 + options."todo.sr.ht::mail" = {
1565 + posting-domain = mkOption {
1566 + description = "Posting domain.";
1567 + type = types.str;
1568 + default = "todo.localhost.localdomain";
1569 + };
1570 + sock = mkOption {
1571 + description = ''
1572 + Path for the lmtp daemon's unix socket. Direct incoming mail to this socket.
1573 + Alternatively, specify IP:PORT and an SMTP server will be run instead.
1574 + '';
1575 + type = types.str;
1576 + default = "/tmp/todo.sr.ht-lmtp.sock";
1577 + };
1578 + sock-group = mkOption {
1579 + description = ''
1580 + The lmtp daemon will make the unix socket group-read/write
1581 + for users in this group.
1582 + '';
1583 + type = types.str;
1584 + default = "postfix";
1585 + };
1586 + };
1587 };
1588 default = { };
1589 description = ''
1590 The configuration for the sourcehut network.
1591 '';
1592 };
1593 - };
1594
1595 - config = mkIf cfg.enable {
1596 - assertions =
1597 - [
1598 - {
1599 - assertion = with cfgIni.webhooks; private-key != null && stringLength private-key == 44;
1600 - message = "The webhook's private key must be defined and of a 44 byte length.";
1601 - }
1602 + builds = {
1603 + enableWorker = mkEnableOption "worker for builds.sr.ht";
1604
1605 - {
1606 - assertion = hasAttrByPath [ "meta.sr.ht" "origin" ] cfgIni && cfgIni."meta.sr.ht".origin != null;
1607 - message = "meta.sr.ht's origin must be defined.";
1608 - }
1609 - ];
1610 + images = mkOption {
1611 + type = with types; attrsOf (attrsOf (attrsOf package));
1612 + default = { };
1613 + example = lib.literalExample ''(let
1614 + # Pinning unstable to allow usage with flakes and limit rebuilds.
1615 + pkgs_unstable = builtins.fetchGit {
1616 + url = "https://github.com/NixOS/nixpkgs";
1617 + rev = "ff96a0fa5635770390b184ae74debea75c3fd534";
1618 + ref = "nixos-unstable";
1619 + };
1620 + image_from_nixpkgs = (import ("${pkgs.sourcehut.buildsrht}/lib/images/nixos/image.nix") {
1621 + pkgs = (import pkgs_unstable {});
1622 + });
1623 + in
1624 + {
1625 + nixos.unstable.x86_64 = image_from_nixpkgs;
1626 + }
1627 + )'';
1628 + description = ''
1629 + Images for builds.sr.ht. Each package should be distro.release.arch and point to a /nix/store/package/root.img.qcow2.
1630 + '';
1631 + };
1632 + };
1633
1634 - virtualisation.docker.enable = true;
1635 - environment.etc."sr.ht/config.ini".source =
1636 - settingsFormat.generate "sourcehut-config.ini" (mapAttrsRecursive
1637 - (
1638 - path: v: if v == null then "" else v
1639 - )
1640 - cfg.settings);
1641 + git = {
1642 + package = mkOption {
1643 + type = types.package;
1644 + default = pkgs.git;
1645 + example = literalExample "pkgs.gitFull";
1646 + description = ''
1647 + Git package for git.sr.ht. This can help silence collisions.
1648 + '';
1649 + };
1650 + fcgiwrap.preforkProcess = mkOption {
1651 + description = "Number of fcgiwrap processes to prefork.";
1652 + type = types.int;
1653 + default = 4;
1654 + };
1655 + };
1656
1657 - environment.systemPackages = [ pkgs.sourcehut.coresrht ];
1658 + hg = {
1659 + package = mkOption {
1660 + type = types.package;
1661 + default = pkgs.mercurial;
1662 + description = ''
1663 + Mercurial package for hg.sr.ht. This can help silence collisions.
1664 + '';
1665 + };
1666 + cloneBundles = mkOption {
1667 + type = types.bool;
1668 + default = false;
1669 + description = ''
1670 + Generate clonebundles (which require more disk space but dramatically speed up cloning large repositories).
1671 + '';
1672 + };
1673 + };
1674
1675 - # PostgreSQL server
1676 - services.postgresql.enable = mkOverride 999 true;
1677 - # Mail server
1678 - services.postfix.enable = mkOverride 999 true;
1679 - # Cron daemon
1680 - services.cron.enable = mkOverride 999 true;
1681 - # Redis server
1682 - services.redis.enable = mkOverride 999 true;
1683 - services.redis.bind = mkOverride 999 "127.0.0.1";
1684 -
1685 - services.sourcehut.settings = {
1686 - # The name of your network of sr.ht-based sites
1687 - "sr.ht".site-name = mkDefault "sourcehut";
1688 - # The top-level info page for your site
1689 - "sr.ht".site-info = mkDefault "https://sourcehut.org";
1690 - # {{ site-name }}, {{ site-blurb }}
1691 - "sr.ht".site-blurb = mkDefault "the hacker's forge";
1692 - # If this != production, we add a banner to each page
1693 - "sr.ht".environment = mkDefault "development";
1694 - # Contact information for the site owners
1695 - "sr.ht".owner-name = mkDefault "Drew DeVault";
1696 - "sr.ht".owner-email = mkDefault "sir@cmpwn.com";
1697 - # The source code for your fork of sr.ht
1698 - "sr.ht".source-url = mkDefault "https://git.sr.ht/~sircmpwn/srht";
1699 - # A secret key to encrypt session cookies with
1700 - "sr.ht".secret-key = mkDefault null;
1701 - "sr.ht".global-domain = mkDefault null;
1702 -
1703 - # Outgoing SMTP settings
1704 - mail.smtp-host = mkDefault null;
1705 - mail.smtp-port = mkDefault null;
1706 - mail.smtp-user = mkDefault null;
1707 - mail.smtp-password = mkDefault null;
1708 - mail.smtp-from = mkDefault null;
1709 - # Application exceptions are emailed to this address
1710 - mail.error-to = mkDefault null;
1711 - mail.error-from = mkDefault null;
1712 - # Your PGP key information (DO NOT mix up pub and priv here)
1713 - # You must remove the password from your secret key, if present.
1714 - # You can do this with gpg --edit-key [key-id], then use the passwd
1715 - # command and do not enter a new password.
1716 - mail.pgp-privkey = mkDefault null;
1717 - mail.pgp-pubkey = mkDefault null;
1718 - mail.pgp-key-id = mkDefault null;
1719 -
1720 - # base64-encoded Ed25519 key for signing webhook payloads. This should be
1721 - # consistent for all *.sr.ht sites, as we'll use this key to verify signatures
1722 - # from other sites in your network.
1723 - #
1724 - # Use the srht-webhook-keygen command to generate a key.
1725 - webhooks.private-key = mkDefault null;
1726 + lists = {
1727 + process = {
1728 + extraArgs = mkOption {
1729 + type = with types; listOf str;
1730 + default = [ "--loglevel DEBUG" "--pool eventlet" "--without-heartbeat" ];
1731 + description = "Extra arguments passed to the Celery responsible for processing mails.";
1732 + };
1733 + celeryConfig = mkOption {
1734 + type = types.lines;
1735 + default = "";
1736 + description = "Content of the <literal>celeryconfig.py</literal> used by the Celery of <literal>listssrht-process</literal>.";
1737 + };
1738 + };
1739 };
1740 };
1741 +
1742 + config = mkIf cfg.enable (mkMerge [
1743 + {
1744 + environment.systemPackages = [ pkgs.sourcehut.coresrht ];
1745 +
1746 + services.sourcehut.settings = {
1747 + "git.sr.ht".outgoing-domain = mkDefault "https://git.${domain}";
1748 + "lists.sr.ht".notify-from = mkDefault "lists-notify@${domain}";
1749 + "lists.sr.ht".posting-domain = mkDefault "lists.${domain}";
1750 + "meta.sr.ht::settings".onboarding-redirect = mkDefault "https://meta.${domain}";
1751 + "todo.sr.ht".notify-from = mkDefault "todo-notify@${domain}";
1752 + "todo.sr.ht::mail".posting-domain = mkDefault "todo.${domain}";
1753 + };
1754 + }
1755 + (mkIf cfg.postgresql.enable {
1756 + assertions = [
1757 + { assertion = postgresql.enable;
1758 + message = "postgresql must be enabled and configured";
1759 + }
1760 + ];
1761 + })
1762 + (mkIf cfg.postfix.enable {
1763 + assertions = [
1764 + { assertion = postfix.enable;
1765 + message = "postfix must be enabled and configured";
1766 + }
1767 + ];
1768 + # Needed for sharing the LMTP sockets with JoinsNamespaceOf=
1769 + systemd.services.postfix.serviceConfig.PrivateTmp = true;
1770 + })
1771 + (mkIf cfg.redis.enable {
1772 + services.redis.vmOverCommit = mkDefault true;
1773 + })
1774 + (mkIf cfg.nginx.enable {
1775 + assertions = [
1776 + { assertion = nginx.enable;
1777 + message = "nginx must be enabled and configured";
1778 + }
1779 + ];
1780 + # For proxyPass= in virtual-hosts for Sourcehut services.
1781 + services.nginx.recommendedProxySettings = mkDefault true;
1782 + })
1783 + (mkIf (cfg.builds.enable || cfg.git.enable || cfg.hg.enable) {
1784 + services.openssh = {
1785 + # Note that sshd will continue to honor AuthorizedKeysFile.
1786 + # Note that you may want automatically rotate
1787 + # or link to /dev/null the following log files:
1788 + # - /var/log/gitsrht-dispatch
1789 + # - /var/log/{build,git,hg}srht-keys
1790 + # - /var/log/{git,hg}srht-shell
1791 + # - /var/log/gitsrht-update-hook
1792 + authorizedKeysCommand = ''/etc/ssh/sourcehut/subdir/srht-dispatch "%u" "%h" "%t" "%k"'';
1793 + # srht-dispatch will setuid/setgid according to [git.sr.ht::dispatch]
1794 + authorizedKeysCommandUser = "root";
1795 + extraConfig = ''
1796 + PermitUserEnvironment SRHT_*
1797 + '';
1798 + };
1799 + environment.etc."ssh/sourcehut/config.ini".source =
1800 + settingsFormat.generate "sourcehut-dispatch-config.ini"
1801 + (filterAttrs (k: v: k == "git.sr.ht::dispatch")
1802 + cfg.settings);
1803 + environment.etc."ssh/sourcehut/subdir/srht-dispatch" = {
1804 + # sshd_config(5): The program must be owned by root, not writable by group or others
1805 + mode = "0755";
1806 + source = pkgs.writeShellScript "srht-dispatch" ''
1807 + set -e
1808 + cd /etc/ssh/sourcehut/subdir
1809 + ${cfg.python}/bin/gitsrht-dispatch "$@"
1810 + '';
1811 + };
1812 + systemd.services.sshd = {
1813 + #path = optional cfg.git.enable [ cfg.git.package ];
1814 + serviceConfig = {
1815 + BindReadOnlyPaths =
1816 + # Note that those /usr/bin/* paths are hardcoded in multiple places in *.sr.ht,
1817 + # for instance to get the user from the [git.sr.ht::dispatch] settings.
1818 + # *srht-keys needs to:
1819 + # - access a redis-server in [sr.ht] redis-host,
1820 + # - access the PostgreSQL server in [*.sr.ht] connection-string,
1821 + # - query metasrht-api (through the HTTP API).
1822 + # Using this has the side effect of creating empty files in /usr/bin/
1823 + optionals cfg.builds.enable [
1824 + "${pkgs.writeShellScript "buildsrht-keys-wrapper" ''
1825 + set -ex
1826 + cd /run/sourcehut/buildsrht/subdir
1827 + exec -a "$0" ${pkgs.sourcehut.buildsrht}/bin/buildsrht-keys "$@"
1828 + ''}:/usr/bin/buildsrht-keys"
1829 + "${pkgs.sourcehut.buildsrht}/bin/master-shell:/usr/bin/master-shell"
1830 + "${pkgs.sourcehut.buildsrht}/bin/runner-shell:/usr/bin/runner-shell"
1831 + ] ++
1832 + optionals cfg.git.enable [
1833 + # /path/to/gitsrht-keys calls /path/to/gitsrht-shell,
1834 + # or [git.sr.ht] shell= if set.
1835 + "${pkgs.writeShellScript "gitsrht-keys-wrapper" ''
1836 + set -ex
1837 + cd /run/sourcehut/gitsrht/subdir
1838 + exec -a "$0" ${pkgs.sourcehut.gitsrht}/bin/gitsrht-keys "$@"
1839 + ''}:/usr/bin/gitsrht-keys"
1840 + "${pkgs.writeShellScript "gitsrht-shell-wrapper" ''
1841 + set -e
1842 + cd /run/sourcehut/gitsrht/subdir
1843 + exec -a "$0" ${pkgs.sourcehut.gitsrht}/bin/gitsrht-shell "$@"
1844 + ''}:/usr/bin/gitsrht-shell"
1845 + ] ++
1846 + optionals cfg.hg.enable [
1847 + # /path/to/hgsrht-keys calls /path/to/hgsrht-shell,
1848 + # or [hg.sr.ht] shell= if set.
1849 + "${pkgs.writeShellScript "hgsrht-keys-wrapper" ''
1850 + set -ex
1851 + cd /run/sourcehut/hgsrht/subdir
1852 + exec -a "$0" ${pkgs.sourcehut.hgsrht}/bin/hgsrht-keys "$@"
1853 + ''}:/usr/bin/hgsrht-keys"
1854 + ":/usr/bin/hgsrht-shell"
1855 + "${pkgs.writeShellScript "hgsrht-shell-wrapper" ''
1856 + set -e
1857 + cd /run/sourcehut/hgsrht/subdir
1858 + exec -a "$0" ${pkgs.sourcehut.hgsrht}/bin/hgsrht-shell "$@"
1859 + ''}:/usr/bin/hgsrht-shell"
1860 + ];
1861 + };
1862 + };
1863 + })
1864 + ]);
1865 +
1866 + imports = [
1867 +
1868 + (import ./service.nix "builds" {
1869 + inherit configIniOfService;
1870 + srvsrht = "buildsrht";
1871 + port = 5002;
1872 + # TODO: a celery worker on the master and worker are apparently needed
1873 + extraServices.buildsrht-worker = let
1874 + qemuPackage = pkgs.qemu_kvm;
1875 + serviceName = "buildsrht-worker";
1876 + statePath = "/var/lib/sourcehut/${serviceName}";
1877 + in mkIf cfg.builds.enableWorker {
1878 + path = [ pkgs.openssh pkgs.docker ];
1879 + preStart = ''
1880 + set -x
1881 + if test -z "$(docker images -q qemu:latest 2>/dev/null)" \
1882 + || test "$(cat ${statePath}/docker-image-qemu)" != "${qemuPackage.version}"
1883 + then
1884 + # Create and import qemu:latest image for docker
1885 + ${pkgs.dockerTools.streamLayeredImage {
1886 + name = "qemu";
1887 + tag = "latest";
1888 + contents = [ qemuPackage ];
1889 + }} | docker load
1890 + # Mark down current package version
1891 + echo '${qemuPackage.version}' >${statePath}/docker-image-qemu
1892 + fi
1893 + '';
1894 + serviceConfig = {
1895 + ExecStart = "${pkgs.sourcehut.buildsrht}/bin/builds.sr.ht-worker";
1896 + RuntimeDirectory = [ "sourcehut/${serviceName}/subdir" ];
1897 + # builds.sr.ht-worker looks up ../config.ini
1898 + LogsDirectory = [ "sourcehut/${serviceName}" ];
1899 + StateDirectory = [ "sourcehut/${serviceName}" ];
1900 + WorkingDirectory = "-"+"/run/sourcehut/${serviceName}/subdir";
1901 + };
1902 + };
1903 + extraConfig = let
1904 + image_dirs = flatten (
1905 + mapAttrsToList (distro: revs:
1906 + mapAttrsToList (rev: archs:
1907 + mapAttrsToList (arch: image:
1908 + pkgs.runCommand "buildsrht-images" { } ''
1909 + mkdir -p $out/${distro}/${rev}/${arch}
1910 + ln -s ${image}/*.qcow2 $out/${distro}/${rev}/${arch}/root.img.qcow2
1911 + ''
1912 + ) archs
1913 + ) revs
1914 + ) cfg.builds.images
1915 + );
1916 + image_dir_pre = pkgs.symlinkJoin {
1917 + name = "builds.sr.ht-worker-images-pre";
1918 + paths = image_dirs;
1919 + # FIXME: not working, apparently because ubuntu/latest is a broken link
1920 + # ++ [ "${pkgs.sourcehut.buildsrht}/lib/images" ];
1921 + };
1922 + image_dir = pkgs.runCommand "builds.sr.ht-worker-images" { } ''
1923 + mkdir -p $out/images
1924 + cp -Lr ${image_dir_pre}/* $out/images
1925 + '';
1926 + in mkMerge [
1927 + {
1928 + users.users.${cfg.builds.user}.shell = pkgs.bash;
1929 +
1930 + virtualisation.docker.enable = true;
1931 +
1932 + services.sourcehut.settings = mkMerge [
1933 + { # Note that git.sr.ht::dispatch is not a typo,
1934 + # gitsrht-dispatch always use this section
1935 + "git.sr.ht::dispatch"."/usr/bin/buildsrht-keys" =
1936 + mkDefault "${cfg.builds.user}:${cfg.builds.group}";
1937 + }
1938 + (mkIf cfg.builds.enableWorker {
1939 + "builds.sr.ht::worker".shell = "/usr/bin/runner-shell";
1940 + "builds.sr.ht::worker".images = mkDefault "${image_dir}/images";
1941 + "builds.sr.ht::worker".controlcmd = mkDefault "${image_dir}/images/control";
1942 + })
1943 + ];
1944 + }
1945 + (mkIf cfg.builds.enableWorker {
1946 + users.groups = {
1947 + docker.members = [ cfg.builds.user ];
1948 + };
1949 + })
1950 + (mkIf (cfg.builds.enableWorker && cfg.nginx.enable) {
1951 + # Allow nginx access to buildlogs
1952 + users.users.${nginx.user}.extraGroups = [ cfg.builds.group ];
1953 + systemd.services.nginx = {
1954 + serviceConfig.BindReadOnlyPaths = [ "${cfg.settings."builds.sr.ht::worker".buildlogs}:/var/log/nginx/buildsrht/logs" ];
1955 + };
1956 + services.nginx.virtualHosts."logs.${domain}" = mkMerge [ {
1957 + /* FIXME: is a listen needed?
1958 + listen = with builtins;
1959 + # FIXME: not compatible with IPv6
1960 + let address = split ":" cfg.settings."builds.sr.ht::worker".name; in
1961 + [{ addr = elemAt address 0; port = lib.toInt (elemAt address 2); }];
1962 + */
1963 + locations."/logs/".alias = "/var/log/nginx/buildsrht/logs/";
1964 + } cfg.nginx.virtualHost ];
1965 + })
1966 + ];
1967 + })
1968 +
1969 + (import ./service.nix "dispatch" {
1970 + inherit configIniOfService;
1971 + port = 5005;
1972 + })
1973 +
1974 + (import ./service.nix "git" (let
1975 + baseService = {
1976 + path = [ cfg.git.package ];
1977 + serviceConfig.BindPaths = [ "${cfg.settings."git.sr.ht".repos}:/var/lib/sourcehut/gitsrht/repos" ];
1978 + serviceConfig.BindReadOnlyPaths = [ "${cfg.settings."git.sr.ht".post-update-script}:/var/lib/sourcehut/gitsrht/bin/post-update-script" ];
1979 + };
1980 + in {
1981 + inherit configIniOfService;
1982 + mainService = mkMerge [ baseService {
1983 + serviceConfig.StateDirectory = [ "sourcehut/gitsrht" "sourcehut/gitsrht/repos" ];
1984 + } ];
1985 + port = 5001;
1986 + webhooks = true;
1987 + extraTimers.gitsrht-periodic = {
1988 + service = baseService;
1989 + timerConfig.OnCalendar = ["20min"];
1990 + };
1991 + extraConfig = mkMerge [
1992 + {
1993 + # https://stackoverflow.com/questions/22314298/git-push-results-in-fatal-protocol-error-bad-line-length-character-this
1994 + # Probably could use gitsrht-shell if output is restricted to just parameters...
1995 + users.users.${cfg.git.user}.shell = pkgs.bash;
1996 + services.sourcehut.settings = {
1997 + "git.sr.ht::dispatch"."/usr/bin/gitsrht-keys" =
1998 + mkDefault "${cfg.git.user}:${cfg.git.group}";
1999 + };
2000 + systemd.services.sshd = baseService;
2001 + }
2002 + (mkIf cfg.nginx.enable {
2003 + services.nginx.virtualHosts."git.${domain}" = {
2004 + locations."/authorize" = {
2005 + proxyPass = "http://${cfg.listenAddress}:${toString cfg.git.port}";
2006 + extraConfig = ''
2007 + proxy_pass_request_body off;
2008 + proxy_set_header Content-Length "";
2009 + proxy_set_header X-Original-URI $request_uri;
2010 + '';
2011 + };
2012 + locations."~ ^/([^/]+)/([^/]+)/(HEAD|info/refs|objects/info/.*|git-upload-pack).*$" = {
2013 + root = "/var/lib/sourcehut/gitsrht/repos";
2014 + fastcgiParams = {
2015 + GIT_HTTP_EXPORT_ALL = "";
2016 + GIT_PROJECT_ROOT = "$document_root";
2017 + PATH_INFO = "$uri";
2018 + SCRIPT_FILENAME = "${cfg.git.package}/bin/git-http-backend";
2019 + };
2020 + extraConfig = ''
2021 + auth_request /authorize;
2022 + fastcgi_read_timeout 500s;
2023 + fastcgi_pass unix:/run/gitsrht-fcgiwrap.sock;
2024 + gzip off;
2025 + '';
2026 + };
2027 + };
2028 + systemd.sockets.gitsrht-fcgiwrap = {
2029 + before = [ "nginx.service" ];
2030 + wantedBy = [ "sockets.target" "gitsrht.service" ];
2031 + # This path remains accessible to nginx.service, which has no RootDirectory=
2032 + socketConfig.ListenStream = "/run/gitsrht-fcgiwrap.sock";
2033 + socketConfig.SocketUser = nginx.user;
2034 + socketConfig.SocketMode = "600";
2035 + };
2036 + })
2037 + ];
2038 + extraServices.gitsrht-fcgiwrap = mkIf cfg.nginx.enable {
2039 + serviceConfig = {
2040 + # Socket is passed by gitsrht-fcgiwrap.socket
2041 + ExecStart = "${pkgs.fcgiwrap}/sbin/fcgiwrap -c ${toString cfg.git.fcgiwrap.preforkProcess}";
2042 + # No need for config.ini
2043 + ExecStartPre = mkForce [];
2044 + User = null;
2045 + DynamicUser = true;
2046 + BindReadOnlyPaths = [ "${cfg.settings."git.sr.ht".repos}:/var/lib/sourcehut/gitsrht/repos" ];
2047 + IPAddressDeny = "any";
2048 + InaccessiblePaths = [ "-+/run/postgresql" "-+/run/redis-sourcehut" ];
2049 + PrivateNetwork = true;
2050 + RestrictAddressFamilies = mkForce [ "none" ];
2051 + SystemCallFilter = mkForce [
2052 + "@system-service"
2053 + "~@aio" "~@keyring" "~@memlock" "~@privileged" "~@resources" "~@setuid"
2054 + # @timer is needed for alarm()
2055 + ];
2056 + };
2057 + };
2058 + }))
2059 +
2060 + (import ./service.nix "hg" (let
2061 + baseService = {
2062 + path = [ cfg.hg.package ];
2063 + serviceConfig.BindPaths = [ "${cfg.settings."hg.sr.ht".repos}:/var/lib/sourcehut/hgsrht/repos" ];
2064 + serviceConfig.BindReadOnlyPaths = [ "${cfg.settings."ht.sr.ht".changegroup-script}:/var/lib/sourcehut/hgsrht/bin/changegroup-script" ];
2065 + };
2066 + in {
2067 + inherit configIniOfService;
2068 + mainService = mkMerge [ baseService {
2069 + serviceConfig.StateDirectory = [ "sourcehut/hgsrht" "sourcehut/hgsrht/repos" ];
2070 + } ];
2071 + port = 5010;
2072 + webhooks = true;
2073 + extraTimers.hgsrht-periodic = {
2074 + service = baseService;
2075 + timerConfig.OnCalendar = ["20min"];
2076 + };
2077 + extraTimers.hgsrht-clonebundles = mkIf cfg.hg.cloneBundles {
2078 + service = baseService;
2079 + timerConfig.OnCalendar = ["daily"];
2080 + timerConfig.AccuracySec = "1h";
2081 + };
2082 + extraConfig = mkMerge [
2083 + {
2084 + users.users.${cfg.hg.user}.shell = pkgs.bash;
2085 + services.sourcehut.settings = {
2086 + # Note that git.sr.ht::dispatch is not a typo,
2087 + # gitsrht-dispatch always uses this section.
2088 + "git.sr.ht::dispatch"."/usr/bin/hgsrht-keys" =
2089 + mkDefault "${cfg.hg.user}:${cfg.hg.group}";
2090 + };
2091 + systemd.services.sshd = baseService;
2092 + }
2093 + (mkIf cfg.nginx.enable {
2094 + # Allow nginx access to repositories
2095 + users.users.${nginx.user}.extraGroups = [ cfg.hg.group ];
2096 + services.nginx.virtualHosts."hg.${domain}" = {
2097 + locations."/authorize" = {
2098 + proxyPass = "http://${cfg.listenAddress}:${toString cfg.hg.port}";
2099 + extraConfig = ''
2100 + proxy_pass_request_body off;
2101 + proxy_set_header Content-Length "";
2102 + proxy_set_header X-Original-URI $request_uri;
2103 + '';
2104 + };
2105 + # Let clients reach pull bundles. We don't really need to lock this down even for
2106 + # private repos because the bundles are named after the revision hashes...
2107 + # so someone would need to know or guess a SHA value to download anything.
2108 + # TODO: proxyPass to an hg serve service?
2109 + locations."~ ^/[~^][a-z0-9_]+/[a-zA-Z0-9_.-]+/\\.hg/bundles/.*$" = {
2110 + root = "/var/lib/nginx/hgsrht/repos";
2111 + extraConfig = ''
2112 + auth_request /authorize;
2113 + gzip off;
2114 + '';
2115 + };
2116 + };
2117 + systemd.services.nginx = {
2118 + serviceConfig.BindReadOnlyPaths = [ "${cfg.settings."hg.sr.ht".repos}:/var/lib/nginx/hgsrht/repos" ];
2119 + };
2120 + })
2121 + ];
2122 + }))
2123 +
2124 + (import ./service.nix "hub" {
2125 + inherit configIniOfService;
2126 + port = 5014;
2127 + extraConfig = {
2128 + services.nginx = mkIf cfg.nginx.enable {
2129 + virtualHosts."hub.${domain}" = mkMerge [ {
2130 + serverAliases = [ domain ];
2131 + } cfg.nginx.virtualHost ];
2132 + };
2133 + };
2134 + })
2135 +
2136 + (import ./service.nix "lists" (let
2137 + srvsrht = "listssrht";
2138 + in {
2139 + inherit configIniOfService;
2140 + port = 5006;
2141 + webhooks = true;
2142 + # Receive the mail from Postfix and enqueue them into Redis and PostgreSQL
2143 + extraServices.listssrht-lmtp = {
2144 + wants = [ "postfix.service" ];
2145 + unitConfig.JoinsNamespaceOf = optional cfg.postfix.enable "postfix.service";
2146 + serviceConfig.ExecStart = "${cfg.python}/bin/listssrht-lmtp";
2147 + # Avoid crashing: os.chown(sock, os.getuid(), sock_gid)
2148 + serviceConfig.PrivateUsers = mkForce false;
2149 + };
2150 + # Dequeue the mails from Redis and dispatch them
2151 + extraServices.listssrht-process = {
2152 + serviceConfig = {
2153 + preStart = ''
2154 + cp ${pkgs.writeText "${srvsrht}-webhooks-celeryconfig.py" cfg.lists.process.celeryConfig} \
2155 + /run/sourcehut/${srvsrht}-webhooks/celeryconfig.py
2156 + '';
2157 + ExecStart = "${cfg.python}/bin/celery --app listssrht.process worker --hostname listssrht-process@%%h " + concatStringsSep " " cfg.lists.process.extraArgs;
2158 + # Avoid crashing: os.getloadavg()
2159 + ProcSubset = mkForce "all";
2160 + };
2161 + };
2162 + extraConfig = mkIf cfg.postfix.enable {
2163 + users.groups.${postfix.group}.members = [ cfg.lists.user ];
2164 + services.sourcehut.settings."lists.sr.ht::mail".sock-group = postfix.group;
2165 + services.postfix = {
2166 + destination = [ "lists.${domain}" ];
2167 + # FIXME: an accurate recipient list should be queried
2168 + # from the lists.sr.ht PostgreSQL database to avoid backscattering.
2169 + # But usernames are unfortunately not in that database but in meta.sr.ht.
2170 + # Note that two syntaxes are allowed:
2171 + # - ~username/list-name@lists.${domain}
2172 + # - u.username.list-name@lists.${domain}
2173 + localRecipients = [ "@lists.${domain}" ];
2174 + transport = ''
2175 + lists.${domain} lmtp:unix:${cfg.settings."lists.sr.ht::worker".sock}
2176 + '';
2177 + };
2178 + };
2179 + }))
2180 +
2181 + (import ./service.nix "man" {
2182 + inherit configIniOfService;
2183 + port = 5004;
2184 + })
2185 +
2186 + (import ./service.nix "meta" {
2187 + inherit configIniOfService;
2188 + port = 5000;
2189 + webhooks = true;
2190 + extraServices.metasrht-api = {
2191 + serviceConfig.Restart = "always";
2192 + serviceConfig.RestartSec = "2s";
2193 + preStart = "set -x\n" + concatStringsSep "\n\n" (attrValues (mapAttrs (k: s:
2194 + let srvMatch = builtins.match "^([a-z]*)\\.sr\\.ht$" k;
2195 + srv = head srvMatch;
2196 + in
2197 + # Configure client(s) as "preauthorized"
2198 + optionalString (srvMatch != null && cfg.${srv}.enable && ((s.oauth-client-id or null) != null)) ''
2199 + # Configure ${srv}'s OAuth client as "preauthorized"
2200 + ${postgresql.package}/bin/psql '${cfg.settings."meta.sr.ht".connection-string}' \
2201 + -c "UPDATE oauthclient SET preauthorized = true WHERE client_id = '${s.oauth-client-id}'"
2202 + ''
2203 + ) cfg.settings));
2204 + serviceConfig.ExecStart = "${pkgs.sourcehut.metasrht}/bin/metasrht-api -b ${cfg.listenAddress}:${toString (cfg.meta.port + 100)}";
2205 + };
2206 + extraTimers.metasrht-daily.timerConfig = {
2207 + OnCalendar = ["daily"];
2208 + AccuracySec = "1h";
2209 + };
2210 + extraConfig = mkMerge [
2211 + {
2212 + assertions = [
2213 + { assertion = let s = cfg.settings."meta.sr.ht::billing"; in
2214 + s.enabled == "yes" -> (s.stripe-public-key != null && s.stripe-secret-key != null);
2215 + message = "If meta.sr.ht::billing is enabled, the keys must be defined.";
2216 + }
2217 + ];
2218 + environment.systemPackages = optional cfg.meta.enable
2219 + (pkgs.writeShellScriptBin "metasrht-manageuser" ''
2220 + set -eux
2221 + if test "$(${pkgs.coreutils}/bin/id -n -u)" != '${cfg.meta.user}'
2222 + then exec sudo -u '${cfg.meta.user}' "$0" "$@"
2223 + else
2224 + # In order to load config.ini
2225 + if cd /run/sourcehut/metasrht
2226 + then exec ${cfg.python}/bin/metasrht-manageuser "$@"
2227 + else cat <<EOF
2228 + Please run: sudo systemctl start metasrht
2229 + EOF
2230 + exit 1
2231 + fi
2232 + fi
2233 + '');
2234 + }
2235 + (mkIf cfg.nginx.enable {
2236 + services.nginx.virtualHosts."meta.${domain}" = {
2237 + locations."/query" = {
2238 + proxyPass = cfg.settings."meta.sr.ht".api-origin;
2239 + extraConfig = ''
2240 + if ($request_method = 'OPTIONS') {
2241 + add_header 'Access-Control-Allow-Origin' '*';
2242 + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
2243 + add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
2244 + add_header 'Access-Control-Max-Age' 1728000;
2245 + add_header 'Content-Type' 'text/plain; charset=utf-8';
2246 + add_header 'Content-Length' 0;
2247 + return 204;
2248 + }
2249 +
2250 + add_header 'Access-Control-Allow-Origin' '*';
2251 + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
2252 + add_header 'Access-Control-Allow-Headers' 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
2253 + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
2254 + '';
2255 + };
2256 + };
2257 + })
2258 + ];
2259 + })
2260 +
2261 + (import ./service.nix "pages" {
2262 + inherit configIniOfService;
2263 + port = 5112;
2264 + mainService = let
2265 + srvsrht = "pagessrht";
2266 + version = pkgs.sourcehut.${srvsrht}.version;
2267 + stateDir = "/var/lib/sourcehut/${srvsrht}";
2268 + iniKey = "pages.sr.ht";
2269 + in {
2270 + preStart = mkBefore ''
2271 + set -x
2272 + # Use the /run/sourcehut/${srvsrht}/config.ini
2273 + # installed by a previous ExecStartPre= in baseService
2274 + cd /run/sourcehut/${srvsrht}
2275 +
2276 + if test ! -e ${stateDir}/db; then
2277 + ${postgresql.package}/bin/psql '${cfg.settings.${iniKey}.connection-string}' -f ${pkgs.sourcehut.pagessrht}/share/sql/schema.sql
2278 + echo ${version} >${stateDir}/db
2279 + fi
2280 +
2281 + ${optionalString cfg.settings.${iniKey}.migrate-on-upgrade ''
2282 + # Just try all the migrations because they're not linked to the version
2283 + for sql in ${pkgs.sourcehut.pagessrht}/share/sql/migrations/*.sql; do
2284 + ${postgresql.package}/bin/psql '${cfg.settings.${iniKey}.connection-string}' -f "$sql" || true
2285 + done
2286 + ''}
2287 +
2288 + # Disable webhook
2289 + touch ${stateDir}/webhook
2290 + '';
2291 + serviceConfig = {
2292 + ExecStart = mkForce "${pkgs.sourcehut.pagessrht}/bin/pages.sr.ht -b ${cfg.listenAddress}:${toString cfg.pages.port}";
2293 + };
2294 + };
2295 + })
2296 +
2297 + (import ./service.nix "paste" {
2298 + inherit configIniOfService;
2299 + port = 5011;
2300 + })
2301 +
2302 + (import ./service.nix "todo" {
2303 + inherit configIniOfService;
2304 + port = 5003;
2305 + webhooks = true;
2306 + extraServices.todosrht-lmtp = {
2307 + wants = [ "postfix.service" ];
2308 + unitConfig.JoinsNamespaceOf = optional cfg.postfix.enable "postfix.service";
2309 + serviceConfig.ExecStart = "${cfg.python}/bin/todosrht-lmtp";
2310 + # Avoid crashing: os.chown(sock, os.getuid(), sock_gid)
2311 + serviceConfig.PrivateUsers = mkForce false;
2312 + };
2313 + extraConfig = mkIf cfg.postfix.enable {
2314 + users.groups.${postfix.group}.members = [ cfg.todo.user ];
2315 + services.sourcehut.settings."todo.sr.ht::mail".sock-group = postfix.group;
2316 + services.postfix = {
2317 + destination = [ "todo.${domain}" ];
2318 + # FIXME: an accurate recipient list should be queried
2319 + # from the todo.sr.ht PostgreSQL database to avoid backscattering.
2320 + # But usernames are unfortunately not in that database but in meta.sr.ht.
2321 + # Note that two syntaxes are allowed:
2322 + # - ~username/tracker-name@todo.${domain}
2323 + # - u.username.tracker-name@todo.${domain}
2324 + localRecipients = [ "@todo.${domain}" ];
2325 + transport = ''
2326 + todo.${domain} lmtp:unix:${cfg.settings."todo.sr.ht::mail".sock}
2327 + '';
2328 + };
2329 + };
2330 + })
2331 +
2332 + (mkRenamedOptionModule [ "services" "sourcehut" "originBase" ]
2333 + [ "services" "sourcehut" "settings" "sr.ht" "global-domain" ])
2334 + (mkRenamedOptionModule [ "services" "sourcehut" "address" ]
2335 + [ "services" "sourcehut" "listenAddress" ])
2336 +
2337 + ];
2338 +
2339 meta.doc = ./sourcehut.xml;
2340 - meta.maintainers = with maintainers; [ tomberek ];
2341 + meta.maintainers = with maintainers; [ julm tomberek ];
2342 }
2343 diff --git a/nixos/modules/services/misc/sourcehut/dispatch.nix b/nixos/modules/services/misc/sourcehut/dispatch.nix
2344 deleted file mode 100644
2345 index a9db17bebe8..00000000000
2346 --- a/nixos/modules/services/misc/sourcehut/dispatch.nix
2347 +++ /dev/null
2348 @@ -1,125 +0,0 @@
2349 -{ config, lib, pkgs, ... }:
2350 -
2351 -with lib;
2352 -let
2353 - cfg = config.services.sourcehut;
2354 - cfgIni = cfg.settings;
2355 - scfg = cfg.dispatch;
2356 - iniKey = "dispatch.sr.ht";
2357 -
2358 - drv = pkgs.sourcehut.dispatchsrht;
2359 -in
2360 -{
2361 - options.services.sourcehut.dispatch = {
2362 - user = mkOption {
2363 - type = types.str;
2364 - default = "dispatchsrht";
2365 - description = ''
2366 - User for dispatch.sr.ht.
2367 - '';
2368 - };
2369 -
2370 - port = mkOption {
2371 - type = types.port;
2372 - default = 5005;
2373 - description = ''
2374 - Port on which the "dispatch" module should listen.
2375 - '';
2376 - };
2377 -
2378 - database = mkOption {
2379 - type = types.str;
2380 - default = "dispatch.sr.ht";
2381 - description = ''
2382 - PostgreSQL database name for dispatch.sr.ht.
2383 - '';
2384 - };
2385 -
2386 - statePath = mkOption {
2387 - type = types.path;
2388 - default = "${cfg.statePath}/dispatchsrht";
2389 - description = ''
2390 - State path for dispatch.sr.ht.
2391 - '';
2392 - };
2393 - };
2394 -
2395 - config = with scfg; lib.mkIf (cfg.enable && elem "dispatch" cfg.services) {
2396 -
2397 - users = {
2398 - users = {
2399 - "${user}" = {
2400 - isSystemUser = true;
2401 - group = user;
2402 - description = "dispatch.sr.ht user";
2403 - };
2404 - };
2405 -
2406 - groups = {
2407 - "${user}" = { };
2408 - };
2409 - };
2410 -
2411 - services.postgresql = {
2412 - authentication = ''
2413 - local ${database} ${user} trust
2414 - '';
2415 - ensureDatabases = [ database ];
2416 - ensureUsers = [
2417 - {
2418 - name = user;
2419 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
2420 - }
2421 - ];
2422 - };
2423 -
2424 - systemd = {
2425 - tmpfiles.rules = [
2426 - "d ${statePath} 0750 ${user} ${user} -"
2427 - ];
2428 -
2429 - services.dispatchsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
2430 - after = [ "postgresql.service" "network.target" ];
2431 - requires = [ "postgresql.service" ];
2432 - wantedBy = [ "multi-user.target" ];
2433 -
2434 - description = "dispatch.sr.ht website service";
2435 -
2436 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
2437 - };
2438 - };
2439 -
2440 - services.sourcehut.settings = {
2441 - # URL dispatch.sr.ht is being served at (protocol://domain)
2442 - "dispatch.sr.ht".origin = mkDefault "http://dispatch.${cfg.originBase}";
2443 - # Address and port to bind the debug server to
2444 - "dispatch.sr.ht".debug-host = mkDefault "0.0.0.0";
2445 - "dispatch.sr.ht".debug-port = mkDefault port;
2446 - # Configures the SQLAlchemy connection string for the database.
2447 - "dispatch.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
2448 - # Set to "yes" to automatically run migrations on package upgrade.
2449 - "dispatch.sr.ht".migrate-on-upgrade = mkDefault "yes";
2450 - # dispatch.sr.ht's OAuth client ID and secret for meta.sr.ht
2451 - # Register your client at meta.example.org/oauth
2452 - "dispatch.sr.ht".oauth-client-id = mkDefault null;
2453 - "dispatch.sr.ht".oauth-client-secret = mkDefault null;
2454 -
2455 - # Github Integration
2456 - "dispatch.sr.ht::github".oauth-client-id = mkDefault null;
2457 - "dispatch.sr.ht::github".oauth-client-secret = mkDefault null;
2458 -
2459 - # Gitlab Integration
2460 - "dispatch.sr.ht::gitlab".enabled = mkDefault null;
2461 - "dispatch.sr.ht::gitlab".canonical-upstream = mkDefault "gitlab.com";
2462 - "dispatch.sr.ht::gitlab".repo-cache = mkDefault "./repo-cache";
2463 - # "dispatch.sr.ht::gitlab"."gitlab.com" = mkDefault "GitLab:application id:secret";
2464 - };
2465 -
2466 - services.nginx.virtualHosts."dispatch.${cfg.originBase}" = {
2467 - forceSSL = true;
2468 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
2469 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
2470 - locations."/static".root = "${pkgs.sourcehut.dispatchsrht}/${pkgs.sourcehut.python.sitePackages}/dispatchsrht";
2471 - };
2472 - };
2473 -}
2474 diff --git a/nixos/modules/services/misc/sourcehut/git.nix b/nixos/modules/services/misc/sourcehut/git.nix
2475 deleted file mode 100644
2476 index 99b9aec0612..00000000000
2477 --- a/nixos/modules/services/misc/sourcehut/git.nix
2478 +++ /dev/null
2479 @@ -1,214 +0,0 @@
2480 -{ config, lib, pkgs, ... }:
2481 -
2482 -with lib;
2483 -let
2484 - cfg = config.services.sourcehut;
2485 - scfg = cfg.git;
2486 - iniKey = "git.sr.ht";
2487 -
2488 - rcfg = config.services.redis;
2489 - drv = pkgs.sourcehut.gitsrht;
2490 -in
2491 -{
2492 - options.services.sourcehut.git = {
2493 - user = mkOption {
2494 - type = types.str;
2495 - visible = false;
2496 - internal = true;
2497 - readOnly = true;
2498 - default = "git";
2499 - description = ''
2500 - User for git.sr.ht.
2501 - '';
2502 - };
2503 -
2504 - port = mkOption {
2505 - type = types.port;
2506 - default = 5001;
2507 - description = ''
2508 - Port on which the "git" module should listen.
2509 - '';
2510 - };
2511 -
2512 - database = mkOption {
2513 - type = types.str;
2514 - default = "git.sr.ht";
2515 - description = ''
2516 - PostgreSQL database name for git.sr.ht.
2517 - '';
2518 - };
2519 -
2520 - statePath = mkOption {
2521 - type = types.path;
2522 - default = "${cfg.statePath}/gitsrht";
2523 - description = ''
2524 - State path for git.sr.ht.
2525 - '';
2526 - };
2527 -
2528 - package = mkOption {
2529 - type = types.package;
2530 - default = pkgs.git;
2531 - example = literalExample "pkgs.gitFull";
2532 - description = ''
2533 - Git package for git.sr.ht. This can help silence collisions.
2534 - '';
2535 - };
2536 - };
2537 -
2538 - config = with scfg; lib.mkIf (cfg.enable && elem "git" cfg.services) {
2539 - # sshd refuses to run with `Unsafe AuthorizedKeysCommand ... bad ownership or modes for directory /nix/store`
2540 - environment.etc."ssh/gitsrht-dispatch" = {
2541 - mode = "0755";
2542 - text = ''
2543 - #! ${pkgs.stdenv.shell}
2544 - ${cfg.python}/bin/gitsrht-dispatch "$@"
2545 - '';
2546 - };
2547 -
2548 - # Needs this in the $PATH when sshing into the server
2549 - environment.systemPackages = [ cfg.git.package ];
2550 -
2551 - users = {
2552 - users = {
2553 - "${user}" = {
2554 - isSystemUser = true;
2555 - group = user;
2556 - # https://stackoverflow.com/questions/22314298/git-push-results-in-fatal-protocol-error-bad-line-length-character-this
2557 - # Probably could use gitsrht-shell if output is restricted to just parameters...
2558 - shell = pkgs.bash;
2559 - description = "git.sr.ht user";
2560 - };
2561 - };
2562 -
2563 - groups = {
2564 - "${user}" = { };
2565 - };
2566 - };
2567 -
2568 - services = {
2569 - cron.systemCronJobs = [ "*/20 * * * * ${cfg.python}/bin/gitsrht-periodic" ];
2570 - fcgiwrap.enable = true;
2571 -
2572 - openssh.authorizedKeysCommand = ''/etc/ssh/gitsrht-dispatch "%u" "%h" "%t" "%k"'';
2573 - openssh.authorizedKeysCommandUser = "root";
2574 - openssh.extraConfig = ''
2575 - PermitUserEnvironment SRHT_*
2576 - '';
2577 -
2578 - postgresql = {
2579 - authentication = ''
2580 - local ${database} ${user} trust
2581 - '';
2582 - ensureDatabases = [ database ];
2583 - ensureUsers = [
2584 - {
2585 - name = user;
2586 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
2587 - }
2588 - ];
2589 - };
2590 - };
2591 -
2592 - systemd = {
2593 - tmpfiles.rules = [
2594 - # /var/log is owned by root
2595 - "f /var/log/git-srht-shell 0644 ${user} ${user} -"
2596 -
2597 - "d ${statePath} 0750 ${user} ${user} -"
2598 - "d ${cfg.settings."${iniKey}".repos} 2755 ${user} ${user} -"
2599 - ];
2600 -
2601 - services = {
2602 - gitsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
2603 - after = [ "redis.service" "postgresql.service" "network.target" ];
2604 - requires = [ "redis.service" "postgresql.service" ];
2605 - wantedBy = [ "multi-user.target" ];
2606 -
2607 - # Needs internally to create repos at the very least
2608 - path = [ pkgs.git ];
2609 - description = "git.sr.ht website service";
2610 -
2611 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
2612 - };
2613 -
2614 - gitsrht-webhooks = {
2615 - after = [ "postgresql.service" "network.target" ];
2616 - requires = [ "postgresql.service" ];
2617 - wantedBy = [ "multi-user.target" ];
2618 -
2619 - description = "git.sr.ht webhooks service";
2620 - serviceConfig = {
2621 - Type = "simple";
2622 - User = user;
2623 - Restart = "always";
2624 - };
2625 -
2626 - serviceConfig.ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel=info";
2627 - };
2628 - };
2629 - };
2630 -
2631 - services.sourcehut.settings = {
2632 - # URL git.sr.ht is being served at (protocol://domain)
2633 - "git.sr.ht".origin = mkDefault "http://git.${cfg.originBase}";
2634 - # Address and port to bind the debug server to
2635 - "git.sr.ht".debug-host = mkDefault "0.0.0.0";
2636 - "git.sr.ht".debug-port = mkDefault port;
2637 - # Configures the SQLAlchemy connection string for the database.
2638 - "git.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
2639 - # Set to "yes" to automatically run migrations on package upgrade.
2640 - "git.sr.ht".migrate-on-upgrade = mkDefault "yes";
2641 - # The redis connection used for the webhooks worker
2642 - "git.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/1";
2643 -
2644 - # A post-update script which is installed in every git repo.
2645 - "git.sr.ht".post-update-script = mkDefault "${pkgs.sourcehut.gitsrht}/bin/gitsrht-update-hook";
2646 -
2647 - # git.sr.ht's OAuth client ID and secret for meta.sr.ht
2648 - # Register your client at meta.example.org/oauth
2649 - "git.sr.ht".oauth-client-id = mkDefault null;
2650 - "git.sr.ht".oauth-client-secret = mkDefault null;
2651 - # Path to git repositories on disk
2652 - "git.sr.ht".repos = mkDefault "/var/lib/git";
2653 -
2654 - "git.sr.ht".outgoing-domain = mkDefault "http://git.${cfg.originBase}";
2655 -
2656 - # The authorized keys hook uses this to dispatch to various handlers
2657 - # The format is a program to exec into as the key, and the user to match as the
2658 - # value. When someone tries to log in as this user, this program is executed
2659 - # and is expected to omit an AuthorizedKeys file.
2660 - #
2661 - # Discard of the string context is in order to allow derivation-derived strings.
2662 - # This is safe if the relevant package is installed which will be the case if the setting is utilized.
2663 - "git.sr.ht::dispatch".${builtins.unsafeDiscardStringContext "${pkgs.sourcehut.gitsrht}/bin/gitsrht-keys"} = mkDefault "${user}:${user}";
2664 - };
2665 -
2666 - services.nginx.virtualHosts."git.${cfg.originBase}" = {
2667 - forceSSL = true;
2668 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
2669 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
2670 - locations."/static".root = "${pkgs.sourcehut.gitsrht}/${pkgs.sourcehut.python.sitePackages}/gitsrht";
2671 - extraConfig = ''
2672 - location = /authorize {
2673 - proxy_pass http://${cfg.address}:${toString port};
2674 - proxy_pass_request_body off;
2675 - proxy_set_header Content-Length "";
2676 - proxy_set_header X-Original-URI $request_uri;
2677 - }
2678 - location ~ ^/([^/]+)/([^/]+)/(HEAD|info/refs|objects/info/.*|git-upload-pack).*$ {
2679 - auth_request /authorize;
2680 - root /var/lib/git;
2681 - fastcgi_pass unix:/run/fcgiwrap.sock;
2682 - fastcgi_param SCRIPT_FILENAME ${pkgs.git}/bin/git-http-backend;
2683 - fastcgi_param PATH_INFO $uri;
2684 - fastcgi_param GIT_PROJECT_ROOT $document_root;
2685 - fastcgi_read_timeout 500s;
2686 - include ${pkgs.nginx}/conf/fastcgi_params;
2687 - gzip off;
2688 - }
2689 - '';
2690 -
2691 - };
2692 - };
2693 -}
2694 diff --git a/nixos/modules/services/misc/sourcehut/hg.nix b/nixos/modules/services/misc/sourcehut/hg.nix
2695 deleted file mode 100644
2696 index 5cd36bb0455..00000000000
2697 --- a/nixos/modules/services/misc/sourcehut/hg.nix
2698 +++ /dev/null
2699 @@ -1,173 +0,0 @@
2700 -{ config, lib, pkgs, ... }:
2701 -
2702 -with lib;
2703 -let
2704 - cfg = config.services.sourcehut;
2705 - scfg = cfg.hg;
2706 - iniKey = "hg.sr.ht";
2707 -
2708 - rcfg = config.services.redis;
2709 - drv = pkgs.sourcehut.hgsrht;
2710 -in
2711 -{
2712 - options.services.sourcehut.hg = {
2713 - user = mkOption {
2714 - type = types.str;
2715 - internal = true;
2716 - readOnly = true;
2717 - default = "hg";
2718 - description = ''
2719 - User for hg.sr.ht.
2720 - '';
2721 - };
2722 -
2723 - port = mkOption {
2724 - type = types.port;
2725 - default = 5010;
2726 - description = ''
2727 - Port on which the "hg" module should listen.
2728 - '';
2729 - };
2730 -
2731 - database = mkOption {
2732 - type = types.str;
2733 - default = "hg.sr.ht";
2734 - description = ''
2735 - PostgreSQL database name for hg.sr.ht.
2736 - '';
2737 - };
2738 -
2739 - statePath = mkOption {
2740 - type = types.path;
2741 - default = "${cfg.statePath}/hgsrht";
2742 - description = ''
2743 - State path for hg.sr.ht.
2744 - '';
2745 - };
2746 -
2747 - cloneBundles = mkOption {
2748 - type = types.bool;
2749 - default = false;
2750 - description = ''
2751 - Generate clonebundles (which require more disk space but dramatically speed up cloning large repositories).
2752 - '';
2753 - };
2754 - };
2755 -
2756 - config = with scfg; lib.mkIf (cfg.enable && elem "hg" cfg.services) {
2757 - # In case it ever comes into being
2758 - environment.etc."ssh/hgsrht-dispatch" = {
2759 - mode = "0755";
2760 - text = ''
2761 - #! ${pkgs.stdenv.shell}
2762 - ${cfg.python}/bin/gitsrht-dispatch $@
2763 - '';
2764 - };
2765 -
2766 - environment.systemPackages = [ pkgs.mercurial ];
2767 -
2768 - users = {
2769 - users = {
2770 - "${user}" = {
2771 - isSystemUser = true;
2772 - group = user;
2773 - # Assuming hg.sr.ht needs this too
2774 - shell = pkgs.bash;
2775 - description = "hg.sr.ht user";
2776 - };
2777 - };
2778 -
2779 - groups = {
2780 - "${user}" = { };
2781 - };
2782 - };
2783 -
2784 - services = {
2785 - cron.systemCronJobs = [ "*/20 * * * * ${cfg.python}/bin/hgsrht-periodic" ]
2786 - ++ optional cloneBundles "0 * * * * ${cfg.python}/bin/hgsrht-clonebundles";
2787 -
2788 - openssh.authorizedKeysCommand = ''/etc/ssh/hgsrht-dispatch "%u" "%h" "%t" "%k"'';
2789 - openssh.authorizedKeysCommandUser = "root";
2790 - openssh.extraConfig = ''
2791 - PermitUserEnvironment SRHT_*
2792 - '';
2793 -
2794 - postgresql = {
2795 - authentication = ''
2796 - local ${database} ${user} trust
2797 - '';
2798 - ensureDatabases = [ database ];
2799 - ensureUsers = [
2800 - {
2801 - name = user;
2802 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
2803 - }
2804 - ];
2805 - };
2806 - };
2807 -
2808 - systemd = {
2809 - tmpfiles.rules = [
2810 - # /var/log is owned by root
2811 - "f /var/log/hg-srht-shell 0644 ${user} ${user} -"
2812 -
2813 - "d ${statePath} 0750 ${user} ${user} -"
2814 - "d ${cfg.settings."${iniKey}".repos} 2755 ${user} ${user} -"
2815 - ];
2816 -
2817 - services.hgsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
2818 - after = [ "redis.service" "postgresql.service" "network.target" ];
2819 - requires = [ "redis.service" "postgresql.service" ];
2820 - wantedBy = [ "multi-user.target" ];
2821 -
2822 - path = [ pkgs.mercurial ];
2823 - description = "hg.sr.ht website service";
2824 -
2825 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
2826 - };
2827 - };
2828 -
2829 - services.sourcehut.settings = {
2830 - # URL hg.sr.ht is being served at (protocol://domain)
2831 - "hg.sr.ht".origin = mkDefault "http://hg.${cfg.originBase}";
2832 - # Address and port to bind the debug server to
2833 - "hg.sr.ht".debug-host = mkDefault "0.0.0.0";
2834 - "hg.sr.ht".debug-port = mkDefault port;
2835 - # Configures the SQLAlchemy connection string for the database.
2836 - "hg.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
2837 - # The redis connection used for the webhooks worker
2838 - "hg.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/1";
2839 - # A post-update script which is installed in every mercurial repo.
2840 - "hg.sr.ht".changegroup-script = mkDefault "${cfg.python}/bin/hgsrht-hook-changegroup";
2841 - # hg.sr.ht's OAuth client ID and secret for meta.sr.ht
2842 - # Register your client at meta.example.org/oauth
2843 - "hg.sr.ht".oauth-client-id = mkDefault null;
2844 - "hg.sr.ht".oauth-client-secret = mkDefault null;
2845 - # Path to mercurial repositories on disk
2846 - "hg.sr.ht".repos = mkDefault "/var/lib/hg";
2847 - # Path to the srht mercurial extension
2848 - # (defaults to where the hgsrht code is)
2849 - # "hg.sr.ht".srhtext = mkDefault null;
2850 - # .hg/store size (in MB) past which the nightly job generates clone bundles.
2851 - # "hg.sr.ht".clone_bundle_threshold = mkDefault 50;
2852 - # Path to hg-ssh (if not in $PATH)
2853 - # "hg.sr.ht".hg_ssh = mkDefault /path/to/hg-ssh;
2854 -
2855 - # The authorized keys hook uses this to dispatch to various handlers
2856 - # The format is a program to exec into as the key, and the user to match as the
2857 - # value. When someone tries to log in as this user, this program is executed
2858 - # and is expected to omit an AuthorizedKeys file.
2859 - #
2860 - # Uncomment the relevant lines to enable the various sr.ht dispatchers.
2861 - "hg.sr.ht::dispatch"."/run/current-system/sw/bin/hgsrht-keys" = mkDefault "${user}:${user}";
2862 - };
2863 -
2864 - # TODO: requires testing and addition of hg-specific requirements
2865 - services.nginx.virtualHosts."hg.${cfg.originBase}" = {
2866 - forceSSL = true;
2867 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
2868 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
2869 - locations."/static".root = "${pkgs.sourcehut.hgsrht}/${pkgs.sourcehut.python.sitePackages}/hgsrht";
2870 - };
2871 - };
2872 -}
2873 diff --git a/nixos/modules/services/misc/sourcehut/hub.nix b/nixos/modules/services/misc/sourcehut/hub.nix
2874 deleted file mode 100644
2875 index be3ea21011c..00000000000
2876 --- a/nixos/modules/services/misc/sourcehut/hub.nix
2877 +++ /dev/null
2878 @@ -1,118 +0,0 @@
2879 -{ config, lib, pkgs, ... }:
2880 -
2881 -with lib;
2882 -let
2883 - cfg = config.services.sourcehut;
2884 - cfgIni = cfg.settings;
2885 - scfg = cfg.hub;
2886 - iniKey = "hub.sr.ht";
2887 -
2888 - drv = pkgs.sourcehut.hubsrht;
2889 -in
2890 -{
2891 - options.services.sourcehut.hub = {
2892 - user = mkOption {
2893 - type = types.str;
2894 - default = "hubsrht";
2895 - description = ''
2896 - User for hub.sr.ht.
2897 - '';
2898 - };
2899 -
2900 - port = mkOption {
2901 - type = types.port;
2902 - default = 5014;
2903 - description = ''
2904 - Port on which the "hub" module should listen.
2905 - '';
2906 - };
2907 -
2908 - database = mkOption {
2909 - type = types.str;
2910 - default = "hub.sr.ht";
2911 - description = ''
2912 - PostgreSQL database name for hub.sr.ht.
2913 - '';
2914 - };
2915 -
2916 - statePath = mkOption {
2917 - type = types.path;
2918 - default = "${cfg.statePath}/hubsrht";
2919 - description = ''
2920 - State path for hub.sr.ht.
2921 - '';
2922 - };
2923 - };
2924 -
2925 - config = with scfg; lib.mkIf (cfg.enable && elem "hub" cfg.services) {
2926 - users = {
2927 - users = {
2928 - "${user}" = {
2929 - isSystemUser = true;
2930 - group = user;
2931 - description = "hub.sr.ht user";
2932 - };
2933 - };
2934 -
2935 - groups = {
2936 - "${user}" = { };
2937 - };
2938 - };
2939 -
2940 - services.postgresql = {
2941 - authentication = ''
2942 - local ${database} ${user} trust
2943 - '';
2944 - ensureDatabases = [ database ];
2945 - ensureUsers = [
2946 - {
2947 - name = user;
2948 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
2949 - }
2950 - ];
2951 - };
2952 -
2953 - systemd = {
2954 - tmpfiles.rules = [
2955 - "d ${statePath} 0750 ${user} ${user} -"
2956 - ];
2957 -
2958 - services.hubsrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
2959 - after = [ "postgresql.service" "network.target" ];
2960 - requires = [ "postgresql.service" ];
2961 - wantedBy = [ "multi-user.target" ];
2962 -
2963 - description = "hub.sr.ht website service";
2964 -
2965 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
2966 - };
2967 - };
2968 -
2969 - services.sourcehut.settings = {
2970 - # URL hub.sr.ht is being served at (protocol://domain)
2971 - "hub.sr.ht".origin = mkDefault "http://hub.${cfg.originBase}";
2972 - # Address and port to bind the debug server to
2973 - "hub.sr.ht".debug-host = mkDefault "0.0.0.0";
2974 - "hub.sr.ht".debug-port = mkDefault port;
2975 - # Configures the SQLAlchemy connection string for the database.
2976 - "hub.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
2977 - # Set to "yes" to automatically run migrations on package upgrade.
2978 - "hub.sr.ht".migrate-on-upgrade = mkDefault "yes";
2979 - # hub.sr.ht's OAuth client ID and secret for meta.sr.ht
2980 - # Register your client at meta.example.org/oauth
2981 - "hub.sr.ht".oauth-client-id = mkDefault null;
2982 - "hub.sr.ht".oauth-client-secret = mkDefault null;
2983 - };
2984 -
2985 - services.nginx.virtualHosts."${cfg.originBase}" = {
2986 - forceSSL = true;
2987 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
2988 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
2989 - locations."/static".root = "${pkgs.sourcehut.hubsrht}/${pkgs.sourcehut.python.sitePackages}/hubsrht";
2990 - };
2991 - services.nginx.virtualHosts."hub.${cfg.originBase}" = {
2992 - globalRedirect = "${cfg.originBase}";
2993 - forceSSL = true;
2994 - };
2995 - };
2996 -}
2997 diff --git a/nixos/modules/services/misc/sourcehut/lists.nix b/nixos/modules/services/misc/sourcehut/lists.nix
2998 deleted file mode 100644
2999 index 7b1fe9fd463..00000000000
3000 --- a/nixos/modules/services/misc/sourcehut/lists.nix
3001 +++ /dev/null
3002 @@ -1,185 +0,0 @@
3003 -# Email setup is fairly involved, useful references:
3004 -# https://drewdevault.com/2018/08/05/Local-mail-server.html
3005 -
3006 -{ config, lib, pkgs, ... }:
3007 -
3008 -with lib;
3009 -let
3010 - cfg = config.services.sourcehut;
3011 - cfgIni = cfg.settings;
3012 - scfg = cfg.lists;
3013 - iniKey = "lists.sr.ht";
3014 -
3015 - rcfg = config.services.redis;
3016 - drv = pkgs.sourcehut.listssrht;
3017 -in
3018 -{
3019 - options.services.sourcehut.lists = {
3020 - user = mkOption {
3021 - type = types.str;
3022 - default = "listssrht";
3023 - description = ''
3024 - User for lists.sr.ht.
3025 - '';
3026 - };
3027 -
3028 - port = mkOption {
3029 - type = types.port;
3030 - default = 5006;
3031 - description = ''
3032 - Port on which the "lists" module should listen.
3033 - '';
3034 - };
3035 -
3036 - database = mkOption {
3037 - type = types.str;
3038 - default = "lists.sr.ht";
3039 - description = ''
3040 - PostgreSQL database name for lists.sr.ht.
3041 - '';
3042 - };
3043 -
3044 - statePath = mkOption {
3045 - type = types.path;
3046 - default = "${cfg.statePath}/listssrht";
3047 - description = ''
3048 - State path for lists.sr.ht.
3049 - '';
3050 - };
3051 - };
3052 -
3053 - config = with scfg; lib.mkIf (cfg.enable && elem "lists" cfg.services) {
3054 - users = {
3055 - users = {
3056 - "${user}" = {
3057 - isSystemUser = true;
3058 - group = user;
3059 - extraGroups = [ "postfix" ];
3060 - description = "lists.sr.ht user";
3061 - };
3062 - };
3063 - groups = {
3064 - "${user}" = { };
3065 - };
3066 - };
3067 -
3068 - services.postgresql = {
3069 - authentication = ''
3070 - local ${database} ${user} trust
3071 - '';
3072 - ensureDatabases = [ database ];
3073 - ensureUsers = [
3074 - {
3075 - name = user;
3076 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
3077 - }
3078 - ];
3079 - };
3080 -
3081 - systemd = {
3082 - tmpfiles.rules = [
3083 - "d ${statePath} 0750 ${user} ${user} -"
3084 - ];
3085 -
3086 - services = {
3087 - listssrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
3088 - after = [ "postgresql.service" "network.target" ];
3089 - requires = [ "postgresql.service" ];
3090 - wantedBy = [ "multi-user.target" ];
3091 -
3092 - description = "lists.sr.ht website service";
3093 -
3094 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
3095 - };
3096 -
3097 - listssrht-process = {
3098 - after = [ "postgresql.service" "network.target" ];
3099 - requires = [ "postgresql.service" ];
3100 - wantedBy = [ "multi-user.target" ];
3101 -
3102 - description = "lists.sr.ht process service";
3103 - serviceConfig = {
3104 - Type = "simple";
3105 - User = user;
3106 - Restart = "always";
3107 - ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.process worker --loglevel=info";
3108 - };
3109 - };
3110 -
3111 - listssrht-lmtp = {
3112 - after = [ "postgresql.service" "network.target" ];
3113 - requires = [ "postgresql.service" ];
3114 - wantedBy = [ "multi-user.target" ];
3115 -
3116 - description = "lists.sr.ht process service";
3117 - serviceConfig = {
3118 - Type = "simple";
3119 - User = user;
3120 - Restart = "always";
3121 - ExecStart = "${cfg.python}/bin/listssrht-lmtp";
3122 - };
3123 - };
3124 -
3125 -
3126 - listssrht-webhooks = {
3127 - after = [ "postgresql.service" "network.target" ];
3128 - requires = [ "postgresql.service" ];
3129 - wantedBy = [ "multi-user.target" ];
3130 -
3131 - description = "lists.sr.ht webhooks service";
3132 - serviceConfig = {
3133 - Type = "simple";
3134 - User = user;
3135 - Restart = "always";
3136 - ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel=info";
3137 - };
3138 - };
3139 - };
3140 - };
3141 -
3142 - services.sourcehut.settings = {
3143 - # URL lists.sr.ht is being served at (protocol://domain)
3144 - "lists.sr.ht".origin = mkDefault "http://lists.${cfg.originBase}";
3145 - # Address and port to bind the debug server to
3146 - "lists.sr.ht".debug-host = mkDefault "0.0.0.0";
3147 - "lists.sr.ht".debug-port = mkDefault port;
3148 - # Configures the SQLAlchemy connection string for the database.
3149 - "lists.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
3150 - # Set to "yes" to automatically run migrations on package upgrade.
3151 - "lists.sr.ht".migrate-on-upgrade = mkDefault "yes";
3152 - # lists.sr.ht's OAuth client ID and secret for meta.sr.ht
3153 - # Register your client at meta.example.org/oauth
3154 - "lists.sr.ht".oauth-client-id = mkDefault null;
3155 - "lists.sr.ht".oauth-client-secret = mkDefault null;
3156 - # Outgoing email for notifications generated by users
3157 - "lists.sr.ht".notify-from = mkDefault "CHANGEME@example.org";
3158 - # The redis connection used for the webhooks worker
3159 - "lists.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/2";
3160 - # The redis connection used for the celery worker
3161 - "lists.sr.ht".redis = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/4";
3162 - # Network-key
3163 - "lists.sr.ht".network-key = mkDefault null;
3164 - # Allow creation
3165 - "lists.sr.ht".allow-new-lists = mkDefault "no";
3166 - # Posting Domain
3167 - "lists.sr.ht".posting-domain = mkDefault "lists.${cfg.originBase}";
3168 -
3169 - # Path for the lmtp daemon's unix socket. Direct incoming mail to this socket.
3170 - # Alternatively, specify IP:PORT and an SMTP server will be run instead.
3171 - "lists.sr.ht::worker".sock = mkDefault "/tmp/lists.sr.ht-lmtp.sock";
3172 - # The lmtp daemon will make the unix socket group-read/write for users in this
3173 - # group.
3174 - "lists.sr.ht::worker".sock-group = mkDefault "postfix";
3175 - "lists.sr.ht::worker".reject-url = mkDefault "https://man.sr.ht/lists.sr.ht/etiquette.md";
3176 - "lists.sr.ht::worker".reject-mimetypes = mkDefault "text/html";
3177 -
3178 - };
3179 -
3180 - services.nginx.virtualHosts."lists.${cfg.originBase}" = {
3181 - forceSSL = true;
3182 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
3183 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
3184 - locations."/static".root = "${pkgs.sourcehut.listssrht}/${pkgs.sourcehut.python.sitePackages}/listssrht";
3185 - };
3186 - };
3187 -}
3188 diff --git a/nixos/modules/services/misc/sourcehut/man.nix b/nixos/modules/services/misc/sourcehut/man.nix
3189 deleted file mode 100644
3190 index 7693396d187..00000000000
3191 --- a/nixos/modules/services/misc/sourcehut/man.nix
3192 +++ /dev/null
3193 @@ -1,122 +0,0 @@
3194 -{ config, lib, pkgs, ... }:
3195 -
3196 -with lib;
3197 -let
3198 - cfg = config.services.sourcehut;
3199 - cfgIni = cfg.settings;
3200 - scfg = cfg.man;
3201 - iniKey = "man.sr.ht";
3202 -
3203 - drv = pkgs.sourcehut.mansrht;
3204 -in
3205 -{
3206 - options.services.sourcehut.man = {
3207 - user = mkOption {
3208 - type = types.str;
3209 - default = "mansrht";
3210 - description = ''
3211 - User for man.sr.ht.
3212 - '';
3213 - };
3214 -
3215 - port = mkOption {
3216 - type = types.port;
3217 - default = 5004;
3218 - description = ''
3219 - Port on which the "man" module should listen.
3220 - '';
3221 - };
3222 -
3223 - database = mkOption {
3224 - type = types.str;
3225 - default = "man.sr.ht";
3226 - description = ''
3227 - PostgreSQL database name for man.sr.ht.
3228 - '';
3229 - };
3230 -
3231 - statePath = mkOption {
3232 - type = types.path;
3233 - default = "${cfg.statePath}/mansrht";
3234 - description = ''
3235 - State path for man.sr.ht.
3236 - '';
3237 - };
3238 - };
3239 -
3240 - config = with scfg; lib.mkIf (cfg.enable && elem "man" cfg.services) {
3241 - assertions =
3242 - [
3243 - {
3244 - assertion = hasAttrByPath [ "git.sr.ht" "oauth-client-id" ] cfgIni;
3245 - message = "man.sr.ht needs access to git.sr.ht.";
3246 - }
3247 - ];
3248 -
3249 - users = {
3250 - users = {
3251 - "${user}" = {
3252 - isSystemUser = true;
3253 - group = user;
3254 - description = "man.sr.ht user";
3255 - };
3256 - };
3257 -
3258 - groups = {
3259 - "${user}" = { };
3260 - };
3261 - };
3262 -
3263 - services.postgresql = {
3264 - authentication = ''
3265 - local ${database} ${user} trust
3266 - '';
3267 - ensureDatabases = [ database ];
3268 - ensureUsers = [
3269 - {
3270 - name = user;
3271 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
3272 - }
3273 - ];
3274 - };
3275 -
3276 - systemd = {
3277 - tmpfiles.rules = [
3278 - "d ${statePath} 0750 ${user} ${user} -"
3279 - ];
3280 -
3281 - services.mansrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
3282 - after = [ "postgresql.service" "network.target" ];
3283 - requires = [ "postgresql.service" ];
3284 - wantedBy = [ "multi-user.target" ];
3285 -
3286 - description = "man.sr.ht website service";
3287 -
3288 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
3289 - };
3290 - };
3291 -
3292 - services.sourcehut.settings = {
3293 - # URL man.sr.ht is being served at (protocol://domain)
3294 - "man.sr.ht".origin = mkDefault "http://man.${cfg.originBase}";
3295 - # Address and port to bind the debug server to
3296 - "man.sr.ht".debug-host = mkDefault "0.0.0.0";
3297 - "man.sr.ht".debug-port = mkDefault port;
3298 - # Configures the SQLAlchemy connection string for the database.
3299 - "man.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
3300 - # Set to "yes" to automatically run migrations on package upgrade.
3301 - "man.sr.ht".migrate-on-upgrade = mkDefault "yes";
3302 - # man.sr.ht's OAuth client ID and secret for meta.sr.ht
3303 - # Register your client at meta.example.org/oauth
3304 - "man.sr.ht".oauth-client-id = mkDefault null;
3305 - "man.sr.ht".oauth-client-secret = mkDefault null;
3306 - };
3307 -
3308 - services.nginx.virtualHosts."man.${cfg.originBase}" = {
3309 - forceSSL = true;
3310 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
3311 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
3312 - locations."/static".root = "${pkgs.sourcehut.mansrht}/${pkgs.sourcehut.python.sitePackages}/mansrht";
3313 - };
3314 - };
3315 -}
3316 diff --git a/nixos/modules/services/misc/sourcehut/meta.nix b/nixos/modules/services/misc/sourcehut/meta.nix
3317 deleted file mode 100644
3318 index 56127a824eb..00000000000
3319 --- a/nixos/modules/services/misc/sourcehut/meta.nix
3320 +++ /dev/null
3321 @@ -1,211 +0,0 @@
3322 -{ config, lib, pkgs, ... }:
3323 -
3324 -with lib;
3325 -let
3326 - cfg = config.services.sourcehut;
3327 - cfgIni = cfg.settings;
3328 - scfg = cfg.meta;
3329 - iniKey = "meta.sr.ht";
3330 -
3331 - rcfg = config.services.redis;
3332 - drv = pkgs.sourcehut.metasrht;
3333 -in
3334 -{
3335 - options.services.sourcehut.meta = {
3336 - user = mkOption {
3337 - type = types.str;
3338 - default = "metasrht";
3339 - description = ''
3340 - User for meta.sr.ht.
3341 - '';
3342 - };
3343 -
3344 - port = mkOption {
3345 - type = types.port;
3346 - default = 5000;
3347 - description = ''
3348 - Port on which the "meta" module should listen.
3349 - '';
3350 - };
3351 -
3352 - database = mkOption {
3353 - type = types.str;
3354 - default = "meta.sr.ht";
3355 - description = ''
3356 - PostgreSQL database name for meta.sr.ht.
3357 - '';
3358 - };
3359 -
3360 - statePath = mkOption {
3361 - type = types.path;
3362 - default = "${cfg.statePath}/metasrht";
3363 - description = ''
3364 - State path for meta.sr.ht.
3365 - '';
3366 - };
3367 - };
3368 -
3369 - config = with scfg; lib.mkIf (cfg.enable && elem "meta" cfg.services) {
3370 - assertions =
3371 - [
3372 - {
3373 - assertion = with cfgIni."meta.sr.ht::billing"; enabled == "yes" -> (stripe-public-key != null && stripe-secret-key != null);
3374 - message = "If meta.sr.ht::billing is enabled, the keys should be defined.";
3375 - }
3376 - ];
3377 -
3378 - users = {
3379 - users = {
3380 - ${user} = {
3381 - isSystemUser = true;
3382 - group = user;
3383 - description = "meta.sr.ht user";
3384 - };
3385 - };
3386 -
3387 - groups = {
3388 - "${user}" = { };
3389 - };
3390 - };
3391 -
3392 - services.cron.systemCronJobs = [ "0 0 * * * ${cfg.python}/bin/metasrht-daily" ];
3393 - services.postgresql = {
3394 - authentication = ''
3395 - local ${database} ${user} trust
3396 - '';
3397 - ensureDatabases = [ database ];
3398 - ensureUsers = [
3399 - {
3400 - name = user;
3401 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
3402 - }
3403 - ];
3404 - };
3405 -
3406 - systemd = {
3407 - tmpfiles.rules = [
3408 - "d ${statePath} 0750 ${user} ${user} -"
3409 - ];
3410 -
3411 - services = {
3412 - metasrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
3413 - after = [ "postgresql.service" "network.target" ];
3414 - requires = [ "postgresql.service" ];
3415 - wantedBy = [ "multi-user.target" ];
3416 -
3417 - description = "meta.sr.ht website service";
3418 -
3419 - preStart = ''
3420 - # Configure client(s) as "preauthorized"
3421 - ${concatMapStringsSep "\n\n"
3422 - (attr: ''
3423 - if ! test -e "${statePath}/${attr}.oauth" || [ "$(cat ${statePath}/${attr}.oauth)" != "${cfgIni."${attr}".oauth-client-id}" ]; then
3424 - # Configure ${attr}'s OAuth client as "preauthorized"
3425 - psql ${database} \
3426 - -c "UPDATE oauthclient SET preauthorized = true WHERE client_id = '${cfgIni."${attr}".oauth-client-id}'"
3427 -
3428 - printf "%s" "${cfgIni."${attr}".oauth-client-id}" > "${statePath}/${attr}.oauth"
3429 - fi
3430 - '')
3431 - (builtins.attrNames (filterAttrs
3432 - (k: v: !(hasInfix "::" k) && builtins.hasAttr "oauth-client-id" v && v.oauth-client-id != null)
3433 - cfg.settings))}
3434 - '';
3435 -
3436 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
3437 - };
3438 -
3439 - metasrht-api = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
3440 - after = [ "postgresql.service" "network.target" ];
3441 - requires = [ "postgresql.service" ];
3442 - wantedBy = [ "multi-user.target" ];
3443 -
3444 - description = "meta.sr.ht api service";
3445 -
3446 - preStart = ''
3447 - # Configure client(s) as "preauthorized"
3448 - ${concatMapStringsSep "\n\n"
3449 - (attr: ''
3450 - if ! test -e "${statePath}/${attr}.oauth" || [ "$(cat ${statePath}/${attr}.oauth)" != "${cfgIni."${attr}".oauth-client-id}" ]; then
3451 - # Configure ${attr}'s OAuth client as "preauthorized"
3452 - psql ${database} \
3453 - -c "UPDATE oauthclient SET preauthorized = true WHERE client_id = '${cfgIni."${attr}".oauth-client-id}'"
3454 -
3455 - printf "%s" "${cfgIni."${attr}".oauth-client-id}" > "${statePath}/${attr}.oauth"
3456 - fi
3457 - '')
3458 - (builtins.attrNames (filterAttrs
3459 - (k: v: !(hasInfix "::" k) && builtins.hasAttr "oauth-client-id" v && v.oauth-client-id != null)
3460 - cfg.settings))}
3461 - '';
3462 -
3463 - serviceConfig.ExecStart = "${pkgs.sourcehut.metasrht}/bin/metasrht-api -b :${toString (port + 100)}";
3464 - };
3465 -
3466 - metasrht-webhooks = {
3467 - after = [ "postgresql.service" "network.target" ];
3468 - requires = [ "postgresql.service" ];
3469 - wantedBy = [ "multi-user.target" ];
3470 -
3471 - description = "meta.sr.ht webhooks service";
3472 - serviceConfig = {
3473 - Type = "simple";
3474 - User = user;
3475 - Restart = "always";
3476 - ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel=info";
3477 - };
3478 -
3479 - };
3480 - };
3481 - };
3482 -
3483 - services.sourcehut.settings = {
3484 - # URL meta.sr.ht is being served at (protocol://domain)
3485 - "meta.sr.ht".origin = mkDefault "https://meta.${cfg.originBase}";
3486 - # Address and port to bind the debug server to
3487 - "meta.sr.ht".debug-host = mkDefault "0.0.0.0";
3488 - "meta.sr.ht".debug-port = mkDefault port;
3489 - # Configures the SQLAlchemy connection string for the database.
3490 - "meta.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
3491 - # Set to "yes" to automatically run migrations on package upgrade.
3492 - "meta.sr.ht".migrate-on-upgrade = mkDefault "yes";
3493 - # If "yes", the user will be sent the stock sourcehut welcome emails after
3494 - # signup (requires cron to be configured properly). These are specific to the
3495 - # sr.ht instance so you probably want to patch these before enabling this.
3496 - "meta.sr.ht".welcome-emails = mkDefault "no";
3497 -
3498 - # The redis connection used for the webhooks worker
3499 - "meta.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/6";
3500 -
3501 - # If "no", public registration will not be permitted.
3502 - "meta.sr.ht::settings".registration = mkDefault "no";
3503 - # Where to redirect new users upon registration
3504 - "meta.sr.ht::settings".onboarding-redirect = mkDefault "https://meta.${cfg.originBase}";
3505 - # How many invites each user is issued upon registration (only applicable if
3506 - # open registration is disabled)
3507 - "meta.sr.ht::settings".user-invites = mkDefault 5;
3508 -
3509 - # Origin URL for API, 100 more than web
3510 - "meta.sr.ht".api-origin = mkDefault "http://localhost:5100";
3511 -
3512 - # You can add aliases for the client IDs of commonly used OAuth clients here.
3513 - #
3514 - # Example:
3515 - "meta.sr.ht::aliases" = mkDefault { };
3516 - # "meta.sr.ht::aliases"."git.sr.ht" = 12345;
3517 -
3518 - # "yes" to enable the billing system
3519 - "meta.sr.ht::billing".enabled = mkDefault "no";
3520 - # Get your keys at https://dashboard.stripe.com/account/apikeys
3521 - "meta.sr.ht::billing".stripe-public-key = mkDefault null;
3522 - "meta.sr.ht::billing".stripe-secret-key = mkDefault null;
3523 - };
3524 -
3525 - services.nginx.virtualHosts."meta.${cfg.originBase}" = {
3526 - forceSSL = true;
3527 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
3528 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
3529 - locations."/static".root = "${pkgs.sourcehut.metasrht}/${pkgs.sourcehut.python.sitePackages}/metasrht";
3530 - };
3531 - };
3532 -}
3533 diff --git a/nixos/modules/services/misc/sourcehut/paste.nix b/nixos/modules/services/misc/sourcehut/paste.nix
3534 deleted file mode 100644
3535 index b2d5151969e..00000000000
3536 --- a/nixos/modules/services/misc/sourcehut/paste.nix
3537 +++ /dev/null
3538 @@ -1,133 +0,0 @@
3539 -{ config, lib, pkgs, ... }:
3540 -
3541 -with lib;
3542 -let
3543 - cfg = config.services.sourcehut;
3544 - cfgIni = cfg.settings;
3545 - scfg = cfg.paste;
3546 - iniKey = "paste.sr.ht";
3547 -
3548 - rcfg = config.services.redis;
3549 - drv = pkgs.sourcehut.pastesrht;
3550 -in
3551 -{
3552 - options.services.sourcehut.paste = {
3553 - user = mkOption {
3554 - type = types.str;
3555 - default = "pastesrht";
3556 - description = ''
3557 - User for paste.sr.ht.
3558 - '';
3559 - };
3560 -
3561 - port = mkOption {
3562 - type = types.port;
3563 - default = 5011;
3564 - description = ''
3565 - Port on which the "paste" module should listen.
3566 - '';
3567 - };
3568 -
3569 - database = mkOption {
3570 - type = types.str;
3571 - default = "paste.sr.ht";
3572 - description = ''
3573 - PostgreSQL database name for paste.sr.ht.
3574 - '';
3575 - };
3576 -
3577 - statePath = mkOption {
3578 - type = types.path;
3579 - default = "${cfg.statePath}/pastesrht";
3580 - description = ''
3581 - State path for pastesrht.sr.ht.
3582 - '';
3583 - };
3584 - };
3585 -
3586 - config = with scfg; lib.mkIf (cfg.enable && elem "paste" cfg.services) {
3587 - users = {
3588 - users = {
3589 - "${user}" = {
3590 - isSystemUser = true;
3591 - group = user;
3592 - description = "paste.sr.ht user";
3593 - };
3594 - };
3595 -
3596 - groups = {
3597 - "${user}" = { };
3598 - };
3599 - };
3600 -
3601 - services.postgresql = {
3602 - authentication = ''
3603 - local ${database} ${user} trust
3604 - '';
3605 - ensureDatabases = [ database ];
3606 - ensureUsers = [
3607 - {
3608 - name = user;
3609 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
3610 - }
3611 - ];
3612 - };
3613 -
3614 - systemd = {
3615 - tmpfiles.rules = [
3616 - "d ${statePath} 0750 ${user} ${user} -"
3617 - ];
3618 -
3619 - services = {
3620 - pastesrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
3621 - after = [ "postgresql.service" "network.target" ];
3622 - requires = [ "postgresql.service" ];
3623 - wantedBy = [ "multi-user.target" ];
3624 -
3625 - description = "paste.sr.ht website service";
3626 -
3627 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
3628 - };
3629 -
3630 - pastesrht-webhooks = {
3631 - after = [ "postgresql.service" "network.target" ];
3632 - requires = [ "postgresql.service" ];
3633 - wantedBy = [ "multi-user.target" ];
3634 -
3635 - description = "paste.sr.ht webhooks service";
3636 - serviceConfig = {
3637 - Type = "simple";
3638 - User = user;
3639 - Restart = "always";
3640 - ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel=info";
3641 - };
3642 -
3643 - };
3644 - };
3645 - };
3646 -
3647 - services.sourcehut.settings = {
3648 - # URL paste.sr.ht is being served at (protocol://domain)
3649 - "paste.sr.ht".origin = mkDefault "http://paste.${cfg.originBase}";
3650 - # Address and port to bind the debug server to
3651 - "paste.sr.ht".debug-host = mkDefault "0.0.0.0";
3652 - "paste.sr.ht".debug-port = mkDefault port;
3653 - # Configures the SQLAlchemy connection string for the database.
3654 - "paste.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
3655 - # Set to "yes" to automatically run migrations on package upgrade.
3656 - "paste.sr.ht".migrate-on-upgrade = mkDefault "yes";
3657 - # paste.sr.ht's OAuth client ID and secret for meta.sr.ht
3658 - # Register your client at meta.example.org/oauth
3659 - "paste.sr.ht".oauth-client-id = mkDefault null;
3660 - "paste.sr.ht".oauth-client-secret = mkDefault null;
3661 - "paste.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/5";
3662 - };
3663 -
3664 - services.nginx.virtualHosts."paste.${cfg.originBase}" = {
3665 - forceSSL = true;
3666 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
3667 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
3668 - locations."/static".root = "${pkgs.sourcehut.pastesrht}/${pkgs.sourcehut.python.sitePackages}/pastesrht";
3669 - };
3670 - };
3671 -}
3672 diff --git a/nixos/modules/services/misc/sourcehut/service.nix b/nixos/modules/services/misc/sourcehut/service.nix
3673 index 65b4ad020f9..b3c0efc07dd 100644
3674 --- a/nixos/modules/services/misc/sourcehut/service.nix
3675 +++ b/nixos/modules/services/misc/sourcehut/service.nix
3676 @@ -1,66 +1,375 @@
3677 -{ config, pkgs, lib }:
3678 -serviceCfg: serviceDrv: iniKey: attrs:
3679 +srv:
3680 +{ configIniOfService
3681 +, srvsrht ? "${srv}srht" # Because "buildsrht" does not follow that pattern (missing an "s").
3682 +, iniKey ? "${srv}.sr.ht"
3683 +, webhooks ? false
3684 +, extraTimers ? {}
3685 +, mainService ? {}
3686 +, extraServices ? {}
3687 +, extraConfig ? {}
3688 +, port
3689 +}:
3690 +{ config, lib, pkgs, ... }:
3691 +
3692 +with lib;
3693 let
3694 + inherit (config.services) postgresql;
3695 + redis = config.services.redis.servers."sourcehut-${srvsrht}";
3696 + inherit (config.users) users;
3697 cfg = config.services.sourcehut;
3698 - cfgIni = cfg.settings."${iniKey}";
3699 - pgSuperUser = config.services.postgresql.superUser;
3700 -
3701 - setupDB = pkgs.writeScript "${serviceDrv.pname}-gen-db" ''
3702 - #! ${cfg.python}/bin/python
3703 - from ${serviceDrv.pname}.app import db
3704 - db.create()
3705 - '';
3706 + configIni = configIniOfService srv;
3707 + srvCfg = cfg.${srv};
3708 + baseService = serviceName: { allowStripe ? false }: extraService: let
3709 + runDir = "/run/sourcehut/${serviceName}";
3710 + rootDir = "/run/sourcehut/chroots/${serviceName}";
3711 + in
3712 + mkMerge [ extraService {
3713 + after = [ "network.target" ] ++
3714 + optional cfg.postgresql.enable "postgresql.service" ++
3715 + optional cfg.redis.enable "redis-sourcehut-${srvsrht}.service";
3716 + requires =
3717 + optional cfg.postgresql.enable "postgresql.service" ++
3718 + optional cfg.redis.enable "redis-sourcehut-${srvsrht}.service";
3719 + path = [ pkgs.gawk ];
3720 + environment.HOME = runDir;
3721 + serviceConfig = {
3722 + User = mkDefault srvCfg.user;
3723 + Group = mkDefault srvCfg.group;
3724 + RuntimeDirectory = [
3725 + "sourcehut/${serviceName}"
3726 + # Used by *srht-keys which reads ../config.ini
3727 + "sourcehut/${serviceName}/subdir"
3728 + "sourcehut/chroots/${serviceName}"
3729 + ];
3730 + RuntimeDirectoryMode = "2750";
3731 + # No need for the chroot path once inside the chroot
3732 + InaccessiblePaths = [ "-+${rootDir}" ];
3733 + # g+rx is for group members (eg. fcgiwrap or nginx)
3734 + # to read Git/Mercurial repositories, buildlogs, etc.
3735 + # o+x is for intermediate directories created by BindPaths= and like,
3736 + # as they're owned by root:root.
3737 + UMask = "0026";
3738 + RootDirectory = rootDir;
3739 + RootDirectoryStartOnly = true;
3740 + PrivateTmp = true;
3741 + MountAPIVFS = true;
3742 + # config.ini is looked up in there, before /etc/srht/config.ini
3743 + # Note that it fails to be set in ExecStartPre=
3744 + WorkingDirectory = mkDefault ("-"+runDir);
3745 + BindReadOnlyPaths = [
3746 + builtins.storeDir
3747 + "/etc"
3748 + "/run/booted-system"
3749 + "/run/current-system"
3750 + "/run/systemd"
3751 + ] ++
3752 + optional cfg.postgresql.enable "/run/postgresql" ++
3753 + optional cfg.redis.enable "/run/redis-sourcehut-${srvsrht}";
3754 + # LoadCredential= are unfortunately not available in ExecStartPre=
3755 + # Hence this one is run as root (the +) with RootDirectoryStartOnly=
3756 + # to reach credentials wherever they are.
3757 + # Note that each systemd service gets its own ${runDir}/config.ini file.
3758 + ExecStartPre = mkBefore [("+"+pkgs.writeShellScript "${serviceName}-credentials" ''
3759 + set -x
3760 + # Replace values begining with a '<' by the content of the file whose name is after.
3761 + gawk '{ if (match($0,/^([^=]+=)<(.+)/,m)) { getline f < m[2]; print m[1] f } else print $0 }' ${configIni} |
3762 + ${optionalString (!allowStripe) "gawk '!/^stripe-secret-key=/' |"}
3763 + install -o ${srvCfg.user} -g root -m 400 /dev/stdin ${runDir}/config.ini
3764 + '')];
3765 + # The following options are only for optimizing:
3766 + # systemd-analyze security
3767 + AmbientCapabilities = "";
3768 + CapabilityBoundingSet = "";
3769 + # ProtectClock= adds DeviceAllow=char-rtc r
3770 + DeviceAllow = "";
3771 + LockPersonality = true;
3772 + MemoryDenyWriteExecute = true;
3773 + NoNewPrivileges = true;
3774 + PrivateDevices = true;
3775 + PrivateMounts = true;
3776 + PrivateNetwork = mkDefault false;
3777 + PrivateUsers = true;
3778 + ProcSubset = "pid";
3779 + ProtectClock = true;
3780 + ProtectControlGroups = true;
3781 + ProtectHome = true;
3782 + ProtectHostname = true;
3783 + ProtectKernelLogs = true;
3784 + ProtectKernelModules = true;
3785 + ProtectKernelTunables = true;
3786 + ProtectProc = "invisible";
3787 + ProtectSystem = "strict";
3788 + RemoveIPC = true;
3789 + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
3790 + RestrictNamespaces = true;
3791 + RestrictRealtime = true;
3792 + RestrictSUIDSGID = true;
3793 + #SocketBindAllow = [ "tcp:${toString srvCfg.port}" "tcp:${toString srvCfg.prometheusPort}" ];
3794 + #SocketBindDeny = "any";
3795 + SystemCallFilter = [
3796 + "@system-service"
3797 + "~@aio" "~@keyring" "~@memlock" "~@privileged" "~@resources" "~@timer"
3798 + "@chown" "@setuid"
3799 + ];
3800 + SystemCallArchitectures = "native";
3801 + };
3802 + } ];
3803 in
3804 -with serviceCfg; with lib; recursiveUpdate
3805 {
3806 - environment.HOME = statePath;
3807 - path = [ config.services.postgresql.package ] ++ (attrs.path or [ ]);
3808 - restartTriggers = [ config.environment.etc."sr.ht/config.ini".source ];
3809 - serviceConfig = {
3810 - Type = "simple";
3811 - User = user;
3812 - Group = user;
3813 - Restart = "always";
3814 - WorkingDirectory = statePath;
3815 - } // (if (cfg.statePath == "/var/lib/sourcehut/${serviceDrv.pname}") then {
3816 - StateDirectory = [ "sourcehut/${serviceDrv.pname}" ];
3817 - } else {})
3818 - ;
3819 + options.services.sourcehut.${srv} = {
3820 + enable = mkEnableOption "${srv} service";
3821
3822 - preStart = ''
3823 - if ! test -e ${statePath}/db; then
3824 - # Setup the initial database
3825 - ${setupDB}
3826 + user = mkOption {
3827 + type = types.str;
3828 + default = srvsrht;
3829 + description = ''
3830 + User for ${srv}.sr.ht.
3831 + '';
3832 + };
3833
3834 - # Set the initial state of the database for future database upgrades
3835 - if test -e ${cfg.python}/bin/${serviceDrv.pname}-migrate; then
3836 - # Run alembic stamp head once to tell alembic the schema is up-to-date
3837 - ${cfg.python}/bin/${serviceDrv.pname}-migrate stamp head
3838 - fi
3839 + group = mkOption {
3840 + type = types.str;
3841 + default = srvsrht;
3842 + description = ''
3843 + Group for ${srv}.sr.ht.
3844 + Membership grants access to the Git/Mercurial repositories by default,
3845 + but not to the config.ini file (where secrets are).
3846 + '';
3847 + };
3848
3849 - printf "%s" "${serviceDrv.version}" > ${statePath}/db
3850 - fi
3851 + port = mkOption {
3852 + type = types.port;
3853 + default = port;
3854 + description = ''
3855 + Port on which the "${srv}" backend should listen.
3856 + '';
3857 + };
3858
3859 - # Update copy of each users' profile to the latest
3860 - # See https://lists.sr.ht/~sircmpwn/sr.ht-admins/<20190302181207.GA13778%40cirno.my.domain>
3861 - if ! test -e ${statePath}/webhook; then
3862 - # Update ${iniKey}'s users' profile copy to the latest
3863 - ${cfg.python}/bin/srht-update-profiles ${iniKey}
3864 + redis = {
3865 + host = mkOption {
3866 + type = types.str;
3867 + default = "unix:/run/redis-sourcehut-${srvsrht}/redis.sock?db=0";
3868 + example = "redis://shared.wireguard:6379/0";
3869 + description = ''
3870 + The redis host URL. This is used for caching and temporary storage, and must
3871 + be shared between nodes (e.g. git1.sr.ht and git2.sr.ht), but need not be
3872 + shared between services. It may be shared between services, however, with no
3873 + ill effect, if this better suits your infrastructure.
3874 + '';
3875 + };
3876 + };
3877
3878 - touch ${statePath}/webhook
3879 - fi
3880 + postgresql = {
3881 + database = mkOption {
3882 + type = types.str;
3883 + default = "${srv}.sr.ht";
3884 + description = ''
3885 + PostgreSQL database name for the ${srv}.sr.ht service,
3886 + used if <xref linkend="opt-services.sourcehut.postgresql.enable"/> is <literal>true</literal>.
3887 + '';
3888 + };
3889 + };
3890
3891 - ${optionalString (builtins.hasAttr "migrate-on-upgrade" cfgIni && cfgIni.migrate-on-upgrade == "yes") ''
3892 - if [ "$(cat ${statePath}/db)" != "${serviceDrv.version}" ]; then
3893 - # Manage schema migrations using alembic
3894 - ${cfg.python}/bin/${serviceDrv.pname}-migrate -a upgrade head
3895 + gunicorn = {
3896 + extraArgs = mkOption {
3897 + type = with types; listOf str;
3898 + default = ["--timeout 120" "--workers 1" "--log-level=info"];
3899 + description = "Extra arguments passed to Gunicorn.";
3900 + };
3901 + };
3902 + } // optionalAttrs webhooks {
3903 + webhooks = {
3904 + extraArgs = mkOption {
3905 + type = with types; listOf str;
3906 + default = ["--loglevel DEBUG" "--pool eventlet" "--without-heartbeat"];
3907 + description = "Extra arguments passed to the Celery responsible for webhooks.";
3908 + };
3909 + celeryConfig = mkOption {
3910 + type = types.lines;
3911 + default = "";
3912 + description = "Content of the <literal>celeryconfig.py</literal> used by the Celery responsible for webhooks.";
3913 + };
3914 + };
3915 + };
3916
3917 - # Mark down current package version
3918 - printf "%s" "${serviceDrv.version}" > ${statePath}/db
3919 - fi
3920 - ''}
3921 + config = lib.mkIf (cfg.enable && srvCfg.enable) (mkMerge [ extraConfig {
3922 + users = {
3923 + users = {
3924 + "${srvCfg.user}" = {
3925 + isSystemUser = true;
3926 + group = mkDefault srvCfg.group;
3927 + description = mkDefault "sourcehut user for ${srv}.sr.ht";
3928 + };
3929 + };
3930 + groups = {
3931 + "${srvCfg.group}" = { };
3932 + } // optionalAttrs (cfg.postgresql.enable
3933 + && hasSuffix "0" (postgresql.settings.unix_socket_permissions or "")) {
3934 + "postgres".members = [ srvCfg.user ];
3935 + } // optionalAttrs (cfg.redis.enable
3936 + && hasSuffix "0" (redis.settings.unixsocketperm or "")) {
3937 + "redis-sourcehut-${srvsrht}".members = [ srvCfg.user ];
3938 + };
3939 + };
3940
3941 - ${attrs.preStart or ""}
3942 - '';
3943 + services.nginx = mkIf cfg.nginx.enable {
3944 + virtualHosts."${srv}.${cfg.settings."sr.ht".global-domain}" = mkMerge [ {
3945 + forceSSL = true;
3946 + locations."/".proxyPass = "http://${cfg.listenAddress}:${toString srvCfg.port}";
3947 + locations."/static" = {
3948 + root = "${pkgs.sourcehut.${srvsrht}}/${pkgs.sourcehut.python.sitePackages}/${srvsrht}";
3949 + extraConfig = mkDefault ''
3950 + expires 30d;
3951 + '';
3952 + };
3953 + } cfg.nginx.virtualHost ];
3954 + };
3955 +
3956 + services.postgresql = mkIf cfg.postgresql.enable {
3957 + authentication = ''
3958 + local ${srvCfg.postgresql.database} ${srvCfg.user} trust
3959 + '';
3960 + ensureDatabases = [ srvCfg.postgresql.database ];
3961 + ensureUsers = map (name: {
3962 + inherit name;
3963 + ensurePermissions = { "DATABASE \"${srvCfg.postgresql.database}\"" = "ALL PRIVILEGES"; };
3964 + }) [srvCfg.user];
3965 + };
3966 +
3967 + services.sourcehut.services = mkDefault (filter (s: cfg.${s}.enable)
3968 + [ "builds" "dispatch" "git" "hg" "hub" "lists" "man" "meta" "pages" "paste" "todo" ]);
3969 +
3970 + services.sourcehut.settings = mkMerge [
3971 + {
3972 + "${srv}.sr.ht".origin = mkDefault "https://${srv}.${cfg.settings."sr.ht".global-domain}";
3973 + }
3974 +
3975 + (mkIf cfg.postgresql.enable {
3976 + "${srv}.sr.ht".connection-string = mkDefault "postgresql:///${srvCfg.postgresql.database}?user=${srvCfg.user}&host=/run/postgresql";
3977 + })
3978 + ];
3979 +
3980 + services.redis.servers."sourcehut-${srvsrht}" = mkIf cfg.redis.enable {
3981 + enable = true;
3982 + databases = 3;
3983 + syslog = true;
3984 + # TODO: set a more informed value
3985 + save = mkDefault [ [1800 10] [300 100] ];
3986 + settings = {
3987 + # TODO: set a more informed value
3988 + maxmemory = "128MB";
3989 + maxmemory-policy = "volatile-ttl";
3990 + };
3991 + };
3992 +
3993 + systemd.services = mkMerge [
3994 + {
3995 + "${srvsrht}" = baseService srvsrht { allowStripe = srv == "meta"; } (mkMerge [
3996 + {
3997 + description = "sourcehut ${srv}.sr.ht website service";
3998 + before = optional cfg.nginx.enable "nginx.service";
3999 + wants = optional cfg.nginx.enable "nginx.service";
4000 + wantedBy = [ "multi-user.target" ];
4001 + path = optional cfg.postgresql.enable postgresql.package;
4002 + # Beware: change in credentials' content will not trigger restart.
4003 + restartTriggers = [ configIni ];
4004 + serviceConfig = {
4005 + Type = "simple";
4006 + Restart = mkDefault "always";
4007 + #RestartSec = mkDefault "2min";
4008 + StateDirectory = [ "sourcehut/${srvsrht}" ];
4009 + StateDirectoryMode = "2750";
4010 + ExecStart = "${cfg.python}/bin/gunicorn ${srvsrht}.app:app --name ${srvsrht} --bind ${cfg.listenAddress}:${toString srvCfg.port} " + concatStringsSep " " srvCfg.gunicorn.extraArgs;
4011 + };
4012 + preStart = let
4013 + version = pkgs.sourcehut.${srvsrht}.version;
4014 + stateDir = "/var/lib/sourcehut/${srvsrht}";
4015 + in mkBefore ''
4016 + set -x
4017 + # Use the /run/sourcehut/${srvsrht}/config.ini
4018 + # installed by a previous ExecStartPre= in baseService
4019 + cd /run/sourcehut/${srvsrht}
4020 +
4021 + if test ! -e ${stateDir}/db; then
4022 + # Setup the initial database.
4023 + # Note that it stamps the alembic head afterward
4024 + ${cfg.python}/bin/${srvsrht}-initdb
4025 + echo ${version} >${stateDir}/db
4026 + fi
4027 +
4028 + ${optionalString cfg.settings.${iniKey}.migrate-on-upgrade ''
4029 + if [ "$(cat ${stateDir}/db)" != "${version}" ]; then
4030 + # Manage schema migrations using alembic
4031 + ${cfg.python}/bin/${srvsrht}-migrate -a upgrade head
4032 + echo ${version} >${stateDir}/db
4033 + fi
4034 + ''}
4035 +
4036 + # Update copy of each users' profile to the latest
4037 + # See https://lists.sr.ht/~sircmpwn/sr.ht-admins/<20190302181207.GA13778%40cirno.my.domain>
4038 + if test ! -e ${stateDir}/webhook; then
4039 + # Update ${iniKey}'s users' profile copy to the latest
4040 + ${cfg.python}/bin/srht-update-profiles ${iniKey}
4041 + touch ${stateDir}/webhook
4042 + fi
4043 + '';
4044 + } mainService ]);
4045 + }
4046 +
4047 + (mkIf webhooks {
4048 + "${srvsrht}-webhooks" = baseService "${srvsrht}-webhooks" {}
4049 + {
4050 + description = "sourcehut ${srv}.sr.ht webhooks service";
4051 + after = [ "${srvsrht}.service" ];
4052 + wantedBy = [ "${srvsrht}.service" ];
4053 + partOf = [ "${srvsrht}.service" ];
4054 + preStart = ''
4055 + cp ${pkgs.writeText "${srvsrht}-webhooks-celeryconfig.py" srvCfg.webhooks.celeryConfig} \
4056 + /run/sourcehut/${srvsrht}-webhooks/celeryconfig.py
4057 + '';
4058 + serviceConfig = {
4059 + Type = "simple";
4060 + Restart = "always";
4061 + ExecStart = "${cfg.python}/bin/celery --app ${srvsrht}.webhooks worker --hostname ${srvsrht}-webhooks@%%h " + concatStringsSep " " srvCfg.webhooks.extraArgs;
4062 + # Avoid crashing: os.getloadavg()
4063 + ProcSubset = mkForce "all";
4064 + };
4065 + };
4066 + })
4067 +
4068 + (mapAttrs (timerName: timer: (baseService timerName {} (mkMerge [
4069 + {
4070 + description = "sourcehut ${timerName} service";
4071 + after = [ "network.target" "${srvsrht}.service" ];
4072 + serviceConfig = {
4073 + Type = "oneshot";
4074 + ExecStart = "${cfg.python}/bin/${timerName}";
4075 + };
4076 + }
4077 + (timer.service or {})
4078 + ]))) extraTimers)
4079 +
4080 + (mapAttrs (serviceName: extraService: baseService serviceName {} (mkMerge [
4081 + {
4082 + description = "sourcehut ${serviceName} service";
4083 + # So that extraServices have the PostgreSQL database initialized.
4084 + after = [ "${srvsrht}.service" ];
4085 + wantedBy = [ "${srvsrht}.service" ];
4086 + partOf = [ "${srvsrht}.service" ];
4087 + serviceConfig = {
4088 + Type = "simple";
4089 + Restart = mkDefault "always";
4090 + };
4091 + }
4092 + extraService
4093 + ])) extraServices)
4094 + ];
4095 +
4096 + systemd.timers = mapAttrs (timerName: timer:
4097 + {
4098 + description = "sourcehut timer for ${timerName}";
4099 + wantedBy = [ "timers.target" ];
4100 + inherit (timer) timerConfig;
4101 + }) extraTimers;
4102 + } ]);
4103 }
4104 - (builtins.removeAttrs attrs [ "path" "preStart" ])
4105 diff --git a/nixos/modules/services/misc/sourcehut/sourcehut.xml b/nixos/modules/services/misc/sourcehut/sourcehut.xml
4106 index ab9a8c6cb4b..41094f65a94 100644
4107 --- a/nixos/modules/services/misc/sourcehut/sourcehut.xml
4108 +++ b/nixos/modules/services/misc/sourcehut/sourcehut.xml
4109 @@ -14,13 +14,12 @@
4110 <title>Basic usage</title>
4111 <para>
4112 Sourcehut is a Python and Go based set of applications.
4113 - <literal><link linkend="opt-services.sourcehut.enable">services.sourcehut</link></literal>
4114 - by default will use
4115 + This NixOS module also provides basic configuration integrating Sourcehut into locally running
4116 <literal><link linkend="opt-services.nginx.enable">services.nginx</link></literal>,
4117 - <literal><link linkend="opt-services.nginx.enable">services.redis</link></literal>,
4118 - <literal><link linkend="opt-services.nginx.enable">services.cron</link></literal>,
4119 + <literal><link linkend="opt-services.redis.servers">services.redis.servers.sourcehut</link></literal>,
4120 + <literal><link linkend="opt-services.postfix.enable">services.postfix</link></literal>
4121 and
4122 - <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal>.
4123 + <literal><link linkend="opt-services.postgresql.enable">services.postgresql</link></literal> services.
4124 </para>
4125
4126 <para>
4127 @@ -42,18 +41,23 @@ in {
4128
4129 services.sourcehut = {
4130 <link linkend="opt-services.sourcehut.enable">enable</link> = true;
4131 - <link linkend="opt-services.sourcehut.originBase">originBase</link> = fqdn;
4132 - <link linkend="opt-services.sourcehut.services">services</link> = [ "meta" "man" "git" ];
4133 + <link linkend="opt-services.sourcehut.git.enable">git.enable</link> = true;
4134 + <link linkend="opt-services.sourcehut.man.enable">man.enable</link> = true;
4135 + <link linkend="opt-services.sourcehut.meta.enable">meta.enable</link> = true;
4136 + <link linkend="opt-services.sourcehut.nginx.enable">nginx.enable</link> = true;
4137 + <link linkend="opt-services.sourcehut.postfix.enable">postfix.enable</link> = true;
4138 + <link linkend="opt-services.sourcehut.postgresql.enable">postgresql.enable</link> = true;
4139 + <link linkend="opt-services.sourcehut.redis.enable">redis.enable</link> = true;
4140 <link linkend="opt-services.sourcehut.settings">settings</link> = {
4141 "sr.ht" = {
4142 environment = "production";
4143 global-domain = fqdn;
4144 origin = "https://${fqdn}";
4145 # Produce keys with srht-keygen from <package>sourcehut.coresrht</package>.
4146 - network-key = "SECRET";
4147 - service-key = "SECRET";
4148 + network-key = "/run/keys/path/to/network-key";
4149 + service-key = "/run/keys/path/to/service-key";
4150 };
4151 - webhooks.private-key= "SECRET";
4152 + webhooks.private-key= "/run/keys/path/to/webhook-key";
4153 };
4154 };
4155
4156 diff --git a/nixos/modules/services/misc/sourcehut/todo.nix b/nixos/modules/services/misc/sourcehut/todo.nix
4157 deleted file mode 100644
4158 index aec773b0669..00000000000
4159 --- a/nixos/modules/services/misc/sourcehut/todo.nix
4160 +++ /dev/null
4161 @@ -1,161 +0,0 @@
4162 -{ config, lib, pkgs, ... }:
4163 -
4164 -with lib;
4165 -let
4166 - cfg = config.services.sourcehut;
4167 - cfgIni = cfg.settings;
4168 - scfg = cfg.todo;
4169 - iniKey = "todo.sr.ht";
4170 -
4171 - rcfg = config.services.redis;
4172 - drv = pkgs.sourcehut.todosrht;
4173 -in
4174 -{
4175 - options.services.sourcehut.todo = {
4176 - user = mkOption {
4177 - type = types.str;
4178 - default = "todosrht";
4179 - description = ''
4180 - User for todo.sr.ht.
4181 - '';
4182 - };
4183 -
4184 - port = mkOption {
4185 - type = types.port;
4186 - default = 5003;
4187 - description = ''
4188 - Port on which the "todo" module should listen.
4189 - '';
4190 - };
4191 -
4192 - database = mkOption {
4193 - type = types.str;
4194 - default = "todo.sr.ht";
4195 - description = ''
4196 - PostgreSQL database name for todo.sr.ht.
4197 - '';
4198 - };
4199 -
4200 - statePath = mkOption {
4201 - type = types.path;
4202 - default = "${cfg.statePath}/todosrht";
4203 - description = ''
4204 - State path for todo.sr.ht.
4205 - '';
4206 - };
4207 - };
4208 -
4209 - config = with scfg; lib.mkIf (cfg.enable && elem "todo" cfg.services) {
4210 - users = {
4211 - users = {
4212 - "${user}" = {
4213 - isSystemUser = true;
4214 - group = user;
4215 - extraGroups = [ "postfix" ];
4216 - description = "todo.sr.ht user";
4217 - };
4218 - };
4219 - groups = {
4220 - "${user}" = { };
4221 - };
4222 - };
4223 -
4224 - services.postgresql = {
4225 - authentication = ''
4226 - local ${database} ${user} trust
4227 - '';
4228 - ensureDatabases = [ database ];
4229 - ensureUsers = [
4230 - {
4231 - name = user;
4232 - ensurePermissions = { "DATABASE \"${database}\"" = "ALL PRIVILEGES"; };
4233 - }
4234 - ];
4235 - };
4236 -
4237 - systemd = {
4238 - tmpfiles.rules = [
4239 - "d ${statePath} 0750 ${user} ${user} -"
4240 - ];
4241 -
4242 - services = {
4243 - todosrht = import ./service.nix { inherit config pkgs lib; } scfg drv iniKey {
4244 - after = [ "postgresql.service" "network.target" ];
4245 - requires = [ "postgresql.service" ];
4246 - wantedBy = [ "multi-user.target" ];
4247 -
4248 - description = "todo.sr.ht website service";
4249 -
4250 - serviceConfig.ExecStart = "${cfg.python}/bin/gunicorn ${drv.pname}.app:app -b ${cfg.address}:${toString port}";
4251 - };
4252 -
4253 - todosrht-lmtp = {
4254 - after = [ "postgresql.service" "network.target" ];
4255 - bindsTo = [ "postgresql.service" ];
4256 - wantedBy = [ "multi-user.target" ];
4257 -
4258 - description = "todo.sr.ht process service";
4259 - serviceConfig = {
4260 - Type = "simple";
4261 - User = user;
4262 - Restart = "always";
4263 - ExecStart = "${cfg.python}/bin/todosrht-lmtp";
4264 - };
4265 - };
4266 -
4267 - todosrht-webhooks = {
4268 - after = [ "postgresql.service" "network.target" ];
4269 - requires = [ "postgresql.service" ];
4270 - wantedBy = [ "multi-user.target" ];
4271 -
4272 - description = "todo.sr.ht webhooks service";
4273 - serviceConfig = {
4274 - Type = "simple";
4275 - User = user;
4276 - Restart = "always";
4277 - ExecStart = "${cfg.python}/bin/celery -A ${drv.pname}.webhooks worker --loglevel=info";
4278 - };
4279 -
4280 - };
4281 - };
4282 - };
4283 -
4284 - services.sourcehut.settings = {
4285 - # URL todo.sr.ht is being served at (protocol://domain)
4286 - "todo.sr.ht".origin = mkDefault "http://todo.${cfg.originBase}";
4287 - # Address and port to bind the debug server to
4288 - "todo.sr.ht".debug-host = mkDefault "0.0.0.0";
4289 - "todo.sr.ht".debug-port = mkDefault port;
4290 - # Configures the SQLAlchemy connection string for the database.
4291 - "todo.sr.ht".connection-string = mkDefault "postgresql:///${database}?user=${user}&host=/var/run/postgresql";
4292 - # Set to "yes" to automatically run migrations on package upgrade.
4293 - "todo.sr.ht".migrate-on-upgrade = mkDefault "yes";
4294 - # todo.sr.ht's OAuth client ID and secret for meta.sr.ht
4295 - # Register your client at meta.example.org/oauth
4296 - "todo.sr.ht".oauth-client-id = mkDefault null;
4297 - "todo.sr.ht".oauth-client-secret = mkDefault null;
4298 - # Outgoing email for notifications generated by users
4299 - "todo.sr.ht".notify-from = mkDefault "CHANGEME@example.org";
4300 - # The redis connection used for the webhooks worker
4301 - "todo.sr.ht".webhooks = mkDefault "redis://${rcfg.bind}:${toString rcfg.port}/1";
4302 - # Network-key
4303 - "todo.sr.ht".network-key = mkDefault null;
4304 -
4305 - # Path for the lmtp daemon's unix socket. Direct incoming mail to this socket.
4306 - # Alternatively, specify IP:PORT and an SMTP server will be run instead.
4307 - "todo.sr.ht::mail".sock = mkDefault "/tmp/todo.sr.ht-lmtp.sock";
4308 - # The lmtp daemon will make the unix socket group-read/write for users in this
4309 - # group.
4310 - "todo.sr.ht::mail".sock-group = mkDefault "postfix";
4311 -
4312 - "todo.sr.ht::mail".posting-domain = mkDefault "todo.${cfg.originBase}";
4313 - };
4314 -
4315 - services.nginx.virtualHosts."todo.${cfg.originBase}" = {
4316 - forceSSL = true;
4317 - locations."/".proxyPass = "http://${cfg.address}:${toString port}";
4318 - locations."/query".proxyPass = "http://${cfg.address}:${toString (port + 100)}";
4319 - locations."/static".root = "${pkgs.sourcehut.todosrht}/${pkgs.sourcehut.python.sitePackages}/todosrht";
4320 - };
4321 - };
4322 -}
4323 diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
4324 index dab99dd8d04..2b6ba687fe8 100644
4325 --- a/nixos/tests/all-tests.nix
4326 +++ b/nixos/tests/all-tests.nix
4327 @@ -408,6 +408,7 @@ in
4328 solanum = handleTest ./solanum.nix {};
4329 solr = handleTest ./solr.nix {};
4330 sonarr = handleTest ./sonarr.nix {};
4331 + sourcehut = handleTest ./sourcehut.nix {};
4332 spacecookie = handleTest ./spacecookie.nix {};
4333 spike = handleTest ./spike.nix {};
4334 sslh = handleTest ./sslh.nix {};
4335 diff --git a/nixos/tests/sourcehut.nix b/nixos/tests/sourcehut.nix
4336 index b56a14ebf85..6492250bd57 100644
4337 --- a/nixos/tests/sourcehut.nix
4338 +++ b/nixos/tests/sourcehut.nix
4339 @@ -12,10 +12,20 @@ import ./make-test-python.nix ({ pkgs, ... }:
4340 services.sourcehut = {
4341 enable = true;
4342 services = [ "meta" ];
4343 - originBase = "sourcehut";
4344 - settings."sr.ht".service-key = "8888888888888888888888888888888888888888888888888888888888888888";
4345 - settings."sr.ht".network-key = "0000000000000000000000000000000000000000000=";
4346 - settings.webhooks.private-key = "0000000000000000000000000000000000000000000=";
4347 + redis.enable = true;
4348 + postgresql.enable = true;
4349 + meta.enable = true;
4350 + settings."sr.ht" = {
4351 + global-domain = "sourcehut";
4352 + service-key = pkgs.writeText "service-key" "8b327279b77e32a3620e2fc9aabce491cc46e7d821fd6713b2a2e650ce114d01";
4353 + network-key = pkgs.writeText "network-key" "cEEmc30BRBGkgQZcHFksiG7hjc6_dK1XR2Oo5Jb9_nQ=";
4354 + };
4355 + settings.webhooks.private-key = pkgs.writeText "webhook-key" "Ra3IjxgFiwG9jxgp4WALQIZw/BMYt30xWiOsqD0J7EA=";
4356 + };
4357 + services.postgresql = {
4358 + enable = true;
4359 + enableTCPIP = false;
4360 + settings.unix_socket_permissions = "0770";
4361 };
4362 };
4363
4364 diff --git a/pkgs/applications/version-management/sourcehut/builds.nix b/pkgs/applications/version-management/sourcehut/builds.nix
4365 index c8163caf8ea..a0bd6e83b3c 100644
4366 --- a/pkgs/applications/version-management/sourcehut/builds.nix
4367 +++ b/pkgs/applications/version-management/sourcehut/builds.nix
4368 @@ -11,26 +11,55 @@
4369 , python
4370 }:
4371 let
4372 - version = "0.66.7";
4373 -
4374 - buildWorker = src: buildGoModule {
4375 - inherit src version;
4376 - pname = "builds-sr-ht-worker";
4377 -
4378 - vendorSha256 = "sha256-giOaldV46aBqXyFH/cQVsbUr6Rb4VMhbBO86o48tRZY=";
4379 - };
4380 -in
4381 -buildPythonPackage rec {
4382 - inherit version;
4383 - pname = "buildsrht";
4384 + version = "0.71.0";
4385
4386 src = fetchFromSourcehut {
4387 owner = "~sircmpwn";
4388 repo = "builds.sr.ht";
4389 rev = version;
4390 - sha256 = "sha256-2MLs/DOXHjEYarXDVUcPZe3o0fmZbzVxn528SE72lhM=";
4391 + sha256 = "sha256-S3mMndUdVGi+YxAOI3wSNlSZrH3cwumxatXpErS2yQI=";
4392 };
4393
4394 + worker = buildGoModule rec {
4395 + inherit src version;
4396 + sourceRoot = "source/worker";
4397 + pname = "buildsrht-worker";
4398 +
4399 + vendorSha256 = "sha256-iMlCZPCIwhppPAYUi6E8td1BoNaqBuQCI5E83cnEBJ0=";
4400 +
4401 + # What follows is only to update go-redis,
4402 + # and thus also using a patched srht-keys.
4403 + # go.{mod,sum} could be patched directly but that would be less resilient
4404 + # to changes from upstream, and thus harder to maintain the patching
4405 + # while it hasn't been merged upstream.
4406 +
4407 + overrideModAttrs = old: {
4408 + inherit patches patchFlags;
4409 + preBuild = ''
4410 + go get github.com/go-redis/redis/v8
4411 + go get github.com/go-redis/redis@none
4412 + go mod tidy
4413 + '';
4414 + # Pass updated go.{mod,sum} from go-modules to worker's vendor/go.{mod,sum}
4415 + postInstall = ''
4416 + cp --reflink=auto go.* $out/
4417 + '';
4418 + };
4419 +
4420 + patches = [
4421 + # Update go-redis to support Unix sockets
4422 + patches/redis-socket/build/v3-0001-worker-update-go-redis-to-support-Unix-sockets.patch
4423 + ];
4424 + patchFlags = "-p2";
4425 + postConfigure = ''
4426 + cp -v vendor/go.{mod,sum} .
4427 + '';
4428 + };
4429 +in
4430 +buildPythonPackage rec {
4431 + inherit src version;
4432 + pname = "buildsrht";
4433 +
4434 nativeBuildInputs = srht.nativeBuildInputs;
4435
4436 propagatedBuildInputs = [
4437 @@ -53,13 +82,18 @@ buildPythonPackage rec {
4438
4439 cp -r images $out/lib
4440 cp contrib/submit_image_build $out/bin/builds.sr.ht
4441 - cp ${buildWorker "${src}/worker"}/bin/worker $out/bin/builds.sr.ht-worker
4442 + cp ${worker}/bin/worker $out/bin/builds.sr.ht-worker
4443 + cp --reflink=auto *.go vendor/go.* $out
4444 '';
4445
4446 + pythonImportsCheck = [ "buildsrht" ];
4447 +
4448 + passthru = { inherit worker; };
4449 +
4450 meta = with lib; {
4451 homepage = "https://git.sr.ht/~sircmpwn/builds.sr.ht";
4452 description = "Continuous integration service for the sr.ht network";
4453 - license = licenses.agpl3;
4454 + license = licenses.agpl3Only;
4455 maintainers = with maintainers; [ eadwu ];
4456 };
4457 }
4458 diff --git a/pkgs/applications/version-management/sourcehut/core.nix b/pkgs/applications/version-management/sourcehut/core.nix
4459 index 7c3a516ed9d..2e2c55617dc 100644
4460 --- a/pkgs/applications/version-management/sourcehut/core.nix
4461 +++ b/pkgs/applications/version-management/sourcehut/core.nix
4462 @@ -25,17 +25,16 @@
4463 , sassc
4464 , nodejs
4465 , redis
4466 -, writeText
4467 }:
4468
4469 buildPythonPackage rec {
4470 pname = "srht";
4471 - version = "0.67.4";
4472 + version = "0.67.18";
4473
4474 src = fetchgit {
4475 url = "https://git.sr.ht/~sircmpwn/core.sr.ht";
4476 rev = version;
4477 - sha256 = "sha256-XvzFfcBK5Mq8p7xEBAF/eupUE1kkUBh5k+ByM/WA9bc=";
4478 + sha256 = "sha256-lPPB1DRWHANGBBfWeu0pUn1xBkd37ZhyreozLlxX6cA=";
4479 fetchSubmodules = true;
4480 };
4481
4482 @@ -46,7 +45,12 @@ buildPythonPackage rec {
4483 };
4484
4485 patches = [
4486 - ./disable-npm-install.patch
4487 + # Disable check for npm
4488 + patches/disable-npm-install.patch
4489 + # Fix broken hack: removing dots from "builds.sr.ht" does not produce "buildsrht"
4490 + patches/srht-update-profiles/0001-fix-disgusting-hack-in-the-case-of-buildsrht.patch
4491 + # Add Unix socket support for redis-host=
4492 + patches/redis-socket/core/v3-0001-add-Unix-socket-support-for-redis-host.patch
4493 ];
4494
4495 nativeBuildInputs = [
4496 @@ -87,6 +91,7 @@ buildPythonPackage rec {
4497 '';
4498
4499 dontUseSetuptoolsCheck = true;
4500 + pythonImportsCheck = [ "srht" ];
4501
4502 meta = with lib; {
4503 homepage = "https://git.sr.ht/~sircmpwn/srht";
4504 diff --git a/pkgs/applications/version-management/sourcehut/default.nix b/pkgs/applications/version-management/sourcehut/default.nix
4505 index 401a1437b7d..7dde841b543 100644
4506 --- a/pkgs/applications/version-management/sourcehut/default.nix
4507 +++ b/pkgs/applications/version-management/sourcehut/default.nix
4508 @@ -22,10 +22,12 @@ let
4509 listssrht = self.callPackage ./lists.nix { };
4510 mansrht = self.callPackage ./man.nix { };
4511 metasrht = self.callPackage ./meta.nix { };
4512 + pagessrht = self.callPackage ./pages.nix { };
4513 pastesrht = self.callPackage ./paste.nix { };
4514 todosrht = self.callPackage ./todo.nix { };
4515
4516 scmsrht = self.callPackage ./scm.nix { };
4517 + srht-keys = self.scmsrht.srht-keys;
4518 };
4519 };
4520 in
4521 @@ -40,6 +42,8 @@ with python.pkgs; recurseIntoAttrs {
4522 listssrht = toPythonApplication listssrht;
4523 mansrht = toPythonApplication mansrht;
4524 metasrht = toPythonApplication metasrht;
4525 + pagessrht = pagessrht;
4526 pastesrht = toPythonApplication pastesrht;
4527 todosrht = toPythonApplication todosrht;
4528 + srht-keys = scmsrht.srht-keys;
4529 }
4530 diff --git a/pkgs/applications/version-management/sourcehut/dispatch.nix b/pkgs/applications/version-management/sourcehut/dispatch.nix
4531 index 637c6f9c1df..9456d0c998c 100644
4532 --- a/pkgs/applications/version-management/sourcehut/dispatch.nix
4533 +++ b/pkgs/applications/version-management/sourcehut/dispatch.nix
4534 @@ -9,13 +9,13 @@
4535
4536 buildPythonPackage rec {
4537 pname = "dispatchsrht";
4538 - version = "0.15.8";
4539 + version = "0.15.32";
4540
4541 src = fetchFromSourcehut {
4542 owner = "~sircmpwn";
4543 repo = "dispatch.sr.ht";
4544 rev = version;
4545 - sha256 = "sha256-zWCGPjIgMKHXHJUs9aciV7IFgo0rpahon6KXHDwcfss=";
4546 + sha256 = "sha256-4P4cXhjcZ8IBzpRfmYIJkzl9U4Plo36a48Pf/KjmhFY=";
4547 };
4548
4549 nativeBuildInputs = srht.nativeBuildInputs;
4550 @@ -31,10 +31,12 @@ buildPythonPackage rec {
4551 export SRHT_PATH=${srht}/${python.sitePackages}/srht
4552 '';
4553
4554 + pythonImportsCheck = [ "dispatchsrht" ];
4555 +
4556 meta = with lib; {
4557 homepage = "https://dispatch.sr.ht/~sircmpwn/dispatch.sr.ht";
4558 description = "Task dispatcher and service integration tool for the sr.ht network";
4559 - license = licenses.agpl3;
4560 + license = licenses.agpl3Only;
4561 maintainers = with maintainers; [ eadwu ];
4562 };
4563 }
4564 diff --git a/pkgs/applications/version-management/sourcehut/git.nix b/pkgs/applications/version-management/sourcehut/git.nix
4565 index e44fb9cd6c6..33394e13ac8 100644
4566 --- a/pkgs/applications/version-management/sourcehut/git.nix
4567 +++ b/pkgs/applications/version-management/sourcehut/git.nix
4568 @@ -6,42 +6,111 @@
4569 , srht
4570 , pygit2
4571 , scmsrht
4572 +, srht-keys
4573 }:
4574 let
4575 - version = "0.72.8";
4576 + version = "0.72.44";
4577
4578 src = fetchFromSourcehut {
4579 owner = "~sircmpwn";
4580 repo = "git.sr.ht";
4581 rev = version;
4582 - sha256 = "sha256-AB2uzajO5PtcpJfbOOTfuDFM6is5K39v3AZJ1hShRNc=";
4583 + sha256 = "sha256-U+hJiQpAJIHBC//M/Lfw82DLhZF46qHhz8zZW1ZvJoo=";
4584 };
4585
4586 - buildShell = src: buildGoModule {
4587 + gitsrht-shell = buildGoModule {
4588 inherit src version;
4589 + sourceRoot = "source/gitsrht-shell";
4590 pname = "gitsrht-shell";
4591 vendorSha256 = "sha256-aqUFICp0C2reqb2p6JCPAUIRsxzSv0t9BHoNWrTYfqk=";
4592 };
4593
4594 - buildDispatcher = src: buildGoModule {
4595 + gitsrht-dispatch = buildGoModule {
4596 inherit src version;
4597 + sourceRoot = "source/gitsrht-dispatch";
4598 pname = "gitsrht-dispatcher";
4599 vendorSha256 = "sha256-qWXPHo86s6iuRBhRMtmD5jxnAWKdrWHtA/iSUkdw89M=";
4600 + patches = [
4601 + # Add support for supplementary groups
4602 + patches/redis-socket/git/v3-0003-gitsrht-dispatch-add-support-for-supplementary-gr.patch
4603 + ];
4604 + patchFlags = "-p2";
4605 };
4606
4607 - buildKeys = src: buildGoModule {
4608 + gitsrht-keys = buildGoModule rec {
4609 inherit src version;
4610 + sourceRoot = "source/gitsrht-keys";
4611 pname = "gitsrht-keys";
4612 - vendorSha256 = "1d94cqy7x0q0agwg515xxsbl70b3qrzxbzsyjhn1pbyj532brn7f";
4613 + vendorSha256 = "sha256-0Rnyo4IRQFhM4LFi0499+xJaboMiKEYOgoR5BumzRE8=";
4614 +
4615 + # What follows is only to update go-redis,
4616 + # and thus also using a patched srht-keys.
4617 + # go.{mod,sum} could be patched directly but that would be less resilient
4618 + # to changes from upstream, and thus harder to maintain the patching
4619 + # while it hasn't been merged upstream.
4620 +
4621 + overrideModAttrs = old: {
4622 + inherit patches patchFlags;
4623 + preBuild = ''
4624 + # This is a fixed-output derivation so it is not allowed to reference other derivations,
4625 + # but here srht-keys will be copied to vendor/ by go mod vendor
4626 + ln -s ${srht-keys} srht-keys
4627 + go mod edit -replace git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys=$PWD/srht-keys
4628 + go get github.com/go-redis/redis/v8
4629 + go get github.com/go-redis/redis@none
4630 + go mod tidy
4631 + '';
4632 + # Pass updated go.{mod,sum} from go-modules to gitsrht-keys' vendor/go.{mod,sum}
4633 + postInstall = ''
4634 + cp --reflink=auto go.* $out/
4635 + '';
4636 + };
4637 +
4638 + patches = [
4639 + # Update go-redis to support Unix sockets
4640 + patches/redis-socket/git/v3-0001-gitsrht-keys-update-go-redis-to-support-Unix-sock.patch
4641 + ];
4642 + patchFlags = "-p2";
4643 + postConfigure = ''
4644 + cp -v vendor/go.{mod,sum} .
4645 + '';
4646 };
4647
4648 - buildUpdateHook = src: buildGoModule {
4649 + gitsrht-update-hook = buildGoModule rec {
4650 inherit src version;
4651 + sourceRoot = "source/gitsrht-update-hook";
4652 pname = "gitsrht-update-hook";
4653 - vendorSha256 = "0fwzqpjv8x5y3w3bfjd0x0cvqjjak23m0zj88hf32jpw49xmjkih";
4654 - };
4655 + vendorSha256 = "sha256-UoHxGVYEgTDqFzVQ2Dv6BRT4jVt+/QpNqEH3G2UWFjs=";
4656
4657 - updateHook = buildUpdateHook "${src}/gitsrht-update-hook";
4658 + # What follows is only to update go-redis
4659 + # and thus also using a patched srht-keys.
4660 +
4661 + overrideModAttrs = old: {
4662 + inherit patches patchFlags;
4663 + preBuild = ''
4664 + # This is a fixed-output derivation so it is not allowed to reference other derivations,
4665 + # but here srht-keys will be copied to vendor/ by go mod vendor
4666 + ln -s ${srht-keys} srht-keys
4667 + go mod edit -replace git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys=$PWD/srht-keys
4668 + go get github.com/go-redis/redis/v8
4669 + go get github.com/go-redis/redis@none
4670 + go mod tidy
4671 + '';
4672 + # Pass updated go.{mod,sum} from go-modules to gitsrht-keys' vendor/go.{mod,sum}
4673 + postInstall = ''
4674 + cp --reflink=auto go.* $out/
4675 + '';
4676 + };
4677 +
4678 + patches = [
4679 + # Update go-redis to support Unix sockets
4680 + patches/redis-socket/git/v3-0002-gitsrht-update-hook-update-go-redis-to-support-Un.patch
4681 + ];
4682 + patchFlags = "-p2";
4683 + postConfigure = ''
4684 + cp -v vendor/go.{mod,sum} .
4685 + '';
4686 + };
4687
4688 in
4689 buildPythonPackage rec {
4690 @@ -63,19 +132,21 @@ buildPythonPackage rec {
4691
4692 postInstall = ''
4693 mkdir -p $out/bin
4694 - cp ${buildShell "${src}/gitsrht-shell"}/bin/gitsrht-shell $out/bin/gitsrht-shell
4695 - cp ${buildDispatcher "${src}/gitsrht-dispatch"}/bin/gitsrht-dispatch $out/bin/gitsrht-dispatch
4696 - cp ${buildKeys "${src}/gitsrht-keys"}/bin/gitsrht-keys $out/bin/gitsrht-keys
4697 - cp ${updateHook}/bin/gitsrht-update-hook $out/bin/gitsrht-update-hook
4698 + cp ${gitsrht-shell}/bin/gitsrht-shell $out/bin/gitsrht-shell
4699 + cp ${gitsrht-dispatch}/bin/gitsrht-dispatch $out/bin/gitsrht-dispatch
4700 + cp ${gitsrht-keys}/bin/gitsrht-keys $out/bin/gitsrht-keys
4701 + cp ${gitsrht-update-hook}/bin/gitsrht-update-hook $out/bin/gitsrht-update-hook
4702 '';
4703 passthru = {
4704 - inherit updateHook;
4705 + inherit gitsrht-shell gitsrht-dispatch gitsrht-keys gitsrht-update-hook;
4706 };
4707
4708 + pythonImportsCheck = [ "gitsrht" ];
4709 +
4710 meta = with lib; {
4711 homepage = "https://git.sr.ht/~sircmpwn/git.sr.ht";
4712 description = "Git repository hosting service for the sr.ht network";
4713 - license = licenses.agpl3;
4714 + license = licenses.agpl3Only;
4715 maintainers = with maintainers; [ eadwu ];
4716 };
4717 }
4718 diff --git a/pkgs/applications/version-management/sourcehut/hg.nix b/pkgs/applications/version-management/sourcehut/hg.nix
4719 index cddb76cabf2..1d6062d81cc 100644
4720 --- a/pkgs/applications/version-management/sourcehut/hg.nix
4721 +++ b/pkgs/applications/version-management/sourcehut/hg.nix
4722 @@ -10,12 +10,12 @@
4723
4724 buildPythonPackage rec {
4725 pname = "hgsrht";
4726 - version = "0.27.4";
4727 + version = "0.27.6";
4728
4729 src = fetchhg {
4730 url = "https://hg.sr.ht/~sircmpwn/hg.sr.ht";
4731 rev = version;
4732 - sha256 = "1c0qfi0gmbfngvds6917fy9ii2iglawn429757rh7b4bvzn7n6mr";
4733 + sha256 = "ibijvKjS4CiWTYrO6Qdh3RkD0EUE7BY8wjdPwrD6vkA=";
4734 };
4735
4736 nativeBuildInputs = srht.nativeBuildInputs;
4737 @@ -32,10 +32,12 @@ buildPythonPackage rec {
4738 export SRHT_PATH=${srht}/${python.sitePackages}/srht
4739 '';
4740
4741 + pythonImportsCheck = [ "hgsrht" ];
4742 +
4743 meta = with lib; {
4744 homepage = "https://git.sr.ht/~sircmpwn/hg.sr.ht";
4745 description = "Mercurial repository hosting service for the sr.ht network";
4746 - license = licenses.agpl3;
4747 + license = licenses.agpl3Only;
4748 maintainers = with maintainers; [ eadwu ];
4749 };
4750 }
4751 diff --git a/pkgs/applications/version-management/sourcehut/hub.nix b/pkgs/applications/version-management/sourcehut/hub.nix
4752 index 17cb3fe4b61..31191cba713 100644
4753 --- a/pkgs/applications/version-management/sourcehut/hub.nix
4754 +++ b/pkgs/applications/version-management/sourcehut/hub.nix
4755 @@ -6,13 +6,13 @@
4756
4757 buildPythonPackage rec {
4758 pname = "hubsrht";
4759 - version = "0.13.1";
4760 + version = "0.13.8";
4761
4762 src = fetchFromSourcehut {
4763 owner = "~sircmpwn";
4764 repo = "hub.sr.ht";
4765 rev = version;
4766 - sha256 = "sha256-Kqzy4mh5Nn1emzHBco/LVuXro/tW3NX+OYqdEwBSQ/U=";
4767 + sha256 = "sha256-RsRJxwViEoQLh86o+8kQE5PBlLrOyIFM7hkSGjXhqdg=";
4768 };
4769
4770 nativeBuildInputs = srht.nativeBuildInputs;
4771 @@ -26,11 +26,12 @@ buildPythonPackage rec {
4772 '';
4773
4774 dontUseSetuptoolsCheck = true;
4775 + pythonImportsCheck = [ "hubsrht" ];
4776
4777 meta = with lib; {
4778 homepage = "https://git.sr.ht/~sircmpwn/hub.sr.ht";
4779 description = "Project hub service for the sr.ht network";
4780 - license = licenses.agpl3;
4781 + license = licenses.agpl3Only;
4782 maintainers = with maintainers; [ eadwu ];
4783 };
4784 }
4785 diff --git a/pkgs/applications/version-management/sourcehut/lists.nix b/pkgs/applications/version-management/sourcehut/lists.nix
4786 index b419b49f7b5..0882241401a 100644
4787 --- a/pkgs/applications/version-management/sourcehut/lists.nix
4788 +++ b/pkgs/applications/version-management/sourcehut/lists.nix
4789 @@ -12,13 +12,13 @@
4790
4791 buildPythonPackage rec {
4792 pname = "listssrht";
4793 - version = "0.48.19";
4794 + version = "0.49.3";
4795
4796 src = fetchFromSourcehut {
4797 owner = "~sircmpwn";
4798 repo = "lists.sr.ht";
4799 rev = version;
4800 - sha256 = "sha256-bsakEMyvWaxiE4/SGcAP4mlGG9jkdHfFxpt9H+TJn/8=";
4801 + sha256 = "sha256-kEzKgB8godIL7hEXMrqaxVte6RJAegjT4keZifXbOq0=";
4802 };
4803
4804 nativeBuildInputs = srht.nativeBuildInputs;
4805 @@ -37,10 +37,12 @@ buildPythonPackage rec {
4806 export SRHT_PATH=${srht}/${python.sitePackages}/srht
4807 '';
4808
4809 + pythonImportsCheck = [ "listssrht" ];
4810 +
4811 meta = with lib; {
4812 homepage = "https://git.sr.ht/~sircmpwn/lists.sr.ht";
4813 description = "Mailing list service for the sr.ht network";
4814 - license = licenses.agpl3;
4815 + license = licenses.agpl3Only;
4816 maintainers = with maintainers; [ eadwu ];
4817 };
4818 }
4819 diff --git a/pkgs/applications/version-management/sourcehut/man.nix b/pkgs/applications/version-management/sourcehut/man.nix
4820 index bd331f000a7..47c6bb0ac4f 100644
4821 --- a/pkgs/applications/version-management/sourcehut/man.nix
4822 +++ b/pkgs/applications/version-management/sourcehut/man.nix
4823 @@ -8,13 +8,13 @@
4824
4825 buildPythonPackage rec {
4826 pname = "mansrht";
4827 - version = "0.15.12";
4828 + version = "0.15.20";
4829
4830 src = fetchFromSourcehut {
4831 owner = "~sircmpwn";
4832 repo = "man.sr.ht";
4833 rev = version;
4834 - sha256 = "sha256-MqH/8K9XRvEg6P7GHE6XXtWnhDP3wT8iGoNaFtYQbio=";
4835 + sha256 = "sha256-ulwdrVrw2bwdafgc3NrJ1J15evQ5btpHLTaiqsyA58U=";
4836 };
4837
4838 nativeBuildInputs = srht.nativeBuildInputs;
4839 @@ -29,10 +29,12 @@ buildPythonPackage rec {
4840 export SRHT_PATH=${srht}/${python.sitePackages}/srht
4841 '';
4842
4843 + pythonImportsCheck = [ "mansrht" ];
4844 +
4845 meta = with lib; {
4846 homepage = "https://git.sr.ht/~sircmpwn/man.sr.ht";
4847 description = "Wiki service for the sr.ht network";
4848 - license = licenses.agpl3;
4849 + license = licenses.agpl3Only;
4850 maintainers = with maintainers; [ eadwu ];
4851 };
4852 }
4853 diff --git a/pkgs/applications/version-management/sourcehut/meta.nix b/pkgs/applications/version-management/sourcehut/meta.nix
4854 index 86d293973d7..46e9475b8f8 100644
4855 --- a/pkgs/applications/version-management/sourcehut/meta.nix
4856 +++ b/pkgs/applications/version-management/sourcehut/meta.nix
4857 @@ -18,19 +18,19 @@
4858 , python
4859 }:
4860 let
4861 - version = "0.53.14";
4862 + version = "0.54.4";
4863
4864 src = fetchFromSourcehut {
4865 owner = "~sircmpwn";
4866 repo = "meta.sr.ht";
4867 rev = version;
4868 - sha256 = "sha256-/+r/XLDkcSTW647xPMh5bcJmR2xZNNH74AJ5jemna2k=";
4869 + sha256 = "sha256-MleyF6aqFWbYtxRdMHXpy7HBgJKL9doBmDcYLLe8bW4=";
4870 };
4871
4872 buildApi = src: buildGoModule {
4873 inherit src version;
4874 pname = "metasrht-api";
4875 - vendorSha256 = "sha256-eZyDrr2VcNMxI++18qUy7LA1Q1YDlWCoRtl00L8lfR4=";
4876 + vendorSha256 = "sha256-gi+dGQPVzrZI+1s9SSa2M3bdgi8vwpR/ofaLG2ZX4kU=";
4877 };
4878
4879 in
4880 @@ -66,10 +66,12 @@ buildPythonPackage rec {
4881 cp ${buildApi "${src}/api/"}/bin/api $out/bin/metasrht-api
4882 '';
4883
4884 + pythonImportsCheck = [ "metasrht" ];
4885 +
4886 meta = with lib; {
4887 homepage = "https://git.sr.ht/~sircmpwn/meta.sr.ht";
4888 description = "Account management service for the sr.ht network";
4889 - license = licenses.agpl3;
4890 + license = licenses.agpl3Only;
4891 maintainers = with maintainers; [ eadwu ];
4892 };
4893 }
4894 diff --git a/pkgs/applications/version-management/sourcehut/pages-fix-syntax-error-in-schema.sql.patch b/pkgs/applications/version-management/sourcehut/pages-fix-syntax-error-in-schema.sql.patch
4895 new file mode 100644
4896 index 00000000000..9b3f6fbc6fb
4897 --- /dev/null
4898 +++ b/pkgs/applications/version-management/sourcehut/pages-fix-syntax-error-in-schema.sql.patch
4899 @@ -0,0 +1,27 @@
4900 +From 3df160ad289b25574322f587095d00d6641f057c Mon Sep 17 00:00:00 2001
4901 +From: Juan Picca <juan.picca@jumapico.uy>
4902 +Date: Wed, 21 Jul 2021 08:26:56 -0300
4903 +Subject: [PATCH] Fix syntax error in schema.sql
4904 +
4905 +---
4906 + schema.sql | 4 ++--
4907 + 1 file changed, 2 insertions(+), 2 deletions(-)
4908 +
4909 +diff --git a/schema.sql b/schema.sql
4910 +index 168377f..2e473ea 100644
4911 +--- a/schema.sql
4912 ++++ b/schema.sql
4913 +@@ -28,8 +28,8 @@ CREATE TABLE sites (
4914 + user_id integer NOT NULL references "user"(id),
4915 + domain varchar NOT NULL,
4916 + protocol protocol NOT NULL,
4917 +- version varchar NOT NULL
4918 +- UNIQUE (domain, protocol),
4919 ++ version varchar NOT NULL,
4920 ++ UNIQUE (domain, protocol)
4921 + );
4922 +
4923 + COMMIT;
4924 +--
4925 +2.32.0
4926 +
4927 diff --git a/pkgs/applications/version-management/sourcehut/pages.nix b/pkgs/applications/version-management/sourcehut/pages.nix
4928 new file mode 100644
4929 index 00000000000..d04182251a7
4930 --- /dev/null
4931 +++ b/pkgs/applications/version-management/sourcehut/pages.nix
4932 @@ -0,0 +1,34 @@
4933 +{ lib
4934 +, fetchFromSourcehut
4935 +, buildGoModule
4936 +}:
4937 +buildGoModule rec {
4938 + pname = "pagessrht";
4939 + version = "0.4.8";
4940 +
4941 + src = fetchFromSourcehut {
4942 + owner = "~sircmpwn";
4943 + repo = "pages.sr.ht";
4944 + rev = version;
4945 + sha256 = "sha256-z9w8v5e6LY6VUEczltyD55KEUUH7Gw1vUO00KPmT+D8=";
4946 + };
4947 +
4948 + vendorSha256 = "sha256-xOd9i+PNlLxZrw/+z/C9V+AbOLEociW2YHY+x1K+mJI=";
4949 +
4950 + patches = [
4951 + # Upstream after 0.4.8
4952 + ./pages-fix-syntax-error-in-schema.sql.patch
4953 + ];
4954 +
4955 + postInstall = ''
4956 + mkdir -p $out/share/sql/
4957 + cp -r -t $out/share/sql/ schema.sql migrations
4958 + '';
4959 +
4960 + meta = with lib; {
4961 + homepage = "https://git.sr.ht/~sircmpwn/pages.sr.ht";
4962 + description = "Web hosting service for the sr.ht network";
4963 + license = licenses.agpl3Only;
4964 + maintainers = with maintainers; [ eadwu ];
4965 + };
4966 +}
4967 diff --git a/pkgs/applications/version-management/sourcehut/paste.nix b/pkgs/applications/version-management/sourcehut/paste.nix
4968 index 0d8c9135493..ecd31c25deb 100644
4969 --- a/pkgs/applications/version-management/sourcehut/paste.nix
4970 +++ b/pkgs/applications/version-management/sourcehut/paste.nix
4971 @@ -8,13 +8,13 @@
4972
4973 buildPythonPackage rec {
4974 pname = "pastesrht";
4975 - version = "0.12.1";
4976 + version = "0.12.4";
4977
4978 src = fetchFromSourcehut {
4979 owner = "~sircmpwn";
4980 repo = "paste.sr.ht";
4981 rev = version;
4982 - sha256 = "sha256-QQhd2LeH9BLmlHilhsv+9fZ+RPNmEMSmOpFA3dsMBFc=";
4983 + sha256 = "sha256-hFjWa7L7JiQoG3Hm9NyoP2FNypDiW+nGDmQ2DoZkAIw=";
4984 };
4985
4986 nativeBuildInputs = srht.nativeBuildInputs;
4987 @@ -29,10 +29,12 @@ buildPythonPackage rec {
4988 export SRHT_PATH=${srht}/${python.sitePackages}/srht
4989 '';
4990
4991 + pythonImportsCheck = [ "pastesrht" ];
4992 +
4993 meta = with lib; {
4994 homepage = "https://git.sr.ht/~sircmpwn/paste.sr.ht";
4995 description = "Ad-hoc text file hosting service for the sr.ht network";
4996 - license = licenses.agpl3;
4997 + license = licenses.agpl3Only;
4998 maintainers = with maintainers; [ eadwu ];
4999 };
5000 }
5001 diff --git a/pkgs/applications/version-management/sourcehut/disable-npm-install.patch b/pkgs/applications/version-management/sourcehut/patches/disable-npm-install.patch
5002 similarity index 100%
5003 rename from pkgs/applications/version-management/sourcehut/disable-npm-install.patch
5004 rename to pkgs/applications/version-management/sourcehut/patches/disable-npm-install.patch
5005 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0001-worker-update-go-redis-to-support-Unix-sockets.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0001-worker-update-go-redis-to-support-Unix-sockets.patch
5006 new file mode 100644
5007 index 00000000000..4efd12be875
5008 --- /dev/null
5009 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0001-worker-update-go-redis-to-support-Unix-sockets.patch
5010 @@ -0,0 +1,113 @@
5011 +From 5991960a5d412f0e1bdc505b970248c68b44a720 Mon Sep 17 00:00:00 2001
5012 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5013 +Date: Wed, 15 Sep 2021 19:45:41 +0200
5014 +Subject: [PATCH builds.sr.ht v3 1/2] worker: update go-redis to support Unix
5015 + sockets
5016 +
5017 +---
5018 + worker/context.go | 4 ++--
5019 + worker/main.go | 11 +++++++----
5020 + worker/tasks.go | 10 +++++-----
5021 + 3 files changed, 14 insertions(+), 11 deletions(-)
5022 +
5023 +diff --git a/worker/context.go b/worker/context.go
5024 +index f84a60c..be54717 100644
5025 +--- a/worker/context.go
5026 ++++ b/worker/context.go
5027 +@@ -14,7 +14,7 @@ import (
5028 + "strings"
5029 + "time"
5030 +
5031 +- "github.com/go-redis/redis"
5032 ++ goredis "github.com/go-redis/redis/v8"
5033 + "github.com/google/shlex"
5034 + "github.com/pkg/errors"
5035 + "github.com/prometheus/client_golang/prometheus"
5036 +@@ -41,7 +41,7 @@ var (
5037 +
5038 + type WorkerContext struct {
5039 + Db *sql.DB
5040 +- Redis *redis.Client
5041 ++ Redis *goredis.Client
5042 + Conf func(section, key string) string
5043 + }
5044 +
5045 +diff --git a/worker/main.go b/worker/main.go
5046 +index 274ba68..e22ab6b 100644
5047 +--- a/worker/main.go
5048 ++++ b/worker/main.go
5049 +@@ -1,6 +1,7 @@
5050 + package main
5051 +
5052 + import (
5053 ++ "context"
5054 + "database/sql"
5055 + "flag"
5056 + "log"
5057 +@@ -9,7 +10,7 @@ import (
5058 + "runtime"
5059 + "sync"
5060 +
5061 +- "github.com/go-redis/redis"
5062 ++ goredis "github.com/go-redis/redis/v8"
5063 + "github.com/vaughan0/go-ini"
5064 + "git.sr.ht/~sircmpwn/core-go/crypto"
5065 +
5066 +@@ -26,6 +27,8 @@ var (
5067 + jobsMutex sync.Mutex
5068 + )
5069 +
5070 ++var redisctx = context.Background()
5071 ++
5072 + func main() {
5073 + flag.IntVar(&workers, "workers", runtime.NumCPU(),
5074 + "configure number of workers")
5075 +@@ -68,12 +71,12 @@ func main() {
5076 + if !ok {
5077 + redisHost = "redis://localhost:6379"
5078 + }
5079 +- ropts, err := redis.ParseURL(redisHost)
5080 ++ ropts, err := goredis.ParseURL(redisHost)
5081 + if err != nil {
5082 + panic(err)
5083 + }
5084 +- localRedis := redis.NewClient(ropts)
5085 +- if _, err := localRedis.Ping().Result(); err != nil {
5086 ++ localRedis := goredis.NewClient(ropts)
5087 ++ if _, err := localRedis.Ping(redisctx).Result(); err != nil {
5088 + panic(err)
5089 + }
5090 +
5091 +diff --git a/worker/tasks.go b/worker/tasks.go
5092 +index d27bf33..d0c28f1 100644
5093 +--- a/worker/tasks.go
5094 ++++ b/worker/tasks.go
5095 +@@ -19,7 +19,7 @@ import (
5096 + "time"
5097 +
5098 + "git.sr.ht/~sircmpwn/core-go/auth"
5099 +- "github.com/go-redis/redis"
5100 ++ goredis "github.com/go-redis/redis/v8"
5101 + "github.com/kr/pty"
5102 + "github.com/minio/minio-go/v6"
5103 + "github.com/pkg/errors"
5104 +@@ -39,12 +39,12 @@ var (
5105 + }, []string{"image", "arch"})
5106 + )
5107 +
5108 +-func (ctx *JobContext) Boot(r *redis.Client) func() {
5109 +- port, err := r.Incr("builds.sr.ht.ssh-port").Result()
5110 ++func (ctx *JobContext) Boot(r *goredis.Client) func() {
5111 ++ port, err := r.Incr(ctx.Context, "builds.sr.ht.ssh-port").Result()
5112 + if err == nil && port < 22000 {
5113 +- err = r.Set("builds.sr.ht.ssh-port", 22100, 0).Err()
5114 ++ err = r.Set(ctx.Context, "builds.sr.ht.ssh-port", 22100, 0).Err()
5115 + } else if err == nil && port >= 23000 {
5116 +- err = r.Set("builds.sr.ht.ssh-port", 22000, 0).Err()
5117 ++ err = r.Set(ctx.Context, "builds.sr.ht.ssh-port", 22000, 0).Err()
5118 + }
5119 + if err != nil {
5120 + panic(errors.Wrap(err, "assign port"))
5121 +--
5122 +2.32.0
5123 +
5124 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0002-worker-update-go.-mod-sum-for-go-redis.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0002-worker-update-go.-mod-sum-for-go-redis.patch
5125 new file mode 100644
5126 index 00000000000..c9368d05c18
5127 --- /dev/null
5128 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/build/v3-0002-worker-update-go.-mod-sum-for-go-redis.patch
5129 @@ -0,0 +1,378 @@
5130 +From eac18e913e4ee48895b94acfa56cf1c6a3fb49fa Mon Sep 17 00:00:00 2001
5131 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5132 +Date: Wed, 15 Sep 2021 20:11:49 +0200
5133 +Subject: [PATCH builds.sr.ht v3 2/2] worker: update go.{mod,sum} for go-redis
5134 +
5135 +---
5136 + worker/go.mod | 8 +------
5137 + worker/go.sum | 64 +++++++++++++++++++--------------------------------
5138 + 2 files changed, 25 insertions(+), 47 deletions(-)
5139 +
5140 +diff --git a/worker/go.mod b/worker/go.mod
5141 +index 6e9a11c..4893dfa 100644
5142 +--- a/worker/go.mod
5143 ++++ b/worker/go.mod
5144 +@@ -2,24 +2,18 @@ module git.sr.ht/~sircmpwn/builds.sr.ht/worker
5145 +
5146 + require (
5147 + git.sr.ht/~sircmpwn/core-go v0.0.0-20210108160653-070566136c1a
5148 +- github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
5149 +- github.com/go-redis/redis v6.15.2+incompatible
5150 ++ github.com/go-redis/redis/v8 v8.2.3
5151 + github.com/gocelery/gocelery v0.0.0-20201111034804-825d89059344
5152 +- github.com/gomodule/redigo v2.0.0+incompatible // indirect
5153 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
5154 +- github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629
5155 + github.com/kr/pty v1.1.3
5156 + github.com/lib/pq v1.8.0
5157 + github.com/martinlindhe/base36 v1.1.0
5158 +- github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
5159 + github.com/minio/minio-go/v6 v6.0.49
5160 + github.com/mitchellh/mapstructure v1.1.2
5161 + github.com/pkg/errors v0.9.1
5162 + github.com/prometheus/client_golang v1.7.1
5163 +- github.com/shicky/gocelery v0.0.0-20180807061531-b2f0dd7ec05b
5164 + github.com/streadway/amqp v1.0.0 // indirect
5165 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
5166 +- golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb
5167 + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
5168 + gopkg.in/mail.v2 v2.3.1
5169 + gopkg.in/yaml.v2 v2.3.0
5170 +diff --git a/worker/go.sum b/worker/go.sum
5171 +index 1cd3989..4a2d6d9 100644
5172 +--- a/worker/go.sum
5173 ++++ b/worker/go.sum
5174 +@@ -10,6 +10,7 @@ git.sr.ht/~sircmpwn/go-bare v0.0.0-20200812160916-d2c72e1a5018/go.mod h1:BVJwbDf
5175 + github.com/99designs/gqlgen v0.13.0 h1:haLTcUp3Vwp80xMVEg5KRNwzfUrgFdRmtBY8fuB8scA=
5176 + github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyyoi3rEfXIk=
5177 + github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
5178 ++github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
5179 + github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
5180 + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
5181 + github.com/Masterminds/squirrel v1.4.0 h1:he5i/EXixZxrBUWcxzDYMiju9WZ3ld/l7QBNuo/eN3w=
5182 +@@ -25,6 +26,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
5183 + github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
5184 + github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
5185 + github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
5186 ++github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
5187 + github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
5188 + github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
5189 + github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
5190 +@@ -36,7 +38,6 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l
5191 + github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
5192 + github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
5193 + github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
5194 +-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
5195 + github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
5196 + github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
5197 + github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
5198 +@@ -58,8 +59,10 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
5199 + github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
5200 + github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
5201 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5202 ++github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5203 + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5204 + github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
5205 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
5206 + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
5207 + github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
5208 + github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
5209 +@@ -84,22 +87,18 @@ github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001/go.mod h1:2H9hjfb
5210 + github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
5211 + github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
5212 + github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
5213 ++github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
5214 + github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
5215 + github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
5216 + github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
5217 + github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
5218 +-github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df h1:Bao6dhmbTA1KFVxmJ6nBoMuOJit2yjEgLJpIMYpop0E=
5219 +-github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df/go.mod h1:GJr+FCSXshIwgHBtLglIg9M2l2kQSi6QjVAngtzI08Y=
5220 + github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
5221 + github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
5222 + github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
5223 + github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
5224 + github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
5225 + github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
5226 +-github.com/go-redis/redis v6.14.1+incompatible h1:kSJohAREGMr344uMa8PzuIg5OU6ylCbyDkWkkNOfEik=
5227 +-github.com/go-redis/redis v6.14.1+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
5228 +-github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
5229 +-github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
5230 ++github.com/go-redis/redis/v8 v8.2.3 h1:eNesND+DWt/sjQOtPFxAbQkTIXaXX00qNLxjVWkZ70k=
5231 + github.com/go-redis/redis/v8 v8.2.3/go.mod h1:ysgGY09J/QeDYbu3HikWEIPCwaeOkuNoTgKayTEaEOw=
5232 + github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
5233 + github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
5234 +@@ -114,7 +113,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
5235 + github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
5236 + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
5237 + github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
5238 +-github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
5239 + github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5240 + github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5241 + github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5242 +@@ -136,12 +134,14 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
5243 + github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
5244 + github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5245 + github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5246 ++github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
5247 + github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5248 + github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
5249 + github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
5250 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
5251 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
5252 + github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5253 ++github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
5254 + github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
5255 + github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
5256 + github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
5257 +@@ -180,12 +180,11 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod
5258 + github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
5259 + github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
5260 + github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
5261 +-github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629 h1:1dSBUfGlorLAua2CRx0zFN7kQsTpE2DQSmr7rrTNgY8=
5262 +-github.com/jpillora/longestcommon v0.0.0-20161227235612-adb9d91ee629/go.mod h1:mb5nS4uRANwOJSZj8rlCWAfAcGi72GGMIXx+xGOjA7M=
5263 + github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
5264 + github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
5265 + github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
5266 + github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
5267 ++github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
5268 + github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
5269 + github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
5270 + github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
5271 +@@ -200,20 +199,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
5272 + github.com/kr/pty v1.1.3 h1:/Um6a/ZmD5tF7peoOJ5oN5KMQ0DrGVQSXLNwyckutPk=
5273 + github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
5274 + github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
5275 ++github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
5276 + github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
5277 + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
5278 + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
5279 + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
5280 + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
5281 +-github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
5282 +-github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
5283 + github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
5284 + github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
5285 + github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
5286 + github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
5287 + github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
5288 + github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
5289 +-github.com/martinlindhe/base36 v1.0.0 h1:eYsumTah144C0A8P1T/AVSUk5ZoLnhfYFM3OGQxB52A=
5290 + github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
5291 + github.com/martinlindhe/base36 v1.1.0 h1:cIwvvwYse/0+1CkUPYH5ZvVIYG3JrILmQEIbLuar02Y=
5292 + github.com/martinlindhe/base36 v1.1.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
5293 +@@ -228,7 +225,6 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
5294 + github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
5295 + github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
5296 + github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
5297 +-github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
5298 + github.com/minio/minio-go/v6 v6.0.49 h1:bU4kIa/qChTLC1jrWZ8F+8gOiw1MClubddAJVR4gW3w=
5299 + github.com/minio/minio-go/v6 v6.0.49/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg=
5300 + github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
5301 +@@ -242,8 +238,6 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
5302 + github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
5303 + github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
5304 + github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
5305 +-github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
5306 +-github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
5307 + github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
5308 + github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
5309 + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
5310 +@@ -259,7 +253,9 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
5311 + github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
5312 + github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
5313 + github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
5314 ++github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
5315 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
5316 ++github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
5317 + github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
5318 + github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
5319 + github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
5320 +@@ -267,10 +263,12 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
5321 + github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
5322 + github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
5323 + github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
5324 ++github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4=
5325 + github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
5326 + github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
5327 + github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
5328 + github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
5329 ++github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
5330 + github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
5331 + github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
5332 + github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
5333 +@@ -287,22 +285,20 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
5334 + github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
5335 + github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
5336 + github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
5337 +-github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
5338 + github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
5339 + github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
5340 + github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
5341 + github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
5342 + github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
5343 ++github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5344 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5345 + github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
5346 +-github.com/prometheus/client_golang v0.9.1 h1:K47Rk0v/fkEfwfQet2KWhscE0cJzjgCCDBG2KHZoVno=
5347 + github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
5348 + github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
5349 + github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
5350 + github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
5351 + github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
5352 + github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
5353 +-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
5354 + github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
5355 + github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
5356 + github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
5357 +@@ -310,15 +306,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
5358 + github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
5359 + github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
5360 + github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
5361 +-github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPBkJ/3YHn1iDGDGc/Z+sW+AEMKHMVvN4=
5362 +-github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
5363 + github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
5364 + github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
5365 + github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
5366 + github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
5367 + github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4=
5368 + github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
5369 +-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
5370 + github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
5371 + github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
5372 + github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
5373 +@@ -333,36 +326,28 @@ github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
5374 + github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
5375 + github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
5376 + github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
5377 +-github.com/satori/go.uuid v1.1.0 h1:B9KXyj+GzIpJbV7gmr873NsY6zpbxNy24CBtGrk7jHo=
5378 +-github.com/satori/go.uuid v1.1.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
5379 +-github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
5380 +-github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
5381 +-github.com/satori/go.uuid v1.2.1-0.20180103174451-36e9d2ebbde5 h1:Jw7W4WMfQDxsXvfeFSaS2cHlY7bAF4MGrgnbd0+Uo78=
5382 +-github.com/satori/go.uuid v1.2.1-0.20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
5383 + github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM=
5384 + github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
5385 + github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
5386 + github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
5387 ++github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
5388 + github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
5389 +-github.com/shicky/gocelery v0.0.0-20180807061531-b2f0dd7ec05b h1:7kJLeBNcPG1orS3ksAFN0qoJGtf8jvwgOh5Q+bsNZvc=
5390 +-github.com/shicky/gocelery v0.0.0-20180807061531-b2f0dd7ec05b/go.mod h1:kn4CkFIzvsrXBvbNk2hX9DpIM8xo/74mYhiYTpGhYXE=
5391 + github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
5392 + github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
5393 + github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
5394 + github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
5395 + github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
5396 + github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
5397 ++github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
5398 + github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
5399 + github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
5400 ++github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
5401 + github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
5402 + github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
5403 + github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
5404 + github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
5405 + github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
5406 +-github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864 h1:Oj3PUEs+OUSYUpn35O+BE/ivHGirKixA3+vqA0Atu9A=
5407 +-github.com/streadway/amqp v0.0.0-20180806233856-70e15c650864/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
5408 + github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
5409 +-github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw=
5410 + github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
5411 + github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
5412 + github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
5413 +@@ -373,6 +358,7 @@ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
5414 + github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
5415 + github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
5416 + github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
5417 ++github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
5418 + github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5419 + github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
5420 + github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
5421 +@@ -391,6 +377,7 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI
5422 + go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
5423 + go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
5424 + go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
5425 ++go.opentelemetry.io/otel v0.11.0 h1:IN2tzQa9Gc4ZVKnTaMbPVcHjvzOdg5n9QfnmlqiET7E=
5426 + go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0=
5427 + go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
5428 + go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
5429 +@@ -403,7 +390,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
5430 + golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
5431 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5432 + golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5433 +-golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo=
5434 + golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5435 + golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5436 + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5437 +@@ -431,7 +417,6 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r
5438 + golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
5439 + golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
5440 + golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
5441 +-golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
5442 + golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
5443 + golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
5444 + golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
5445 +@@ -451,7 +436,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
5446 + golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5447 + golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5448 + golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5449 +-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
5450 + golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5451 + golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5452 + golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5453 +@@ -460,7 +444,6 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h
5454 + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5455 + golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5456 + golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5457 +-golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
5458 + golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5459 + golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5460 + golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5461 +@@ -477,7 +460,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w
5462 + golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5463 + golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb h1:HS9IzC4UFbpMBLQUDSQcU+ViVT1vdFCQVjdPVpTlZrs=
5464 + golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5465 +-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
5466 + golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
5467 + golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
5468 + golang.org/x/text v0.3.4-0.20201021145329-22f1617af38e h1:0kyKOEC0chG7FKmnf/1uNwvDLc3NtNTRip2rXAN9nwI=
5469 +@@ -502,6 +484,7 @@ golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapK
5470 + golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
5471 + golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5472 + golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5473 ++golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
5474 + golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5475 + google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
5476 + google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
5477 +@@ -539,6 +522,7 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod
5478 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5479 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5480 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5481 ++gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
5482 + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5483 + gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
5484 + gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
5485 +@@ -549,6 +533,7 @@ gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
5486 + gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
5487 + gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
5488 + gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
5489 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
5490 + gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
5491 + gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
5492 + gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
5493 +@@ -556,10 +541,9 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5494 + gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5495 + gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5496 + gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5497 +-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
5498 +-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5499 + gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
5500 + gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5501 ++gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
5502 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
5503 + honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
5504 + honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
5505 +--
5506 +2.32.0
5507 +
5508 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/core/v3-0001-add-Unix-socket-support-for-redis-host.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/core/v3-0001-add-Unix-socket-support-for-redis-host.patch
5509 new file mode 100644
5510 index 00000000000..299ad3d83c5
5511 --- /dev/null
5512 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/core/v3-0001-add-Unix-socket-support-for-redis-host.patch
5513 @@ -0,0 +1,30 @@
5514 +From c0ccc8db051a2f8278edf59b41ed238fa71aa4c0 Mon Sep 17 00:00:00 2001
5515 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5516 +Date: Mon, 23 Aug 2021 18:43:18 +0200
5517 +Subject: [PATCH core.sr.ht v3] add Unix socket support for redis-host=
5518 +
5519 +---
5520 + srht/redis.py | 11 ++---------
5521 + 1 file changed, 2 insertions(+), 9 deletions(-)
5522 +
5523 +diff --git a/srht/redis.py b/srht/redis.py
5524 +index 8a9347c..2e91c35 100644
5525 +--- a/srht/redis.py
5526 ++++ b/srht/redis.py
5527 +@@ -1,11 +1,4 @@
5528 +-from redis import Redis
5529 ++from redis import from_url
5530 + from srht.config import cfg
5531 +-from urllib.parse import urlparse
5532 +
5533 +-url = cfg("sr.ht", "redis-host", "redis://localhost")
5534 +-url = urlparse(url)
5535 +-
5536 +-redis = Redis(host=url.hostname,
5537 +- port=(url.port or 6379),
5538 +- password=url.password,
5539 +- db=int(url.path[1:]) if url.path else 0)
5540 ++redis = from_url(cfg("sr.ht", "redis-host", "redis://localhost"))
5541 +--
5542 +2.32.0
5543 +
5544 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0001-gitsrht-keys-update-go-redis-to-support-Unix-sock.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0001-gitsrht-keys-update-go-redis-to-support-Unix-sock.patch
5545 new file mode 100644
5546 index 00000000000..8b210fbb6e1
5547 --- /dev/null
5548 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0001-gitsrht-keys-update-go-redis-to-support-Unix-sock.patch
5549 @@ -0,0 +1,26 @@
5550 +From 2f949b484b62b2cdb71d417c52935978fab10f62 Mon Sep 17 00:00:00 2001
5551 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5552 +Date: Fri, 27 Aug 2021 15:38:28 +0200
5553 +Subject: [PATCH git.sr.ht v3 1/5] gitsrht-keys: update go-redis to support
5554 + Unix sockets
5555 +
5556 +---
5557 + gitsrht-keys/main.go | 2 +-
5558 + 1 file changed, 1 insertion(+), 1 deletion(-)
5559 +
5560 +diff --git a/gitsrht-keys/main.go b/gitsrht-keys/main.go
5561 +index 0c1aea1..fa17183 100644
5562 +--- a/gitsrht-keys/main.go
5563 ++++ b/gitsrht-keys/main.go
5564 +@@ -5,7 +5,7 @@ import (
5565 + "os"
5566 + "path"
5567 +
5568 +- goredis "github.com/go-redis/redis"
5569 ++ goredis "github.com/go-redis/redis/v8"
5570 + "github.com/vaughan0/go-ini"
5571 + "git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys"
5572 + )
5573 +--
5574 +2.32.0
5575 +
5576 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0002-gitsrht-update-hook-update-go-redis-to-support-Un.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0002-gitsrht-update-hook-update-go-redis-to-support-Un.patch
5577 new file mode 100644
5578 index 00000000000..ecca8227115
5579 --- /dev/null
5580 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0002-gitsrht-update-hook-update-go-redis-to-support-Un.patch
5581 @@ -0,0 +1,109 @@
5582 +From 1ac95fc65ea68eb207e0cae1b1f3c0afac70613b Mon Sep 17 00:00:00 2001
5583 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5584 +Date: Fri, 27 Aug 2021 15:39:29 +0200
5585 +Subject: [PATCH git.sr.ht v3 2/5] gitsrht-update-hook: update go-redis to
5586 + support Unix sockets
5587 +
5588 +---
5589 + gitsrht-update-hook/options.go | 12 +++++++-----
5590 + gitsrht-update-hook/post-update.go | 4 ++--
5591 + gitsrht-update-hook/update.go | 4 ++--
5592 + 3 files changed, 11 insertions(+), 9 deletions(-)
5593 +
5594 +diff --git a/gitsrht-update-hook/options.go b/gitsrht-update-hook/options.go
5595 +index 8efbb0a..962502a 100644
5596 +--- a/gitsrht-update-hook/options.go
5597 ++++ b/gitsrht-update-hook/options.go
5598 +@@ -1,15 +1,17 @@
5599 + package main
5600 +
5601 + import (
5602 ++ "context"
5603 + "fmt"
5604 + "os"
5605 + "strconv"
5606 + "strings"
5607 + "time"
5608 +
5609 +- goredis "github.com/go-redis/redis"
5610 ++ goredis "github.com/go-redis/redis/v8"
5611 + )
5612 +
5613 ++var ctx = context.Background()
5614 + var options map[string]string
5615 +
5616 + func loadOptions() {
5617 +@@ -35,10 +37,10 @@ func loadOptions() {
5618 + var n int
5619 + if nopts, ok := os.LookupEnv("GIT_PUSH_OPTION_COUNT"); ok {
5620 + n, _ = strconv.Atoi(nopts)
5621 +- redis.Set(fmt.Sprintf("git.sr.ht.options.%s", uuid),
5622 ++ redis.Set(ctx, fmt.Sprintf("git.sr.ht.options.%s", uuid),
5623 + nopts, 10*time.Minute)
5624 + } else {
5625 +- nopts, err := redis.Get(fmt.Sprintf(
5626 ++ nopts, err := redis.Get(ctx, fmt.Sprintf(
5627 + "git.sr.ht.options.%s", uuid)).Result()
5628 + if err != nil {
5629 + return
5630 +@@ -51,12 +53,12 @@ func loadOptions() {
5631 + opt, ok := os.LookupEnv(fmt.Sprintf("GIT_PUSH_OPTION_%d", i))
5632 + optkey := fmt.Sprintf("git.sr.ht.options.%s.%d", uuid, i)
5633 + if !ok {
5634 +- opt, err = redis.Get(optkey).Result()
5635 ++ opt, err = redis.Get(ctx, optkey).Result()
5636 + if err != nil {
5637 + return
5638 + }
5639 + } else {
5640 +- redis.Set(optkey, opt, 10*time.Minute)
5641 ++ redis.Set(ctx, optkey, opt, 10*time.Minute)
5642 + }
5643 + parts := strings.SplitN(opt, "=", 2)
5644 + if len(parts) == 1 {
5645 +diff --git a/gitsrht-update-hook/post-update.go b/gitsrht-update-hook/post-update.go
5646 +index d14d616..fcd7864 100644
5647 +--- a/gitsrht-update-hook/post-update.go
5648 ++++ b/gitsrht-update-hook/post-update.go
5649 +@@ -15,7 +15,7 @@ import (
5650 + "github.com/go-git/go-git/v5/plumbing"
5651 + "github.com/go-git/go-git/v5/plumbing/object"
5652 + "github.com/go-git/go-git/v5/plumbing/storer"
5653 +- goredis "github.com/go-redis/redis"
5654 ++ goredis "github.com/go-redis/redis/v8"
5655 + _ "github.com/lib/pq"
5656 + )
5657 +
5658 +@@ -220,7 +220,7 @@ func postUpdate() {
5659 + var oldref, newref string
5660 + var oldobj, newobj object.Object
5661 + updateKey := fmt.Sprintf("update.%s.%s", pushUuid, refname)
5662 +- update, err := redis.Get(updateKey).Result()
5663 ++ update, err := redis.Get(ctx, updateKey).Result()
5664 + if update == "" || err != nil {
5665 + logger.Println("redis.Get: missing key")
5666 + continue
5667 +diff --git a/gitsrht-update-hook/update.go b/gitsrht-update-hook/update.go
5668 +index 72c661a..e33fd4b 100644
5669 +--- a/gitsrht-update-hook/update.go
5670 ++++ b/gitsrht-update-hook/update.go
5671 +@@ -5,7 +5,7 @@ import (
5672 + "os"
5673 + "time"
5674 +
5675 +- goredis "github.com/go-redis/redis"
5676 ++ goredis "github.com/go-redis/redis/v8"
5677 + )
5678 +
5679 + // XXX: This is run once for every single ref that's pushed. If someone pushes
5680 +@@ -31,6 +31,6 @@ func update() {
5681 + logger.Fatalf("Failed to parse redis host: %v", err)
5682 + }
5683 + redis := goredis.NewClient(ropts)
5684 +- redis.Set(fmt.Sprintf("update.%s.%s", pushUuid, refname),
5685 ++ redis.Set(ctx, fmt.Sprintf("update.%s.%s", pushUuid, refname),
5686 + fmt.Sprintf("%s:%s", oldref, newref), 10*time.Minute)
5687 + }
5688 +--
5689 +2.32.0
5690 +
5691 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0003-gitsrht-dispatch-add-support-for-supplementary-gr.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0003-gitsrht-dispatch-add-support-for-supplementary-gr.patch
5692 new file mode 100644
5693 index 00000000000..a5b6a5f699e
5694 --- /dev/null
5695 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0003-gitsrht-dispatch-add-support-for-supplementary-gr.patch
5696 @@ -0,0 +1,57 @@
5697 +From f8da7df610a77003d1bc06c1fae453f5e1efe0e6 Mon Sep 17 00:00:00 2001
5698 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5699 +Date: Fri, 27 Aug 2021 17:42:33 +0200
5700 +Subject: [PATCH git.sr.ht v3 3/5] gitsrht-dispatch: add support for
5701 + supplementary groups
5702 +
5703 +---
5704 + gitsrht-dispatch/main.go | 17 ++++++++++++++---
5705 + 1 file changed, 14 insertions(+), 3 deletions(-)
5706 +
5707 +diff --git a/gitsrht-dispatch/main.go b/gitsrht-dispatch/main.go
5708 +index d7aee14..5f17b75 100644
5709 +--- a/gitsrht-dispatch/main.go
5710 ++++ b/gitsrht-dispatch/main.go
5711 +@@ -17,6 +17,7 @@ type Dispatcher struct {
5712 + cmd string
5713 + uid int
5714 + gid int
5715 ++ gids []int
5716 + }
5717 +
5718 + func main() {
5719 +@@ -70,11 +71,20 @@ AuthorizedKeysUser=root`, os.Args[0])
5720 + if err != nil {
5721 + logger.Fatalf("Error looking up group %s: %v", spec[1], err)
5722 + }
5723 ++ groups, err := user.GroupIds()
5724 ++ if err != nil {
5725 ++ logger.Fatalf("Error looking up supplementary groups of user %s: %v", spec[0], err)
5726 ++ }
5727 ++ gids := make([]int, len(groups))
5728 ++ for i, grp := range groups {
5729 ++ sgid, _ := strconv.Atoi(grp)
5730 ++ gids[i] = sgid
5731 ++ }
5732 + uid, _ := strconv.Atoi(user.Uid)
5733 + gid, _ := strconv.Atoi(group.Gid)
5734 +- dispatchers[uid] = Dispatcher{cmd, uid, gid}
5735 +- logger.Printf("Registered dispatcher for %s(%d):%s(%d): %s",
5736 +- spec[0], uid, spec[1], gid, cmd)
5737 ++ dispatchers[uid] = Dispatcher{cmd, uid, gid, gids}
5738 ++ logger.Printf("Registered dispatcher for %s(%d):%s(%d):(%s): %s",
5739 ++ spec[0], uid, spec[1], gid, strings.Join(groups, ","), cmd)
5740 + }
5741 +
5742 + var user *osuser.User
5743 +@@ -93,6 +103,7 @@ AuthorizedKeysUser=root`, os.Args[0])
5744 +
5745 + if dispatcher, ok := dispatchers[uid]; ok {
5746 + logger.Printf("Dispatching to %s", dispatcher.cmd)
5747 ++ syscall.Setgroups(dispatcher.gids)
5748 + syscall.Setgid(dispatcher.gid)
5749 + syscall.Setuid(dispatcher.uid)
5750 + if err := syscall.Exec(dispatcher.cmd, append([]string{
5751 +--
5752 +2.32.0
5753 +
5754 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0004-gitsrht-keys-update-go.-mod-sum-for-go-redis.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0004-gitsrht-keys-update-go.-mod-sum-for-go-redis.patch
5755 new file mode 100644
5756 index 00000000000..d2140d97cc0
5757 --- /dev/null
5758 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0004-gitsrht-keys-update-go.-mod-sum-for-go-redis.patch
5759 @@ -0,0 +1,174 @@
5760 +From c650827afa6f5b393ddd73ff7d4ba1e44cf36962 Mon Sep 17 00:00:00 2001
5761 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5762 +Date: Fri, 27 Aug 2021 15:39:15 +0200
5763 +Subject: [PATCH git.sr.ht v3 4/5] gitsrht-keys: update go.{mod,sum} for
5764 + go-redis
5765 +
5766 +---
5767 + gitsrht-keys/go.mod | 4 +-
5768 + gitsrht-keys/go.sum | 115 ++++++++++++++++++++++++++++++++++++++------
5769 + 2 files changed, 101 insertions(+), 18 deletions(-)
5770 +
5771 +diff --git a/gitsrht-keys/go.mod b/gitsrht-keys/go.mod
5772 +index 8189248..15ca698 100644
5773 +--- a/gitsrht-keys/go.mod
5774 ++++ b/gitsrht-keys/go.mod
5775 +@@ -3,8 +3,8 @@ module git.sr.ht/~sircmpwn/git.sr.ht/gitsrht-keys
5776 + go 1.13
5777 +
5778 + require (
5779 +- git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20201005173856-253d4b3ba1aa
5780 +- github.com/go-redis/redis v6.15.9+incompatible
5781 ++ git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20210728080601-bfa237a21e3c
5782 ++ github.com/go-redis/redis/v8 v8.11.3
5783 + github.com/google/uuid v1.1.2 // indirect
5784 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
5785 + )
5786 +diff --git a/gitsrht-keys/go.sum b/gitsrht-keys/go.sum
5787 +index 6a148e7..bfafaa3 100644
5788 +--- a/gitsrht-keys/go.sum
5789 ++++ b/gitsrht-keys/go.sum
5790 +@@ -1,41 +1,124 @@
5791 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e h1:TJqf/neVU5peFAS9WcR1aADXcflPOvAd7ABEirmU7m0=
5792 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e/go.mod h1:aXSNgRsGoI3tTFKlwD0xm2htbEzKlR2xUm1osRxfhOM=
5793 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6 h1:Ky6HzcRmbMUxOrWXv04+mb97GkyxO/Nx7v8uJBUdpNk=
5794 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6/go.mod h1:HpPX22ilJUWKOA4NDhrOcIyblQhdiKHPg4oMJFYdh0Y=
5795 +-git.sr.ht/~sircmpwn/scm.sr.ht v0.0.0-20200818140842-69dc60d7baaf h1:5qYB5U4zn97aUu1RA90ke0xi5SEn7F7+NPykkpeiRDM=
5796 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20200818140842-69dc60d7baaf h1:qFAjPhZDlKqQejSbloU+SHwiClcD8mwe135MzTU7+DA=
5797 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20200818140842-69dc60d7baaf/go.mod h1:Agf7zmDrTdkJ5BiCLb9jwpEiV3JCMAVFyzUtLVHUgOE=
5798 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20200820140830-14788ed2b332 h1:ATNQ3dAJWOtm4yguxwHeCh2p5qtIpYJmo/8jsnVTNTI=
5799 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20200820140830-14788ed2b332/go.mod h1:ARwiMukA8HXQ4lv54NglccZKTx+RcKAg5XXpkVH+fvQ=
5800 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20201005173805-6de3fddf5862 h1:f7nKVC/wyxv1Q6SI4fd+D3r42reZ1A+rPvYtRP8AA0Q=
5801 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20201005173805-6de3fddf5862/go.mod h1:OwtcEVWvnvuJiHPbe4gR28ot8zEjtjAmDVgPCWUmxcQ=
5802 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20201005173856-253d4b3ba1aa h1:yZUhFN9adGsqKIRRH2SEop3/XgoYYDqMqbzi50DcEkM=
5803 +-git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20201005173856-253d4b3ba1aa/go.mod h1:OwtcEVWvnvuJiHPbe4gR28ot8zEjtjAmDVgPCWUmxcQ=
5804 ++git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20210728080601-bfa237a21e3c h1:RE8x0GE0eQmlZERWYvhxRmK0yxTQgud051PZwBVsTbs=
5805 ++git.sr.ht/~sircmpwn/scm.sr.ht/srht-keys v0.0.0-20210728080601-bfa237a21e3c/go.mod h1:OwtcEVWvnvuJiHPbe4gR28ot8zEjtjAmDVgPCWUmxcQ=
5806 ++github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
5807 ++github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5808 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5809 ++github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5810 ++github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5811 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
5812 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
5813 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001 h1:/UMxx5lGDg30aioUL9e7xJnbJfJeX7vhcm57fa5udaI=
5814 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
5815 +-github.com/go-redis/redis v6.15.6+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
5816 ++github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
5817 ++github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
5818 ++github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
5819 + github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
5820 + github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
5821 +-github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
5822 ++github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8=
5823 ++github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc=
5824 ++github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
5825 ++github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
5826 ++github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
5827 ++github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
5828 ++github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
5829 ++github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
5830 ++github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
5831 ++github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
5832 ++github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
5833 ++github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
5834 ++github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
5835 ++github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
5836 ++github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
5837 ++github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5838 ++github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5839 ++github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
5840 ++github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5841 + github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5842 + github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
5843 + github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5844 +-github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
5845 +-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
5846 ++github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
5847 + github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
5848 + github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
5849 ++github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
5850 ++github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
5851 ++github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
5852 ++github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
5853 ++github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
5854 ++github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
5855 ++github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
5856 ++github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
5857 ++github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
5858 ++github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
5859 ++github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
5860 ++github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5861 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5862 + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5863 ++github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
5864 ++github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
5865 + github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5866 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
5867 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
5868 ++github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
5869 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
5870 +-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
5871 ++golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5872 ++golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
5873 + golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
5874 ++golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
5875 ++golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
5876 + golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
5877 ++golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
5878 ++golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
5879 ++golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
5880 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
5881 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
5882 ++golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5883 ++golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5884 ++golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
5885 ++golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5886 + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
5887 + golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5888 ++golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5889 ++golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5890 ++golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5891 ++golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5892 ++golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5893 ++golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5894 ++golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5895 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
5896 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5897 ++golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
5898 + golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
5899 ++golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
5900 ++golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
5901 ++golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
5902 ++golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
5903 ++golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
5904 ++golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
5905 ++golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5906 ++golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5907 ++golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5908 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
5909 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5910 ++google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
5911 ++google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
5912 ++google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
5913 ++google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
5914 ++google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
5915 ++google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
5916 ++google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
5917 ++google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
5918 ++google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
5919 ++gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
5920 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5921 ++gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
5922 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
5923 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
5924 ++gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5925 ++gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5926 ++gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
5927 ++gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
5928 ++gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
5929 ++gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
5930 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
5931 +--
5932 +2.32.0
5933 +
5934 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0005-gitsrht-update-hook-update-go.-mod-sum-for-go-red.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0005-gitsrht-update-hook-update-go.-mod-sum-for-go-red.patch
5935 new file mode 100644
5936 index 00000000000..d8ee71f17bd
5937 --- /dev/null
5938 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/git/v3-0005-gitsrht-update-hook-update-go.-mod-sum-for-go-red.patch
5939 @@ -0,0 +1,263 @@
5940 +From bfe2cf682527fe41e9eb44bc4bf818ba828a2e5c Mon Sep 17 00:00:00 2001
5941 +From: Julien Moutinho <julm+srht@sourcephile.fr>
5942 +Date: Fri, 27 Aug 2021 15:39:38 +0200
5943 +Subject: [PATCH git.sr.ht v3 5/5] gitsrht-update-hook: update go.{mod,sum} for
5944 + go-redis
5945 +
5946 +---
5947 + gitsrht-update-hook/go.mod | 4 +-
5948 + gitsrht-update-hook/go.sum | 115 ++++++++++++++++++++++++++++++++-----
5949 + 2 files changed, 102 insertions(+), 17 deletions(-)
5950 +
5951 +diff --git a/gitsrht-update-hook/go.mod b/gitsrht-update-hook/go.mod
5952 +index 6d29243..c39beb9 100644
5953 +--- a/gitsrht-update-hook/go.mod
5954 ++++ b/gitsrht-update-hook/go.mod
5955 +@@ -7,12 +7,12 @@ require (
5956 + github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964
5957 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001
5958 + github.com/go-git/go-git/v5 v5.1.0
5959 +- github.com/go-redis/redis v6.15.9+incompatible
5960 ++ github.com/go-redis/redis/v8 v8.11.3
5961 + github.com/google/uuid v1.1.1
5962 + github.com/lib/pq v1.8.0
5963 + github.com/mattn/go-runewidth v0.0.9
5964 + github.com/minio/minio-go/v7 v7.0.5
5965 + github.com/pkg/errors v0.9.1
5966 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
5967 +- gopkg.in/yaml.v2 v2.3.0
5968 ++ gopkg.in/yaml.v2 v2.4.0
5969 + )
5970 +diff --git a/gitsrht-update-hook/go.sum b/gitsrht-update-hook/go.sum
5971 +index cc41162..973519d 100644
5972 +--- a/gitsrht-update-hook/go.sum
5973 ++++ b/gitsrht-update-hook/go.sum
5974 +@@ -1,37 +1,65 @@
5975 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e h1:TJqf/neVU5peFAS9WcR1aADXcflPOvAd7ABEirmU7m0=
5976 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e/go.mod h1:aXSNgRsGoI3tTFKlwD0xm2htbEzKlR2xUm1osRxfhOM=
5977 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6 h1:Ky6HzcRmbMUxOrWXv04+mb97GkyxO/Nx7v8uJBUdpNk=
5978 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6/go.mod h1:HpPX22ilJUWKOA4NDhrOcIyblQhdiKHPg4oMJFYdh0Y=
5979 ++github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
5980 + github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
5981 ++github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
5982 + github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
5983 ++github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
5984 + github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
5985 ++github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
5986 ++github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5987 + github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
5988 + github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
5989 + github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
5990 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5991 ++github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5992 + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5993 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
5994 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
5995 + github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
5996 + github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
5997 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001 h1:/UMxx5lGDg30aioUL9e7xJnbJfJeX7vhcm57fa5udaI=
5998 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
5999 ++github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
6000 + github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
6001 ++github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
6002 ++github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
6003 ++github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
6004 ++github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
6005 + github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
6006 + github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
6007 + github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
6008 + github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
6009 + github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
6010 +-github.com/go-git/go-git v1.0.0 h1:YcN9iDGDoXuIw0vHls6rINwV416HYa0EB2X+RBsyYp4=
6011 +-github.com/go-git/go-git v4.7.0+incompatible h1:+W9rgGY4DOKKdX2x6HxSR7HNeTxqiKrOvKnuittYVdA=
6012 ++github.com/go-git/go-git-fixtures/v4 v4.0.1 h1:q+IFMfLx200Q3scvt2hN79JsEzy4AmBTp/pqnefH+Bc=
6013 + github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
6014 + github.com/go-git/go-git/v5 v5.1.0 h1:HxJn9g/E7eYvKW3Fm7Jt4ee8LXfPOm/H1cdDu8vEssk=
6015 + github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM=
6016 +-github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
6017 +-github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
6018 ++github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8=
6019 ++github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc=
6020 ++github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
6021 ++github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
6022 ++github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
6023 ++github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
6024 ++github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
6025 ++github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
6026 ++github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
6027 ++github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
6028 ++github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
6029 ++github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
6030 ++github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
6031 + github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
6032 ++github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
6033 ++github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6034 ++github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6035 ++github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
6036 ++github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6037 + github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
6038 + github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
6039 + github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6040 ++github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
6041 + github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
6042 ++github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
6043 + github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
6044 + github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
6045 + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
6046 +@@ -39,6 +67,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i
6047 + github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
6048 + github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
6049 + github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
6050 ++github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
6051 + github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
6052 + github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
6053 + github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
6054 +@@ -48,6 +77,7 @@ github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd
6055 + github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
6056 + github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
6057 + github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
6058 ++github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
6059 + github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
6060 + github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
6061 + github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
6062 +@@ -55,8 +85,6 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
6063 + github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
6064 + github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
6065 + github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
6066 +-github.com/minio/minio-go v1.0.0 h1:ooSujki+Z1PRGZsYffJw5jnF5eMBvzMVV86TLAlM0UM=
6067 +-github.com/minio/minio-go v6.0.14+incompatible h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=
6068 + github.com/minio/minio-go/v7 v7.0.5 h1:I2NIJ2ojwJqD/YByemC1M59e1b4FW9kS7NlOar7HPV4=
6069 + github.com/minio/minio-go/v7 v7.0.5/go.mod h1:TA0CQCjJZHM5SJj9IjqR0NmpmQJ6bCbXifAJ3mUU6Hw=
6070 + github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=
6071 +@@ -69,64 +97,121 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
6072 + github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
6073 + github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
6074 + github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
6075 ++github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
6076 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
6077 ++github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
6078 ++github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
6079 ++github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
6080 ++github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
6081 ++github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
6082 ++github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
6083 ++github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
6084 ++github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
6085 ++github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
6086 ++github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
6087 ++github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
6088 + github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
6089 + github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
6090 + github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
6091 ++github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6092 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6093 + github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
6094 + github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
6095 + github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
6096 + github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
6097 ++github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
6098 + github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
6099 ++github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
6100 + github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
6101 + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6102 + github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
6103 + github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
6104 ++github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
6105 ++github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
6106 + github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
6107 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
6108 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
6109 + github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
6110 + github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
6111 ++github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
6112 + golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
6113 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
6114 +-golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
6115 ++golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
6116 + golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6117 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6118 + golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6119 + golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
6120 + golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6121 ++golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6122 ++golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
6123 + golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
6124 + golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
6125 +-golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
6126 ++golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6127 + golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6128 +-golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
6129 ++golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
6130 + golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
6131 ++golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
6132 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
6133 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
6134 ++golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6135 ++golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6136 ++golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6137 ++golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6138 + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6139 + golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6140 + golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6141 +-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
6142 ++golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6143 ++golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6144 ++golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6145 + golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6146 + golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6147 +-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
6148 + golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6149 ++golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6150 ++golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6151 ++golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6152 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
6153 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6154 ++golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
6155 + golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
6156 + golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
6157 +-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
6158 + golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
6159 ++golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
6160 ++golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
6161 + golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
6162 + golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
6163 ++golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
6164 ++golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
6165 ++golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6166 ++golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6167 ++golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6168 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
6169 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6170 ++google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
6171 ++google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
6172 ++google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
6173 ++google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
6174 ++google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
6175 ++google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
6176 ++google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
6177 ++google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
6178 ++google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
6179 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6180 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6181 + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6182 ++gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
6183 + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6184 ++gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
6185 + gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
6186 + gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
6187 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
6188 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
6189 + gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
6190 + gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
6191 + gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6192 + gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6193 + gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6194 +-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
6195 + gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6196 ++gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
6197 ++gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
6198 ++gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
6199 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6200 +--
6201 +2.32.0
6202 +
6203 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0001-srht-keys-update-go-redis-to-support-Unix-sockets.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0001-srht-keys-update-go-redis-to-support-Unix-sockets.patch
6204 new file mode 100644
6205 index 00000000000..191ff61b826
6206 --- /dev/null
6207 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0001-srht-keys-update-go-redis-to-support-Unix-sockets.patch
6208 @@ -0,0 +1,61 @@
6209 +From e244cb7398758f91cc6deaabf278a1b6412ee477 Mon Sep 17 00:00:00 2001
6210 +From: Julien Moutinho <julm+srht@sourcephile.fr>
6211 +Date: Fri, 27 Aug 2021 12:48:56 +0200
6212 +Subject: [PATCH scm.sr.ht v3 1/2] srht-keys: update go-redis to support Unix
6213 + sockets
6214 +
6215 +---
6216 + srht-keys/srhtkeys.go | 9 ++++++---
6217 + 1 file changed, 6 insertions(+), 3 deletions(-)
6218 +
6219 +diff --git a/srht-keys/srhtkeys.go b/srht-keys/srhtkeys.go
6220 +index be925ed..1a300d5 100644
6221 +--- a/srht-keys/srhtkeys.go
6222 ++++ b/srht-keys/srhtkeys.go
6223 +@@ -1,6 +1,7 @@
6224 + package srhtkeys
6225 +
6226 + import (
6227 ++ "context"
6228 + "database/sql"
6229 + "encoding/json"
6230 + "errors"
6231 +@@ -12,7 +13,7 @@ import (
6232 + "path"
6233 + "time"
6234 +
6235 +- goredis "github.com/go-redis/redis"
6236 ++ goredis "github.com/go-redis/redis/v8"
6237 + "github.com/google/uuid"
6238 + _ "github.com/lib/pq"
6239 + "github.com/vaughan0/go-ini"
6240 +@@ -37,6 +38,8 @@ type MetaSSHKey struct {
6241 + Owner MetaUser `json:"owner"`
6242 + }
6243 +
6244 ++var ctx = context.Background()
6245 ++
6246 + // Stores the SSH key in the database and returns the user's ID.
6247 + func storeKey(logger *log.Logger, db *sql.DB, key *MetaSSHKey) (int, error) {
6248 + logger.Println("Storing meta.sr.ht key in database")
6249 +@@ -145,7 +148,7 @@ func fetchKeysFromMeta(logger *log.Logger, config ini.File,
6250 + if err != nil {
6251 + logger.Printf("Caching SSH key in redis failed: %v", err)
6252 + } else {
6253 +- redis.Set(cacheKey, cacheBytes, 7*24*time.Hour)
6254 ++ redis.Set(ctx, cacheKey, cacheBytes, 7*24*time.Hour)
6255 + }
6256 +
6257 + return key.Owner.Username, userId
6258 +@@ -168,7 +171,7 @@ func UserFromKey(logger *log.Logger, config ini.File,
6259 +
6260 + cacheKey := fmt.Sprintf("%s.ssh-keys.%s", service, b64key)
6261 + logger.Printf("Cache key for SSH key lookup: %s", cacheKey)
6262 +- cacheBytes, err := redis.Get(cacheKey).Bytes()
6263 ++ cacheBytes, err := redis.Get(ctx, cacheKey).Bytes()
6264 + var (
6265 + username string
6266 + userId int
6267 +--
6268 +2.32.0
6269 +
6270 diff --git a/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0002-srht-keys-update-go.-mod-sum-for-go-redis.patch b/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0002-srht-keys-update-go.-mod-sum-for-go-redis.patch
6271 new file mode 100644
6272 index 00000000000..c5407a26491
6273 --- /dev/null
6274 +++ b/pkgs/applications/version-management/sourcehut/patches/redis-socket/scm/v3-0002-srht-keys-update-go.-mod-sum-for-go-redis.patch
6275 @@ -0,0 +1,155 @@
6276 +From aeb3e0dc2270e6ab3cd0f651ea735275e527e7ce Mon Sep 17 00:00:00 2001
6277 +From: Julien Moutinho <julm+srht@sourcephile.fr>
6278 +Date: Fri, 27 Aug 2021 13:06:27 +0200
6279 +Subject: [PATCH scm.sr.ht v3 2/2] srht-keys: update go.{mod,sum} for go-redis
6280 +
6281 +---
6282 + srht-keys/go.mod | 2 +-
6283 + srht-keys/go.sum | 103 ++++++++++++++++++++++++++++++++++++++++++++---
6284 + 2 files changed, 99 insertions(+), 6 deletions(-)
6285 +
6286 +diff --git a/srht-keys/go.mod b/srht-keys/go.mod
6287 +index d275913..8d1c10a 100644
6288 +--- a/srht-keys/go.mod
6289 ++++ b/srht-keys/go.mod
6290 +@@ -4,7 +4,7 @@ go 1.13
6291 +
6292 + require (
6293 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6
6294 +- github.com/go-redis/redis v6.15.9+incompatible
6295 ++ github.com/go-redis/redis/v8 v8.11.3
6296 + github.com/google/uuid v1.1.1
6297 + github.com/lib/pq v1.8.0
6298 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec
6299 +diff --git a/srht-keys/go.sum b/srht-keys/go.sum
6300 +index 974326e..a264a26 100644
6301 +--- a/srht-keys/go.sum
6302 ++++ b/srht-keys/go.sum
6303 +@@ -1,26 +1,119 @@
6304 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e h1:TJqf/neVU5peFAS9WcR1aADXcflPOvAd7ABEirmU7m0=
6305 +-git.sr.ht/~sircmpwn/core-go v0.0.0-20200820135923-98806e712f5e/go.mod h1:aXSNgRsGoI3tTFKlwD0xm2htbEzKlR2xUm1osRxfhOM=
6306 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6 h1:Ky6HzcRmbMUxOrWXv04+mb97GkyxO/Nx7v8uJBUdpNk=
6307 + git.sr.ht/~sircmpwn/core-go v0.0.0-20201005173246-a9e49d17a1e6/go.mod h1:HpPX22ilJUWKOA4NDhrOcIyblQhdiKHPg4oMJFYdh0Y=
6308 ++github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
6309 ++github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
6310 + github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6311 ++github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
6312 ++github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6313 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
6314 ++github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
6315 ++github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001 h1:/UMxx5lGDg30aioUL9e7xJnbJfJeX7vhcm57fa5udaI=
6316 + github.com/fernet/fernet-go v0.0.0-20191111064656-eff2850e6001/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c=
6317 +-github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
6318 +-github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
6319 ++github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
6320 ++github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
6321 ++github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
6322 ++github.com/go-redis/redis/v8 v8.11.3 h1:GCjoYp8c+yQTJfc0n69iwSiHjvuAdruxl7elnZCxgt8=
6323 ++github.com/go-redis/redis/v8 v8.11.3/go.mod h1:xNJ9xDG09FsIPwh3bWdk+0oDWHbtF9rPN0F/oD9XeKc=
6324 ++github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
6325 ++github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
6326 ++github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
6327 ++github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
6328 ++github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
6329 ++github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
6330 ++github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
6331 ++github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
6332 ++github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
6333 ++github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
6334 ++github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
6335 ++github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
6336 ++github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
6337 ++github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6338 ++github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6339 ++github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
6340 ++github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
6341 + github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
6342 + github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6343 ++github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
6344 + github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
6345 + github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
6346 ++github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
6347 ++github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
6348 ++github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
6349 ++github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
6350 ++github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
6351 ++github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
6352 ++github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
6353 ++github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
6354 ++github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
6355 ++github.com/onsi/gomega v1.15.0 h1:WjP/FQ/sk43MRmnEcT+MlDw2TFvkrXlprrPST/IudjU=
6356 ++github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
6357 ++github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6358 + github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6359 + github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6360 ++github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
6361 ++github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
6362 + github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
6363 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks=
6364 + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw=
6365 ++github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
6366 + golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
6367 +-golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de h1:ikNHVSjEfnvz6sxdSPCaPt572qowuyMDMJLLm3Db3ig=
6368 ++golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
6369 ++golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6370 + golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
6371 ++golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6372 ++golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
6373 + golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
6374 ++golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6375 ++golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
6376 ++golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
6377 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
6378 ++golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
6379 ++golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6380 ++golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6381 ++golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6382 ++golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6383 + golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
6384 + golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6385 ++golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6386 ++golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6387 ++golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6388 ++golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6389 ++golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6390 ++golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6391 ++golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6392 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
6393 ++golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
6394 ++golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
6395 + golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
6396 ++golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
6397 ++golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
6398 ++golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
6399 ++golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
6400 ++golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
6401 ++golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
6402 ++golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6403 ++golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6404 ++golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6405 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
6406 ++golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6407 ++google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
6408 ++google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
6409 ++google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
6410 ++google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
6411 ++google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
6412 ++google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
6413 ++google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
6414 ++google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
6415 ++google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
6416 ++gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
6417 + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6418 ++gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
6419 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
6420 ++gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
6421 ++gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6422 ++gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6423 ++gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6424 ++gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
6425 ++gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
6426 ++gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
6427 + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6428 +--
6429 +2.32.0
6430 +
6431 diff --git a/pkgs/applications/version-management/sourcehut/patches/srht-update-profiles/0001-fix-disgusting-hack-in-the-case-of-buildsrht.patch b/pkgs/applications/version-management/sourcehut/patches/srht-update-profiles/0001-fix-disgusting-hack-in-the-case-of-buildsrht.patch
6432 new file mode 100644
6433 index 00000000000..9db31c9e554
6434 --- /dev/null
6435 +++ b/pkgs/applications/version-management/sourcehut/patches/srht-update-profiles/0001-fix-disgusting-hack-in-the-case-of-buildsrht.patch
6436 @@ -0,0 +1,25 @@
6437 +From 8bb7c927c815582b26d026f4b2ea72f0245ccab7 Mon Sep 17 00:00:00 2001
6438 +From: Julien Moutinho <julm+srht@sourcephile.fr>
6439 +Date: Mon, 23 Aug 2021 18:45:07 +0200
6440 +Subject: [PATCH core.sr.ht] fix "disgusting hack" in the case of buildsrht
6441 +
6442 +---
6443 + srht-update-profiles | 2 +-
6444 + 1 file changed, 1 insertion(+), 1 deletion(-)
6445 +
6446 +diff --git a/srht-update-profiles b/srht-update-profiles
6447 +index 0d9588c..063d6e2 100755
6448 +--- a/srht-update-profiles
6449 ++++ b/srht-update-profiles
6450 +@@ -3,7 +3,7 @@ import sys
6451 + import os
6452 + sys.path.append(os.getcwd())
6453 + site = sys.argv[1]
6454 +-app = __import__(site.replace(".", "") + ".app").app.app # disgusting hack
6455 ++app = __import__(site.replace(".", "").replace("builds","build") + ".app").app.app # disgusting hack
6456 + from srht.config import cfg
6457 + from srht.database import db, DbSession
6458 + db = DbSession(cfg(site, "connection-string"))
6459 +--
6460 +2.32.0
6461 +
6462 diff --git a/pkgs/applications/version-management/sourcehut/scm.nix b/pkgs/applications/version-management/sourcehut/scm.nix
6463 index 1f385265360..6efb48cd557 100644
6464 --- a/pkgs/applications/version-management/sourcehut/scm.nix
6465 +++ b/pkgs/applications/version-management/sourcehut/scm.nix
6466 @@ -1,22 +1,59 @@
6467 { lib
6468 , fetchFromSourcehut
6469 +, buildGoModule
6470 , buildPythonPackage
6471 , srht
6472 , redis
6473 , pyyaml
6474 , buildsrht
6475 -, writeText
6476 +, applyPatches
6477 }:
6478
6479 buildPythonPackage rec {
6480 pname = "scmsrht";
6481 - version = "0.22.9";
6482 + version = "0.22.13";
6483
6484 src = fetchFromSourcehut {
6485 owner = "~sircmpwn";
6486 repo = "scm.sr.ht";
6487 rev = version;
6488 - sha256 = "sha256-327G6C8FW+iZx+167D7TQsFtV6FGc8MpMVo9L/cUUqU=";
6489 + sha256 = "sha256-9iRmQBt4Cxr5itTk34b8iDRyXYDHTDfZjV0SIDT/kkM=";
6490 + };
6491 +
6492 + passthru = {
6493 + srht-keys = buildGoModule rec {
6494 + inherit src version;
6495 + sourceRoot = "source/srht-keys";
6496 + pname = "srht-keys";
6497 + vendorSha256 = "sha256-lQk1dymMCefHMFJhO3yC/muBP/cxI//5Yz991D2YZY4=";
6498 +
6499 + # What follows is only to update go-redis
6500 + # go.{mod,sum} could be patched directly but that would be less resilient
6501 + # to changes from upstream, and thus harder to maintain the patching
6502 + # while it hasn't been merged upstream.
6503 +
6504 + overrideModAttrs = old: {
6505 + inherit patches patchFlags;
6506 + preBuild = ''
6507 + go get github.com/go-redis/redis/v8
6508 + go get github.com/go-redis/redis@none
6509 + go mod tidy
6510 + '';
6511 + # Pass updated go.{mod,sum} from go-modules to srht-keys's vendor/go.{mod,sum}
6512 + postInstall = ''
6513 + cp --reflink=auto go.* $out
6514 + '';
6515 + };
6516 +
6517 + patches = [
6518 + # Update go-redis to support Unix sockets
6519 + patches/redis-socket/scm/v3-0001-srht-keys-update-go-redis-to-support-Unix-sockets.patch
6520 + ];
6521 + patchFlags = "-p2";
6522 + postInstall = ''
6523 + cp --reflink=auto *.go vendor/go.* $out
6524 + '';
6525 + };
6526 };
6527
6528 nativeBuildInputs = srht.nativeBuildInputs;
6529 @@ -33,11 +70,12 @@ buildPythonPackage rec {
6530 '';
6531
6532 dontUseSetuptoolsCheck = true;
6533 + pythonImportsCheck = [ "scmsrht" ];
6534
6535 meta = with lib; {
6536 homepage = "https://git.sr.ht/~sircmpwn/git.sr.ht";
6537 description = "Shared support code for sr.ht source control services.";
6538 - license = licenses.agpl3;
6539 + license = licenses.agpl3Only;
6540 maintainers = with maintainers; [ eadwu ];
6541 };
6542 }
6543 diff --git a/pkgs/applications/version-management/sourcehut/todo.nix b/pkgs/applications/version-management/sourcehut/todo.nix
6544 index 85e1f5637b6..e091341c7dd 100644
6545 --- a/pkgs/applications/version-management/sourcehut/todo.nix
6546 +++ b/pkgs/applications/version-management/sourcehut/todo.nix
6547 @@ -12,13 +12,13 @@
6548
6549 buildPythonPackage rec {
6550 pname = "todosrht";
6551 - version = "0.64.14";
6552 + version = "0.64.24";
6553
6554 src = fetchFromSourcehut {
6555 owner = "~sircmpwn";
6556 repo = "todo.sr.ht";
6557 rev = version;
6558 - sha256 = "sha256-huIAhn6h1F5w5ST4/yBwr82kAzyYwhLu+gpRuOQgnsE=";
6559 + sha256 = "sha256-H2XGOxHyurXw3GekZJXSO6RMChRjNbjqxik/mvFVqfY=";
6560 };
6561
6562 nativeBuildInputs = srht.nativeBuildInputs;
6563 @@ -42,11 +42,12 @@ buildPythonPackage rec {
6564 ];
6565
6566 dontUseSetuptoolsCheck = true;
6567 + pythonImportsCheck = [ "todosrht" ];
6568
6569 meta = with lib; {
6570 homepage = "https://todo.sr.ht/~sircmpwn/todo.sr.ht";
6571 description = "Ticket tracking service for the sr.ht network";
6572 - license = licenses.agpl3;
6573 + license = licenses.agpl3Only;
6574 maintainers = with maintainers; [ eadwu ];
6575 };
6576 }
6577 diff --git a/pkgs/applications/version-management/sourcehut/update.sh b/pkgs/applications/version-management/sourcehut/update.sh
6578 index 156d4cc35e4..6733046d000 100755
6579 --- a/pkgs/applications/version-management/sourcehut/update.sh
6580 +++ b/pkgs/applications/version-management/sourcehut/update.sh
6581 @@ -1,8 +1,11 @@
6582 #! /usr/bin/env nix-shell
6583 #! nix-shell -i bash -p git mercurial common-updater-scripts
6584 +set -x
6585
6586 -cd "$(dirname "${BASH_SOURCE[0]}")"
6587 +cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1
6588 root=../../../..
6589 +tmp=$(mktemp -d)
6590 +trap 'rm -rf "$tmp"' EXIT
6591
6592 default() {
6593 (cd "$root" && nix-instantiate --eval --strict -A "sourcehut.python.pkgs.$1.meta.position" | sed -re 's/^"(.*):[0-9]+"$/\1/')
6594 @@ -13,19 +16,18 @@ version() {
6595 }
6596
6597 src_url() {
6598 - (cd "$root" && nix-instantiate --eval --strict -A "sourcehut.python.pkgs.$1.src.drvAttrs.url" | tr -d '"')
6599 + nix-instantiate --eval --strict --expr " with import $root {}; let src = sourcehut.python.pkgs.$1.drvAttrs.src; in src.url or src.meta.homepage" | tr -d '"'
6600 }
6601
6602 get_latest_version() {
6603 src="$(src_url "$1")"
6604 - tmp=$(mktemp -d)
6605 -
6606 + rm -rf "$tmp"
6607 if [ "$1" = "hgsrht" ]; then
6608 - hg clone "$src" "$tmp" &> /dev/null
6609 + hg clone "$src" "$tmp" >/dev/null
6610 printf "%s" "$(cd "$tmp" && hg log --limit 1 --template '{latesttag}')"
6611 else
6612 - git clone "$src" "$tmp"
6613 - printf "%s" "$(cd "$tmp" && git describe $(git rev-list --tags --max-count=1))"
6614 + git clone "$src" "$tmp" >/dev/null
6615 + printf "%s" "$(cd "$tmp" && git describe "$(git rev-list --tags --max-count=1)")"
6616 fi
6617 }
6618
6619 @@ -36,19 +38,33 @@ update_version() {
6620
6621 (cd "$root" && update-source-version "sourcehut.python.pkgs.$1" "$version")
6622
6623 + # Update vendorSha256 of Go modules
6624 + nixFile="${1%srht}".nix
6625 + nixFile="${nixFile/build/builds}"
6626 + retry=true
6627 + while "$retry"; do
6628 + retry=false;
6629 + exec < <(exec nix -L build -f "$root" sourcehut.python.pkgs."$1" 2>&1)
6630 + while IFS=' :' read -r origin hash; do
6631 + case "$origin" in
6632 + (expected|specified) oldHash="$hash";;
6633 + (got) sed -i "s|$oldHash|$(nix hash to-sri --type sha256 "$hash")|" "$nixFile"; retry=true; break;;
6634 + (*) printf >&2 "%s\n" "$origin${hash:+:$hash}"
6635 + esac
6636 + done
6637 + done
6638 +
6639 git add "$default_nix"
6640 - git commit -m "$1: $version_old -> $version"
6641 + git commit -m "sourcehut.$1: $version_old -> $version"
6642 }
6643
6644 -services=( "srht" "buildsrht" "dispatchsrht" "gitsrht" "hgsrht" "hubsrht" "listssrht" "mansrht"
6645 - "metasrht" "pastesrht" "todosrht" "scmsrht" )
6646 -
6647 -# Whether or not a specific service is requested
6648 -if [ -n "$1" ]; then
6649 - version="$(get_latest_version "$1")"
6650 - (cd "$root" && update-source-version "sourcehut.python.pkgs.$1" "$version")
6651 +if [ $# -gt 0 ]; then
6652 + services=("$@")
6653 else
6654 - for service in "${services[@]}"; do
6655 - update_version "$service"
6656 - done
6657 + services=( "srht" "buildsrht" "dispatchsrht" "gitsrht" "hgsrht" "hubsrht" "listssrht" "mansrht"
6658 + "metasrht" "pagessrht" "pastesrht" "todosrht" "scmsrht" )
6659 fi
6660 +
6661 +for service in "${services[@]}"; do
6662 + update_version "$service"
6663 +done