150 lines
6.2 KiB
Bash
150 lines
6.2 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
source ./lib.sh
|
||
|
||
log "MOTD installieren …"
|
||
install -d /usr/local/bin
|
||
|
||
cat >/usr/local/bin/mw-motd <<'SH'
|
||
#!/usr/bin/env bash
|
||
# MOTD – MailWolt
|
||
# bewusst KEIN "set -e" und KEIN pipefail; MOTD darf nie hart abbrechen
|
||
set -u
|
||
|
||
# ---------- Farben ----------
|
||
NC="\033[0m"; WH="\033[1;37m"; CY="\033[1;36m"; GY="\033[0;90m"
|
||
GR="\033[1;32m"; YE="\033[1;33m"; RD="\033[1;31m"
|
||
|
||
# ---------- Breite / Zentrierung ----------
|
||
W=110
|
||
term_cols=$(tput cols 2>/dev/null || echo $W)
|
||
[ "$term_cols" -gt "$W" ] && pad=$(( (term_cols - W)/2 )) || pad=0
|
||
sp(){ [ "$1" -gt 0 ] && printf "%${1}s" " " || true; }
|
||
center() { local s="$1"; local n=$(( (W - ${#s})/2 )); sp $((pad+n)); printf "%s\n" "$s"; }
|
||
rule(){ sp "$pad"; printf "%0.s=" $(seq 1 "$W"); printf "\n"; }
|
||
title(){ sp "$pad"; local t="$1"; local lf=$(( (W - ${#t} - 2)/2 )); local rf=$(( W - ${#t} - 2 - lf )); \
|
||
printf "%s" "$(printf '─%.0s' $(seq 1 $lf))"; printf " %s " "$t"; printf "%s\n" "$(printf '─%.0s' $(seq 1 $rf))"; }
|
||
kv(){ sp "$pad"; printf "%-12s: %s\n" "$1" "$2"; }
|
||
|
||
# ---------- Installer-/App-Variablen ----------
|
||
UI_HOST=""; WEBMAIL_HOST=""; MAIL_HOSTNAME=""
|
||
[ -r /etc/mailwolt/installer.env ] && . /etc/mailwolt/installer.env || true
|
||
|
||
# ---------- Systemdaten ----------
|
||
now="$(date '+%Y-%m-%d %H:%M:%S %Z' 2>/dev/null || echo '-')"
|
||
upt="$(uptime -p 2>/dev/null || echo '-')"
|
||
cores="$(nproc 2>/dev/null || echo 1)"
|
||
load_raw="$(awk '{printf "%s / %s / %s",$1,$2,$3}' /proc/loadavg 2>/dev/null || echo '0.00 / 0.00 / 0.00')"
|
||
load1="$(awk '{print $1}' /proc/loadavg 2>/dev/null || echo 0)"
|
||
|
||
# RAM/SWAP
|
||
mem_total="$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 0)"
|
||
mem_avail="$(awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 0)"
|
||
mem_used=$(( mem_total - mem_avail ))
|
||
swap_total="$(awk '/SwapTotal/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 0)"
|
||
swap_free="$(awk '/SwapFree/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 0)"
|
||
swap_used=$(( swap_total - swap_free ))
|
||
|
||
pct(){ local u="$1" t="$2"; [ "$t" -gt 0 ] || { echo 0; return; }; awk -v u="$u" -v t="$t" 'BEGIN{printf "%d",(u*100)/t}' ; }
|
||
ram_pct=$(pct "$mem_used" "$mem_total")
|
||
swap_pct=$(pct "$swap_used" "$swap_total")
|
||
|
||
# Disks
|
||
df_line(){ df -hP "$1" 2>/dev/null | awk 'NR==2{printf "%s / %s (%s)",$3,$2,$5}'; }
|
||
df_pct(){ df -P "$1" 2>/dev/null | awk 'NR==2{gsub("%","",$5);print $5+0}'; }
|
||
disk_root="$(df_line /)"; pct_root="$(df_pct /)"
|
||
disk_var="$(df_line /var 2>/dev/null)"; [ -n "$disk_var" ] || disk_var="-"
|
||
pct_var="$(df_pct /var 2>/dev/null)"; [ -n "$pct_var" ] || pct_var=0
|
||
|
||
# IPs (int/ext)
|
||
ipv4_int="$(hostname -I 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i!~/:/){print $i;exit}}')"
|
||
ipv6_int="$(hostname -I 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i~/:/){print $i;exit}}')"
|
||
ipv4_ext="$(curl -4fsS --max-time 1 https://ifconfig.me 2>/dev/null || true)"
|
||
ipv6_ext="$(curl -6fsS --max-time 1 https://ifconfig.me 2>/dev/null || true)"
|
||
|
||
# ---------- Status-Farben ----------
|
||
mark(){ # value thresholdY thresholdR
|
||
local v="$1" y="$2" r="$3"
|
||
if [ "$v" -ge "$r" ]; then printf "${RD}[HIGH]${NC}"
|
||
elif [ "$v" -ge "$y" ]; then printf "${YE}[WARN]${NC}"
|
||
else printf "${GR}[OK]${NC}"
|
||
fi
|
||
}
|
||
# Load/CPU-Schwellen (pro Core)
|
||
load_pct=$(awk -v l="$load1" -v c="$cores" 'BEGIN{if(c<1)c=1; printf "%d", (l/c)*100}')
|
||
m_load="$(mark "$load_pct" 70 100)"
|
||
m_ram="$(mark "$ram_pct" 75 90)"
|
||
m_swap="$(mark "$swap_pct" 10 50)"
|
||
m_root="$(mark "$pct_root" 75 90)"
|
||
m_var="$(mark "$pct_var" 75 90)"
|
||
|
||
# ---------- Header ----------
|
||
rule
|
||
center ""
|
||
center ":::: :::: ::: ::::::::::: ::: ::: ::: :::::::: ::: :::::::::::"
|
||
center ":+:+:+ :+:+:+ :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: "
|
||
center ":+: +:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ "
|
||
center "+#+ +:+ +#+ +#++:++#++: +#+ +#+ +#+ +:+ +#+ +#+ +:+ +#+ +#+ "
|
||
center "+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+#+ +#+ +#+ +#+ +#+ +#+ "
|
||
center "#+# #+# #+# #+# #+# #+# #+#+# #+#+# #+# #+# #+# #+# "
|
||
center "### ### ### ### ########### ########## ### ### ######## ########## ### "
|
||
center ""
|
||
rule
|
||
|
||
# ---------- System ----------
|
||
kv "Date / Time" "${YE}${now}${NC}"
|
||
sp "$pad"; printf "%-12s: int %-40s ext %s\n" "IPv4" "${ipv4_int:--}" "${ipv4_ext:--}"
|
||
sp "$pad"; printf "%-12s: int %-40s ext %s\n" "IPv6" "${ipv6_int:--}" "${ipv6_ext:--}"
|
||
kv "Uptime" "$upt"
|
||
sp "$pad"; printf "%-12s: %s cores, load %s %b\n" "CPU" "$cores" "$load_raw" "$m_load"
|
||
sp "$pad"; printf "%-12s: %s MiB / %s MiB (%d%%) %b %-5s %s MiB / %s MiB (%d%%) %b\n" \
|
||
"RAM" "$mem_used" "$mem_total" "$ram_pct" "$m_ram" "SWAP:" "$swap_used" "$swap_total" "$swap_pct" "$m_swap"
|
||
sp "$pad"; printf "%-12s: / %s %b %-5s %s %b\n" \
|
||
"Disk" "$disk_root" "$m_root" "/var:" "$disk_var" "$m_var"
|
||
echo
|
||
|
||
# ---------- Domains ----------
|
||
title "Domains"
|
||
[ -n "${UI_HOST:-}" ] && kv "UI" "${UI_HOST}"
|
||
[ -n "${WEBMAIL_HOST:-}" ] && kv "Webmail" "${WEBMAIL_HOST}"
|
||
[ -n "${MAIL_HOSTNAME:-}" ]&& kv "MX" "${MAIL_HOSTNAME}"
|
||
echo
|
||
|
||
# ---------- Services (4 Spalten, bündig) ----------
|
||
title "Services"
|
||
svc_state(){ systemctl is-active --quiet "$1" && printf "${GR}[OK]${NC}" || printf "${RD}[FAIL]${NC}"; }
|
||
SVC=( nginx mariadb redis-server postfix dovecot rspamd opendkim opendmarc clamav-daemon fail2ban mailwolt-ws mailwolt-queue mailwolt-schedule )
|
||
|
||
i=0; line=""
|
||
for s in "${SVC[@]}"; do
|
||
st="$(svc_state "$s")"
|
||
seg="$(printf "%-18s %-7s" "$s" "$st")"
|
||
line="$line$seg"
|
||
i=$((i+1))
|
||
if [ $((i%4)) -eq 0 ]; then sp "$pad"; echo "$line"; line=""; else line="$line "; fi
|
||
done
|
||
[ -n "$line" ] && { sp "$pad"; echo "$line"; }
|
||
echo
|
||
|
||
exit 0
|
||
SH
|
||
|
||
chmod 755 /usr/local/bin/mw-motd
|
||
|
||
# update-motd Hook
|
||
if [[ -d /etc/update-motd.d ]]; then
|
||
cat >/etc/update-motd.d/10-mailwolt <<'SH'
|
||
#!/usr/bin/env bash
|
||
/usr/local/bin/mw-motd
|
||
SH
|
||
chmod +x /etc/update-motd.d/10-mailwolt
|
||
[[ -f /etc/update-motd.d/50-motd-news ]] && chmod -x /etc/update-motd.d/50-motd-news || true
|
||
else
|
||
# Fallback für Systeme ohne dynamic MOTD
|
||
cat >/etc/profile.d/10-mailwolt-motd.sh <<'SH'
|
||
case "$-" in *i*) /usr/local/bin/mw-motd ;; esac
|
||
SH
|
||
fi
|
||
|
||
: > /etc/motd 2>/dev/null || true
|
||
log "[✓] MOTD installiert." |