Script zum zeitgesteuerten runterfahren funktioniert nur im Direktaufruf fehlerfrei *gelöst*

TomSonstNix

New Member
Dec 9, 2024
10
0
1
Guten Morgen liebe Forenteilnehmer,
ich habe hier ein Phänomen, bei dem ich Euer Schwarmwissen benötige:

Mein Proxmox BackUp Server läuft auf einem eigenen Rechner und sichert täglich meine Vm´s und Container meiner Proxmox PVE, die ebenfalls auf einem eigenen Rechner läuft.
Das funktioniert absolut fehlerlos. Nun möchte ich gerne den Proxmox PBS nach getaner Arbeit automatisiert herunterfahren und habe hier im Forum bereits recherchiert.
Der Tip aus diesem Post hat mir sehr geholfen, er ist so aufgebaut
Code:
#!/bin/bash

count=$(proxmox-backup-manager task list | grep running | wc -l);

if [ $count -gt 0 ]; then
    echo "tasks running"
else
    echo "shutdown possible"
    poweroff
fi

Da ich eine Ausgabe nicht benötige, habe ich den Code an meine Bedürfnisse angepasst, er sieht so aus
Code:
#!/bin/bash

count=$(proxmox-backup-manager task list | grep running | wc -l);

if [ $count -eq 0 ]; then
    /sbin/poweroff
fi

Ich habe ihn in ein Script geschrieben und das Script ausführbar gemacht. Wenn ich dieses Script aufrufe und ein Task läuft, passiert nichts. Ist kein laufender Task vorhanden, dann schaltet sich der Proxmox PBS aus. Funktioniert wunderbar, ich dachte mir also, ich steuere dieses Script über einen Cronjob an.

Der Cronjob ist so aufgebaut
Code:
10,20,30,40,50 4-8 * * * /usr/local/bin/pbs_shutdown_daily.sh

Der Cronjob wird täglich alle 10 Minuten zwischen 4 und 8 Uhr ausgeführt. Da meine Sicherung meist um 03:30h beendet ist, passt das ganz gut.

Nun kommt der Fehler: der Cronjob schaltet den Rechner ab, egal ob da noch ein Task läuft.
Das Script durchläuft also die If-Abfrage aber schaltet trotz laufendem Task den Rechner ab.
Wenn ich das Script für sich alleine aufrufe, funkionert es .
Jetzt bin ich mit meinem Latein am Ende und bräuchte Euren Rat.

Besten Dank vorab und viele Grüße
Thomas
 
Last edited:
nimm doch einfach ein hook-script da kannst Du sagen das er wenn das Backup zu Ende ist er den Rechner runterfahren soll

Code:
#!/bin/bash
#set -e;
#set -x;
# fstrim vor backup
if [ "$1" == 'pre-start' ]; then
    /usr/sbin/qm guest exec "$3" -- fstrim -v /boot ; /usr/sbin/qm guest exec "$3" -- fstrim -av ;
fi

if [ "$1" == 'pre-restart' ]; then
fi

if [ "$1" == "job-init" ]; then
fi

if [[ "$1" == "pre-stop" ]]; then
fi

if [ "$1" == "backup-start" ]; then
fi

if [ "$1" == "backup-end" ]; then
fi

if [[ "$1" == "post-restart" ]]; then
fi

if [[ "$1" == "post-stop" ]]; then
fi

if [ "$1" == "job-end" ]; then
    /usr/local/bin/prune_pbs
    ssh pbs "/sbin/poweroff"
fi

exit 0

das script unter /usr/local/bin/hook-script ablegen
chmod +x /usr/local/bin/hook-script

dann noch in die Datei /etc/vzdump.conf folgendes einfügen:

Code:
script: /usr/local/bin/hook-script

ich lass meinen pbs noch aufräumen am Ende mit folgendem Script /usr/local/bin/prune_pbs

Code:
#!/bin/sh
HASH="$(openssl x509 -in /etc/proxmox-backup/proxy.pem -noout -fingerprint -sha256 | cut -d'=' -f2)"
PBS_FINGERPRINT=${HASH}
export PBS_FINGERPRINT
export PBS_PASSWORD='pbstoken'  #token vom pbs server
export PBS_USER_STRING='root@pam!pbs'
export PBS_SERVER='pbs'
export PBS_DATASTORE='pbs'
export PBS_REPOSITORY="${PBS_USER_STRING}@${PBS_SERVER}:${PBS_DATASTORE}"
export PBS_HOSTNAME="$(hostname -s)"

proxmox-backup-client list --output-format json-pretty | jq -r '.[]|."backup-type" + "/" + ."backup-id"' | while read group; do
    proxmox-backup-client prune "${group}"  --keep-last 7
done

proxmox-backup-manager verify ${PBS_DATASTORE}
proxmox-backup-manager garbage-collection start ${PBS_DATASTORE}
 
Last edited:
ja die scripte liegen auf dem pve,
ich lass den verify über das hook script laufen damit der erst danach runterfährt wenn er fertig ist
bzw nutze ich das für meinen zweiten pbs der einmal die Woche die Backups vom Haupt PBS synct der ist dann immer aus sonst.
 
Last edited:
  • Like
Reactions: TomSonstNix
Ich nehme mal an, dass die Binary einfach nicht im PATH ist. Probier mal das
Bash:
#!/usr/bin/env bash
set -euo pipefail

if ! /usr/sbin/proxmox-backup-manager task list | /usr/bin/grep -q "running"; then
    /usr/bin/logger -t pbs_shutdown_daily "Shutting down as no tasks were running"
    /sbin/poweroff
fi
Ansonsten ist hier ein Workaround.
Du kannst das auch ganz simpel direkt so im cronjob erledigen
Bash:
10,20,30,40,50 4-8 * * * /usr/sbin/proxmox-backup-manager task list | /usr/bin/grep -q "running" || /sbin/poweroff
 
Last edited:
Vielen Dank an bluesite und Impact für die schnelle Hilfe.

@Impact: Führe ich Dein Script aus, passiert nichts, habe das mal testweise so eingesetzt:
Code:
#!/usr/bin/env bash
set -eou pipefail

count=$(/usr/sbin/proxmox-backup-manager task list | /usr/bin/grep "running" | /usr/bin/wc -l);

if [ $count -eq 0 ]; then
    echo "PowerOff at: $(date)" >> /usr/local/bin/pbs_shutdown.log
else
    echo "Tasks still running at: $(date)" >> /usr/local/bin/pbs_shutdown.log
fi

Es schreibt nichts in die Log Datei.
Setze ich die Variable auf count=1, dann funktioniert es. Irgendetwas scheint in der Variablen Definition nicht zu passen?

VG Thomas
 
Probier mal bash -x scripthier.sh um zu sehen was passiert. Ansonsten lass das set -euo pipefail weg.
Ich habe das Script oben etwas angepasst. Könnte nun funktionieren.
 
Last edited:
  • Like
Reactions: TomSonstNix
Bash:
root@pbs:/usr/local/bin# bash -x pbs_shutdown_daily.sh
+ set -eou pipefail
++ /usr/sbin/proxmox-backup-manager task list
++ /usr/bin/grep running
++ /usr/bin/wc -l
+ count=0
root@pbs:/usr/local/bin#

hmm, das sieht gut aus.
 
Ich habe das Script und den Einzeiler oben noch mal angepasst und auch getestet. Sollte jetzt funktionieren.
Ich habe es etwas umgeschrieben denn Die Anzahl der Jobs ist ja nicht relevant sondern nur ob running vorhanden ist.
Ich konnte es nicht auf mir sitzen lassen ein Script mit set -euo pipefail nicht ans laufen zu bekommen :D
 
Last edited:
  • Like
Reactions: TomSonstNix
Ich danke Dir vielmals für Deine ausführliche uund schnelle Hilfe, ich bin begeistert.
Da ich noch relativ unerfahren im Scripting bin, würde mich brennend interessieren, wieso es für Dich so wichtig ist, set -euo pipefail zu integrieren?
 
Das setzt einige Bash Optionen die die Ausführung strikter machen und für mehr Sicherheit/Robusheit sorgen.
- https://foreops.com/blog/enhancing-bash-script-reliability-with-set-xeuo-pipefail/
- https://www.namehero.com/blog/how-to-use-set-e-o-pipefail-in-bash-and-why/
- https://translucentcomputing.com/blog/unofficial-bash-strict-mode-pipefail/

Das zusammen mit dem #!/usr/bin/env bash anstatt #!/usr/bin/bash sind einfach so ein paar best practices.
Ich nutze das auch nicht immer, aber wenn ich Code teile versuche ich meist ein gutes Beispiel zu setzen.
 
Last edited: