release 1.5.0: Mattermost monitoring (mattermost.taler.net)
This commit is contained in:
parent
4f092b90cc
commit
9a6929ae92
12 changed files with 219 additions and 9 deletions
|
|
@ -9,6 +9,7 @@ Checks for **GNU Taler** stacks (bank, exchange, merchant; optional surface inve
|
|||
| **Host-agent + HTML** | Optional: timers run the suite and publish sticky-bar HTML under `…/monitoring/` (and surface/aptdeploy paths) |
|
||||
|
||||
Outside-only example: `./taler-monitoring.sh -d demo.taler.net urls`
|
||||
Mattermost chat: `./taler-monitoring.sh mattermost` (default `https://mattermost.taler.net`)
|
||||
Full local GOA example: `./taler-monitoring.sh -d hacktivism.ch urls inside versions`
|
||||
|
||||
Repo: https://git.hacktivism.ch/hernani/taler-monitoring · tree: `~/src/taler-monitoring`
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
1.4.1
|
||||
1.5.0
|
||||
11
VERSIONS.md
11
VERSIONS.md
|
|
@ -13,11 +13,12 @@ Tags and `VERSION` use **MAJOR.FEATURE.FIX** (three components):
|
|||
| **FEATURE** | New capabilities (phases, HTML features, i18n packs, …) |
|
||||
| **FIX** | Bugfixes and docs that do not add a feature |
|
||||
|
||||
Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.4.1`). File `VERSION` omits the `v` prefix.
|
||||
Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.5.0`). File `VERSION` omits the `v` prefix.
|
||||
|
||||
| Tag | Date (UTC) | Notes |
|
||||
|-----|------------|--------|
|
||||
| **v1.5.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). |
|
||||
| **v1.6.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). |
|
||||
| **v1.5.0** | 2026-07-18 | **Mattermost monitoring:** phase `mattermost` (`check_mattermost.sh`) for `mattermost.taler.net` (SPA + `/api/v4/system/ping` + TLS); host-agent HTML `/taler-monitoring-mattermost*`; hourly timer. |
|
||||
| **v1.4.1** | 2026-07-18 | **Docs/versioning:** canonical tree `~/src/taler-monitoring`; docs use generic ops/outside-runner wording (no client hostnames); tags always **MAJOR.FEATURE.FIX**. |
|
||||
| **v1.3.4** | 2026-07-18 | Summary i18n, monpages code-21, aptdeploy rsync path. |
|
||||
| **v1.3.3** | 2026-07-18 | GIT notes vs GUI notes; monpages in TESTS. |
|
||||
|
|
@ -32,7 +33,7 @@ Older short tags (`v1`, `v1.0`, `v1.1`, `v1.2`, `v1.3`) are obsolete; use the th
|
|||
|
||||
## Sticky bar version (v1.3.0+)
|
||||
|
||||
Generated HTML shows the installed release tag (e.g. `v1.4.1`) next to the host line.
|
||||
Generated HTML shows the installed release tag (e.g. `v1.5.0`) next to the host line.
|
||||
Clicking opens the tag page on Forgejo:
|
||||
|
||||
`https://git.hacktivism.ch/hernani/taler-monitoring/src/tag/<tag>`
|
||||
|
|
@ -64,11 +65,11 @@ sudo ~/koopa-caddy/apply-monitoring-live.sh
|
|||
| Env | `TALER_MON_LANG=en` or `fr` |
|
||||
| Auto | `*lefrancpaysan*` → fr, else en |
|
||||
|
||||
Full locale packs (fr-CH / de-CH) are scheduled for **v1.5.0**.
|
||||
Full locale packs (fr-CH / de-CH) are scheduled for **v1.6.0**.
|
||||
|
||||
## Pin a release
|
||||
|
||||
```bash
|
||||
git clone https://git.hacktivism.ch/hernani/taler-monitoring.git ~/src/taler-monitoring
|
||||
cd ~/src/taler-monitoring && git checkout v1.4.1
|
||||
cd ~/src/taler-monitoring && git checkout v1.5.0
|
||||
```
|
||||
|
|
|
|||
113
check_mattermost.sh
Executable file
113
check_mattermost.sh
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/env bash
|
||||
# check_mattermost.sh — outside-in checks for Taler Mattermost (chat)
|
||||
#
|
||||
# Default host: mattermost.taler.net
|
||||
# Override: MATTERMOST_PUBLIC=https://mattermost.example.org
|
||||
# MATTERMOST_HOST=mattermost.example.org
|
||||
#
|
||||
# Outside-only (no SSH). Phase name: mattermost
|
||||
#
|
||||
set -euo pipefail
|
||||
ROOT=$(cd "$(dirname "$0")" && pwd)
|
||||
# shellcheck source=lib.sh
|
||||
source "$ROOT/lib.sh"
|
||||
|
||||
set_area mattermost
|
||||
section "mattermost · public chat (outside-in)"
|
||||
|
||||
if [ -n "${MATTERMOST_PUBLIC:-}" ]; then
|
||||
BASE="${MATTERMOST_PUBLIC%/}"
|
||||
elif [ -n "${MATTERMOST_HOST:-}" ]; then
|
||||
BASE="https://${MATTERMOST_HOST}"
|
||||
else
|
||||
BASE="https://mattermost.taler.net"
|
||||
fi
|
||||
HOST=${BASE#https://}
|
||||
HOST=${HOST#http://}
|
||||
HOST=${HOST%%/*}
|
||||
|
||||
info "target" "$BASE"
|
||||
|
||||
tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$tmp"' EXIT
|
||||
|
||||
# GET with follow redirects (Mattermost SPA often 302 → /)
|
||||
mm_get() {
|
||||
local url="$1" out="$2"
|
||||
curl -skS -L --max-redirs 5 -m "${TIMEOUT:-12}" -o "$out" -w '%{http_code}' "$url" 2>/dev/null || echo 000
|
||||
}
|
||||
|
||||
# --- DNS / HTTPS landing ---
|
||||
set_group landing
|
||||
code=$(mm_get "$BASE/" "$tmp/root.html")
|
||||
if [ "$code" = "200" ] && head -c 512 "$tmp/root.html" | grep -qiE '<!doctype html|<html'; then
|
||||
ok "landing" "$BASE/ → HTTP $code HTML"
|
||||
else
|
||||
fail "landing" "$BASE/ → HTTP $code (want 200 HTML Mattermost SPA)"
|
||||
fi
|
||||
|
||||
# --- Official Mattermost health API ---
|
||||
set_group api
|
||||
code=$(mm_get "$BASE/api/v4/system/ping" "$tmp/ping.json")
|
||||
if [ "$code" != "200" ]; then
|
||||
fail "system/ping" "$BASE/api/v4/system/ping → HTTP $code (want 200 JSON)"
|
||||
else
|
||||
# Ping returns JSON object (fields vary by MM version)
|
||||
if python3 - "$tmp/ping.json" <<'PY' 2>/dev/null
|
||||
import json, sys
|
||||
p = sys.argv[1]
|
||||
with open(p) as f:
|
||||
d = json.load(f)
|
||||
if not isinstance(d, dict):
|
||||
sys.exit(2)
|
||||
# older builds may include status; newer still return object with backends
|
||||
sys.exit(0)
|
||||
PY
|
||||
then
|
||||
ok "system/ping" "$BASE/api/v4/system/ping → HTTP 200 JSON"
|
||||
else
|
||||
fail "system/ping" "$BASE/api/v4/system/ping → HTTP 200 but not valid JSON object"
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Login SPA (must be served for users) ---
|
||||
set_group login
|
||||
code=$(mm_get "$BASE/login" "$tmp/login.html")
|
||||
if [ "$code" = "200" ] && head -c 512 "$tmp/login.html" | grep -qiE '<!doctype html|<html'; then
|
||||
ok "login" "$BASE/login → HTTP $code HTML"
|
||||
else
|
||||
fail "login" "$BASE/login → HTTP $code (want 200 HTML)"
|
||||
fi
|
||||
|
||||
# --- TLS certificate expiry (openssl s_client if available) ---
|
||||
set_group tls
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
end=$(echo | openssl s_client -servername "$HOST" -connect "${HOST}:443" 2>/dev/null \
|
||||
| openssl x509 -noout -enddate 2>/dev/null | sed 's/notAfter=//')
|
||||
if [ -n "$end" ]; then
|
||||
# days remaining
|
||||
end_epoch=$(date -d "$end" +%s 2>/dev/null || date -j -f "%b %d %T %Y %Z" "$end" +%s 2>/dev/null || echo 0)
|
||||
now_epoch=$(date +%s)
|
||||
if [ "$end_epoch" -gt 0 ]; then
|
||||
days=$(( (end_epoch - now_epoch) / 86400 ))
|
||||
if [ "$days" -lt 0 ]; then
|
||||
fail "tls cert" "$HOST cert expired ($end)"
|
||||
elif [ "$days" -lt 14 ]; then
|
||||
warn "tls cert" "$HOST expires in ${days}d ($end)"
|
||||
elif [ "$days" -lt 30 ]; then
|
||||
warn "tls cert" "$HOST expires in ${days}d ($end)"
|
||||
else
|
||||
ok "tls cert" "$HOST valid · ${days}d left · $end"
|
||||
fi
|
||||
else
|
||||
info "tls cert" "$HOST notAfter=$end"
|
||||
fi
|
||||
else
|
||||
warn "tls cert" "$HOST could not read certificate"
|
||||
fi
|
||||
else
|
||||
info "tls cert" "openssl not available — skip expiry check"
|
||||
fi
|
||||
|
||||
info "hint" "surface catalog also lists $HOST; this phase is Mattermost-specific (SPA + /api/v4/system/ping)"
|
||||
exit 0
|
||||
|
|
@ -125,6 +125,8 @@ Units:
|
|||
| `taler-monitoring-hacktivism.service` | oneshot → `/monitoring*` (urls inside versions) |
|
||||
| `taler-monitoring-surface.timer` | every **1h** |
|
||||
| `taler-monitoring-surface.service` | → `/taler-monitoring-surface*` (taler only) |
|
||||
| `taler-monitoring-mattermost.timer` | every **1h** |
|
||||
| `taler-monitoring-mattermost.service` | → `/taler-monitoring-mattermost*` (mattermost.taler.net) |
|
||||
| `taler-monitoring-aptdeploy.timer` | every **4h** |
|
||||
| `taler-monitoring-aptdeploy.service` | → `/taler-monitoring-aptdeploy*` (taler only) |
|
||||
|
||||
|
|
|
|||
|
|
@ -62,29 +62,35 @@ install_local() {
|
|||
install -m 644 "$ROOT/taler-monitoring-surface.timer" "$home_unit/"
|
||||
install -m 644 "$ROOT/taler-monitoring-aptdeploy.service" "$home_unit/"
|
||||
install -m 644 "$ROOT/taler-monitoring-aptdeploy.timer" "$home_unit/"
|
||||
install -m 644 "$ROOT/taler-monitoring-mattermost.service" "$home_unit/"
|
||||
install -m 644 "$ROOT/taler-monitoring-mattermost.timer" "$home_unit/"
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now taler-monitoring-hacktivism.path
|
||||
systemctl --user enable --now taler-monitoring-hacktivism.timer
|
||||
systemctl --user enable --now taler-monitoring-surface.timer
|
||||
systemctl --user enable --now taler-monitoring-aptdeploy.timer
|
||||
systemctl --user enable --now taler-monitoring-mattermost.timer
|
||||
# initial stamp so path exists
|
||||
"$ROOT/touch-software-stamp.sh"
|
||||
systemctl --user start taler-monitoring-hacktivism.service || true
|
||||
systemctl --user start taler-monitoring-surface.service || true
|
||||
systemctl --user start taler-monitoring-aptdeploy.service || true
|
||||
systemctl --user start taler-monitoring-mattermost.service || true
|
||||
|
||||
echo "--- status ---"
|
||||
systemctl --user status taler-monitoring-hacktivism.path --no-pager -l | head -15
|
||||
systemctl --user status taler-monitoring-hacktivism.timer --no-pager -l | head -12
|
||||
systemctl --user status taler-monitoring-surface.timer --no-pager -l | head -12
|
||||
systemctl --user status taler-monitoring-aptdeploy.timer --no-pager -l | head -12
|
||||
systemctl --user status taler-monitoring-mattermost.timer --no-pager -l | head -12
|
||||
systemctl --user list-timers --all | grep taler-monitoring || true
|
||||
echo "OK host-agent (hacktivism 4h + surface 1h + aptdeploy 4h)"
|
||||
echo "OK host-agent (hacktivism 4h + surface 1h + aptdeploy 4h + mattermost 1h)"
|
||||
echo "suite: $mon"
|
||||
echo "manual: systemctl --user start taler-monitoring-hacktivism.service"
|
||||
echo "manual surface: systemctl --user start taler-monitoring-surface.service"
|
||||
echo "manual aptdeploy: systemctl --user start taler-monitoring-aptdeploy.service"
|
||||
echo "manual mattermost: systemctl --user start taler-monitoring-mattermost.service"
|
||||
echo "after upgrades: $ROOT/touch-software-stamp.sh"
|
||||
}
|
||||
|
||||
|
|
|
|||
35
host-agent/run-mattermost-monitoring.sh
Executable file
35
host-agent/run-mattermost-monitoring.sh
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env bash
|
||||
# run-mattermost-monitoring.sh — Mattermost (mattermost.taler.net) → public HTML
|
||||
# Public only on taler.hacktivism.ch:
|
||||
# https://taler.hacktivism.ch/taler-monitoring-mattermost/
|
||||
# https://taler.hacktivism.ch/taler-monitoring-mattermost_err/
|
||||
#
|
||||
set -uo pipefail
|
||||
AGENT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
|
||||
export AGENT_LABEL="${AGENT_LABEL:-mattermost-host-agent}"
|
||||
export STATE_NAME="${STATE_NAME:-taler-mattermost-monitoring}"
|
||||
export TALER_DOMAIN="${TALER_DOMAIN:-hacktivism.ch}"
|
||||
# remote public service — no SSH / podman
|
||||
export INSIDE_PODMAN=0
|
||||
export LOCAL_STACK=0
|
||||
export SKIP_SSH=1
|
||||
export INSIDE_MODE="${INSIDE_MODE:-none}"
|
||||
export CONTINUE_ON_ERROR="${CONTINUE_ON_ERROR:-1}"
|
||||
export RUN_TIMEOUT="${RUN_TIMEOUT:-300}"
|
||||
# dedicated job: mattermost + public page check
|
||||
export PHASES="${PHASES:-mattermost monpages}"
|
||||
export MON_HOSTS="${MON_HOSTS:-taler.hacktivism.ch}"
|
||||
export HTML_OUT="${HTML_OUT:-$HOME/monitoring-sites-staging}"
|
||||
export DEPLOY_WWW_ROOT="${DEPLOY_WWW_ROOT:-/var/www/monitoring-sites}"
|
||||
|
||||
export HTML_OK_DIR="taler-monitoring-mattermost"
|
||||
export HTML_ERR_DIR="taler-monitoring-mattermost_err"
|
||||
export HTML_URL_OK="/taler-monitoring-mattermost/"
|
||||
export HTML_URL_ERR="/taler-monitoring-mattermost_err/"
|
||||
export PAGE_LABEL="taler-monitoring-mattermost"
|
||||
|
||||
export MATTERMOST_PUBLIC="${MATTERMOST_PUBLIC:-https://mattermost.taler.net}"
|
||||
export APT_DEPLOY_ENSURE=0
|
||||
|
||||
exec bash "$AGENT_DIR/run-host-report.sh" "$@"
|
||||
18
host-agent/taler-monitoring-mattermost.service
Normal file
18
host-agent/taler-monitoring-mattermost.service
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[Unit]
|
||||
Description=Taler monitoring Mattermost (mattermost.taler.net outside-in)
|
||||
Documentation=file:%h/src/taler-monitoring/host-agent/README.md
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
|
||||
Environment=CONTINUE_ON_ERROR=1
|
||||
Environment=RUN_TIMEOUT=300
|
||||
WorkingDirectory=%h/src/taler-monitoring
|
||||
ExecStart=%h/src/taler-monitoring/host-agent/run-mattermost-monitoring.sh
|
||||
Nice=10
|
||||
TimeoutStartSec=15min
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
14
host-agent/taler-monitoring-mattermost.timer
Normal file
14
host-agent/taler-monitoring-mattermost.timer
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=Periodic taler-monitoring Mattermost (chat health)
|
||||
Documentation=file:%h/src/taler-monitoring/host-agent/README.md
|
||||
|
||||
[Timer]
|
||||
OnBootSec=25min
|
||||
OnUnitActiveSec=1h
|
||||
AccuracySec=2min
|
||||
Persistent=true
|
||||
RandomizedDelaySec=5min
|
||||
Unit=taler-monitoring-mattermost.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
# /monitoring* → bank + exchange + taler.hacktivism.ch
|
||||
# /taler-monitoring-surface* → taler.hacktivism.ch only
|
||||
# /taler-monitoring-aptdeploy* → taler.hacktivism.ch only
|
||||
# /taler-monitoring-mattermost* → taler.hacktivism.ch only
|
||||
|
||||
# --- only inside taler.hacktivism.ch { ... } ---
|
||||
handle /taler-monitoring-surface_err {
|
||||
|
|
@ -40,6 +41,21 @@
|
|||
file_server
|
||||
}
|
||||
|
||||
handle /taler-monitoring-mattermost_err {
|
||||
redir /taler-monitoring-mattermost_err/ 302
|
||||
}
|
||||
handle /taler-monitoring-mattermost_err/ {
|
||||
root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mattermost_err
|
||||
file_server
|
||||
}
|
||||
handle /taler-monitoring-mattermost {
|
||||
redir /taler-monitoring-mattermost/ 302
|
||||
}
|
||||
handle /taler-monitoring-mattermost/ {
|
||||
root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mattermost
|
||||
file_server
|
||||
}
|
||||
|
||||
# --- bank + exchange + taler (each site block) ---
|
||||
handle /monitoring_err {
|
||||
redir /monitoring_err/ 302
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ git.taler.net 443,22 https taler-git
|
|||
bugs.taler.net 443 https taler-bugs
|
||||
lists.taler.net 443 https taler-lists
|
||||
tutorials.taler.net 443 https taler-tutorials
|
||||
mattermost.taler.net 443 https mattermost
|
||||
bank.demo.taler.net 443 https demo-bank
|
||||
exchange.demo.taler.net 443 https demo-exchange
|
||||
backend.demo.taler.net 443 https demo-merchant
|
||||
|
|
@ -35,7 +36,6 @@ stage.my.taler-ops.ch 443 https tops-stage-merchant
|
|||
exchange.stage.taler-ops.ch 443 https tops-stage-exchange
|
||||
nexus.stage.taler-ops.ch 443 https tops-stage-nexus
|
||||
shops.taler-ops.ch 443 https tops-shops
|
||||
mattermost.taler.net 443 https mattermost
|
||||
|
||||
# --- gnunet.org ---
|
||||
www.gnunet.org 443,80 https gnunet-www
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ Phases:
|
|||
surface REMOTE-ONLY public inventory (NOT in default/all/full):
|
||||
ecosystem hosts (taler.net, gnunet.org, taler-systems.com, mattermost, …)
|
||||
or -d DOMAIN → that domain’s surface; port/protocol/TLS/CVE (OSV)
|
||||
mattermost Mattermost chat health (default mattermost.taler.net; SPA + /api/v4/system/ping)
|
||||
monpages public monitoring HTML via FQDN (HTTP 200 + suite page, not code 21)
|
||||
uses MON_HOSTS + HTML_URL_OK (same as host-agent); v1.3.1+
|
||||
all urls + inside + versions + sanity + e2e (SSH phases only on koopa)
|
||||
|
|
@ -111,6 +112,7 @@ Remote surface / ecosystem (explicit only — never default):
|
|||
./taler-monitoring.sh surface
|
||||
./taler-monitoring.sh -d hacktivism.ch surface
|
||||
./taler-monitoring.sh -d lefrancpaysan.ch surface
|
||||
./taler-monitoring.sh mattermost # mattermost.taler.net chat health
|
||||
|
||||
SPA pin after selfbuild:
|
||||
EXPECT_WEBUI_VERSION=1.6.11 EXPECT_WEBUI_OVERLAY=selfbuild-v1.6.11 \\
|
||||
|
|
@ -179,7 +181,7 @@ while [ $# -gt 0 ]; do
|
|||
CURRENCY_OVERRIDE="$2"; shift 2
|
||||
;;
|
||||
--no-probe) NO_PROBE=1; shift ;;
|
||||
urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|monpages|pages|all|full) PHASES+=("$1"); shift ;;
|
||||
urls|inside|versions|sanity|server|e2e|ladder|goa-ladder|auth401|aptdeploy|apt-deploy|apt_src|surface|ecosystem|mattermost|monpages|pages|all|full) PHASES+=("$1"); shift ;;
|
||||
*)
|
||||
# bare domain shorthand: ./taler-monitoring.sh taler.net
|
||||
if [[ "$1" == *.* && "$1" != *://* && "$1" != -* ]]; then
|
||||
|
|
@ -344,6 +346,7 @@ if [ "${PROGRESS_TOTAL:-0}" = "0" ] || [ -z "${PROGRESS_TOTAL:-}" ]; then
|
|||
aptdeploy) _pt=$((_pt + 20)) ;;
|
||||
surface|ecosystem) _pt=$((_pt + 80)) ;;
|
||||
monpages|pages) _pt=$((_pt + 30)) ;;
|
||||
mattermost) _pt=$((_pt + 25)) ;;
|
||||
esac
|
||||
done
|
||||
set_progress_total "$_pt"
|
||||
|
|
@ -461,6 +464,7 @@ for p in "${PHASES[@]}"; do
|
|||
auth401) run_phase auth401 "$ROOT/check_auth401.sh" || ec=1 ;;
|
||||
aptdeploy|apt-deploy|apt_src) run_phase aptdeploy "$ROOT/check_apt_deploy.sh" || ec=1 ;;
|
||||
surface|ecosystem) run_phase surface "$ROOT/check_surface.sh" || ec=1 ;;
|
||||
mattermost) run_phase mattermost "$ROOT/check_mattermost.sh" || ec=1 ;;
|
||||
monpages|pages) run_phase monpages "$ROOT/check_monitoring_pages.sh" || ec=1 ;;
|
||||
esac
|
||||
done
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue