diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index 2772d8d37..f76d3c536 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -50,6 +50,7 @@ let ./shadow.nix ./ssl.nix ./sync-containers.nix + ./systemd.nix ./tinc.nix ./tinc_graphs.nix ./upstream diff --git a/krebs/3modules/systemd.nix b/krebs/3modules/systemd.nix new file mode 100644 index 000000000..c30b2264a --- /dev/null +++ b/krebs/3modules/systemd.nix @@ -0,0 +1,51 @@ +{ config, options, pkgs, ... }: let { + lib = import ../../lib; + + body.options.krebs.systemd.services = lib.mkOption { + default = {}; + type = lib.types.attrs; + description = '' + Definition of systemd service units with bonus features. + + Services defined using this option will be restarted whenever any file + (described by an absolute path) used in LoadCredential changes. + ''; + }; + + body.config.systemd = + lib.mkMerge + (lib.flatten + (lib.mapAttrsToList (serviceName: cfg: let + prefix = [ "krebs" "systemd" "services" serviceName ]; + opts = options.systemd.services.type.getSubOptions prefix; + + paths = + lib.filter + lib.types.absolute-pathname.check + (map + (lib.compose [ lib.maybeHead (lib.match "[^:]*:(.*)") ]) + (cfg.serviceConfig.LoadCredential or [])); + in + lib.singleton { + services.${serviceName} = cfg; + } + ++ + lib.optionals (cfg.enable or opts.enable.default) (map (path: let + triggerName = "trigger-${lib.systemd.encodeName path}"; + in { + paths.${triggerName} = { + wantedBy = ["multi-user.target"]; + pathConfig.PathChanged = path; + }; + services.${triggerName} = { + serviceConfig = { + Type = "oneshot"; + ExecStart = lib.singleton (toString [ + "${pkgs.systemd}/bin/systemctl restart" + (lib.shell.escape serviceName) + ]); + }; + }; + }) paths) + ) config.krebs.systemd.services)); +}