···
+
# TODO: create a common module generator for Taler and Libeufin?
+
options.services.libeufin.${libeufinComponent} = {
+
enable = lib.mkEnableOption "libeufin core banking system and web interface";
+
package = lib.mkPackageOption pkgs "libeufin" { };
+
debug = lib.mkEnableOption "debug logging";
+
createLocalDatabase = lib.mkEnableOption "automatic creation of a local postgres database";
+
openFirewall = lib.mkOption {
+
description = "Whether to open ports in the firewall";
+
cfg = cfgMain.${libeufinComponent};
+
cfgMain = config.services.libeufin;
+
configFile = config.environment.etc."libeufin/libeufin.conf".source;
+
serviceName = "libeufin-${libeufinComponent}";
+
isNexus = libeufinComponent == "nexus";
+
# get database name from config
+
# TODO: should this always be the same db? In which case, should this be an option directly under `services.libeufin`?
+
lib.removePrefix "postgresql:///"
+
cfg.settings."libeufin-${libeufinComponent}db-postgres".CONFIG;
+
bankPort = cfg.settings."${if isNexus then "nexus-httpd" else "libeufin-bank"}".PORT;
+
services.libeufin.settings = cfg.settings;
+
# TODO add system-libeufin.slice?
+
args = lib.cli.toGNUCommandLineShell { } {
+
L = if cfg.debug then "debug" else null;
+
"${lib.getExe' cfg.package "libeufin-${libeufinComponent}"} serve ${args}";
+
Restart = "on-failure";
+
requires = [ "libeufin-dbinit.service" ];
+
after = [ "libeufin-dbinit.service" ];
+
wantedBy = [ "multi-user.target" ];
+
# Database Initialisation
+
dbScript = pkgs.writers.writeText "libeufin-db-permissions.sql" ''
+
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA libeufin_bank TO "${serviceName}";
+
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA libeufin_nexus TO "${serviceName}";
+
GRANT USAGE ON SCHEMA libeufin_bank TO "${serviceName}";
+
GRANT USAGE ON SCHEMA libeufin_nexus TO "${serviceName}";
+
# Accounts to be created after the bank database initialization.
+
# For example, if the bank's currency conversion is enabled, it's
+
# required that the exchange account is registered before the
+
initialAccountRegistration = lib.concatMapStringsSep "\n" (
+
args = lib.cli.toGNUCommandLineShell { } {
+
inherit (account) username password name;
+
payto_uri = "payto://x-taler-bank/bank:${toString bankPort}/${account.username}?receiver-name=${account.name}";
+
exchange = lib.toLower account.username == "exchange";
+
"${lib.getExe' cfg.package "libeufin-bank"} create-account ${args}"
+
args = lib.cli.toGNUCommandLineShell { } {
+
L = if cfg.debug then "debug" else null;
+
path = [ config.services.postgresql.package ];
+
StateDirectory = "libeufin-dbinit";
+
StateDirectoryMode = "0750";
+
script = lib.optionalString cfg.enable ''
+
${lib.getExe' cfg.package "libeufin-${libeufinComponent}"} dbinit ${args}
+
# Grant DB permissions after schemas have been created
+
psql -U "${dbName}" -f "${dbScript}"
+
+ lib.optionalString ((!isNexus) && (cfg.initialAccounts != [ ])) ''
+
# only register initial accounts once
+
if [ ! -e /var/lib/libeufin-dbinit/init ]; then
+
${initialAccountRegistration}
+
touch /var/lib/libeufin-dbinit/init
+
echo "Bank initialisation complete"
+
requires = lib.optionals cfg.createLocalDatabase [ "postgresql.service" ];
+
after = [ "network.target" ] ++ lib.optionals cfg.createLocalDatabase [ "postgresql.service" ];
+
networking.firewall = lib.mkIf cfg.openFirewall {
+
environment.systemPackages = [ cfg.package ];
+
services.postgresql = lib.mkIf cfg.createLocalDatabase {
+
ensureDatabases = [ dbName ];
+
{ name = serviceName; }
+
ensureDBOwnership = true;
+
cfg.createLocalDatabase || (cfg.settings."libeufin-${libeufinComponent}db-postgres" ? CONFIG);
+
message = "Libeufin ${libeufinComponent} database is not configured.";