diff --git a/README.md b/README.md index ffe6696..0a55dd1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,4 @@ -# template_repository - - - -Wichtig: Link für Lizenz anpassen. +### Doku folgt. @@ -11,5 +7,5 @@ Wichtig: Link für Lizenz anpassen.

-License License | Matrix Matrix | Matrix Mastodon +License License | Matrix Matrix | Matrix Mastodon

\ No newline at end of file diff --git a/v1/pbs-backup.v1.sh b/v1/pbs-backup.v1.sh new file mode 100644 index 0000000..202ab1e --- /dev/null +++ b/v1/pbs-backup.v1.sh @@ -0,0 +1,66 @@ +#!/bin/bash +# Script Name: pbs-backup.v1.sh +# Beschreibung: Erstellt Backups auf einem PBS +# Aufruf: ./pbs-backup-script.v1_msmtp.sh +# Autor: Patrick Asmus +# Web: https://www.techniverse.net +# Git-Reposit.: ssh://git@git.techniverse.net:10022/internal-infrastructure/pbs-backup-scripts.git +# Version: 1.1 +# Datum: 13.09.2024 +# Modifikation: added email support +##################################################### + +# Variablen +HOSTNAME="$(hostname)" + +export PBS_REPOSITORY="" +export PBS_PASSWORD="" +export PBS_FINGERPRINT="" + +MAIL_RECIPIENTS="" +MAIL_NOTIFY_ON_SUCCESS=true +MAIL_SUBJECT_SUCCESS=" ${HOSTNAME} | Backup erfolgreich abgeschlossen" +MAIL_SUBJECT_FAILURE=" ${HOSTNAME} | Fehler beim Backup" + +LOGFILE=$(mktemp) + +# Verzeichnisse, die gesichert werden sollen +INCLUDE_DIRS=( + "/root" + "/home" + "/var/lib/docker/volumes/" +) + +BACKUP_COMMAND="proxmox-backup-client backup" + +for dir in "${INCLUDE_DIRS[@]}"; do + dir_name=$(basename "$dir") + BACKUP_COMMAND+=" ${dir_name}.pxar:${dir}" +done + +echo "Starte das Backup..." +eval "$BACKUP_COMMAND" &> "$LOGFILE" + +# Überprüfen, ob das Backup erfolgreich war +if [ $? -eq 0 ]; then + echo "Backup erfolgreich abgeschlossen." | tee -a "$LOGFILE" + if [ "$MAIL_NOTIFY_ON_SUCCESS" = true ]; then + { + echo "Das Backup wurde erfolgreich abgeschlossen." + echo "" + echo "Ausgabe des Backups:" + cat "$LOGFILE" + } | mail -s "$MAIL_SUBJECT_SUCCESS" $MAIL_RECIPIENTS + fi +else + echo "Fehler beim Backup." | tee -a "$LOGFILE" + { + echo "Es ist ein Fehler beim Backup aufgetreten." + echo "" + echo "Ausgabe des Backups:" + cat "$LOGFILE" + } | mail -s "$MAIL_SUBJECT_FAILURE" $MAIL_RECIPIENTS +fi + +# Temporäre Datei löschen +rm "$LOGFILE" \ No newline at end of file diff --git a/v2/pbs-backup.v2.conf b/v2/pbs-backup.v2.conf new file mode 100644 index 0000000..cb5c583 --- /dev/null +++ b/v2/pbs-backup.v2.conf @@ -0,0 +1,40 @@ +# --- PBS --- # +# PBS_FINGERPRINT ist OPTIONAL und nur bei selbstsigniertem Zertifikat nötig. +export PBS_REPOSITORY="" +export PBS_FINGERPRINT="" +PBS_API="" + +# --- Quellen (Array!) --- # +INCLUDE_DIRS=( + "/home/" + "/root/" + "/etc" +) + +# --- Logging & Lock --- # +LOGFILE="/var/log/pbs-backup.v2.log" +LOCKFILE="/var/lock/pbs-backup.v2.lock" + +# --- Mail --- # +MAIL_ENABLED=true +MAIL_CMD="mail" +MAIL_RECIPIENTS="" +MAIL_NOTIFY_ON_SUCCESS=true +MAIL_SUBJECT_SUCCESS=" ${HOSTNAME} | Backup erfolgreich abgeschlossen" +MAIL_SUBJECT_FAILURE=" ${HOSTNAME} | Fehler beim Backup" + +# --- Ntfy --- # +NTFY_ENABLED=true +NTFY_TOPIC_URL="https://ntfy.sh/my-backup-topic" +NTFY_AUTH_TOKEN="" +NTFY_NOTIFY_ON_SUCCESS=true +NTFY_TITLE_SUCCESS="Backup erfolgreich: ${HOSTNAME}" +NTFY_TITLE_FAILURE="Backup FEHLGESCHLAGEN: ${HOSTNAME}" +NTFY_PRIORITY_SUCCESS="3" +NTFY_PRIORITY_FAILURE="5" +NTFY_TAIL_LINES="200" + +# --- Monitoring Healthcheck-Datei --- # +# Wenn der Backup-Lauf erfolgreich war, wird diese Datei erstellt/aktualisiert. +# Bei Fehler wird sie gelöscht. +HEALTHCHECK_OK_FILE="/var/run/pbs-backup.ok" diff --git a/v2/pbs-backup.v2.sh b/v2/pbs-backup.v2.sh new file mode 100644 index 0000000..e882199 --- /dev/null +++ b/v2/pbs-backup.v2.sh @@ -0,0 +1,246 @@ +#!/usr/bin/env bash +# Script Name: pbs-backup.v2.sh +# Beschreibung: Host-Backups zu Proxmox Backup Server (PBS) inkl. Notifications +# Aufruf: ./pbs-backup.v2.sh [--dry-run] [--no-mail] [--no-ntfy] [-q] [-h] +# Autor: Patrick Asmus +# Web: https://www.cleveradmin.de +# Git-Reposit.: https://git.techniverse.net/scriptos/pbs-backup-client-script.git +# Version: 2.0 +# Datum: 22.08.2025 +# Modifikation: - Ntfy-Support mit Auth +# - Logging zu Datei & Terminal (mit Timestamps) +# - Locking, Exit-Codes, externe Config, Dry-Run, robuste Fehlerbehandlung +# - Konfiguration ausgelagertin pbs-backup.v2.conf +# - Backup-OK-Datei für externes Monitoring + +set -Eeuo pipefail +umask 077 + +# ---------- Variablen ---------- # +SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" +CONFIG_FILE="${CONFIG_FILE:-$SCRIPT_DIR/pbs-backup.v2.conf}" + +DRY_RUN=false +FORCE_NO_MAIL=false +FORCE_NO_NTFY=false +VERBOSE=true + +SCRIPT_NAME="$(basename "$0")" +HOSTNAME="$(hostname)" + +# ---------- Helpers ---------- # +_timestamp() { date +"%Y-%m-%d %H:%M:%S"; } + +log() { + local level="$1"; shift + local msg="$*" + local line="[$(_timestamp)] [$level] $msg" + echo "$line" | tee -a "$LOGFILE" +} + +die() { + log "ERROR" "$*" + exit 1 +} + +check_dep() { + local bin="$1" hint="${2:-}" + command -v "$bin" >/dev/null 2>&1 || die "Benötigtes Programm '$bin' fehlt. $hint" +} + +bool() { [[ "${1,,}" == "true" || "$1" == "1" || "${1,,}" == "yes" ]]; } + +print_usage() { + cat </dev/null 2>&1; then + die "INCLUDE_DIRS ist nicht gesetzt (Array) in $CONFIG_FILE." +fi +[[ "${#INCLUDE_DIRS[@]}" -gt 0 ]] || die "INCLUDE_DIRS ist leer in $CONFIG_FILE." + +[[ -n "${LOGFILE:-}" ]] || die "LOGFILE ist nicht gesetzt (in $CONFIG_FILE)." +[[ -n "${LOCKFILE:-}" ]] || die "LOCKFILE ist nicht gesetzt (in $CONFIG_FILE)." + +HEALTHCHECK_OK_FILE="${HEALTHCHECK_OK_FILE:-}" + +$FORCE_NO_MAIL && MAIL_ENABLED=false +$FORCE_NO_NTFY && NTFY_ENABLED=false +$VERBOSE || exec >/dev/null 2>&1 + +RUNLOG="$(mktemp)" +_cleanup() { rm -f "$RUNLOG"; } +trap _cleanup EXIT + +# ---------- Lock & Log ---------- # +if ! touch "$LOGFILE" 2>/dev/null; then + LOGFILE="/tmp/pbs-backup.v2.log" + touch "$LOGFILE" || die "Kann Logfile nicht anlegen: $LOGFILE" +fi + +mkdir -p "$(dirname "$LOCKFILE")" +exec 9>"$LOCKFILE" +flock -n 9 || die "Es läuft bereits ein anderer Backup-Prozess (Lock: $LOCKFILE)" + +log "INFO" "Starte $SCRIPT_NAME auf Host $HOSTNAME" +log "INFO" "Config: $CONFIG_FILE" +log "INFO" "Logfile: $LOGFILE" + +check_dep "proxmox-backup-client" "Bitte PBS-Client installieren." +if bool "${MAIL_ENABLED:-}"; then + check_dep "${MAIL_CMD:-mail}" "Mail-/msmtp-Client nicht gefunden? Setze MAIL_CMD in $CONFIG_FILE." +fi +if bool "${NTFY_ENABLED:-}"; then + check_dep "curl" "curl wird für Ntfy benötigt." +fi + +# ---------- Notifications ---------- # +send_mail() { + bool "${MAIL_ENABLED:-}" || return 0 + local subject="$1"; shift + local body="$*" + [[ -n "${MAIL_RECIPIENTS:-}" ]] || { log "WARN" "MAIL_RECIPIENTS leer, Mail wird übersprungen."; return 0; } + local mail_cmd="${MAIL_CMD:-mail}" + printf "%s\n" "$body" | $mail_cmd -s "$subject" $MAIL_RECIPIENTS || log "ERROR" "Mail-Versand fehlgeschlagen." +} + +send_ntfy() { + bool "${NTFY_ENABLED:-}" || return 0 + local title="$1" priority="$2" body="$3" + [[ -n "${NTFY_TOPIC_URL:-}" ]] || { log "WARN" "NTFY_TOPIC_URL leer, Ntfy wird übersprungen."; return 0; } + local -a CURL_ARGS=( -sS -X POST "$NTFY_TOPIC_URL" -H "Title: $title" -H "Priority: $priority" --data-binary "$body" ) + [[ -n "${NTFY_AUTH_TOKEN:-}" ]] && CURL_ARGS+=( -H "Authorization: Bearer $NTFY_AUTH_TOKEN" ) + curl "${CURL_ARGS[@]}" >/dev/null || log "ERROR" "Ntfy-Versand fehlgeschlagen." +} + +# ---------- Backup ---------- # +run_backup() { + local cmd=("proxmox-backup-client" "backup" "--repository" "$PBS_REPOSITORY") + + for dir in "${INCLUDE_DIRS[@]}"; do + local base; base="$(basename "$dir")" + cmd+=("${base}.pxar:${dir}") + done + + local cmd_pretty; cmd_pretty="$(printf "%q " "${cmd[@]}")" + log "INFO" "Backup-Command: ${cmd_pretty} # PBS_PASSWORD via env" + + if $DRY_RUN; then + log "INFO" "DRY-RUN aktiv: Es wird nichts ausgeführt." + return 0 + fi + + { + echo "===== $(_timestamp) | BEGIN BACKUP RUN =====" + echo "Host: $HOSTNAME" + echo "Repository: $PBS_REPOSITORY" + echo "Quellen:" + printf " - %s\n" "${INCLUDE_DIRS[@]}" + echo "------------------------------------------------" + } | tee -a "$LOGFILE" | tee -a "$RUNLOG" + + if ( + [[ -n "${PBS_API:-}" ]] && export PBS_PASSWORD="$PBS_API" + [[ -n "${PBS_FINGERPRINT:-}" ]] && export PBS_FINGERPRINT + "${cmd[@]}" + ) 2>&1 | tee -a "$LOGFILE" | tee -a "$RUNLOG" + then + echo "===== $(_timestamp) | END BACKUP RUN (OK) =====" | tee -a "$LOGFILE" | tee -a "$RUNLOG" + return 0 + else + echo "===== $(_timestamp) | END BACKUP RUN (FAILED) =====" | tee -a "$LOGFILE" | tee -a "$RUNLOG" + return 1 + fi +} + +# ---------- Healthcheck ---------- # +write_health_ok() { + [[ -n "$HEALTHCHECK_OK_FILE" ]] || return 0 + mkdir -p "$(dirname "$HEALTHCHECK_OK_FILE")" || true + cat > "$HEALTHCHECK_OK_FILE" <