From f8f30d57f720f0db675472609236c3c2f929ba47 Mon Sep 17 00:00:00 2001 From: boban Date: Fri, 24 Apr 2026 13:31:30 +0200 Subject: [PATCH] Feature: Installer-Spinner + verbesserter Smoke-Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Spinner (⠋⠙⠹…) läuft während quietly() auf Abschluss wartet - stop_spin() in ok/warn/err integriert, EXIT-Trap sichert Cleanup - Smoke-Test: kein eval, separate Funktionen pro Protokoll (smtp/tls/imap/pop3) - Service-Namen neben Port, Zusammenfassung X/7 Dienste erreichbar Co-Authored-By: Claude Sonnet 4.6 --- installer.sh | 104 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 24 deletions(-) diff --git a/installer.sh b/installer.sh index fa7b19e..a1aed81 100644 --- a/installer.sh +++ b/installer.sh @@ -86,29 +86,54 @@ footer_ok() { } _STEP_T=0 +_SPIN_PID= + +_spin_bg() { + local chars='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' + local n=${#chars} i=0 + while true; do + printf "\r \033[0;90m${chars:$i:1}\033[0m" + i=$(( (i + 1) % n )) + sleep 0.1 + done +} +start_spin() { _spin_bg & _SPIN_PID=$!; } +stop_spin() { + [[ -n "${_SPIN_PID:-}" ]] || return 0 + kill "$_SPIN_PID" 2>/dev/null || true + wait "$_SPIN_PID" 2>/dev/null || true + _SPIN_PID= + printf "\r\033[K" +} +trap 'stop_spin' EXIT INT TERM + step() { local msg="$1" dur="${2:-}" [ -n "$dur" ] && dur=" ${GREY}(~${dur})${NC}" || dur="" printf "\n${CYAN} ▸${NC} %-42s%b\n" "$msg" "$dur" _STEP_T=$SECONDS } -ok() { +ok() { + stop_spin local t=$(( SECONDS - _STEP_T )) [ $t -gt 1 ] && printf " ${GREEN}✔${NC} ${GREY}%ds${NC}\n" $t || printf " ${GREEN}✔${NC}\n" } -warn() { printf " ${YELLOW}⚠${NC} %s\n" "$*"; } -err() { printf " ${RED}✗${NC} %s\n" "$*"; } +warn() { stop_spin; printf " ${YELLOW}⚠${NC} %s\n" "$*"; } +err() { stop_spin; printf " ${RED}✗${NC} %s\n" "$*"; } quietly() { + start_spin if ! "$@" >> "$LOG_FILE" 2>&1; then - printf "\n ${RED}✗${NC} Fehlgeschlagen. Letzte Log-Zeilen:\n\n" + stop_spin + printf " ${RED}✗${NC} Fehlgeschlagen. Letzte Log-Zeilen:\n\n" tail -20 "$LOG_FILE" | sed 's/^/ /' printf "\n ${GREY}Vollständiges Log: %s${NC}\n\n" "$LOG_FILE" exit 1 fi + stop_spin } try_quiet() { "$@" >> "$LOG_FILE" 2>&1 || true; } -log() { :; } # Kompatibilität — stille Ausgabe +log() { :; } require_root() { [ "$(id -u)" -eq 0 ] || { err "Bitte als root ausführen."; exit 1; }; } # ===== IP ermitteln ===== @@ -869,28 +894,59 @@ chmod 600 /etc/monit/monitrc try_quiet systemctl enable --now monit # ===== Smoke-Test ===== -step "Port-Check" "30 Sek" -set +e -_smoke_ok=0; _smoke_fail=0 -smoke_port() { - local port="$1" result - result=$(eval "$2" 2>&1) - if echo "$result" | grep -qiE '(220|OK|\+OK|CAPABILITY)'; then - printf " ${GREEN}✔${NC} Port %-5s erreichbar\n" "$port" - (( _smoke_ok++ )) || true +step "Dienste prüfen (Port-Check)" +_sok=0; _sfail=0 + +smoke_smtp() { + local port="$1" label="$2" + local out + out=$(printf "EHLO localhost\r\nQUIT\r\n" | timeout 5s nc -w3 127.0.0.1 "$port" 2>/dev/null || true) + if echo "$out" | grep -q '^220'; then + printf " ${GREEN}✔${NC} %-5s %s\n" "$port" "$label"; (( _sok++ )) || true else - printf " ${YELLOW}⚠${NC} Port %-5s nicht erreichbar\n" "$port" - (( _smoke_fail++ )) || true + printf " ${YELLOW}⚠${NC} %-5s %s — nicht erreichbar\n" "$port" "$label"; (( _sfail++ )) || true fi } -smoke_port 25 "timeout 5s bash -c 'printf \"EHLO localhost\r\nQUIT\r\n\" | nc -w3 127.0.0.1 25'" -smoke_port 465 "timeout 5s openssl s_client -connect 127.0.0.1:465 -brief -quiet &1 || true) + if echo "$out" | grep -qiE '(CONNECTED|depth|Verify|^220|\+OK|OK)'; then + printf " ${GREEN}✔${NC} %-5s %s\n" "$port" "$label"; (( _sok++ )) || true + else + printf " ${YELLOW}⚠${NC} %-5s %s — nicht erreichbar\n" "$port" "$label"; (( _sfail++ )) || true + fi +} +smoke_imap() { + local port="$1" label="$2" + local out + out=$(printf ". CAPABILITY\r\n. LOGOUT\r\n" | timeout 5s nc -w3 127.0.0.1 "$port" 2>/dev/null || true) + if echo "$out" | grep -qi 'CAPABILITY'; then + printf " ${GREEN}✔${NC} %-5s %s\n" "$port" "$label"; (( _sok++ )) || true + else + printf " ${YELLOW}⚠${NC} %-5s %s — nicht erreichbar\n" "$port" "$label"; (( _sfail++ )) || true + fi +} +smoke_pop3() { + local port="$1" label="$2" + local out + out=$(printf "QUIT\r\n" | timeout 5s nc -w3 127.0.0.1 "$port" 2>/dev/null || true) + if echo "$out" | grep -qi '^\+OK'; then + printf " ${GREEN}✔${NC} %-5s %s\n" "$port" "$label"; (( _sok++ )) || true + else + printf " ${YELLOW}⚠${NC} %-5s %s — nicht erreichbar\n" "$port" "$label"; (( _sfail++ )) || true + fi +} + +smoke_smtp 25 "SMTP" +smoke_tls 465 "SMTPS" "" +smoke_tls 587 "Submission" "-starttls smtp" +smoke_imap 143 "IMAP" +smoke_tls 993 "IMAPS" "" +smoke_pop3 110 "POP3" +smoke_tls 995 "POP3S" "" + +printf "\n ${GREY}%d/%d Dienste erreichbar${NC}\n" "$_sok" "$(( _sok + _sfail ))" echo echo -e " ${GREY}Bootstrap-Login (nur für ERSTEN Login & Wizard):${NC}"