ops: GOA vanilla landings stats wdGet + collect greening

This commit is contained in:
Hernâni Marques 2026-09-16 23:55:47 +02:00
parent 0d881cd726
commit 337d253691
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
24 changed files with 1074 additions and 107 deletions

View file

@ -56,9 +56,9 @@ COLLECT_MERCHANT="${COLLECT_MERCHANT:-1}"
COLLECT_RESOURCES="${COLLECT_RESOURCES:-1}"
# Containers (empty = skip podman publish for that role)
BANK_CTR="${BANK_CTR:-taler-hacktivism-bank}"
EX_CTR="${EX_CTR:-taler-hacktivism-exchange-ansible}"
MER_CTR="${MER_CTR:-taler-hacktivism}"
BANK_CTR="${BANK_CTR:-goa-regio-ng}"
EX_CTR="${EX_CTR:-goa-regio-ng}"
MER_CTR="${MER_CTR:-goa-regio-ng}"
BANK_URL="${BANK_URL:-http://127.0.0.1:9012}"
BANK_PUBLIC_URL="${BANK_PUBLIC_URL:-https://bank.hacktivism.ch}"
@ -322,10 +322,14 @@ run_incontainer_stats() {
fi
log "$label: run $script inside $ctr"
set +e
# Pass optional DB overrides (vanilla regio-ng: EXCHANGE_DB=exchange)
podman exec \
-e LANDING_DIR="$landing" \
-e TZ=Europe/Zurich \
-e PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
${EXCHANGE_DB:+-e EXCHANGE_DB="$EXCHANGE_DB"} \
${MERCHANT_DB:+-e MERCHANT_DB="$MERCHANT_DB"} \
${EXCHANGE_BASE_URL:+-e EXCHANGE_BASE_URL="$EXCHANGE_BASE_URL"} \
"$ctr" bash "$script" >>"$LOG_DIR/${label}.log" 2>&1
local ec=$?
set -e

View file

@ -130,6 +130,11 @@ def get_token(bank: str, user: str, password: str) -> str:
def list_all_accounts(bank: str, token: str, delta: int) -> List[str]:
"""List accounts; page with start if needed."""
# libeufin-bank: |delta| must be in 1..1024 (same floor as Param 'limit')
if delta == 0:
delta = -1024
elif abs(delta) > 1024:
delta = -1024 if delta < 0 else 1024
names: List[str] = []
seen: Set[str] = set()
start: Optional[int] = None
@ -213,9 +218,10 @@ def iter_transactions(
pages = 0
safety = max_pages if max_pages > 0 else 10_000
page = min(abs(page), 1024) or 1024
while pages < safety:
pages += 1
q = f"delta=-{abs(page)}"
q = f"delta=-{page}"
if start is not None:
q += f"&start={start}"
code, data, raw = http_json(
@ -364,7 +370,7 @@ def main() -> int:
ap.add_argument(
"--accounts-delta",
type=int,
default=int(env("ACCOUNTS_DELTA", "-10000") or "-10000"),
default=int(env("ACCOUNTS_DELTA", "-1024") or "-1024"),
)
ap.add_argument("--recent", type=int, default=int(env("RECENT_WD_N", "10") or "10"))
ap.add_argument("--public-base", default=env("BANK_PUBLIC_URL", "https://bank.hacktivism.ch"))

View file

@ -3,9 +3,11 @@
# listens on 9014 (exchange) / 9015 (merchant).
#
# Port map (wire these in Caddy / podman -p):
# 9013 bank landing (already on taler-hacktivism-bank)
# 9014 exchange landing (taler-hacktivism-exchange-ansible)
# 9015 merchant landing (taler-hacktivism)
# 9013 bank landing
# 9014 exchange landing
# 9015 merchant landing
# Unified vanilla CTR: set LANDING_CTR=goa-regio-ng (default) so all three
# landings land in the same container publishing 9010-9015.
#
# Run on koopa (host) with podman access.
set -euo pipefail
@ -18,9 +20,10 @@ SRC_BANK="${SRC_BANK:-$ROOT/configs/bank-landing}"
SRC_QR="${SRC_QR:-$ROOT/configs/bank-landing/qrcode.min.js}"
SRC_GOA_AMT="${SRC_GOA_AMT:-$ROOT/configs/shared/goa-amount.js}"
C_EX=taler-hacktivism-exchange-ansible
C_MER=taler-hacktivism
C_BANK="${C_BANK:-taler-hacktivism-bank}"
LANDING_CTR="${LANDING_CTR:-goa-regio-ng}"
C_EX="${C_EX:-$LANDING_CTR}"
C_MER="${C_MER:-$LANDING_CTR}"
C_BANK="${C_BANK:-$LANDING_CTR}"
# Prefer per-landing copy, then shared (keeps bank/exchange/merchant in sync)
resolve_goa_amount() {
@ -104,8 +107,8 @@ podman exec "$C_MER" curl -sS -m 3 -o /dev/null -w "merchant_landing=%{http_code
echo
echo "PORTS TO WIRE (host → Caddy / firewall / podman -p):"
echo " 9013 bank landing (taler-hacktivism-bank) already published"
echo " 9014 exchange landing (taler-hacktivism-exchange-ansible) NEEDS -p 9014:9014"
echo " 9015 merchant landing (taler-hacktivism) NEEDS -p 9015:9015"
echo " 9013 bank landing ($C_BANK)"
echo " 9014 exchange landing ($C_EX)"
echo " 9015 merchant landing ($C_MER)"
echo
echo "If host curl to :9014/:9015 fails, republish pasta ports (commit+replace) — see README."

View file

@ -1,8 +1,8 @@
# Stack profile: GOA / hacktivism
# Stack profile: GOA / goa-regio-ng vanilla (9010-9015)
# systemd EnvironmentFile: KEY=value only (no export)
BANK_CTR=taler-hacktivism-bank
EX_CTR=taler-hacktivism-exchange-ansible
MER_CTR=taler-hacktivism
BANK_CTR=goa-regio-ng
EX_CTR=goa-regio-ng
MER_CTR=goa-regio-ng
BANK_URL=http://127.0.0.1:9012
BANK_PUBLIC_URL=https://bank.hacktivism.ch
EXCHANGE_CONFIG_URL=https://exchange.hacktivism.ch/config
@ -15,4 +15,4 @@ COLLECT_EXCHANGE=1
COLLECT_MERCHANT=1
COLLECT_RESOURCES=1
PUBLISH_PODMAN=1
STATS_SOURCE_LABEL="host collect_bank_stats.py goa hacktivism"
STATS_SOURCE_LABEL="host collect_bank_stats.py goa regio-ng vanilla"

View file

@ -0,0 +1,179 @@
#!/usr/bin/env bash
# Fill landing stack-bar package versions from live CTR dpkg (not hand-edited HTML).
#
# Reads: configs/shared/landing-stack.json (package lists + vanilla href)
# Writes: configs/{bank,exchange,merchant}-landing/index.html (<!-- stack-bar --> block)
# configs/shared/landing-stack-versions.json (last dpkg snapshot)
#
# Usage (from koopa-admin-log root, laptop or koopa):
# ./scripts/taler-landing/stamp-landing-stack.sh
# ./scripts/taler-landing/stamp-landing-stack.sh --ctr goa-regio-ng --ssh hernani@192.168.100.95
# ./scripts/taler-landing/stamp-landing-stack.sh bank exchange
#
# After this, bump footer dates with:
# ./scripts/taler-landing/stamp-landing-version.sh --bump --all
# Then deploy (unified vanilla CTR):
# LANDING_CTR=goa-regio-ng ./scripts/taler-landing/deploy-landings.sh
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
STACK_FILE="$ROOT/configs/shared/landing-stack.json"
VERS_OUT="$ROOT/configs/shared/landing-stack-versions.json"
CTR="${LANDING_CTR:-goa-regio-ng}"
SSH_HOST="${LANDING_SSH:-hernani@192.168.100.95}"
USE_SSH=1
sites=()
while [ $# -gt 0 ]; do
case "$1" in
--ctr) CTR="${2:-}"; shift 2 ;;
--ssh) SSH_HOST="${2:-}"; USE_SSH=1; shift 2 ;;
--local) USE_SSH=0; shift ;;
bank|exchange|merchant) sites+=("$1"); shift ;;
-h|--help)
sed -n '2,20p' "$0"
exit 0
;;
*) echo "unknown arg: $1" >&2; exit 2 ;;
esac
done
if [ "${#sites[@]}" -eq 0 ]; then
sites=(bank exchange merchant)
fi
[ -f "$STACK_FILE" ] || { echo "missing $STACK_FILE" >&2; exit 1; }
# Collect unique package names from JSON for the selected sites
mapfile -t PKGS < <(python3 - "$STACK_FILE" "${sites[@]}" <<'PY'
import json, sys
data = json.load(open(sys.argv[1], encoding="utf-8"))
sites = sys.argv[2:]
seen = []
for s in sites:
for p in data["sites"][s]["packages"]:
if p not in seen:
seen.append(p)
print("\n".join(seen))
PY
)
if [ "${#PKGS[@]}" -eq 0 ]; then
echo "no packages configured" >&2
exit 1
fi
pkg_args=$(printf '%q ' "${PKGS[@]}")
query_cmd="podman exec $(printf '%q' "$CTR") dpkg-query -W -f='\${Package}=\${Version}\n' ${pkg_args}"
if [ "$USE_SSH" = 1 ]; then
echo "dpkg ← ${SSH_HOST} ctr=${CTR}"
# shellcheck disable=SC2086
raw=$(ssh -o BatchMode=yes -o ConnectTimeout=12 "$SSH_HOST" "podman exec $(printf '%q' "$CTR") dpkg-query -W -f='\${Package}=\${Version}\n' ${pkg_args}")
else
echo "dpkg ← local ctr=${CTR}"
# shellcheck disable=SC2086
raw=$(podman exec "$CTR" dpkg-query -W -f='${Package}=${Version}\n' "${PKGS[@]}")
fi
python3 - "$STACK_FILE" "$VERS_OUT" "$ROOT" "$CTR" "$SSH_HOST" "$raw" "${sites[@]}" <<'PY'
import json, re, sys
from pathlib import Path
from datetime import datetime
from zoneinfo import ZoneInfo
stack_path, vers_out, root, ctr, ssh_host, raw = sys.argv[1:7]
sites = sys.argv[7:]
stack = json.load(open(stack_path, encoding="utf-8"))
tz = ZoneInfo("Europe/Zurich")
now = datetime.now(tz)
iso = now.isoformat(timespec="seconds")
human = now.strftime("%Y-%m-%d %H:%M %Z")
versions = {}
for line in raw.splitlines():
line = line.strip()
if not line or "=" not in line:
continue
pkg, ver = line.split("=", 1)
# display upstream-ish: drop Debian revision (1.6.10-0+trixie → 1.6.10)
short = re.sub(r"-[0-9].*$", "", ver)
versions[pkg] = {"dpkg": ver, "display": short}
missing = []
for site in sites:
for pkg in stack["sites"][site]["packages"]:
if pkg not in versions:
missing.append(pkg)
if missing:
raise SystemExit(f"dpkg missing packages: {', '.join(sorted(set(missing)))}")
vanilla_href = stack["vanilla_href"]
vanilla_title = stack.get("vanilla_title", "vanilla")
sep = '<span class="sep">·</span>'
def render_block(site: str) -> str:
meta = stack["sites"][site]
parts = [
f' <!-- stack-bar -->',
f' <p class="stack-bar" role="note" title="{meta["title"]}">',
f' <strong>stack</strong>{sep}',
f' <a href="{vanilla_href}" target="_blank" rel="noopener noreferrer" title="{vanilla_title}">vanilla</a>',
]
for pkg in meta["packages"]:
disp = versions[pkg]["display"]
parts.append(f" {sep}")
parts.append(f" {pkg}&nbsp;{disp}")
parts.append(" </p>")
parts.append(" <!-- /stack-bar -->")
return "\n".join(parts) + "\n"
site_html = {
"bank": Path(root) / "configs/bank-landing/index.html",
"exchange": Path(root) / "configs/exchange-landing/index.html",
"merchant": Path(root) / "configs/merchant-landing/index.html",
}
marker_re = re.compile(r"[ \t]*<!-- stack-bar -->.*?<!-- /stack-bar -->\n?", re.S)
bare_re = re.compile(
r"[ \t]*<p class=\"stack-bar\"[^>]*>.*?</p>\n?",
re.S,
)
for site in sites:
path = site_html[site]
text = path.read_text(encoding="utf-8")
block = render_block(site)
if marker_re.search(text):
text = marker_re.sub(block, text, count=1)
elif bare_re.search(text):
text = bare_re.sub(block, text, count=1)
else:
raise SystemExit(f"no stack-bar in {path}")
path.write_text(text, encoding="utf-8")
print(f"stack → {path.relative_to(root)} ({site})")
out = {
"updated_iso": iso,
"updated_human": human,
"ctr": ctr,
"ssh": ssh_host if ssh_host else None,
"packages": versions,
"sites": {
site: {
"packages": {
pkg: versions[pkg]["display"]
for pkg in stack["sites"][site]["packages"]
}
}
for site in ("bank", "exchange", "merchant")
if site in stack["sites"]
},
}
Path(vers_out).write_text(json.dumps(out, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
print(f"versions → {Path(vers_out).relative_to(root)}")
print(f"OK stack stamped: {' '.join(sites)} @ {human}")
PY
echo "OK stamp-landing-stack: ${sites[*]}${CTR}"