HGWBLN Posted March 28 Share Posted March 28 Hallo liebe Community, ich muss ein Script bzw. mehrere Scripte schreiben und habe darin, gelinde gesagt, null Erfahrung und benötige daher etwas Hilfe. Hintergrund: Ich habe eine Synology, die ich für Unraid-Backups nutze. Sowohl die Syno als auch Unraid befinden sich im gleichen Netzwerk. Die Syno fährt aber nur hoch, wenn das Update ansteht und fährt anschließend nach einer gewissen Zeit wieder herunter. Dieses Vorgehen hat mit LuckyBackup Probleme gemacht, die aber dank der Unterstützung von alturismo behoben werden konnte (siehe auch dieses topic: https://forums.unraid.net/topic/158628-luckybackup-sichert-nach-erstmaligem-backup-keine-neue-daten/) Der Zeitplan sieht dabei wie folgt aus: 01:30 Uhr -> Syno fährt hoch 01:55 Uhr -> LuckyBackup wird via Script neugestartet 02:00 Uhr -> LuckyBackup führt sein Backup durch 06:00 Uhr -> Syno fährt herunter Die Syno ist als //192.168.10.52/backup_unraid gemountet. Der Name in Unraid lautet Synology DS220, ich finde die Syno auch unter /mnt/remotes/Synology DS220. Soweit so gut. Problem: Wenn nun die Syno hochfährt, dauert es manchmal ewig bis Unraid diese erkennt. Und selbst wenn das passiert ist, mountet sich die Syno nicht immer automatisch, so dass das LuckyBackup die Syno nicht findet und das Backup nicht startet. Meine Recherche ergab, dass man nach dem Hochfahren der Syno diese via dem Unraid Terminal anpingen soll, so dass Unraid diese schneller erkennt. Lösungsweg: Was muss also getan werden? Die Syno muss via Script angepingt werden. Die Syno muss via Script gemountet werden. Der Docker LuckyBackup muss neugestartet werden (--> dafür habe ich bereits ein Script) Erforderliche Scripte (via UserScript): (1) Syno anpingen Ich denke für die erste Lösung müsste das Script wie folgt aussehen 1 #!/bin/bash 2 ping 192.168.10.52 Frage: Wie lautet der Befehl, dass Unraid mit dem anpingen wieder aufhört, denn wenn ich den Befehl in das Terminal eingebe, läuft der Ping immer weiter. (2) Syno mounten Hier bin vollkommen überfragt und habe mit meiner Recherche auch nichts passendes gefunden. (3) LuckyBackup neustarten Hier habe wie wie bereits geschrieben schon ein Script. 1 #!/bin/bash 2 docker restart luckyBackup Der Zeitplan in Unraid ist ein custom schedule mit 55 1 *** Und jetzt die Frage aller Fragen: Wer kann mir mit den Scripten weiterhelfen? Quote Link to comment
alturismo Posted March 28 Share Posted March 28 3 minutes ago, HGWBLN said: Frage: Wie lautet der Befehl, dass Unraid mit dem anpingen wieder aufhört, denn wenn ich den Befehl in das Terminal eingebe, läuft der Ping immer weiter. auch hier, fast alle cmdline utilities haben eine Hilfe ... 4 minutes ago, HGWBLN said: Hier bin vollkommen überfragt und habe mit meiner Recherche auch nichts passendes gefunden. im passenden Thread anfragen wäre eine Option ... ein Beispiel um die die Suche bzw. die Anfrage zu ersparen ... sollte hiermit selbsterklärend sein ... /usr/local/sbin/rc.unassigned mount //ALSSERVER/Media ersetze mount mit umount zum unmounten (ja, umount NICHT unmount) den Rest wirst du hinbekommen und auch hier sage ich, hört auf euch alles vortippen zu lassen ... liest euch ein, zumindest in die Basics, schaut in den passenden Threads nach oder fragt dort gezielt nach, ziemlich jedes plugin, jeder Docker, ... hat einen eigenen support Thread ... und wenn ich schon anfange scripts zu schreiben, sollte ich die basics per google einfach mal Beispiele anschauen nicht böse gemeint, nur wenn es klemmt fangen wir von vorne an da kein Grundverständnis da ist ... mein Anspruch, zumindest mal einlesen, etwas versuchen, wenn es dann hängt ... anhand Beispielen posten wo ... dann hilft man (ich zumindest) auch gerne mal aus, aber nach dem Motto "wer schreibt das für mich ..." ... sehr ungern mittlerweile, nicht böse gemeint, mehr ein Schubser viel Erfolg dabei mit den gegebenen Infos, steht ja jetzt fast alles da 1 Quote Link to comment
ich777 Posted March 29 Share Posted March 29 13 hours ago, HGWBLN said: Syno Was ist das für eine Synology? Ist die x86_64 basiert? Der bessere weg wäre luckyBackup dort drauf zu installieren und das backup dort zu triggern. Quote Link to comment
Solution Amane Posted March 29 Solution Share Posted March 29 (edited) Hi HGWBLN Ich biete hier gerne Hilfe an. So wie ich das Verstehe wird Automount nichts bringen, da das NAS halt nicht immer online ist.. Natürlich wäre es deswegen sinnvoll LuckBackup auf dem NAS zu installieren (falls möglich) jedoch ist es auch machbar per Skript. Ob LuckyBackup wirklich neu gestartet werden muss, bin ich mir wirklich nicht sicher.. Ich denke eigentlich nicht. (Doch, Luckybackup sollte neu gestartet werden) Dennoch hier mal ein Template (weil ich einfach gern Skripte) 😁 #!/bin/bash #arrayStarted=true # Variablen NAS_IP="192.168.10.52" MOUNT_POINT="//$NAS_IP/backup_unraid" CONTAINER="LuckyBackup" # Überprüfe, ob das NAS erreichbar ist ping -c 1 $NAS_IP &> /dev/null if [ $? -eq 0 ]; then echo "NAS ist erreichbar. Versuche zu mounten.." # Versuche, das NAS zu mounten. mount_test="$(/usr/local/sbin/rc.unassigned mount "$MOUNT_POINT")" if [ $mount_test = "success" ]; then echo "($mount_test) NAS erfolgreich gemountet, starte $CONTAINER neu.." else echo "($mount_test) NAS beriets gemountet? Starte $CONTAINER neu.." fi # Docker-Container neu starten container_test="$(docker restart "$CONTAINER")" if [ "$container_test" = "$CONTAINER" ]; then echo "$container_test wurde neu gestartet." else echo "Fehler beim Neustart von $CONTAINER: $container_test" fi else echo "NAS ist nicht erreichbar, Abbruch.." fi Grüsse Edited May 8 by Amane Fehlerausgabe optimiert 1 Quote Link to comment
HGWBLN Posted March 29 Author Share Posted March 29 11 hours ago, ich777 said: Was ist das für eine Synology? Ist die x86_64 basiert? Der bessere weg wäre luckyBackup dort drauf zu installieren und das backup dort zu triggern. Hi. Das ist eine DS220+ mit einem Intel Celeron J4025. Was wäre der Vorteil wenn LuckyBackup auf der Syno läuft? Quote Link to comment
HGWBLN Posted March 29 Author Share Posted March 29 4 hours ago, Amane said: Hi HGWBLN Dennoch hier mal ein Template (weil ich einfach gern Skripte) 😁 Reveal hidden contents #!/bin/bash #arrayStarted=true # Variablen NAS_IP="192.168.10.52" MOUNT_POINT="//$NAS_IP/backup_unraid" CONTAINER="LuckyBackup" # Überprüfe, ob das NAS erreichbar ist ping -c 1 $NAS_IP &> /dev/null if [ $? -eq 0 ]; then echo "NAS ist erreichbar. Versuche zu mounten.." # Versuche, das NAS zu mounten. mount_test="$(/usr/local/sbin/rc.unassigned mount "$MOUNT_POINT")" if [ $mount_test = "success" ]; then echo "($mount_test) NAS erfolgreich gemountet, starte $CONTAINER neu.." else echo "($mount_test) NAS beriets gemountet? Starte $CONTAINER neu.." fi # Docker-Container neu starten container_test="$(docker restart "$CONTAINER")" if [ "$container_test" = "$CONTAINER" ]; then echo "$container_test wurde neu gestartet." else echo "Fehler beim Neustart von $CONTAINER: $container_test" fi else echo "NAS ist nicht erreichbar, Abbruch.." fi Grüsse Vielen lieben Dank, ich werde das mal ausprobieren und schauen ob es mein Problem löst. Quote Link to comment
Amane Posted March 29 Share Posted March 29 (edited) Just now, HGWBLN said: Was wäre der Vorteil wenn LuckyBackup auf der Syno läuft? Dann ist LuckyBackup immer bereit wenn das NAS an ist und du bräuchtest nie darauf achten, ob das NAS läuft oder nicht. Du startest ja dann von dort das Update, z.B 10min nach dem Start des NAS.. Just now, HGWBLN said: Vielen lieben Dank, ich werde das mal ausprobieren und schauen ob es mein Problem löst. Tausche einfach dein erwähntes Skript gegen meines aus. Und sehr gern geschehen. 01:55 Uhr -> LuckyBackup wird via Script neugestartet (tauschen) Edited March 29 by Amane Quote Link to comment
ich777 Posted March 29 Share Posted March 29 16 minutes ago, HGWBLN said: Was wäre der Vorteil wenn LuckyBackup auf der Syno läuft? Naja, du schaltest die Synology an und dann zieht praktisch die Synology das Backup von deinem Server. Bei mir sieht das so aus das auf meinem Backup Server auch Unraid läuft und dort wird ein User Script bei jedem Start ausgeführt das mir eine Nachricht schickt das eben das Backup in 2 Minuten beginnt (falls ich noch abbrechen möchte oder so) dann wird das Backup in luckyBackup gestartet und am Schluss vom Backup wird ein "controll file" geschrieben das dem User Script dann sagt das es mir nochmal eine Nachricht schickt das eben das Backup fertig ist und dann wird der Backup Server automatisch heruntergefahren. (das User Script läuft die ganze Zeit im Hintergrund und prüft alle paar Minuten ob das "controll file" schon geschrieben wurde wenn es geschrieben wurde, wird es gleich wieder gelöscht und dann eben wie oben beschrieben Nachricht -> Shutdown) Sprich ich muss den nur an den Storm anschließen und auf die Nachrichten warten. Kommt eben drauf an ob du auf der Synology auch ein Script laufen kannst das mit dem Docker Dienst interargieren kann. Quote Link to comment
Amane Posted March 29 Share Posted March 29 Just now, ich777 said: Naja, du schaltest die Synology an und dann zieht praktisch die Synology das Backup von deinem Server. Bei mir sieht das so aus das auf meinem Backup Server auch Unraid läuft und dort wird ein User Script bei jedem Start ausgeführt das mir eine Nachricht schickt das eben das Backup in 2 Minuten beginnt (falls ich noch abbrechen möchte oder so) dann wird das Backup in luckyBackup gestartet und am Schluss vom Backup wird ein "controll file" geschrieben das dem User Script dann sagt das es mir nochmal eine Nachricht schickt das eben das Backup fertig ist und dann wird der Backup Server automatisch heruntergefahren. (das User Script läuft die ganze Zeit im Hintergrund und prüft alle paar Minuten ob das "controll file" schon geschrieben wurde wenn es geschrieben wurde, wird es gleich wieder gelöscht und dann eben wie oben beschrieben Nachricht -> Shutdown) Sprich ich muss den nur an den Storm anschließen und auf die Nachrichten warten. Kommt eben drauf an ob du auf der Synology auch ein Script laufen kannst das mit dem Docker Dienst interargieren kann. Das ist doch viel zu einfach, da musst du dich ja um gar nichts mehr kümmern. Du benötigst ein Skript dass du stehts beobachten musst und hoffen das alles wie geplant funktioniert. Das dein CPU bis ans Limit bringt und die Daten verschlüsselt ablegt und dennoch inkrementelle Backups zulässt, weil du noch zusätzlich eine Datenbank mit dem Änderungsdatum und Hash Wert befüllst. 🤣 Spoiler #!/bin/bash #name=backupSkript #arrayStarted=true #foregroundOnly=true #backgroundOnly=true # Pfadvariablen SOURCE_DIR="/mnt/disk1/backup" TARGET_DIR="/mnt/addons/amane-data-archiv/backup" EXPORT_DIR="/tmp/backupSkript" EXCLUDE_DIRS=("media" "rohner" "transfer") mkdir -p "$EXPORT_DIR" # 7zip-Variablen ARCHIV_PW="mein Passwort halt :D" COMPRESS_LVL=9 # 1 (fastest) ... 9 (ultra) LOG_LVL=0 # 0-3 MAX_CPU_LOAD=35 echo "$MAX_CPU_LOAD" > "$EXPORT_DIR/MAX_CPU_LOAD" && chmod 666 "$EXPORT_DIR/MAX_CPU_LOAD" # Docker-Konfiguration USE_DOCKER=true DOCKER_CONTAINER_NAME="PostgreSQL" # Datenbankverbindungsvariablen DB_HOST="10.10.10.10" DB_USER="backup" DB_NAME="backup" DB_TABLE="file_backup" DB_PORT="5432" # Standardport für PostgreSQL: 5432 # Parameter if [[ "$1" == "-i" ]]; then para_i="true" elif [[ "$1" == "" ]]; then para_i="false" else echo "WARN: Falscher Parameter" exit 1 fi process_controll() { local process_changed=false while true; do local process_count=$(jobs -rp | wc -l) # Gibt Anzahl gleichzeitig laufender Sub-Prozesse zurück local cpu_load=$(mpstat 1 1 | awk '/Average:/ {printf("%d\n", 100 - $NF)}') local call_max_cpu_load="$(cat "$EXPORT_DIR/MAX_CPU_LOAD")" if [[ $call_max_cpu_load =~ ^[0-9]+$ ]]; then MAX_CPU_LOAD=$call_max_cpu_load fi if [[ $process_count -ge $target_processes || $cpu_load -gt $MAX_CPU_LOAD ]]; then if [[ ! $process_changed == true || $cpu_load -gt $MAX_CPU_LOAD ]]; then sleep 2 if [ $cpu_load -gt $MAX_CPU_LOAD ]; then echo "INFO: Warte auf Threadzuweisung.. ($process_count/$target_processes) --" if [[ $target_processes -ge $process_count && $target_processes -gt 0 ]]; then target_processes=$(( $process_count - 1 )) fi else echo "INFO: Warte auf Threadzuweisung.. ($process_count/$target_processes) ++" ((target_processes++)) process_changed=false break fi process_changed=true fi else process_changed=false break fi done } # Funktion, um einfache Anführungszeichen zu escapen escape_single_quotes() { echo "$1" | sed "s/'/''/g" } # Funktion zur Ausführung von psql-Befehlen execute_psql() { local query="$1" if $USE_DOCKER; then docker exec "$DOCKER_CONTAINER_NAME" psql -t -A -U "$DB_USER" -d "$DB_NAME" -c "$query" else psql -h "$DB_HOST" -p "$DB_PORT" -t -A -U "$DB_USER" -d "$DB_NAME" -c "$query" fi } # Hilfsfunktion zum Erstellen eines Hashwerts create_hash() { local file_path="$1" sha256sum "$file_path" | awk '{print $1}' } # Hauptfunktion zum Durchlaufen, Komprimieren und Kopieren von Dateien process_files() { echo "INFO: Starte Ordnersuche.." if [ "$para_i" = "true" ]; then local find_command="find \"$TARGET_DIR\"" for dir in "${EXCLUDE_DIRS[@]}"; do find_command+=" -type d -path \"$TARGET_DIR/$dir\" -prune -o" done find_command+=" -type f ! -name '*.7z' -print" echo -e "$find_command\n..." eval $find_command | while read -r file_path; do # find: -and -name 7z|bz2|gz|rar|tar|xz|zip process_controll local hash_value="$(create_hash "$file_path")" local last_modified="$(date -r "$file_path" +"%Y-%m-%d %H:%M:%S")" local target_rel_path="${file_path#$TARGET_DIR/}" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Erstelle oder Update Datenbank Eintrag für $target_rel_path" echo "" execute_psql "INSERT INTO $DB_TABLE (file_path, hash_value, last_modified) VALUES ('$(escape_single_quotes "$target_rel_path")', '$hash_value', '$last_modified') ON CONFLICT (file_path) DO UPDATE SET hash_value = EXCLUDED.hash_value, last_modified = EXCLUDED.last_modified;" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - if [ $? -eq 0 ]; then printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Archiviere $file_path(.7z)" echo "$(dirname "$file_path")" > "$EXPORT_DIR/backup_workdir" 7z a -aoa -sdel -mx$COMPRESS_LVL -bd -bb$LOG_LVL -p$ARCHIV_PW -mhe=on "$file_path.7z" "$file_path" & printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - fi done else find "$SOURCE_DIR" -type f | while read -r file_path; do process_controll local hash_value="$(create_hash "$file_path")" local last_modified="$(date -r "$file_path" +"%Y-%m-%d %H:%M:%S")" local source_rel_path="${file_path#$SOURCE_DIR/}" local target_rel_path="${file_path#$TARGET_DIR/}" local target_path="$TARGET_DIR/$source_rel_path.7z" local result_exists="$(execute_psql "SELECT file_path FROM $DB_TABLE WHERE file_path = '$(escape_single_quotes "$source_rel_path")'")" local result_modified="$(execute_psql "SELECT file_path FROM $DB_TABLE WHERE file_path = '$(escape_single_quotes "$source_rel_path")' AND (hash_value != '$hash_value' OR last_modified != '$last_modified');")" if [[ -z "$result_exists" || ! -z "$result_modified" ]]; then printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Erstelle oder Update Datenbank Eintrag für $source_rel_path" echo "" execute_psql "INSERT INTO $DB_TABLE (file_path, hash_value, last_modified) VALUES ('$(escape_single_quotes "$source_rel_path")', '$hash_value', '$last_modified') ON CONFLICT (file_path) DO UPDATE SET hash_value = EXCLUDED.hash_value, last_modified = EXCLUDED.last_modified;" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - if [ $? -eq 0 ]; then mkdir -p "$(dirname "$target_path")" # 7z|bz2|gz|rar|tar|xz|zip if [[ ! "${file_path##*.}" =~ ^(7z)$ ]]; then printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Archiviere $file_path nach $target_path" 7z a -aoa -mx$COMPRESS_LVL -bb$LOG_LVL -p$ARCHIV_PW -mhe=on "$target_path" "$file_path" & printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - else printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Kopiere $file_path nach $TARGET_DIR/$source_rel_path" echo "" rsync -av "$file_path" "$TARGET_DIR/$source_rel_path" & printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - fi fi fi done readarray -t db_paths < <(execute_psql "SELECT file_path FROM $DB_TABLE;") local target_dir_path for db_path in "${db_paths[@]}"; do if [[ ! -z "$db_path" && ! -e "$SOURCE_DIR/$db_path" ]]; then local target_to_delete="$TARGET_DIR/$db_path" if [ -f "$TARGET_DIR/$db_path.7z" ]; then printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Entferne $TARGET_DIR/$db_path.7z" echo "" target_dir_path="$(dirname "$TARGET_DIR/$db_path.7z")" rm -f "$TARGET_DIR/$db_path.7z" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - elif [ -e "$TARGET_DIR/$db_path" ]; then printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Entferne $TARGET_DIR/$db_path" echo "" target_dir_path="$(dirname "$TARGET_DIR/$db_path")" rm -f "$TARGET_DIR/$db_path" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - fi find "$target_dir_path" -type d -mindepth 1 -empty -exec sh -c 'rmdir "$1" && echo "INFO: Leerer Ordner entfernt: $1"' sh {} \; printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - echo "INFO: Entferne Datenbank Eintrag: $db_path" echo "" execute_psql "DELETE FROM $DB_TABLE WHERE file_path = '$db_path';" printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' - fi done fi } # Hauptlogik des Skripts main() { target_processes=1 process_files } main "$@" Nimm mich nicht ernst 😉 1 Quote Link to comment
ich777 Posted March 29 Share Posted March 29 3 minutes ago, Amane said: Das ist doch viel zu einfach, da musst du dich ja um gar nichts mehr kümmern. Naja warum sollte ich auch, ich will noch ein Leben auch haben. 3 minutes ago, Amane said: Du benötigst ein Skript dass du stehts beobachten musst und hoffen das alles wie geplant funktioniert. Warum sollte ich, bekomme eine Nachricht, KISS. 4 minutes ago, Amane said: Das dein CPU bis ans Limit bringt und die Daten verschlüsselt ablegt Warum? Mein Backup ist doch bei mir zu Hause, wüsste nicht warum ich das verschlüsseln sollte. 4 minutes ago, Amane said: inkrementelle Backups zulässt Oh no, das soll ein Mirror sein bei mir, inkrementell ist auch nicht 3-2-1. 5 minutes ago, Amane said: weil du noch zusätzlich eine Datenbank mit dem Änderungsdatum und Hash Wert befüllst Wenn das dein einziges Backup ist verstehe ich das. 1 Quote Link to comment
Amane Posted March 29 Share Posted March 29 (edited) Just now, ich777 said: Warum? Mein Backup ist doch bei mir zu Hause, wüsste nicht warum ich das verschlüsseln sollte. Das Skript ist für Google Bucket (Mit gcsfuse direkt gemountet). 😉 Das Backup ist quasi das Backup vom Backup, für das normale nutze ich auch LuckyBackup.. Edited March 29 by Amane Quote Link to comment
HGWBLN Posted March 29 Author Share Posted March 29 1 hour ago, ich777 said: Naja, du schaltest die Synology an und dann zieht praktisch die Synology das Backup von deinem Server. Ja, das mag durchaus Sinn machen, aber ich möchte gerne alle Docker zentral auf dem Unraid laufen lassen. Trotzdem vielen Dank für den Hinweis. Quote Link to comment
ich777 Posted March 29 Share Posted March 29 19 minutes ago, HGWBLN said: Trotzdem vielen Dank für den Hinweis. Kein ding, versteh ich zwar nicht wirklich weil es anders doch wirklich einfacher/sinnhafter wäre bzw. auch aus Sicherheitstechnischer Sicht besser wäre, aber wenn das Ding sowieso bei dir zu Hause steht is es auch egal. Solange es für dich funktioniert alles gut. 1 Quote Link to comment
saber1 Posted March 29 Share Posted March 29 1 hour ago, HGWBLN said: aber ich möchte gerne alle Docker zentral auf dem Unraid laufen lassen. Ich gehe davon aus, das Deine Syno ebenfalls bei Dir zu Hause steht? Dann ist es eigentlich egal. Aber besser ist es, wenn die Maschine, auf der das Backup abgelegt wird, nur Leseberechtigung auf der zu sichernden Maschine hat. Falls die Backup-Maschine kompromittiert wird, kann der "entfernte" Rechner nicht ebenfalls kompromittiert werden. Das war hiermit gemeint: 47 minutes ago, ich777 said: auch aus Sicherheitstechnischer Sicht besser wäre, 1 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.