# TODO: create a common module generator for Taler and Libeufin? { talerComponent ? "", servicesDB ? [ ], servicesNoDB ? [ ], ... }: { lib, pkgs, config, ... }: let cfg = cfgTaler.${talerComponent}; cfgTaler = config.services.taler; settingsFormat = pkgs.formats.ini { }; services = servicesDB ++ servicesNoDB; dbName = "taler-${talerComponent}-httpd"; groupName = "taler-${talerComponent}-services"; inherit (cfgTaler) runtimeDir; in { options = { services.taler.${talerComponent} = { enable = lib.mkEnableOption "the GNU Taler ${talerComponent}"; package = lib.mkPackageOption pkgs "taler-${talerComponent}" { }; # TODO: make option accept multiple debugging levels? debug = lib.mkEnableOption "debug logging"; openFirewall = lib.mkOption { type = lib.types.bool; default = false; description = "Whether to open ports in the firewall"; }; }; }; config = lib.mkIf cfg.enable { services.taler.enable = cfg.enable; systemd.services = lib.mergeAttrsList [ # Main services (lib.genAttrs (map (n: "taler-${talerComponent}-${n}") services) (name: { serviceConfig = { DynamicUser = true; User = name; Group = groupName; ExecStart = toString [ (lib.getExe' cfg.package name) "-c /etc/taler/taler.conf" (lib.optionalString cfg.debug " -L debug") ]; RuntimeDirectory = name; StateDirectory = name; CacheDirectory = name; ReadWritePaths = [ runtimeDir ]; Restart = "always"; RestartSec = "10s"; }; requires = [ "taler-${talerComponent}-dbinit.service" ]; after = [ "taler-${talerComponent}-dbinit.service" ]; wantedBy = [ "multi-user.target" ]; # TODO slice? })) # Database Initialisation { "taler-${talerComponent}-dbinit" = { path = [ config.services.postgresql.package ]; serviceConfig = { Type = "oneshot"; DynamicUser = true; User = dbName; Restart = "on-failure"; RestartSec = "5s"; }; requires = [ "postgresql.service" ]; after = [ "postgresql.service" ]; }; } ]; users.groups.${groupName} = { }; systemd.tmpfiles.settings = { "10-taler-${talerComponent}" = { "${runtimeDir}" = { d = { group = groupName; user = "nobody"; mode = "070"; }; }; }; }; networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.settings."${talerComponent}".PORT ]; }; environment.systemPackages = [ cfg.package ]; services.taler.includes = [ "/etc/taler/conf.d/${talerComponent}.conf" ]; environment.etc."taler/conf.d/${talerComponent}.conf".source = settingsFormat.generate "generated-taler.conf" cfg.settings; services.postgresql = { enable = true; ensureDatabases = [ dbName ]; ensureUsers = map (service: { name = "taler-${talerComponent}-${service}"; }) servicesDB ++ [ { name = dbName; ensureDBOwnership = true; } ]; }; }; }