From 2451c66173aa00a4e12eff29020461d5bbd68c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Marques?= Date: Wed, 22 Jul 2026 03:54:09 +0200 Subject: [PATCH] fix 1.23.7: FP stage host-agent install and tip parity with GOA Ship fp-stage systemd units; install-host-agent.sh --fp-stage for stagepaysan (disables GOA timers on FP host). Env example enforces SUITE_REQUIRE_REMOTE_TIP. --- VERSION | 2 +- VERSIONS.md | 1 + host-agent/README.md | 2 +- host-agent/env/stagepaysan.env.example | 4 + host-agent/install-host-agent.sh | 125 +++++++++++++++++-- host-agent/taler-monitoring-fp-stage.service | 24 ++++ host-agent/taler-monitoring-fp-stage.timer | 11 ++ 7 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 host-agent/taler-monitoring-fp-stage.service create mode 100644 host-agent/taler-monitoring-fp-stage.timer diff --git a/VERSION b/VERSION index d8c40e5..2d27ccb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.23.6 +1.23.7 diff --git a/VERSIONS.md b/VERSIONS.md index ce8f1ff..58d20c9 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -17,6 +17,7 @@ Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.8.0`). File `VERSION` omits the `v` pre | Tag | Date (UTC) | Notes | |-----|------------|--------| +| **v1.23.7** | 2026-07-22 | **FP stage host-agent:** ship `taler-monitoring-fp-stage.{service,timer}`; `install-host-agent.sh --fp-stage` (stagepaysan) enables FP mon only, disables GOA timers on that host, enforces suite tip knobs. Same sticky/publish pipeline as GOA. | | **v1.23.6** | 2026-07-22 | **Strict suite tip for mon pages:** every host-agent run must `fetch`+`reset` to `origin/main` and **refuse** if HEAD ≠ remote tip (`SUITE_REQUIRE_REMOTE_TIP=1`). Overlay is refreshed **from** the tip after update (never re-applied over tip by default — was publishing stale site-gen). `git clean` after reset. Mon HTML still embeds that COMMIT in sticky/meta. | | **v1.23.5** | 2026-07-22 | **Bugfix / host-agent:** multi-agent shared `/var/www/monitoring-sites` — stop full-tree `rsync --delete` (wiped sibling pages e.g. `/monitoring-max-ladder/` after main/surface/aptdeploy runs). Publish **only this job’s** `HTML_OK_DIR`/`HTML_ERR_DIR` per host; `apply-monitoring-live.sh` merges without tree-delete. | | **v1.23.4** | 2026-07-19 | **Bugfix / mon:** shared **normalize_taler_uri** (strip taler:// host :443/:80); ladder/e2e/pay use it. **urls** scans bank+exchange+merchant intros + demo-withdraw/auto-account/stats for default ports (**ERROR** on GOA). Unit test tests/test_normalize_taler_uri.sh. | diff --git a/host-agent/README.md b/host-agent/README.md index 05192be..bb438d6 100644 --- a/host-agent/README.md +++ b/host-agent/README.md @@ -20,7 +20,7 @@ Thin wrappers only set stack defaults: | Wrapper | Stack | Typical user | |---------|-------|----------------| | `run-hacktivism-monitoring.sh` | GOA `hacktivism.ch` | `hernani` @ koopa | -| `run-fp-stage-monitoring.sh` | FP stage | `stagepaysan` | +| `run-fp-stage-monitoring.sh` | FP stage | `stagepaysan` — install: `install-host-agent.sh --fp-stage` (`taler-monitoring-fp-stage.timer`, 4h) | | `run-host-report.sh` + `taler-monitoring-mytops-stage.{service,timer}` | mytops **stage / betel** only | `taler-monitoring` @ betel (4h) | | `run-aptdeploy.sh` | CLI: ensure + **aptdeploy** (no HTML) | local if hostname=koopa, else **ssh $DEPLOY_SSH** | | `run-aptdeploy-monitoring.sh` | apt-src tests → `/taler-monitoring-aptdeploy*` | `hernani` @ koopa (4h) | diff --git a/host-agent/env/stagepaysan.env.example b/host-agent/env/stagepaysan.env.example index abfcdc3..a2d01d7 100644 --- a/host-agent/env/stagepaysan.env.example +++ b/host-agent/env/stagepaysan.env.example @@ -25,7 +25,11 @@ SUITE_DIR=$HOME/src/taler-monitoring SUITE_GIT_URL=https://git.hacktivism.ch/hernani/taler-monitoring.git SUITE_GIT_REF=main SUITE_UPDATE_MODE=reset +SUITE_UPDATE_STRICT=1 +# Mon HTML sticky must pin remote tip (same as GOA host-agent) +SUITE_REQUIRE_REMOTE_TIP=1 SOURCE_REPO_WEB=https://git.hacktivism.ch/hernani/taler-monitoring +SOURCE_REPO_GIT=https://git.hacktivism.ch/hernani/taler-monitoring.git FRANCPAYSAN_SECRETS=$HOME/francpaysan-secrets WALLET_CLI=$HOME/.local/lib/taler-wallet-cli/node_modules/taler-wallet-cli/bin/taler-wallet-cli.mjs diff --git a/host-agent/install-host-agent.sh b/host-agent/install-host-agent.sh index 118ef7f..a5d6e65 100755 --- a/host-agent/install-host-agent.sh +++ b/host-agent/install-host-agent.sh @@ -1,20 +1,118 @@ #!/usr/bin/env bash -# install-host-agent.sh — install hernani user systemd units on koopa +# install-host-agent.sh — install user systemd mon units # -# # on koopa as hernani: +# # GOA / koopa as hernani (default): # ~/src/taler-monitoring/host-agent/install-host-agent.sh -# # or from laptop: +# # FrancPaysan stage as stagepaysan: +# ~/src/taler-monitoring/host-agent/install-host-agent.sh --fp-stage +# # from laptop: # ./install-host-agent.sh --remote $DEPLOY_SSH +# ./install-host-agent.sh --remote $DEPLOY_SSH --fp-stage # # Suite tree is ONLY ~/src/taler-monitoring (standalone repo). No koopa-admin-log. +# Both stacks share run-host-report.sh → update-suite tip enforcement + per-dir publish. # set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) -REMOTE="${1:-}" -[ "${1:-}" = "--remote" ] && REMOTE="${2:-${DEPLOY_SSH:-}}" +REMOTE="" +STACK="${HOST_AGENT_STACK:-goa}" +while [ $# -gt 0 ]; do + case "$1" in + --remote) + REMOTE="${2:-${DEPLOY_SSH:-}}" + shift 2 + ;; + --fp-stage|--fp|--stagepaysan) + STACK=fp-stage + shift + ;; + --goa|goa) + STACK=goa + shift + ;; + *) + # bare host = remote (legacy) + if [ -z "$REMOTE" ] && [ "$1" != "--remote" ]; then + REMOTE="$1" + fi + shift + ;; + esac +done SUITE_URL="${SUITE_GIT_URL:-https://git.hacktivism.ch/hernani/taler-monitoring.git}" +install_fp_stage() { + local mon home_unit + mon=$(cd "$ROOT/.." && pwd) + if [ -d "$HOME/src/taler-monitoring/.git" ] || [ -d "$HOME/src/taler-monitoring" ]; then + mon="$HOME/src/taler-monitoring" + fi + home_unit="$HOME/.config/systemd/user" + mkdir -p "$home_unit" \ + "$HOME/.local/state/taler-monitoring-stage-lfp" \ + "$HOME/monitoring-sites-staging" \ + "$HOME/.config/taler-monitoring" \ + "$HOME/src" + + if [ ! -f "$HOME/.config/taler-monitoring/env" ] && [ -f "$ROOT/env/stagepaysan.env.example" ]; then + cp "$ROOT/env/stagepaysan.env.example" "$HOME/.config/taler-monitoring/env" + echo "created ~/.config/taler-monitoring/env from stagepaysan.env.example" + fi + # Ensure tip-enforcement knobs present (idempotent append if missing) + if [ -f "$HOME/.config/taler-monitoring/env" ]; then + grep -q '^SUITE_UPDATE_MODE=' "$HOME/.config/taler-monitoring/env" 2>/dev/null \ + || echo 'SUITE_UPDATE_MODE=reset' >>"$HOME/.config/taler-monitoring/env" + grep -q '^SUITE_UPDATE_STRICT=' "$HOME/.config/taler-monitoring/env" 2>/dev/null \ + || echo 'SUITE_UPDATE_STRICT=1' >>"$HOME/.config/taler-monitoring/env" + grep -q '^SUITE_REQUIRE_REMOTE_TIP=' "$HOME/.config/taler-monitoring/env" 2>/dev/null \ + || echo 'SUITE_REQUIRE_REMOTE_TIP=1' >>"$HOME/.config/taler-monitoring/env" + fi + + if [ ! -d "$HOME/src/taler-monitoring/.git" ]; then + echo "clone $SUITE_URL → $HOME/src/taler-monitoring" + git clone "$SUITE_URL" "$HOME/src/taler-monitoring" \ + || echo "WARN: clone failed — using tree at $mon if present" + fi + mon="$HOME/src/taler-monitoring" + ln -sfn "$mon" "$HOME/taler-monitoring" 2>/dev/null || true + ( + cd "$mon" + git fetch --tags --force --prune origin 2>/dev/null || true + git checkout -B main origin/main 2>/dev/null || git checkout main 2>/dev/null || true + git reset --hard origin/main 2>/dev/null || true + ) + chmod +x "$mon"/taler-monitoring.sh "$mon"/check_*.sh 2>/dev/null || true + chmod +x "$mon/host-agent"/*.sh 2>/dev/null || true + chmod +x "$mon/site-gen"/*.sh "$mon/site-gen/console_to_html.py" 2>/dev/null || true + + install -m 644 "$ROOT/taler-monitoring-fp-stage.service" "$home_unit/" + install -m 644 "$ROOT/taler-monitoring-fp-stage.timer" "$home_unit/" + chmod +x "$ROOT/run-fp-stage-monitoring.sh" 2>/dev/null || true + + # FP host must not run GOA timers (would write GOA mon dirs / wrong inventory) + for u in taler-monitoring-hacktivism taler-monitoring-surface \ + taler-monitoring-aptdeploy taler-monitoring-max-ladder \ + taler-monitoring-mail taler-monitoring-mattermost; do + systemctl --user disable --now "${u}.timer" 2>/dev/null || true + systemctl --user disable --now "${u}.path" 2>/dev/null || true + systemctl --user stop "${u}.service" 2>/dev/null || true + rm -f "$home_unit/${u}.service" "$home_unit/${u}.timer" "$home_unit/${u}.path" 2>/dev/null || true + done + + systemctl --user daemon-reload + systemctl --user enable --now taler-monitoring-fp-stage.timer + systemctl --user start --no-block taler-monitoring-fp-stage.service || true + + echo "--- FP stage status ---" + systemctl --user status taler-monitoring-fp-stage.timer --no-pager -l | head -12 || true + systemctl --user list-timers --all | grep taler-monitoring || true + echo "OK host-agent FP stage:" + echo " · fp-stage 4h → /monitoring on stage.{bank,exchange,monnaie}.lefrancpaysan.ch" + echo " · suite tip: $mon (SUITE_REQUIRE_REMOTE_TIP=1 via run-host-report)" + echo "manual: systemctl --user start taler-monitoring-fp-stage.service" +} + install_local() { local mon home_unit mon=$(cd "$ROOT/.." && pwd) @@ -115,7 +213,7 @@ install_local() { } if [ -n "$REMOTE" ] && [ "$REMOTE" != "--remote" ]; then - echo "install on $REMOTE …" + echo "install on $REMOTE (stack=$STACK) …" # ROOT = …/taler-monitoring/host-agent → suite root is parent rsync -az --delete \ --exclude secrets.env \ @@ -123,8 +221,17 @@ if [ -n "$REMOTE" ] && [ "$REMOTE" != "--remote" ]; then --exclude '.git' \ "$ROOT/../" \ "${REMOTE}:src/taler-monitoring/" - ssh -o BatchMode=yes "$REMOTE" \ - 'bash $HOME/src/taler-monitoring/host-agent/install-host-agent.sh' + if [ "$STACK" = "fp-stage" ]; then + ssh -o BatchMode=yes "$REMOTE" \ + 'bash $HOME/src/taler-monitoring/host-agent/install-host-agent.sh --fp-stage' + else + ssh -o BatchMode=yes "$REMOTE" \ + 'bash $HOME/src/taler-monitoring/host-agent/install-host-agent.sh' + fi else - install_local + if [ "$STACK" = "fp-stage" ]; then + install_fp_stage + else + install_local + fi fi diff --git a/host-agent/taler-monitoring-fp-stage.service b/host-agent/taler-monitoring-fp-stage.service new file mode 100644 index 0000000..bf38942 --- /dev/null +++ b/host-agent/taler-monitoring-fp-stage.service @@ -0,0 +1,24 @@ +[Unit] +Description=taler-monitoring FrancPaysan stage (urls/inside/versions/monpages/e2e) +Documentation=file:%h/src/taler-monitoring/host-agent/README.md +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +# Quote PHASES (spaces). Do not override PATH here — EnvironmentFile PATH= can break bash. +Environment="PHASES=urls inside versions monpages e2e" +Environment=RUN_TIMEOUT=1800 +Environment=E2E_TIMEOUT=900 +Environment=E2E_USE_TEMPLATES=1 +Environment=FRANCPAYSAN_SECRETS=%h/francpaysan-secrets +Environment=WALLET_CLI=%h/.local/lib/taler-wallet-cli/node_modules/taler-wallet-cli/bin/taler-wallet-cli.mjs +# Shared pipeline: fetch/reset suite tip (SUITE_REQUIRE_REMOTE_TIP) then mon HTML publish +EnvironmentFile=-%h/.config/taler-monitoring/env +WorkingDirectory=%h/src/taler-monitoring +ExecStart=/bin/bash %h/src/taler-monitoring/host-agent/run-fp-stage-monitoring.sh +Nice=10 +TimeoutStartSec=40min + +[Install] +WantedBy=default.target diff --git a/host-agent/taler-monitoring-fp-stage.timer b/host-agent/taler-monitoring-fp-stage.timer new file mode 100644 index 0000000..e30d7c7 --- /dev/null +++ b/host-agent/taler-monitoring-fp-stage.timer @@ -0,0 +1,11 @@ +[Unit] +Description=taler-monitoring FP stage every 4h +Documentation=file:%h/src/taler-monitoring/host-agent/README.md + +[Timer] +OnBootSec=10min +OnUnitActiveSec=4h +Persistent=true + +[Install] +WantedBy=timers.target