release 1.6.0: mail monitoring (firefly + pixel/TSA)

This commit is contained in:
Hernâni Marques 2026-07-18 23:58:53 +02:00
parent 9a6929ae92
commit 8d6aabaab6
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
12 changed files with 415 additions and 8 deletions

View file

@ -10,6 +10,7 @@ Checks for **GNU Taler** stacks (bank, exchange, merchant; optional surface inve
Outside-only example: `./taler-monitoring.sh -d demo.taler.net urls`
Mattermost chat: `./taler-monitoring.sh mattermost` (default `https://mattermost.taler.net`)
Mail (firefly/pixel): `./taler-monitoring.sh mail`
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`

View file

@ -1 +1 @@
1.5.0
1.6.0

View file

@ -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.5.0`). File `VERSION` omits the `v` prefix.
Git tags: `vMAJOR.FEATURE.FIX` (e.g. `v1.6.0`). File `VERSION` omits the `v` prefix.
| Tag | Date (UTC) | Notes |
|-----|------------|--------|
| **v1.6.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). |
| **v1.7.0** | *planned* | **L10n** packs for user-facing strings that need localization: **fr-CH** (FrancPaysan) and **de-CH** (hacktivism / Taler CH German). |
| **v1.6.0** | 2026-07-18 | **Mail monitoring:** phase `mail` (`check_mail.sh` + `mail-catalog.conf`) for **firefly** (taler.net, gnunet.org) and **pixel**/TSA (taler-systems.com, mail.anastasis.lu); MX/SMTP/IMAP/SPF/DMARC; host-agent `/taler-monitoring-mail*`. |
| **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. |
@ -33,7 +34,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.5.0`) next to the host line.
Generated HTML shows the installed release tag (e.g. `v1.6.0`) next to the host line.
Clicking opens the tag page on Forgejo:
`https://git.hacktivism.ch/hernani/taler-monitoring/src/tag/<tag>`
@ -65,11 +66,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.6.0**.
Full locale packs (fr-CH / de-CH) are scheduled for **v1.7.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.5.0
cd ~/src/taler-monitoring && git checkout v1.6.0
```

291
check_mail.sh Executable file
View file

@ -0,0 +1,291 @@
#!/usr/bin/env bash
# check_mail.sh — outside-in mail (MX / SMTP / IMAP / SPF / DMARC)
#
# Catalog: mail-catalog.conf (MAIL_CATALOG=… to override)
# Covers firefly (taler.net, gnunet.org) and pixel (taler-systems.com, …).
#
# Outside-only. Phase: mail
#
set -euo pipefail
ROOT=$(cd "$(dirname "$0")" && pwd)
# shellcheck source=lib.sh
source "$ROOT/lib.sh"
set_area mail
section "mail · MX / SMTP / IMAP / SPF / DMARC (outside-in)"
CATALOG="${MAIL_CATALOG:-$ROOT/mail-catalog.conf}"
PORT_TIMEOUT="${MAIL_PORT_TIMEOUT:-4}"
SMTP_TIMEOUT="${MAIL_SMTP_TIMEOUT:-10}"
if [ ! -f "$CATALOG" ]; then
fail "catalog" "missing $CATALOG"
exit 1
fi
# dig or host fallback
dns_mx() {
local d="$1"
if command -v dig >/dev/null 2>&1; then
dig +short +time=3 +tries=2 MX "$d" 2>/dev/null | awk '{print tolower($2)}' | sed 's/\.$//'
else
host -t MX "$d" 2>/dev/null | awk -F'in mail is |has address ' '/mail is/{print tolower($NF)}' | sed 's/\.$//'
fi
}
dns_a() {
local h="$1"
if command -v dig >/dev/null 2>&1; then
dig +short +time=3 +tries=2 A "$h" 2>/dev/null | grep -E '^[0-9.]+$' || true
dig +short +time=3 +tries=2 AAAA "$h" 2>/dev/null | grep -E ':' || true
else
getent ahosts "$h" 2>/dev/null | awk '{print $1}' | sort -u
fi
}
dns_txt() {
local name="$1"
if command -v dig >/dev/null 2>&1; then
dig +short +time=3 +tries=2 TXT "$name" 2>/dev/null | tr -d '"'
else
host -t TXT "$name" 2>/dev/null | sed 's/.*"\(.*\)"/\1/'
fi
}
tcp_open() {
local h="$1" p="$2"
if command -v timeout >/dev/null 2>&1; then
timeout "$PORT_TIMEOUT" bash -c "echo >/dev/tcp/${h}/${p}" 2>/dev/null
else
bash -c "echo >/dev/tcp/${h}/${p}" 2>/dev/null
fi
}
# SMTP: read banner first, then EHLO (avoids "protocol synchronization")
smtp_probe() {
local host="$1" port="$2"
MAIL_HOST="$host" MAIL_PORT="$port" MAIL_TO="${SMTP_TIMEOUT}" python3 - <<'PY' 2>/dev/null
import os, socket, sys
host = os.environ["MAIL_HOST"]
port = int(os.environ["MAIL_PORT"])
to = float(os.environ.get("MAIL_TO", "10"))
try:
s = socket.create_connection((host, port), to)
s.settimeout(to)
banner = s.recv(1024).decode("utf-8", "replace").strip().split("\n")[0]
if not banner.startswith("220"):
print(f"bad_banner={banner[:80]}")
sys.exit(1)
s.sendall(b"EHLO taler-monitoring.invalid\r\n")
data = b""
while True:
chunk = s.recv(4096)
if not chunk:
break
data += chunk
if b"\n" in chunk and (data.endswith(b"\r\n") or len(data) > 8000):
# multi-line 250-… ends with 250 space
lines = data.decode("utf-8", "replace").splitlines()
if any(l.startswith("250 ") for l in lines):
break
if any(l.startswith("5") for l in lines[:3]):
break
text = data.decode("utf-8", "replace")
s.sendall(b"QUIT\r\n")
try:
s.recv(256)
except Exception:
pass
s.close()
starttls = "starttls" if "STARTTLS" in text.upper() else "no_starttls"
print(f"banner={banner[:60]} · {starttls}")
sys.exit(0)
except Exception as e:
print(f"err={e}")
sys.exit(1)
PY
}
# IMAP unencrypted greeting on 143, or just TCP on 993 (TLS)
imap_probe() {
local host="$1" port="$2"
if [ "$port" = "993" ] || [ "$port" = "995" ]; then
if tcp_open "$host" "$port"; then
echo "tcp_open tls_port=$port"
return 0
fi
return 1
fi
MAIL_HOST="$host" MAIL_PORT="$port" MAIL_TO="${SMTP_TIMEOUT}" python3 - <<'PY' 2>/dev/null
import os, socket, sys
host = os.environ["MAIL_HOST"]
port = int(os.environ["MAIL_PORT"])
to = float(os.environ.get("MAIL_TO", "10"))
try:
s = socket.create_connection((host, port), to)
s.settimeout(to)
banner = s.recv(1024).decode("utf-8", "replace").strip().split("\n")[0]
s.sendall(b"a001 LOGOUT\r\n")
try:
s.recv(256)
except Exception:
pass
s.close()
if banner.upper().startswith("* OK") or "IMAP" in banner.upper():
print(f"banner={banner[:70]}")
sys.exit(0)
print(f"unexpected={banner[:70]}")
sys.exit(1)
except Exception as e:
print(f"err={e}")
sys.exit(1)
PY
}
info "catalog" "$CATALOG"
# Track probed hosts to avoid duplicate SMTP checks
declare -A HOST_DONE=()
while IFS= read -r line || [ -n "$line" ]; do
line=${line%%#*}
line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
[ -z "$line" ] && continue
# shellcheck disable=SC2086
set -- $line
domain=$1
expect_mx=${2:-}
mail_hosts=${3:-}
smtp_ports=${4:-25,465,587}
imap_ports=${5:-143,993}
label=${6:-$domain}
set_group "$label"
info "domain" "$domain · expected_mx=$expect_mx · hosts=$mail_hosts"
# --- MX ---
mapfile -t mx_hosts < <(dns_mx "$domain" | sed '/^$/d')
if [ "${#mx_hosts[@]}" -eq 0 ]; then
fail "mx" "$domain has no MX records"
else
ok "mx" "$domain MX → ${mx_hosts[*]}"
# expected MX match (suffix / exact)
if [ -n "$expect_mx" ]; then
matched=0
IFS=',' read -ra want_list <<<"$expect_mx"
for w in "${want_list[@]}"; do
w=$(echo "$w" | tr '[:upper:]' '[:lower:]' | sed 's/\.$//')
for m in "${mx_hosts[@]}"; do
m=$(echo "$m" | tr '[:upper:]' '[:lower:]')
case "$m" in
"$w"|"$w".*|*."$w") matched=1; break ;;
esac
[ "$m" = "$w" ] && matched=1
done
[ "$matched" = "1" ] && break
done
if [ "$matched" = "1" ]; then
ok "mx expected" "$domain MX matches catalog ($expect_mx)"
else
fail "mx expected" "$domain MX ${mx_hosts[*]} · want one of: $expect_mx"
fi
fi
fi
# --- SPF / DMARC ---
spf=$(dns_txt "$domain" | tr '\n' ' ')
if echo "$spf" | grep -qi 'v=spf1'; then
ok "spf" "$domain has SPF"
else
warn "spf" "$domain no SPF TXT (v=spf1)"
fi
dmarc=$(dns_txt "_dmarc.$domain" | tr '\n' ' ')
if echo "$dmarc" | grep -qi 'v=dmarc1'; then
ok "dmarc" "$domain has DMARC"
else
warn "dmarc" "$domain no DMARC at _dmarc.$domain"
fi
# --- mail hosts: DNS + ports + banners ---
IFS=',' read -ra hosts <<<"$mail_hosts"
for h in "${hosts[@]}"; do
h=$(echo "$h" | tr '[:upper:]' '[:lower:]' | sed 's/\.$//;s/^[[:space:]]*//;s/[[:space:]]*$//')
[ -z "$h" ] && continue
addrs=$(dns_a "$h" | tr '\n' ' ')
if [ -z "${addrs// }" ]; then
fail "dns" "$h does not resolve (A/AAAA)"
continue
fi
ok "dns" "$h$addrs"
# skip full protocol re-probe if already done
if [ "${HOST_DONE[$h]:-}" = "1" ]; then
info "host" "$h already probed this run"
continue
fi
HOST_DONE[$h]=1
IFS=',' read -ra sports <<<"$smtp_ports"
for p in "${sports[@]}"; do
p=${p// /}
[ -z "$p" ] && continue
if ! tcp_open "$h" "$p"; then
# 587 optional on pixel
case "$p" in
587) warn "smtp port" "$h:$p closed/filtered (submission)" ;;
*) fail "smtp port" "$h:$p closed/filtered" ;;
esac
continue
fi
case "$p" in
465)
ok "smtp port" "$h:$p open (SMTPS)"
;;
25|587)
if detail=$(smtp_probe "$h" "$p"); then
ok "smtp" "$h:$p $detail"
else
# port open but banner failed — still ERROR for 25
if [ "$p" = "25" ]; then
fail "smtp" "$h:$p open but SMTP handshake failed · $detail"
else
warn "smtp" "$h:$p open but handshake failed · $detail"
fi
fi
;;
*)
ok "smtp port" "$h:$p open"
;;
esac
done
IFS=',' read -ra iports <<<"$imap_ports"
for p in "${iports[@]}"; do
p=${p// /}
[ -z "$p" ] && continue
if ! tcp_open "$h" "$p"; then
fail "imap port" "$h:$p closed/filtered"
continue
fi
case "$p" in
993|995)
ok "imap port" "$h:$p open (TLS)"
;;
143|110)
if detail=$(imap_probe "$h" "$p"); then
ok "imap" "$h:$p $detail"
else
warn "imap" "$h:$p open but greeting failed · $detail"
fi
;;
*)
ok "imap port" "$h:$p open"
;;
esac
done
done
done <"$CATALOG"
info "hint" "firefly = taler.net/gnunet.org MX; pixel = taler-systems.com (mail.anastasis.lu / mail.taler-systems.com)"
exit 0

View file

@ -127,6 +127,8 @@ Units:
| `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-mail.timer` | every **4h** |
| `taler-monitoring-mail.service` | → `/taler-monitoring-mail*` (firefly + pixel MX/SMTP/IMAP) |
| `taler-monitoring-aptdeploy.timer` | every **4h** |
| `taler-monitoring-aptdeploy.service` | → `/taler-monitoring-aptdeploy*` (taler only) |

View file

@ -64,6 +64,8 @@ install_local() {
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/"
install -m 644 "$ROOT/taler-monitoring-mail.service" "$home_unit/"
install -m 644 "$ROOT/taler-monitoring-mail.timer" "$home_unit/"
systemctl --user daemon-reload
systemctl --user enable --now taler-monitoring-hacktivism.path
@ -71,12 +73,14 @@ install_local() {
systemctl --user enable --now taler-monitoring-surface.timer
systemctl --user enable --now taler-monitoring-aptdeploy.timer
systemctl --user enable --now taler-monitoring-mattermost.timer
systemctl --user enable --now taler-monitoring-mail.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
systemctl --user start taler-monitoring-mail.service || true
echo "--- status ---"
systemctl --user status taler-monitoring-hacktivism.path --no-pager -l | head -15
@ -84,13 +88,15 @@ install_local() {
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 status taler-monitoring-mail.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 + mattermost 1h)"
echo "OK host-agent (hacktivism 4h + surface 1h + aptdeploy 4h + mattermost 1h + mail 4h)"
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 "manual mail: systemctl --user start taler-monitoring-mail.service"
echo "after upgrades: $ROOT/touch-software-stamp.sh"
}

View file

@ -0,0 +1,32 @@
#!/usr/bin/env bash
# run-mail-monitoring.sh — mail MX/SMTP/IMAP (firefly + pixel, …) → public HTML
# Public only on taler.hacktivism.ch:
# https://taler.hacktivism.ch/taler-monitoring-mail/
# https://taler.hacktivism.ch/taler-monitoring-mail_err/
#
set -uo pipefail
AGENT_DIR=$(cd "$(dirname "$0")" && pwd)
export AGENT_LABEL="${AGENT_LABEL:-mail-host-agent}"
export STATE_NAME="${STATE_NAME:-taler-mail-monitoring}"
export TALER_DOMAIN="${TALER_DOMAIN:-hacktivism.ch}"
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:-600}"
export PHASES="${PHASES:-mail 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-mail"
export HTML_ERR_DIR="taler-monitoring-mail_err"
export HTML_URL_OK="/taler-monitoring-mail/"
export HTML_URL_ERR="/taler-monitoring-mail_err/"
export PAGE_LABEL="taler-monitoring-mail"
export APT_DEPLOY_ENSURE=0
exec bash "$AGENT_DIR/run-host-report.sh" "$@"

View file

@ -0,0 +1,18 @@
[Unit]
Description=Taler monitoring mail (firefly/pixel MX SMTP IMAP)
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=600
WorkingDirectory=%h/src/taler-monitoring
ExecStart=%h/src/taler-monitoring/host-agent/run-mail-monitoring.sh
Nice=10
TimeoutStartSec=20min
[Install]
WantedBy=default.target

View file

@ -0,0 +1,14 @@
[Unit]
Description=Periodic taler-monitoring mail (MX/SMTP/IMAP)
Documentation=file:%h/src/taler-monitoring/host-agent/README.md
[Timer]
OnBootSec=30min
OnUnitActiveSec=4h
AccuracySec=5min
Persistent=true
RandomizedDelaySec=10min
Unit=taler-monitoring-mail.service
[Install]
WantedBy=timers.target

22
mail-catalog.conf Normal file
View file

@ -0,0 +1,22 @@
# mail-catalog.conf — domains and mail hosts for phase `mail`
#
# Format (whitespace-separated; # comments):
# domain expected_mx (comma) mail_hosts (comma) smtp_ports imap_ports label
#
# - expected_mx: MX exchange hostnames that should appear (any match = OK if multiple)
# - mail_hosts: servers to probe for SMTP/IMAP (A/AAAA + ports + optional banner)
# - ports: comma-separated; empty = skip that protocol family
#
# Override path: MAIL_CATALOG=/path/to/file
#
# GNU Taler / GNUnet mail (firefly) + TSA (pixel / mail.anastasis.lu)
# --- firefly (primary for taler.net + gnunet.org) ---
taler.net firefly.gnunet.org firefly.gnunet.org 25,465,587 143,993 taler-net
gnunet.org firefly.gnunet.org firefly.gnunet.org 25,465,587 143,993 gnunet
# --- taler-systems.com / pixel (MX mail.anastasis.lu → pixel) ---
taler-systems.com mail.anastasis.lu,pixel.taler-systems.com pixel.taler-systems.com,mail.taler-systems.com,mail.anastasis.lu 25,465 143,993 tsa-pixel
# Optional related (same pixel path; keep expected MX loose)
# anastasis.lu mail.anastasis.lu mail.anastasis.lu,pixel.taler-systems.com 25,465 143,993 anastasis

View file

@ -10,6 +10,7 @@
# /taler-monitoring-surface* → taler.hacktivism.ch only
# /taler-monitoring-aptdeploy* → taler.hacktivism.ch only
# /taler-monitoring-mattermost* → taler.hacktivism.ch only
# /taler-monitoring-mail* → taler.hacktivism.ch only
# --- only inside taler.hacktivism.ch { ... } ---
handle /taler-monitoring-surface_err {
@ -56,6 +57,21 @@
file_server
}
handle /taler-monitoring-mail_err {
redir /taler-monitoring-mail_err/ 302
}
handle /taler-monitoring-mail_err/ {
root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mail_err
file_server
}
handle /taler-monitoring-mail {
redir /taler-monitoring-mail/ 302
}
handle /taler-monitoring-mail/ {
root * /var/www/monitoring-sites/taler.hacktivism.ch/taler-monitoring-mail
file_server
}
# --- bank + exchange + taler (each site block) ---
handle /monitoring_err {
redir /monitoring_err/ 302

View file

@ -41,6 +41,7 @@ Phases:
ecosystem hosts (taler.net, gnunet.org, taler-systems.com, mattermost, …)
or -d DOMAIN → that domains surface; port/protocol/TLS/CVE (OSV)
mattermost Mattermost chat health (default mattermost.taler.net; SPA + /api/v4/system/ping)
mail MX/SMTP/IMAP for Taler mail (firefly, pixel/TSA, catalogued domains)
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)
@ -113,6 +114,7 @@ Remote surface / ecosystem (explicit only — never default):
./taler-monitoring.sh -d hacktivism.ch surface
./taler-monitoring.sh -d lefrancpaysan.ch surface
./taler-monitoring.sh mattermost # mattermost.taler.net chat health
./taler-monitoring.sh mail # firefly + pixel MX/SMTP/IMAP
SPA pin after selfbuild:
EXPECT_WEBUI_VERSION=1.6.11 EXPECT_WEBUI_OVERLAY=selfbuild-v1.6.11 \\
@ -181,7 +183,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|mattermost|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|mail|monpages|pages|all|full) PHASES+=("$1"); shift ;;
*)
# bare domain shorthand: ./taler-monitoring.sh taler.net
if [[ "$1" == *.* && "$1" != *://* && "$1" != -* ]]; then
@ -347,6 +349,7 @@ if [ "${PROGRESS_TOTAL:-0}" = "0" ] || [ -z "${PROGRESS_TOTAL:-}" ]; then
surface|ecosystem) _pt=$((_pt + 80)) ;;
monpages|pages) _pt=$((_pt + 30)) ;;
mattermost) _pt=$((_pt + 25)) ;;
mail) _pt=$((_pt + 40)) ;;
esac
done
set_progress_total "$_pt"
@ -465,6 +468,7 @@ for p in "${PHASES[@]}"; do
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 ;;
mail) run_phase mail "$ROOT/check_mail.sh" || ec=1 ;;
monpages|pages) run_phase monpages "$ROOT/check_monitoring_pages.sh" || ec=1 ;;
esac
done