2023-08-27 17:25:44 +03:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
consul = config.services.consul.package;
|
2023-09-03 22:20:40 +03:00
|
|
|
|
|
|
|
consulCfg = config.services.consul.extraConfig;
|
|
|
|
consulHttpAddr = "${consulCfg.addresses.http or "127.0.0.1"}:${toString (consulCfg.ports.http or 8500)}";
|
2023-08-27 17:25:44 +03:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options.systemd.services = mkOption {
|
|
|
|
type = with types; attrsOf (submodule ({ config, ... }: let
|
|
|
|
cfg = config.distributed;
|
|
|
|
in {
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
config.systemd.packages = pipe config.systemd.services [
|
|
|
|
(filterAttrs (_: v: v.distributed.enable))
|
|
|
|
(mapAttrsToList (n: v: let
|
|
|
|
inherit (v.serviceConfig) ExecStart;
|
|
|
|
|
|
|
|
cfg = v.distributed;
|
|
|
|
|
2024-08-23 03:49:42 +03:00
|
|
|
svcs = map (x: config.consul.services.${x}) cfg.registerServices;
|
2023-08-27 17:25:44 +03:00
|
|
|
|
|
|
|
runWithRegistration = pkgs.writeShellScript "run-with-registration" ''
|
2024-08-23 03:49:42 +03:00
|
|
|
trap '${lib.concatStringsSep ";" (map (svc: svc.commands.deregister) svcs)}' EXIT
|
|
|
|
${lib.concatStringsSep "\n" (
|
|
|
|
map (svc: svc.commands.register) svcs
|
|
|
|
)}
|
2023-08-27 17:25:44 +03:00
|
|
|
''${@}
|
|
|
|
'';
|
|
|
|
|
2023-09-05 01:30:34 +03:00
|
|
|
waitForConsul = pkgs.writeShellScript "wait-for-consul" ''
|
2023-11-01 16:13:22 +02:00
|
|
|
while ! ${consul}/bin/consul lock --name="pre-flight-check" --n=${toString cfg.replicas} --shell=false "$1-pre-flight-check-${config.networking.hostName}-$RANDOM" ${pkgs.coreutils}/bin/true; do
|
2023-09-05 01:30:34 +03:00
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
'';
|
|
|
|
|
2023-08-27 17:25:44 +03:00
|
|
|
hasSpecialPrefix = elem (substring 0 1 ExecStart) [ "@" "-" ":" "+" "!" ];
|
|
|
|
in assert !hasSpecialPrefix; pkgs.writeTextDir "etc/systemd/system/${n}.service.d/distributed.conf" ''
|
2024-07-17 17:32:56 +03:00
|
|
|
[Unit]
|
|
|
|
Requires=consul-ready.service
|
|
|
|
After=consul-ready.service
|
|
|
|
|
2023-08-27 17:25:44 +03:00
|
|
|
[Service]
|
2023-09-05 01:30:34 +03:00
|
|
|
ExecStartPre=${waitForConsul} 'services/${n}%i'
|
2023-08-27 17:25:44 +03:00
|
|
|
ExecStart=
|
2024-08-23 03:49:42 +03:00
|
|
|
ExecStart=${consul}/bin/consul lock --name=${n} --n=${toString cfg.replicas} --shell=false --child-exit-code 'services/${n}%i' ${optionalString (cfg.registerServices != []) runWithRegistration} ${ExecStart}
|
2023-09-03 22:20:40 +03:00
|
|
|
Environment="CONSUL_HTTP_ADDR=${consulHttpAddr}"
|
2023-08-27 17:25:44 +03:00
|
|
|
${optionalString (v.serviceConfig ? RestrictAddressFamilies) "RestrictAddressFamilies=AF_NETLINK"}
|
2024-08-23 03:49:42 +03:00
|
|
|
${optionalString (cfg.registerServices != []) (lib.concatStringsSep "\n" (map (svc: "ExecStopPost=${svc.commands.deregister}") svcs))}
|
2023-08-27 17:25:44 +03:00
|
|
|
''))
|
|
|
|
];
|
|
|
|
}
|