ops: taler-bank auto-confirm + systemd units + README
This commit is contained in:
parent
281873a955
commit
7691ac3065
4 changed files with 89 additions and 13 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
# taler-bank scripts
|
# taler-bank scripts
|
||||||
|
|
||||||
Container: **`taler-hacktivism-bank`** (libeufin-bank, GOA, **no IBAN**).
|
Container: **`goa-regio-ng`** (libeufin-bank, GOA, **no IBAN**; legacy name `taler-hacktivism-bank`).
|
||||||
|
|
||||||
| File | Container path | User |
|
| File | Container path | User |
|
||||||
|------|----------------|------|
|
|------|----------------|------|
|
||||||
|
|
@ -84,20 +84,24 @@ via `./install-demo-withdraw-api.sh` first.
|
||||||
### Auto-confirm (explorer only)
|
### Auto-confirm (explorer only)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# loop inside container — refuses non-explorer unless ALLOW_NON_EXPLORER=1
|
# preferred: systemd inside CTR (Restart=always)
|
||||||
|
systemctl status goa-auto-confirm-withdrawals.service
|
||||||
|
# manual loop — refuses non-explorer unless ALLOW_NON_EXPLORER=1
|
||||||
auto-confirm-withdrawals.sh --loop 2
|
auto-confirm-withdrawals.sh --loop 2
|
||||||
```
|
```
|
||||||
|
|
||||||
Only confirms withdrawals owned by **`explorer`** when status is `selected`
|
Only confirms withdrawals owned by **`explorer`** when status is `selected`
|
||||||
(community demo path). Does not confirm arbitrary customer withdraws.
|
(community demo path). Does not confirm arbitrary customer withdraws.
|
||||||
|
Skips amounts above explorer debt headroom (otherwise libeufin returns HTTP 409).
|
||||||
|
|
||||||
**Stable ops (via `koopa-external` if LAN `koopa` is down):**
|
**Stable ops (via `koopa-external` if LAN `koopa` is down):**
|
||||||
|
|
||||||
|
- Unit: `goa-auto-confirm-withdrawals.service` (install script enables it)
|
||||||
- One process only (`flock` on `/var/run/auto-confirm-withdrawals.lock`)
|
- One process only (`flock` on `/var/run/auto-confirm-withdrawals.lock`)
|
||||||
- `QUIET=1` + summary `tick checked=… selected=…` each loop
|
- `QUIET=1` + summary `tick checked=… selected=…` each loop
|
||||||
- Watch list capped (`WATCH_MAX=80`, prune of bloated `withdraw-watch.ids`)
|
- Watch list capped (`WATCH_MAX=80`, prune of bloated `withdraw-watch.ids`)
|
||||||
- Status via `taler-integration/withdrawal-operation/{id}`
|
- Status via `taler-integration/withdrawal-operation/{id}`
|
||||||
- Reinstall: `./install-demo-withdraw-api.sh` on host with podman access to `taler-hacktivism-bank`
|
- Reinstall: `BANK_CONTAINER=goa-regio-ng ./install-demo-withdraw-api.sh`
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,11 @@ if [ "$LOOP" -eq 1 ]; then
|
||||||
if command -v flock >/dev/null 2>&1; then
|
if command -v flock >/dev/null 2>&1; then
|
||||||
if ! flock -n 9; then
|
if ! flock -n 9; then
|
||||||
echo "auto-confirm already running (lock $LOCK_FILE) — exit"
|
echo "auto-confirm already running (lock $LOCK_FILE) — exit"
|
||||||
|
# Under systemd Restart=always, exit 0 on lock contention flaps the unit
|
||||||
|
# (activating/auto-restart) while the holder is outside the cgroup.
|
||||||
|
if [ -n "${INVOCATION_ID:-}" ]; then
|
||||||
|
exit 75
|
||||||
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
@ -105,6 +110,37 @@ known_ids() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# True if WD amount fits explorer debt headroom (or psql unavailable → allow).
|
||||||
|
id_affordable() {
|
||||||
|
local wid="$1"
|
||||||
|
if ! command -v psql >/dev/null 2>&1 || ! id -u postgres >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local ok
|
||||||
|
ok=$(su -s /bin/bash postgres -c "psql -d ${DB_NAME} -At -c \"
|
||||||
|
WITH explorer AS (
|
||||||
|
SELECT a.bank_account_id, a.has_debt, a.balance, a.max_debt
|
||||||
|
FROM libeufin_bank.bank_accounts a
|
||||||
|
JOIN libeufin_bank.customers c ON c.customer_id = a.owning_customer_id
|
||||||
|
WHERE c.username = '${USER}'
|
||||||
|
LIMIT 1
|
||||||
|
),
|
||||||
|
headroom AS (
|
||||||
|
SELECT CASE WHEN has_debt THEN (max_debt).val - (balance).val
|
||||||
|
ELSE (max_debt).val + (balance).val END AS val
|
||||||
|
FROM explorer
|
||||||
|
)
|
||||||
|
SELECT 1
|
||||||
|
FROM libeufin_bank.taler_withdrawal_operations w
|
||||||
|
JOIN explorer e ON e.bank_account_id = w.wallet_bank_account
|
||||||
|
CROSS JOIN headroom h
|
||||||
|
WHERE w.withdrawal_uuid = '${wid}'::uuid
|
||||||
|
AND (w.amount).val <= h.val
|
||||||
|
LIMIT 1;
|
||||||
|
\"" 2>/dev/null | tr -d '[:space:]')
|
||||||
|
[ "$ok" = "1" ]
|
||||||
|
}
|
||||||
|
|
||||||
# Selected, not yet confirmed, owner = explorer only (runs inside goa CTR).
|
# Selected, not yet confirmed, owner = explorer only (runs inside goa CTR).
|
||||||
db_selected_explorer_ids() {
|
db_selected_explorer_ids() {
|
||||||
if ! command -v psql >/dev/null 2>&1; then
|
if ! command -v psql >/dev/null 2>&1; then
|
||||||
|
|
@ -184,6 +220,11 @@ confirm_one() {
|
||||||
|
|
||||||
case "$st" in
|
case "$st" in
|
||||||
selected)
|
selected)
|
||||||
|
# Watch-list IDs bypass DB headroom filter — skip oversized (HTTP 409 forever).
|
||||||
|
if ! id_affordable "$wid"; then
|
||||||
|
qlog "skip $wid selected but over explorer headroom"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
log "confirming $wid as $USER (status=selected) ..."
|
log "confirming $wid as $USER (status=selected) ..."
|
||||||
conf=$(curl -sS -m 15 -o /tmp/acw-conf.out -w '%{http_code}' \
|
conf=$(curl -sS -m 15 -o /tmp/acw-conf.out -w '%{http_code}' \
|
||||||
-X POST \
|
-X POST \
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,15 @@
|
||||||
# ./scripts/taler-bank/install-demo-withdraw-api.sh
|
# ./scripts/taler-bank/install-demo-withdraw-api.sh
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
ROOT=$(cd "$(dirname "$0")" && pwd)
|
ROOT=$(cd "$(dirname "$0")" && pwd)
|
||||||
CTR="${BANK_CONTAINER:-taler-hacktivism-bank}"
|
CTR="${BANK_CONTAINER:-goa-regio-ng}"
|
||||||
|
|
||||||
podman cp "$ROOT/demo-withdraw-api.py" "$CTR:/usr/local/bin/demo-withdraw-api.py"
|
podman cp "$ROOT/demo-withdraw-api.py" "$CTR:/usr/local/bin/demo-withdraw-api.py"
|
||||||
podman cp "$ROOT/auto-confirm-withdrawals.sh" "$CTR:/usr/local/bin/auto-confirm-withdrawals.sh"
|
podman cp "$ROOT/auto-confirm-withdrawals.sh" "$CTR:/usr/local/bin/auto-confirm-withdrawals.sh"
|
||||||
podman cp "$ROOT/refresh-demo-withdraw.sh" "$CTR:/usr/local/bin/refresh-demo-withdraw.sh"
|
podman cp "$ROOT/refresh-demo-withdraw.sh" "$CTR:/usr/local/bin/refresh-demo-withdraw.sh"
|
||||||
|
if [ -f "$ROOT/systemd/goa-auto-confirm-withdrawals.service" ]; then
|
||||||
|
podman cp "$ROOT/systemd/goa-auto-confirm-withdrawals.service" \
|
||||||
|
"$CTR:/etc/systemd/system/goa-auto-confirm-withdrawals.service"
|
||||||
|
fi
|
||||||
podman exec -u root "$CTR" chmod 755 \
|
podman exec -u root "$CTR" chmod 755 \
|
||||||
/usr/local/bin/demo-withdraw-api.py \
|
/usr/local/bin/demo-withdraw-api.py \
|
||||||
/usr/local/bin/auto-confirm-withdrawals.sh \
|
/usr/local/bin/auto-confirm-withdrawals.sh \
|
||||||
|
|
@ -94,9 +98,7 @@ ps -eo pid=,args= | awk "/demo-withdraw-api\\.py/ && !/awk/" || {
|
||||||
tail -20 /var/log/demo-withdraw-api.log >&2 || true
|
tail -20 /var/log/demo-withdraw-api.log >&2 || true
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
# stop auto-confirm by pid
|
# Prefer systemd unit (Restart=always). Fall back to nohup if systemctl missing.
|
||||||
ps -eo pid=,args= | awk "/auto-confirm-withdrawals\\.sh --loop/ && !/awk/ {print \$1}" | while read p; do kill \$p 2>/dev/null || true; done
|
|
||||||
sleep 0.5
|
|
||||||
if [ -f /var/log/auto-confirm-withdrawals.log ]; then
|
if [ -f /var/log/auto-confirm-withdrawals.log ]; then
|
||||||
sz=$(wc -c </var/log/auto-confirm-withdrawals.log)
|
sz=$(wc -c </var/log/auto-confirm-withdrawals.log)
|
||||||
if [ "${sz:-0}" -gt 5000000 ]; then
|
if [ "${sz:-0}" -gt 5000000 ]; then
|
||||||
|
|
@ -105,12 +107,22 @@ if [ -f /var/log/auto-confirm-withdrawals.log ]; then
|
||||||
cat /tmp/ac-keep.log >> /var/log/auto-confirm-withdrawals.log
|
cat /tmp/ac-keep.log >> /var/log/auto-confirm-withdrawals.log
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
# stop ad-hoc loops (by pid; avoid pkill -f self-match)
|
||||||
|
ps -eo pid=,args= | awk "/auto-confirm-withdrawals\\.sh --loop/ && !/awk/ {print \$1}" | while read p; do kill \$p 2>/dev/null || true; done
|
||||||
|
sleep 0.5
|
||||||
|
if command -v systemctl >/dev/null 2>&1 && [ -f /etc/systemd/system/goa-auto-confirm-withdrawals.service ]; then
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now goa-auto-confirm-withdrawals.service
|
||||||
|
systemctl restart goa-auto-confirm-withdrawals.service
|
||||||
|
systemctl --no-pager --full status goa-auto-confirm-withdrawals.service | head -20
|
||||||
|
else
|
||||||
nohup env QUIET=1 WATCH_MAX=80 \
|
nohup env QUIET=1 WATCH_MAX=80 \
|
||||||
/usr/local/bin/auto-confirm-withdrawals.sh --loop 2 \
|
/usr/local/bin/auto-confirm-withdrawals.sh --loop 2 \
|
||||||
>>/var/log/auto-confirm-withdrawals.log 2>&1 </dev/null &
|
>>/var/log/auto-confirm-withdrawals.log 2>&1 </dev/null &
|
||||||
echo "auto-confirm pid $!"
|
echo "auto-confirm pid $! (no systemd unit)"
|
||||||
sleep 1
|
sleep 1
|
||||||
ps -eo pid=,args= | awk "/auto-confirm-withdrawals\\.sh --loop/ && !/awk/"
|
ps -eo pid=,args= | awk "/auto-confirm-withdrawals\\.sh --loop/ && !/awk/"
|
||||||
|
fi
|
||||||
curl -sS -m 8 http://127.0.0.1:19096/demo-withdraw.json | head -c 300; echo
|
curl -sS -m 8 http://127.0.0.1:19096/demo-withdraw.json | head -c 300; echo
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
[Unit]
|
||||||
|
Description=GOA bank auto-confirm explorer withdrawals
|
||||||
|
After=network.target libeufin-bank.service goa-demo-withdraw-api.service
|
||||||
|
Wants=libeufin-bank.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment=QUIET=1
|
||||||
|
Environment=WATCH_MAX=80
|
||||||
|
Environment=BANK_URL=http://127.0.0.1:9012
|
||||||
|
ExecStart=/usr/local/bin/auto-confirm-withdrawals.sh --loop 2
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
# flock inside script; StandardOutput goes to journal + optional file via install
|
||||||
|
StandardOutput=append:/var/log/auto-confirm-withdrawals.log
|
||||||
|
StandardError=append:/var/log/auto-confirm-withdrawals.log
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Loading…
Add table
Add a link
Reference in a new issue