merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 0a4f998a33cd8597d0488d74dc52ca865afb8aa2
parent addffb91d12cea6a821f754dc29c7d4506a8855c
Author: Florian Dold <dold@taler.net>
Date:   Tue,  8 Sep 2026 00:46:10 +0200

services: apply DD102 restart and exit handling

Diffstat:
Mdebian/rules | 24++++++++++++------------
Mdebian/taler-merchant.postinst | 11+++++------
Mdebian/taler-merchant.prerm | 18+-----------------
Mdebian/taler-merchant.taler-merchant-depositcheck.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-donaukeyupdate.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-exchangekeyupdate.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-httpd.service | 11++++++-----
Mdebian/taler-merchant.taler-merchant-httpd.socket | 1+
Mdebian/taler-merchant.taler-merchant-kyccheck.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-reconciliation.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-report-generator.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-webhook.service | 8+++++---
Mdebian/taler-merchant.taler-merchant-wirewatch.service | 8+++++---
Mdebian/taler-merchant.taler-merchant.target | 3++-
Msrc/backend/taler-merchant-depositcheck.c | 16+++++++++++-----
Msrc/backend/taler-merchant-donaukeyupdate.c | 2+-
Msrc/backend/taler-merchant-exchangekeyupdate.c | 4++--
Msrc/backend/taler-merchant-httpd.c | 12++++++------
Msrc/backend/taler-merchant-kyccheck.c | 2+-
Msrc/backend/taler-merchant-reconciliation.c | 2+-
Msrc/backend/taler-merchant-report-generator.c | 4++--
Msrc/backend/taler-merchant-webhook.c | 2+-
Msrc/backend/taler-merchant-wirewatch.c | 4++--
23 files changed, 94 insertions(+), 86 deletions(-)

diff --git a/debian/rules b/debian/rules @@ -33,19 +33,19 @@ override_dh_auto_clean: override_dh_installsystemd: # Need to specify units manually, since we have multiple # and dh_installsystemd by default only looks for "<package>.service". - dh_installsystemd -ptaler-merchant --name=taler-merchant-depositcheck --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-httpd --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-exchangekeyupdate --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-donaukeyupdate --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-kyccheck --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-reconciliation --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-report-generator --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-webhook --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-wirewatch --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant-dbinit-gc --no-start --no-enable - dh_installsystemd -ptaler-merchant --name=taler-merchant --no-start --no-enable + dh_installsystemd -ptaler-merchant --name=taler-merchant-depositcheck --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-httpd --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-exchangekeyupdate --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-donaukeyupdate --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-kyccheck --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-reconciliation --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-report-generator --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-webhook --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-wirewatch --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant-dbinit-gc --no-start --no-enable --no-stop-on-upgrade + dh_installsystemd -ptaler-merchant --name=taler-merchant --no-start --no-enable --no-stop-on-upgrade # final invocation to generate daemon reload - dh_installsystemd + dh_installsystemd --no-start --no-enable --no-stop-on-upgrade override_dh_install: dh_install diff --git a/debian/taler-merchant.postinst b/debian/taler-merchant.postinst @@ -2,7 +2,7 @@ set -e -# Use $HOME instead of $TMP to survive reboots with 'bad' timing. +# Earlier packages disabled the target during upgrade and left this marker. MARKER="/var/lib/taler-merchant/.was-enabled" SERVICES="taler-merchant-depositcheck taler-merchant-exchangekeyupdate taler-merchant-donaukeyupdate taler-merchant-httpd taler-merchant-kyccheck taler-merchant-reconciliation taler-merchant-report-generator taler-merchant-webhook taler-merchant-wirewatch" @@ -82,11 +82,10 @@ configure) if [ -f "$MARKER" ] && grep -q "enabled" "$MARKER"; then - echo "taler-merchant-httpd was previously enabled, running DB config." - - systemctl enable --now taler-merchant.target || true - else - echo "Not enabling or starting Taler merchant services (marker not found or was 'disabled')." + # Restore boot enablement after an older prerm disabled the target. + # The marker does not record which services were deliberately stopped, + # so the administrator must explicitly start the desired services. + systemctl enable taler-merchant.target || true fi # Cleanup marker file diff --git a/debian/taler-merchant.prerm b/debian/taler-merchant.prerm @@ -1,22 +1,6 @@ #!/bin/sh set -e -MARKER="/var/lib/taler-merchant/.was-enabled" - -if [ -d /run/systemd/system ]; -then - case "$1" in - remove|upgrade|deconfigure) - if systemctl is-enabled --quiet taler-merchant.target; - then - echo "taler-merchant.target was enabled before $1." - mkdir -p /var/lib/taler-merchant - echo enabled > "$MARKER" - systemctl disable --now taler-merchant.target || true - fi - ;; - esac -fi - #DEBHELPER# + exit 0 diff --git a/debian/taler-merchant.taler-merchant-depositcheck.service b/debian/taler-merchant.taler-merchant-depositcheck.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler payment system merchant deposit check service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-depositcheck -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-donaukeyupdate.service b/debian/taler-merchant.taler-merchant-donaukeyupdate.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler merchant donau configuration data download service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-donaukeyupdate -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-exchangekeyupdate.service b/debian/taler-merchant.taler-merchant-exchangekeyupdate.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler merchant exchange configuration data download service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-exchangekeyupdate -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-httpd.service b/debian/taler-merchant.taler-merchant-httpd.service @@ -1,4 +1,5 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler payment system merchant backend After=postgresql.service network.target Requires=taler-merchant-httpd.socket @@ -6,15 +7,15 @@ PartOf=taler-merchant.target AssertPathExists=/run/taler-merchant/httpd [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s +RestartMode=direct User=taler-merchant-httpd Type=simple -Restart=always -RestartSec=1s -RestartPreventExitStatus=9 -RuntimeMaxSec=3600s +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-httpd -c /etc/taler-merchant/taler-merchant.conf -L INFO Slice=taler-merchant.slice StandardOutput=journal StandardError=journal EnvironmentFile=-/etc/taler-merchant/secrets/tan-helper-secrets.env - diff --git a/debian/taler-merchant.taler-merchant-httpd.socket b/debian/taler-merchant.taler-merchant-httpd.socket @@ -1,4 +1,5 @@ [Unit] +BindsTo=taler-merchant-httpd.service Description=Taler Merchant Socket [Socket] diff --git a/debian/taler-merchant.taler-merchant-kyccheck.service b/debian/taler-merchant.taler-merchant-kyccheck.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler merchant KYC status check service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-kyccheck -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-reconciliation.service b/debian/taler-merchant.taler-merchant-reconciliation.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler merchant transaction reconciliation service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-reconciliation -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-report-generator.service b/debian/taler-merchant.taler-merchant-report-generator.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler merchant report generation service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-report-generator -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-webhook.service b/debian/taler-merchant.taler-merchant-webhook.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler payment system merchant backend webhook trigger service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-webhook -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant-wirewatch.service b/debian/taler-merchant.taler-merchant-wirewatch.service @@ -1,15 +1,17 @@ [Unit] +StartLimitIntervalSec=0 Description=GNU Taler payment system merchant bank transfer import service After=postgresql.service PartOf=taler-merchant.target [Service] +# DD102: retry transient failures without a start-rate limit. +Restart=always +RestartSec=10s User=taler-merchant-httpd Type=simple -Restart=always RestartMode=direct -RestartSec=1s -RestartPreventExitStatus=9 +RestartPreventExitStatus=6 9 ExecStart=/usr/bin/taler-merchant-wirewatch -c /etc/taler-merchant/taler-merchant.conf -L INFO PrivateTmp=yes PrivateDevices=yes diff --git a/debian/taler-merchant.taler-merchant.target b/debian/taler-merchant.taler-merchant.target @@ -1,6 +1,7 @@ [Unit] +Wants=postgresql.service Description=GNU Taler merchant -After=postgres.service network.target +After=postgresql.service network.target Wants=taler-merchant-depositcheck.service Wants=taler-merchant-exchangekeyupdate.service diff --git a/src/backend/taler-merchant-depositcheck.c b/src/backend/taler-merchant-depositcheck.c @@ -935,9 +935,15 @@ child_done_cb (void *cls, (int) type, (int) exit_code); GNUNET_SCHEDULER_shutdown (); - global_ret = EXIT_NOTINSTALLED; + /* Preserve explicit permanent failures; a signal is a transient failure, + even when its number happens to be 6 or 9. */ + global_ret = (GNUNET_OS_PROCESS_EXITED == type) + ? (int) exit_code + : EXIT_FAILURE; return; } + /* A successful child finishes when its exchange keys expire. Starting + the next scan is normal work; failed children are handled above. */ if (test_mode && (! GNUNET_TIME_relative_is_zero (c->rd)) ) { @@ -965,7 +971,7 @@ restart_child (void *cls) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "exec"); - global_ret = EXIT_NO_RESTART; + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -1144,7 +1150,7 @@ run (void *cls, { GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); - global_ret = EXIT_NO_RESTART; + global_ret = EXIT_FAILURE; return; } if (NULL == @@ -1153,7 +1159,7 @@ run (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to initialize DB subsystem\n"); GNUNET_SCHEDULER_shutdown (); - global_ret = EXIT_NOTCONFIGURED; + global_ret = EXIT_FAILURE; return; } { @@ -1228,7 +1234,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-donaukeyupdate.c b/src/backend/taler-merchant-donaukeyupdate.c @@ -1219,7 +1219,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-exchangekeyupdate.c b/src/backend/taler-merchant-exchangekeyupdate.c @@ -1074,7 +1074,7 @@ run (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to initialize DB subsystem. Consider running taler-merchant-dbconfig!\n"); GNUNET_SCHEDULER_shutdown (); - global_ret = EXIT_NOTCONFIGURED; + global_ret = EXIT_FAILURE; return; } { @@ -1139,7 +1139,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -1044,7 +1044,7 @@ load_instances (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed initialization. Check database setup.\n"); - global_ret = EXIT_NOPERMISSION; + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -1162,7 +1162,7 @@ run (void *cls, if (NULL == TMH_curl_ctx) { GNUNET_break (0); - global_ret = EXIT_NO_RESTART; + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -1609,7 +1609,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to setup templates\n"); - global_ret = EXIT_NOTINSTALLED; + global_ret = EXIT_NO_RESTART; GNUNET_SCHEDULER_shutdown (); return; } @@ -1618,7 +1618,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to load single page app\n"); - global_ret = EXIT_NOTINSTALLED; + global_ret = EXIT_NO_RESTART; GNUNET_SCHEDULER_shutdown (); return; } @@ -1688,7 +1688,7 @@ run (void *cls, case GNUNET_NO: if (! have_daemons) { - global_ret = EXIT_NOTCONFIGURED; + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -1738,7 +1738,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == res) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == res) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-kyccheck.c b/src/backend/taler-merchant-kyccheck.c @@ -2293,7 +2293,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-reconciliation.c b/src/backend/taler-merchant-reconciliation.c @@ -1352,7 +1352,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; if ( (found_problem) && diff --git a/src/backend/taler-merchant-report-generator.c b/src/backend/taler-merchant-report-generator.c @@ -909,7 +909,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to connect to database. Consider running taler-merchant-dbconfig!\n"); - global_ret = EXIT_NOTINSTALLED; + global_ret = EXIT_FAILURE; GNUNET_SCHEDULER_shutdown (); return; } @@ -969,7 +969,7 @@ main (int argc, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-webhook.c b/src/backend/taler-merchant-webhook.c @@ -639,7 +639,7 @@ main (int argc, options, &run, NULL); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret; diff --git a/src/backend/taler-merchant-wirewatch.c b/src/backend/taler-merchant-wirewatch.c @@ -679,7 +679,7 @@ run (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to obtain wirewatch accounts from database\n"); GNUNET_SCHEDULER_shutdown (); - global_ret = EXIT_NO_RESTART; + global_ret = EXIT_FAILURE; return; } if ( (NULL == w_head) && @@ -735,7 +735,7 @@ main (int argc, } while ( (1 == persist_mode) && config_changed_flag); if (GNUNET_SYSERR == ret) - return EXIT_INVALIDARGUMENT; + return EXIT_NOTCONFIGURED; if (GNUNET_NO == ret) return EXIT_SUCCESS; return global_ret;