#!/usr/bin/env bash # check_apt_deploy.sh — podman apt-src merchant deploy tests on koopa. # # Containers (default): # Fresh (rebuild when repo versions change): # koopa-taler-deploy-test-apt-src-trixie # koopa-taler-deploy-test-apt-src-trixie-testing # Upgrade track (initial install, then mytops-style apt upgrade): # koopa-taler-deploy-test-apt-src-trixie-upgrade # koopa-taler-deploy-test-apt-src-trixie-testing-upgrade # # Env: # APT_DEPLOY_CONTAINERS "name:suite:mode …" mode=fresh|upgrade (optional, default fresh) # APT_DEPLOY_SKIP=1 # APT_DEPLOY_PODMAN=podman # set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) # shellcheck source=lib.sh source "$ROOT/lib.sh" if [ "${APT_DEPLOY_SKIP:-0}" = "1" ]; then echo "[INFO] skip phase aptdeploy (APT_DEPLOY_SKIP=1)" exit 0 fi set_area aptdeploy section "aptdeploy · podman apt-src merchant (fresh + upgrade tracks)" PODMAN_BIN="${APT_DEPLOY_PODMAN:-podman}" DEFAULT_LIST="\ koopa-taler-deploy-test-apt-src-trixie:trixie:fresh \ koopa-taler-deploy-test-apt-src-trixie-testing:trixie-testing:fresh \ koopa-taler-deploy-test-apt-src-trixie-upgrade:trixie:upgrade \ koopa-taler-deploy-test-apt-src-trixie-testing-upgrade:trixie-testing:upgrade" LIST="${APT_DEPLOY_CONTAINERS:-$DEFAULT_LIST}" if ! command -v "$PODMAN_BIN" >/dev/null 2>&1; then err "podman" "podman binary missing ($PODMAN_BIN)" summary exit 1 fi ok "podman" "$("$PODMAN_BIN" --version 2>/dev/null | head -1)" info "host" "$(hostname 2>/dev/null || echo unknown) · whoami=$(whoami)" fail_any=0 print_pkg_table() { local name=$1 local rows rows=$("$PODMAN_BIN" exec "$name" bash -lc ' echo "| package | version |" echo "|---------|---------|" for p in taler-merchant libtalermerchant libtalerexchange libdonau libgnunet \ taler-merchant-webui taler-merchant-typst taler-terms-generator; do v=$(dpkg-query -W -f="\${Version}" "$p" 2>/dev/null || echo missing) echo "| $p | $v |" done ' 2>/dev/null || echo "| (query failed) | |") info "pkg-table" "$name" # emit as plain lines so HTML log keeps the table while IFS= read -r line; do [ -n "$line" ] || continue info "pkg" "$line" done <<<"$rows" } check_ldd_deep() { local name=$1 local out out=$("$PODMAN_BIN" exec "$name" bash -lc ' set +e bin=$(command -v taler-merchant-httpd) echo "=== ldd taler-merchant-httpd ===" ldd "$bin" 2>&1 | grep -E "libtalerutil|libdonau|libgnunet|not found" || true echo "=== ldd libdonau (if present) ===" for f in /usr/lib/*/libdonau.so* /usr/lib/*/libdonauutil.so*; do [ -e "$f" ] || continue echo "-- $f --" ldd "$f" 2>&1 | grep -E "libtalerutil|not found" || true done echo "=== libtalerutil files ===" ls -la /usr/lib/*/libtalerutil* 2>/dev/null || echo "(none)" ' 2>/dev/null || echo "ldd probe failed") while IFS= read -r line; do [ -n "$line" ] || continue info "ldd" "$line" done <<<"$out" if echo "$out" | grep -q 'not found'; then err "ldd" "shared library missing in $name" "see ldd lines above" return 1 fi return 0 } check_systemd() { local name=$1 local out active_target active_httpd enabled out=$("$PODMAN_BIN" exec "$name" bash -lc ' set +e echo "system: $(systemctl is-system-running 2>&1)" echo "target_enabled: $(systemctl is-enabled taler-merchant.target 2>&1)" echo "target_active: $(systemctl is-active taler-merchant.target 2>&1)" echo "httpd_active: $(systemctl is-active taler-merchant-httpd.service 2>&1)" echo "httpd_enabled: $(systemctl is-enabled taler-merchant-httpd.service 2>&1)" systemctl start taler-merchant.target 2>&1 | tail -5 sleep 2 echo "after_start_target: $(systemctl is-active taler-merchant.target 2>&1)" echo "after_start_httpd: $(systemctl is-active taler-merchant-httpd.service 2>&1)" systemctl --failed --no-legend 2>/dev/null | grep -i taler || echo "failed_taler: none" ' 2>/dev/null || echo "systemd probe failed") while IFS= read -r line; do [ -n "$line" ] || continue info "systemd" "$line" done <<<"$out" active_httpd=$(echo "$out" | sed -n 's/^after_start_httpd: //p' | tail -1) if [ "$active_httpd" = "active" ]; then ok "systemd httpd" "taler-merchant-httpd active after start taler-merchant.target" return 0 fi # soft if target not shipped as enabled in container — still ERROR for deploy smoke err "systemd httpd" "taler-merchant-httpd not active" "after_start_httpd=${active_httpd:-?} · see systemd lines" return 1 } check_merchant_basics() { local name=$1 local out code # unix socket or curl localhost if httpd listens out=$("$PODMAN_BIN" exec "$name" bash -lc ' set +e echo "=== binaries ===" command -v taler-merchant-httpd taler-merchant-dbinit taler-config 2>/dev/null echo "=== --version ===" taler-merchant-httpd --version 2>&1 echo "=== config probe ===" # try common paths without TLS for u in \ http://127.0.0.1:9966/config \ http://127.0.0.1:8081/config \ http://127.0.0.1/config do code=$(curl -sS -m 2 -o /tmp/mcfg -w "%{http_code}" "$u" 2>/dev/null || echo 000) echo "curl $u -> $code" [ "$code" = "200" ] && head -c 120 /tmp/mcfg && echo done sock=$(ls /run/taler-merchant/httpd/*.sock 2>/dev/null | head -1) if [ -n "$sock" ]; then echo "socket: $sock" code=$(curl -sS -m 2 --unix-socket "$sock" -o /tmp/mcfg -w "%{http_code}" http://localhost/config 2>/dev/null || echo 000) echo "curl --unix-socket -> $code" [ "$code" = "200" ] && head -c 160 /tmp/mcfg && echo else echo "socket: (none under /run/taler-merchant/httpd/)" fi ' 2>/dev/null || echo "basics probe failed") while IFS= read -r line; do [ -n "$line" ] || continue info "basics" "$line" done <<<"$out" if echo "$out" | grep -qi 'error while loading shared libraries'; then err "httpd" "shared library error on --version" "see basics/ldd" return 1 fi if ! echo "$out" | grep -q 'taler-merchant-httpd --version\|v\.\|taler-merchant-httpd'; then # version line varies; success if exit was ok — check via separate exec : fi set +e "$PODMAN_BIN" exec "$name" taler-merchant-httpd --version >/dev/null 2>&1 local ec=$? set -e if [ "$ec" -eq 0 ]; then ok "httpd --version" "exit 0" else err "httpd --version" "exit $ec" return 1 fi # /config is nice-to-have if stack is fully configured if echo "$out" | grep -qE 'curl .* -> 200'; then ok "merchant /config" "HTTP 200 (local)" else warn "merchant /config" "no local HTTP 200 (unit may need BASE_URL/db — still report version/ldd)" fi return 0 } check_one() { local name="$1" expect_suite="$2" mode="${3:-fresh}" local st suite_line pkgs # group ids: aptdeploy.trixie-01 / aptdeploy.trixie-testing-upgrade-01 set_group "${expect_suite}${mode:+-$mode}" section "aptdeploy · $name (suite=$expect_suite mode=$mode)" if ! "$PODMAN_BIN" container exists "$name" 2>/dev/null; then err "container" "$name missing" "run ensure-apt-deploy-test-containers.sh" fail_any=1 return fi st=$("$PODMAN_BIN" inspect -f '{{.State.Status}}' "$name" 2>/dev/null || echo unknown) if [ "$st" != "running" ]; then err "container" "$name not running" "status=$st" fail_any=1 return fi ok "container" "$name running (mode=$mode)" suite_line=$("$PODMAN_BIN" exec "$name" bash -lc \ 'grep -h "^Suites:" /etc/apt/sources.list.d/*taler* 2>/dev/null | head -1' 2>/dev/null || true) if echo "$suite_line" | grep -qE "Suites:[[:space:]]*${expect_suite}([[:space:]]|$)"; then ok "apt suite" "$expect_suite" else err "apt suite" "expected $expect_suite" "got: ${suite_line:-empty}" fail_any=1 fi print_pkg_table "$name" if ! check_merchant_basics "$name"; then fail_any=1 check_ldd_deep "$name" || fail_any=1 else # still show ldd summary as info when ok ldd_out=$("$PODMAN_BIN" exec "$name" bash -lc \ 'ldd "$(command -v taler-merchant-httpd)" 2>&1 | grep -E "libtalerutil|not found" || true' 2>/dev/null || true) if echo "$ldd_out" | grep -q 'not found'; then err "libtalerutil" "not found" "$ldd_out" check_ldd_deep "$name" || true fail_any=1 else info "libtalerutil" "$(echo "$ldd_out" | tr '\n' ' ')" fi fi if ! check_systemd "$name"; then fail_any=1 check_ldd_deep "$name" || true fi # Disk free inside this deploy-test container (+ host once, first container only) if [ "${_APT_DEPLOY_HOST_DISK_DONE:-0}" != "1" ]; then set_group disk mon_disk_check_host "host" || fail_any=1 _APT_DEPLOY_HOST_DISK_DONE=1 fi set_group disk if ! mon_disk_check_podman "$name" "$PODMAN_BIN"; then fail_any=1 fi } for entry in $LIST; do # name:suite or name:suite:mode cname=${entry%%:*} rest=${entry#*:} case "$rest" in *:*) suite=${rest%%:*} mode=${rest#*:} ;; *) suite=$rest mode=fresh ;; esac check_one "$cname" "$suite" "$mode" done summary if [ "$fail_any" -ne 0 ]; then exit 1 fi exit 0