[TUTORIAL] Proxmox Backup Server PBS automatisch via WOL starten und stoppen

dremeier

New Member
May 9, 2023
9
10
3
hier meine 5 cent um einen externen Proxmox Backup Server automatisch bei jedem Backup-Job sicher zu starten, das Backup-Storage zu aktivieren und wieder aus zu schalten. Anregungen und meinen Dank gehen an diesen Beitrag.

Als Vorbereitung ist es wichtig das man zum PBS mittels ssh-key Zugang ohne Passwort hat. Wie das geht bitte googeln.

Als erstes legen wir ein Script an mit:
nano /usr/local/bin/vzdump-hook-script
Folgenden Inhalt dort rein kopieren:
!!!Natürlich die Variablen auf deine Werte anpassen!!!
Bash:
#!/bin/bash
# script um den Backupserver zu starten wenn ein Backup ansteht. Danach wieder Ausschalten
# dieses Hook-Skript (nano /usr/local/bin/vzdump-hook-script)  zum Backup-Auftrag hinzufügen: nano /etc/pve/jobs.cfg
# by AME 05/2023
#----------------------- Variablen --------------------------------------------------------------------------------#
PATH=/usr/sbin:${PATH}
# SET-X damit die Ausfuehrung protokolliert wird
# set -x
storeid=BackupServer                                            # Variable - um welches storage handelt es sich
mac="aa:bb:cc:dd:ee:ff"                                         # MAC Adresse des PBS-Servers
host="192.168.xxx.xxx"                                          # Hostname oder IP des PBS-Servers
nic=eno1                                                        # Netzwerk-Karte über die WOL läuft

#----------------------- Programmablauf ---------------------------------------------------------------------------#
if [ "$1" == "job-init" ]; then                                 # wenn ein backup job rein kommt dann
        pvesm set $storeid --disable 0                          # der Storage wir enabled
        etherwake -i $nic  $mac                                 # starte den Backup-server
        sleep 10s
#        ping  $host -c 3 < /dev/null &

until [ "$act" == "true" ]                                      # arbeite die loop-schleife ab bis die variable "ack" wahr ist
do
    com=$(pvesm status --storage $storeid | tail -1);           # Abfrage über den Status des Storage
    [[ "$com" =~ ($storeid+ +)(pbs+ +)(active|inactive) ]];

    if [ "${BASH_REMATCH[3]}" == "active" ]; then               # der server ist erreichbar also aktiv?
        echo "Backup-Server ist erreichbar"
        act=true                                                # variable "act" wirt wahr um aus dem loop raus zukommen
        sleep 6s
        exit 0
    else
        ((c=c+1))                                               # counter
    fi

    if [ $c == 180 ]; then                                      # wenn der server nach 180 sec. nicht erreichbar ist exit 1 e>
        echo "ERROR Backup-Server ist nicht erreich bar"
        sleep 2s
        exit 1
    fi
    sleep 1s
done
fi

if [ "$1" == "job-end" ]; then                                  # Wenn der Backup Job erledigt ist dann
        echo "Backup erledigt, warte 20 Sekunden dann wird der Backup-Server gestoppt"
        sleep 20s
        pvesm set $storeid --disable 1                          # der Storage wir disabled, sonst ist er nicht erreichbar und>
        ssh root@$host -p 22 "poweroff < /dev/null &"           # der Backupserver wird heruntergefahren
fi

exit 0
dieses Script ausführbar machen:
chmod +x /usr/local/bin/vzdump-hook-script

dann das Script zu deinem Backup-Auftrag hinzu fügen:
nano /etc/pve/jobs.cfg
das könnte so aussehen:
Code:
vzdump: backup-2b4e2f43-c989
        schedule 05:40
        all 1
        enabled 1
        mailnotification always
        mailto deine@Email.de
        mode snapshot
        notes-template {{guestname}}
        prune-backups keep-daily=3,keep-last=1,keep-monthly=6,keep-weekly=4,keep-yearly=2
        script /usr/local/bin/vzdump-hook-script    #<--------- !!!!
        storage BackupServer
Das war es auch schon. Denke daran beim ausprobieren des Backup-Jobs deine GUI zu refreshen bzw. neu zu laden. Um zusehen was passiert kannst du in dem Script die Zeile: # set -x auskommentieren und mit tail -f /var/log/syslog ansehen.

Will man den Backup-Server manuell starten und stoppen habe ich zwei kleine Scripte erstellt:
nano start-PBS.sh
Bash:
#!/bin/bash
# script um den Backupserver zu starten.
# by AME 05/2023
#----------------------- Variablen --------------------------------------------------------------------------------#
# SET-X damit die Ausfuehrung protokolliert wird
# set -x
storeid=BackupServer                                            # Variable - um welches storage handelt es sich
mac="aa:bb:cc:dd:ee:ff"                                         # MAC Adresse des PBS-Servers
host="192.168.xxx.xxx"                                          # Hostname oder IP des PBS-Servers
nic=eno1                                                        # Netzwerk-Karte über die WOL läuft

#----------------------- Programmablauf ---------------------------------------------------------------------------#
/usr/sbin/etherwake -i $nic $mac                                # starte den Backup-server
sleep 2s
pvesm set $storeid --disable 0                                  # der Storage wir enabled

until [ "$act" == "true" ]                                      # arbeite die loop-schleife ab bis die variable "ack" wahr ist
do
    com=$(pvesm status --storage $storeid | tail -1);           # keine ahnung
    [[ "$com" =~ (BackupServer+ +)(pbs+ +)(active|inactive) ]];

    if [ "${BASH_REMATCH[3]}" == "active" ]; then               # der server ist erreichbar also aktiv?
        echo "Backup-Server ist jetzt erreichbar"
        act=true
        #sleep 1s
        exit 0
    else
        ((c=c+1))                                               # counter
    fi

    if [ $c == 180 ]; then                                      # wenn der server nach 180 sec. nicht erreichbar ist exit 1 e>
        echo "ERROR Backup-Server ist nicht erreich bar"
        sleep 1s
        exit 1
    fi
    sleep 1s
done

exit 0

und nano stop-PBS.sh
Bash:
#!/bin/bash
# script um den Backupserver zu stoppen.
# by AME 05/2023
#----------------------- Variablen --------------------------------------------------------------------------------#
# SET-X damit die Ausfuehrung protokolliert wird
# set -x
storeid=BackupServer                                            # Variable - um welches storage handelt es sich
mac="aa:bb:cc:dd:ee:ff"                                         # MAC Adresse des PBS-Servers
host="192.168.xxx.xxx"                                          # Hostname oder IP des PBS-Servers
nic=eno1                                                        # Netzwerk-Karte über die WOL läuft

#----------------------- Programmablauf ---------------------------------------------------------------------------#
echo "der Backup-Server fährt nun runter, das Backup-Storage wird ausgehangen"
#sleep 2s
pvesm set $storeid --disable 1                                  # der Storage wir disabled umd die syslog nicht zu zu müllen
ssh root@$host -p 22 "/usr/sbin/poweroff < /dev/null &"
exit 0
beide ausführbar machen mit chmod +x start-PBS.sh und chmod +x stop-PBS.sh

Wenn man mag kann man sich ein Alias anlegen, dazu: nano .bashrc z.B. folgendes einfügen:
Bash:
# Alias for BAckup-Server Start Stop
alias uppbs='./start-PBS.sh'
alias dnpbs='./stop-PBS.sh'
root einmal ausloggen und wieder einloggen.
dann einfach mit uppbs den server starten und mit dnpbs ihn wieder stoppen.

so, ich hoffe es können viele gebrauchen.
Toll wäre es wenn die Entwickler so ein Feature mit in die GUI einbauen könnten. Die meisten werden ihren Backup-Server sicher nicht 24/7 laufen lassen um einmal am Tag für 5min. ein Backup zu starten !?
 
Last edited:
Da dies mein erster Post hier in diesem Forum ist erstmal ein freundliches "Hallo" in die Runde :cool:

Erstmal ein großes DANKE an dremeier für das erstellen der Hook-Skripte. Ich konnte diese wunderbar in mein Proxmox-Server integrieren und anpassen. Lediglich das Einrichten der automatischen SSH Vebindung gestaltete sich als kleine Hürde aber es gibt genug gute Tutorials im Netz ;)

Ich habe das Skrip noch mal etwas überarbeitet und einen Bug beseitigt, der nach dem fehlerhaften Start des PBS den Storage nicht mehr deaktiviert.

Als Erweiterung des Skriptes habe ich einen Taskhandler hinzugefügt der überprüft, ob auf dem PBS noch Tasks laufen. Als Beispiel wird nach dem abschluss des Backup-Jobs in den meisten Fällen noch ein garbage_collection-job auf dem PBS gestartet um Speicherplatz durch das löschen älterer Backups zu schaffen.
Siehe dazu den Maintanance-Abschnit in der Proxmox-Doku.

Hier das ergänzte Skript:

Bash:
#!/bin/bash
# script um den Backupserver zu starten wenn ein Backup ansteht. Danach wieder Ausschalten
# dieses Hook-Skript (nano /usr/local/bin/vzdump-hook-script)  zum Backup-Auftrag hinzufügen: nano /etc/pve/jobs.cfg
# by AME 05/2023
#----------------------- Variablen --------------------------------------------------------------------------------#
PATH=/usr/sbin:${PATH}
# SET-X damit die Ausfuehrung protokolliert wird
# set -x
storeid=pbs-storage                                             # Variable - um welches Storage handelt es sich
mac="aa:bb:cc:dd:ee:ff"                                         # MAC Adresse des PBS-Servers
host="1.1.1.1"                                                  # Hostname oder IP des PBS-Servers
nic=eth0                                                        # Netzwerk-Karte über die WOL läuft

#---------------------- Funktionen --------------------------------------------------------------------------------#

format_time() {                                                 # Funktion zur Umrechnung der vergangenen Zeit in ein gängiges Format: hh:mm:ss
    local input_seconds=$1
    local hours=$((input_seconds / 3600))
    local minutes=$(( (input_seconds % 3600) / 60 ))
    local seconds=$((input_seconds % 60))

    printf "%02d:%02d:%02d" "$hours" "$minutes" "$seconds"
}

check_tasks_running() {                                         # Funktion zur Überprüfung auf laufende Tasks via SSH
    tasks_running=$(ssh root@$host proxmox-backup-manager task list | grep running | wc -l)
    echo $tasks_running
}

#----------------------- Programmablauf ---------------------------------------------------------------------------#
if [ "$1" == "job-init" ]; then                                 # wenn ein backup job rein kommt dann
    pvesm set $storeid --disable 0                              # der Storage wird enabled
    etherwake -i $nic  $mac                                     # starte den Backup-Server
    sleep 60s

    until [ "$act" == "true" ]; do                              # arbeite die Schleife ab bis die variable "ack" wahr ist
        com=$(pvesm status --storage $storeid | tail -1);       # Abfrage über den Status des Storage
        [[ $com =~ ($storeid+ +)(pbs+ +)(active|inactive) ]];

        if [ ${BASH_REMATCH[3]} == active ]; then               # der server ist erreichbar also aktiv?
            echo "Backup-Server ist erreichbar"
            act=true                                            # variable "act" wird wahr um aus dem loop rauszukommen
            sleep 6s
            exit 0
        else
            ((c=c+1))                                           # counter
        fi

        if [ $c == 180 ]; then                                  # wenn der server nach 180 sec. nicht erreichbar ist exit 1 und
            echo "ERROR Backup-Server ist nicht erreichbar"
            sleep 2s
            pvesm set $storeid --disable 1                      # deaktiviere den Speicher
            exit 1
        fi
        sleep 1s
    done
fi

if [ "$1" == "job-end" ]; then                                  # Wenn der Backup Job erledigt ist dann
    echo "Backup erledigt, überprüfe auf laufende Tasks"

    while true; do
    tasks_running=$(check_tasks_running)                        # Überprüfung auf laufende Tasks nach Backup auf Backupserver
        if [ $tasks_running -gt 0 ]; then
            start_time=$(date +%s)                              # setze Startzeit
            notification_sent=false                             # Variable für Meldung setzen

            while [ $tasks_running -gt 0 ]; do                  # durchlaufe die Schleife solange, bis alle Tasks beendet sind
            sleep 60s
            tasks_running=$(check_tasks_running)
            elapsed_time=$(( $(date +%s) - $start_time ))       # Berechnung der Zeit zum Durchlaufen der Tasks

            if [ "$notification_sent" == false ]; then          # gebe diese Meldung einmal aus, um auf noch laufende Tasks hinzuweisen
                echo "Es laufen noch $tasks_running Tasks. Warte auf Abschluss der Tasks..."
                notification_sent=true
            fi
            done

            formatted_time=$(format_time "$elapsed_time")       # Aufrufen der Umrechnungsfunktion in hh:mm:ss
            echo "Alle Tasks wurden abgeschlossen. Gesamtdauer: $formatted_time"    # nach abschluss der Schleife, Ausgabe der Gesamtdauer


        else
            echo "Keine laufenden Tasks gefunden. Warte 20 Sekunden, dann wird der Backup-Server gestoppt."
            sleep 20s
            pvesm set $storeid --disable 1                      # deaktiviere den Speicher
            ssh root@$host -p 22 poweroff < /dev/null &         # Backupserver wird heruntergefahren

        sleep 20s

        if ping -c 1 $host &> /dev/null; then                   # wenn der Server noch erreichbar ist
            echo "Fehler: Der Backup-Server konnte nicht heruntergefahren werden."
            exit 1                                              # gibt`s einen Fehler im Log
        else
            echo "Der Backup-Server wurde erfolgreich heruntergefahren."
            exit 0
            fi
        fi
    done
fi
exit 0

Das Skript lief bisher 2x Fehlerfrei durch. Falls dennoch Fehler auftreten sollten, lasst es uns wissen.
Viel Spass mit dem Skript.

Grüße Kochi
 
Last edited:
Moin und nachträglich noch frohe Weihnachten,

da ich über die Feiertage noch etwas Zeit hatte habe ich noch etwas am Skript gearbeitet und zusätzlich noch einen Backup-Jobhandler eingebaut.
Dieser überprüft, ob noch weitere Backup-Jobs laufen und beendet den derzeitigen Backup-Job. Grundlage dafür ist, das die anderen Backup-Jobs auch mit dem Skript gestartet werden. Der letzte, noch laufende Backup-Job fährt dann anschließend den PBS Herunter.


Bash:
#!/bin/bash
# script um den Backupserver zu starten wenn ein Backup ansteht. Danach wieder Ausschalten
# dieses Hook-Skript (nano /usr/local/bin/vzdump-hook-script)  zum Backup-Auftrag hinzufügen: nano /etc/pve/jobs.cfg
# by AME 05/2023
#----------------------- Variablen --------------------------------------------------------------------------------#

PATH=/usr/sbin:${PATH}
# set -x                                                        # SET-X damit die Ausfuehrung protokolliert wird
storeid=pbs-storage                                             # Variable - um welches Storage handelt es sich
mac="aa:bb:cc:dd:ee:ff"                                         # MAC Adresse des PBS-Servers
host="1.1.1.1"                                                  # Hostname oder IP des PBS-Servers
nic=eth0                                                        # Netzwerk-Karte über die WOL läuft

#---------------------- Funktionen --------------------------------------------------------------------------------#

format_time() {                                                 # Funktion zur Umrechnung der vergangenen Zeit in ein gängiges Format: hh:mm:ss
    local input_seconds=$1
    local hours=$((input_seconds / 3600))
    local minutes=$(( (input_seconds % 3600) / 60 ))
    local seconds=$((input_seconds % 60))

    printf "%02d:%02d:%02d" "$hours" "$minutes" "$seconds"
}

check_tasks_running() {                                         # Funktion zur Überprüfung auf laufende Tasks via SSH
    tasks_running=$(ssh root@$host proxmox-backup-manager task list | grep running | wc -l)
    echo $tasks_running
}

#----------------------- Programmablauf ---------------------------------------------------------------------------#
if [ "$1" == "job-init" ]; then                                     # wenn ein Backup-Job rein kommt dann

    if ping -c 1 $host &> /dev/null; then                           # prüfe, ob der Backup-Server schon läuft

        echo "Der Backupserver läuft bereits"
        exit 0
    else
        pvesm set $storeid --disable 0                              # der Storage wird enabled
        etherwake -i $nic  $mac                                     # starte den Backup-Server
        sleep 60s

        until [ "$act" == "true" ]; do                              # arbeite die Schleife ab bis die Variable "ack" wahr ist
            com=$(pvesm status --storage $storeid | tail -1);       # Abfrage über den Status des Storage
            [[ $com =~ ($storeid+ +)(pbs+ +)(active|inactive) ]];

            if [ ${BASH_REMATCH[3]} == active ]; then               # der Server ist erreichbar
                echo "Backup-Server ist erreichbar"
                act=true                                            # Variable "act" wird wahr um aus dem Loop rauszukommen
                sleep 6s
                exit 0
            else
                ((c=c+1))                                           # counter
            fi

            if [ $c == 180 ]; then                                  # wenn der Server nach 180 sec. nicht erreichbar ist exit 1

                echo "ERROR Backup-Server ist nicht erreichbar"
                sleep 2s
                pvesm set $storeid --disable 1                      # deaktiviere den Speicher
                exit 1
            fi
            sleep 1s
        done
    fi
fi

if [ "$1" == "job-end" ]; then                                      # Wenn der Backup-Job erledigt ist
    echo "Backup erledigt, überprüfe auf laufende Tasks"

    while true; do
    tasks_running=$(check_tasks_running)
        if [ $tasks_running -gt 0 ]; then                           # Überprüfung auf laufende Tasks nach Backup auf Backupserver 

            start_time=$(date +%s)                                  # setze Startzeit
            notification_sent=false                                 # Variable für Meldung setzen
            scanned_tasks=0

            while [ $tasks_running -gt 0 ]; do                      # durchlaufe die Schleife solange, bis alle Tasks beendet sind

                sleep 60s
                tasks_running=$(check_tasks_running)
                elapsed_time=$(( $(date +%s) - $start_time ))       # Berechnung der Zeit zum Durchlaufen der Tasks

                if [ "$notification_sent" == false ]; then          # gebe diese Meldung aus, um auf noch laufende Tasks hinzuweisen

                    if [ $tasks_running -gt 1 ]; then
                        echo "Es laufen noch $tasks_running Tasks. Warte auf Abschluss der Tasks..."
                    else
                        echo "Es läuft noch $tasks_running Task. Warte auf Abschluss des Tasks..."
                    fi
                    notification_sent=true
                    scanned_tasks=$(tasks_running)
                else

                    if [ $tasks_running -gt $scanned_tasks ]; then  # wenn sich die Anzahl der Tasks ändert
                        notification_sent=false                     # setze die Variable wieder auf 'false'
                    fi
                fi
            done

            formatted_time=$(format_time "$elapsed_time")           # Aufrufen der Umrechnungsfunktion in hh:mm:ss
            echo "Alle Tasks wurden abgeschlossen. Gesamtdauer: $formatted_time"    # nach abschluss der Schleife, Ausgabe der Gesamtdauer
        else

            other_backups=$(( $(ps auxww | grep 'task.*vzdump' | grep -v grep | wc -l) -1 ))

            if [ $other_backups -lt 0 ]; then
                $other_backups=0
            fi

            if [ $other_backups -ge 1 ]; then                       # sind unter den Tasks noch andere Backupjobs, beende das Skript

                if [ $other_backups -gt 1 ]; then

                    echo "Es laufen noch $other_backups Backup-Jobs. Beende den aktuellen Job."
                else
                    echo "Es läuft noch $other_backups Backup-Job. Beende den aktuellen Job."
                fi
                exit 0
            fi


            echo "Keine laufenden Tasks gefunden. Warte 20 Sekunden, dann wird der Backup-Server gestoppt."
            sleep 20s
            pvesm set $storeid --disable 1                          # deaktiviere den Speicher
            ssh root@$host -p 22 poweroff < /dev/null &                # Backupserver wird heruntergefahren
            sleep 20s

            if ping -c 1 $host &> /dev/null; then                   # wenn der Server noch erreichbar ist
                echo "Fehler: Der Backup-Server konnte nicht heruntergefahren werden."
                exit 1                                              # gibt`s einen Fehler im Log
            else
                echo "Der Backup-Server wurde erfolgreich heruntergefahren."
                exit 0
            fi
        fi
    done
fi
exit 0

Vielleicht könnte am die ganze Ausgabe noch auf Englisch übersetzen, damit die Zeichen UTF-8 konform angezeit werden können.


Viel Spass beim ausprobieren und guten Rutsch ins Jahr '24
 
  • Like
Reactions: macdet
Hey vielen Dank für die Anleitung. Leider muss ich sagen, dass das keine so gute Idee ist. Denn die Prune / GC Jobs sollen ja außerhalb der Backupzeiten laufen. Das kann je nach Datenmenge schonmal ein paar Stunden dauern. Ich hatte schon mehrmals ein volles Storage weil die prune/gc Jobs nicht durchliefen. Aber das sind nur meine 5cts :) Einen guten Rutsch.
 
Danke!

Der uppbs startet mir den Backupserver, leider spuckt er einen Fehler aus:

pbs: error fetching datastores - 500 Can't connect to 192.168.10.10:8007 (Connection timed out)
pbs: error fetching datastores - 500 Can't connect to 192.168.10.10:8007 (Connection timed out)
pbs: error fetching datastores - 500 Can't connect to 192.168.10.10:8007 (No route to host)
pbs: error fetching datastores - 500 Can't connect to 192.168.10.10:8007 (No route to host)
pbs: error fetching datastores - 500 Can't connect to 192.168.10.10:8007 (No route to host)
 
Last edited:
Moin,

der Backupspeicher wird 2s nach dem senden des Befehls etherwake aktiviert. Vielleicht solltest du die Wartezeit so einstellen, bis der Backupserver hochgefahren ist. Je nach verwendeter Hardware kann der Start unterschiedlich lange dauern.

Kannst du dich per ssh auf deinen PBS verbinden?


Grüße
 
  • Like
Reactions: macdet
Zuerst mal vielen Dank Kochi1316.

Ich bin gerade dabei das Script etwas auf meine Umgebung anzupassen.
Ich mache die Backups auf ein QNAP NAS und hab das bisher mit ein paar Änderungen hin bekommen.
Wo ich gerade Hänge ist das Thema: Mehere Backup Jobs.
Ich musste das Backup auf 2 Jobs verteilen.
In dem Script witd jetzt auf Prozesse auf dem Backup server geschaut um zu prüfen ob noch ein weiteres Backup aktiv ist. Das klappt bei meinem NAS natürlich so nicht. Gibt es eine Idee wi man das auch auf dem Proxmox VE lösen kann ?
Wäre halt blöd wenn der schnellere Job dem langsameren Job das NAS runter fährt.

Danke
Peter
 
Vielen Dank für dieses tolle Script! Nach der schwierigen einrichtung und aktivierung des WOL auf meinem Backup Server haben alle Scripte von hier auf anhieb funktioniert :)

Hab mir zudem einen Cronjob angelegt der den Backup Server 2 mal im Monat ausserhalb der Backupzeiten für paar Stunden startet damit dieser eventuelle Hintergrundjobs in Ruhe ausführen kann
 
Last edited:

About

The Proxmox community has been around for many years and offers help and support for Proxmox VE, Proxmox Backup Server, and Proxmox Mail Gateway.
We think our community is one of the best thanks to people like you!

Get your subscription!

The Proxmox team works very hard to make sure you are running the best software and getting stable updates and security enhancements, as well as quick enterprise support. Tens of thousands of happy customers have a Proxmox subscription. Get yours easily in our online shop.

Buy now!