#!/usr/bin/env bash set -euo pipefail source ./lib.sh log "Update-Wrapper & Sudoers …" WRAPPER="/usr/local/sbin/mailwolt-update" LOGFILE="/var/log/mailwolt-update.log" STATEDIR="/var/lib/mailwolt/update" SUDOERS="/etc/sudoers.d/mailwolt-update" VERSION_FILE="/var/lib/mailwolt/version" SUDOERS_SERVICES="/etc/sudoers.d/mailwolt-services" # Kandidaten: wo liegt update.sh? CANDIDATES=( /opt/mailwolt-installer/scripts/update.sh /mailwolt-installer/scripts/update.sh /usr/local/lib/mailwolt/update.sh ) # State/Log vorbereiten install -d -m 0755 "$(dirname "$LOGFILE")" install -d -m 0755 "$STATEDIR" : > "$LOGFILE" || true chmod 0644 "$LOGFILE" # Wrapper erzeugen cat > "$WRAPPER" <<'EOF' #!/usr/bin/env bash set -euo pipefail LOG="/var/log/mailwolt-update.log" STATE_DIR="/var/lib/mailwolt/update" CANDIDATES=( /opt/mailwolt-installer/scripts/update.sh /mailwolt-installer/scripts/update.sh /usr/local/lib/mailwolt/update.sh ) # bestes update.sh finden SCRIPT="" for p in "${CANDIDATES[@]}"; do if [[ -x "$p" ]]; then SCRIPT="$p"; break; fi if [[ -f "$p" && -r "$p" ]]; then SCRIPT="$p"; break; fi done install -d -m 0755 "$(dirname "$LOG")" "$STATE_DIR" /var/lib/mailwolt : > "$LOG" || true chmod 0644 "$LOG" echo "running" > "$STATE_DIR/state" { echo "===== $(date -Is) :: Update gestartet =====" if [[ -z "$SCRIPT" ]]; then echo "[!] update.sh nicht gefunden (versucht: ${CANDIDATES[*]})" rc=127 else echo "[i] benutze: $SCRIPT" if [[ "$(id -u)" -ne 0 ]]; then echo "[!] Bitte als root ausführen" rc=1 else if [[ -x "$SCRIPT" ]]; then ALLOW_DIRTY=1 "$SCRIPT"; else ALLOW_DIRTY=1 bash "$SCRIPT"; fi rc=$? fi fi echo "===== $(date -Is) :: Update beendet (rc=$rc) =====" # ── Version schreiben (aus App-Repo, Fallback Installer) ───────────────────── if command -v git >/dev/null 2>&1; then REPO="/var/www/mailwolt" [[ -d "$REPO/.git" ]] || REPO="/opt/mailwolt-installer" cd "$REPO" >/dev/null 2>&1 || true # Tags sicherstellen; Fehler dürfen den Wrapper nicht abbrechen git rev-parse --is-inside-work-tree >/dev/null 2>&1 && git fetch --tags --quiet origin || true # 1) Bevorzugt beschreibbares Tag (z.B. v1.0.29[-dirty]) raw="$(git describe --tags --dirty --always 2>/dev/null || true)" # 2) Fallback: kurzer Commit-Hash [[ -n "$raw" ]] || raw="$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")" # Normiert: führendes "v" weg + Build-Suffixe/-dirty kappen norm="$(printf '%s' "$raw" | sed -E 's/^v//; s/-.*$//')" printf '%s\n' "$raw" > /var/lib/mailwolt/version_raw printf '%s\n' "$norm" > /var/lib/mailwolt/version chmod 0644 /var/lib/mailwolt/version_raw /var/lib/mailwolt/version echo "[i] Version aktualisiert: raw=$raw norm=$norm (Quelle: $REPO)" else printf '%s\n' "unknown" > /var/lib/mailwolt/version_raw printf '%s\n' "0.0.0" > /var/lib/mailwolt/version chmod 0644 /var/lib/mailwolt/version_raw /var/lib/mailwolt/version fi printf '%s\n' "$rc" > "$STATE_DIR/rc" echo "done" > "$STATE_DIR/state" exit "$rc" } | tee -a "$LOG" EOF chmod 0755 "$WRAPPER" chown root:root "$WRAPPER" # Sudoers: www-data (Laravel) & mailwolt dürfen den Wrapper laufen lassen cat > "$SUDOERS" <<'EOF' Defaults!/usr/local/sbin/mailwolt-update !requiretty www-data ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-update mailwolt ALL=(root) NOPASSWD: /usr/local/sbin/mailwolt-update EOF chown root:root "$SUDOERS" chmod 440 "$SUDOERS" if ! visudo -c -f "$SUDOERS" >/dev/null 2>&1; then echo "[!] Ungültiger sudoers-Eintrag in $SUDOERS – entferne Datei." rm -f "$SUDOERS" fi cat > "$SUDOERS_SERVICES" <<'EOF' Defaults!/usr/bin/systemctl !requiretty Cmnd_Alias MW_SERVICES = \ /usr/bin/systemctl reload nginx.service, \ /usr/bin/systemctl try-reload-or-restart nginx.service, \ /usr/bin/systemctl restart php8.3-fpm.service, \ /usr/bin/systemctl try-reload-or-restart postfix.service, \ /usr/bin/systemctl try-reload-or-restart dovecot.service, \ /usr/bin/systemctl try-reload-or-restart rspamd.service, \ /usr/bin/systemctl try-reload-or-restart opendkim.service, \ /usr/bin/systemctl try-reload-or-restart opendmarc.service, \ /usr/bin/systemctl try-reload-or-restart clamav-daemon.service, \ /usr/bin/systemctl try-reload-or-restart redis-server.service www-data ALL=(root) NOPASSWD: MW_SERVICES EOF chmod 440 "$SUDOERS_SERVICES" chown root:root "$SUDOERS_SERVICES" # Prüfen, ob Syntax gültig ist if ! visudo -c -f "$SUDOERS_SERVICES" >/dev/null 2>&1; then echo "[!] Ungültiger sudoers-Eintrag in $SUDOERS_SERVICES – entferne Datei." rm -f "$SUDOERS_SERVICES" else echo "[✓] Sudoers für Dienststeuerung angelegt: $SUDOERS_SERVICES" fi # Version-File initial anlegen, falls nicht existiert if [[ ! -f "$VERSION_FILE" ]]; then echo "unknown" > "$VERSION_FILE" chmod 0644 "$VERSION_FILE" fi log "[✓] Update-Wrapper bereit: $WRAPPER" log "[✓] Version wird unter $VERSION_FILE gespeichert"