#!/bin/bash # set -e # source job.conf BACKUP_DIR=/backups FILES=ROOT VOLS=VOL CONTAINERS=CON BACKUP_DIR_FILES=$BACKUP_DIR/$FILES BACKUP_DIR_VOLS=$BACKUP_DIR/$VOLS BACKUP_DIR_CONTAINERS=$BACKUP_DIR/$CONTAINERS CONFIG_DIR=/config SSH_CF_DIR=/root/.ssh read_config(){ #Konfiguration resetten source "/reset-conf.sh" if [ ! -f "$CONFIG_DIR/$1" ]; then echo config nicht vorhanden! exit 1 fi source "$CONFIG_DIR/$1" } gen_config(){ [ ! -f "$SSH_CF_DIR/id_rsa" ] && ssh-keygen -t rsa -b 4096 -f "$SSH_CF_DIR/id_rsa" -q -C "rdiff-backup-dockerized @ ${SSH_KEY_MARKER}" && chmod go-rwx $SSH_CF_DIR/id_rsa if [ ! -f "$SSH_CF_DIR/config" ]; then echo 'Host *' > "$SSH_CF_DIR/config" echo ' StrictHostKeyChecking no' >> "$SSH_CF_DIR/config" # echo ' UserKnownHostsFile=/dev/null' >> "$SSH_CF_DIR/config" chmod go-rwx $SSH_CF_DIR/config fi [ ! -f "$CONFIG_DIR/example_conf.sh" ] && cp /example_conf.sh "$CONFIG_DIR/example_conf.sh" } move_to_ROOT(){ # prüfen ob Ordner ROOT, VOL, CONT existieren # wenn nicht ROOT anlegen und alle bisher vorhandene Ordner dorthin verschieben [ ! -d "$BACKUP_DIR_FILES" ] && mkdir -p "$BACKUP_DIR_FILES" || return ### find /home/vitali/find_tests/ -maxdepth 1 -mindepth 1 -type d -name "CONT" -prune -or -name "VOL" -prune -or -name ROOT -prune -or -name "*" -exec mv -t /home/vitali/find_tests/ROOT/ {} + find "$BACKUP_DIR" -maxdepth 1 -mindepth 1 -type d -name "$CONTAINERS" -prune -or -name "$VOLS" -prune -or -name "$FILES" -prune -or -name "*" -exec mv -t "$BACKUP_DIR_FILES/" {} + # anschliessend VOL und CONT anlegen [ ! -d "$BACKUP_DIR_VOLS" ] && mkdir -p "$BACKUP_DIR_VOLS" [ ! -d "$BACKUP_DIR_CONTAINERS" ] && mkdir -p "$BACKUP_DIR_CONTAINERS" } ## Einzelne Backup-Jobs b_files(){ ## einzelne Dateien und Ordner mit rdiff-backup sichern # prüfen ob das backup-ordner existiert ... if [ ! -d "$2" ] then # ... und gegebenfals anlegen mkdir -p "$2" fi # die eigentliche Sicherung ... echo backup file[s]: "$1" rdiff-backup $RDIFF_BACKUP_OPTS "$1" "$2" # alle Sicherungen die älter als $DELETE_OLD_FILES löschen rdiff-backup --remove-older-than $DELETE_OLD_FILES --force "$2" } export_sql(){ ## Export einer MySQL-DB als SQL-Script in ein später (!) zu sicherndes Ordner echo dumb database: "$1" if [ "$MYSQL_CONTAINER" != '' ] then echo from container: "$MYSQL_CONTAINER" ssh ${REMOTE_USER}@${REMOTE_HOST} "docker exec -i \"$MYSQL_CONTAINER\" mysqldump -u \"$MYSQL_USER\" \"-p$MYSQL_PASS\" --events --routines --triggers --single-transaction --add-drop-database -B \"$1\" > \"$MYSQL_DUMP_DIR/$1.sql\"" else ssh ${REMOTE_USER}@${REMOTE_HOST} "mysqldump -u \"$MYSQL_USER\" \"-p$MYSQL_PASS\" --events --routines --triggers --single-transaction --add-drop-database -B \"$1\" > \"$MYSQL_DUMP_DIR/$1.sql\"" fi } b_vol(){ ## Docker volume mit rdiff-backup sichern sleep 1 } backup(){ read_config "$1" echo Start backup $1 echo ================================================== # Backupverzeichnisse einrichten move_to_ROOT # SCHRITT 1: # sichern der MySQL-Datenbanken auf dem remote host # es muss auf dem remote host genug Platz auf der Festplatte geben damit Dump erfolgen kann! if [ ${#MYSQL_DB[@]} -gt 0 ] then [ "$MYSQL_DUMP_DIR" != "" ] && [ "$MYSQL_DUMP_DIR" != "/" ] && ssh ${REMOTE_USER}@${REMOTE_HOST} "[ ! -d \"$MYSQL_DUMP_DIR\" ] && mkdir -p \"$MYSQL_DUMP_DIR\"" for db in "${MYSQL_DB[@]}" do # lokaler Export der DB als SQL export_sql "$db" done # Ordner mit SQL-Dateien sofort (!) sichern if [ "$MYSQL_CONTAINER" != '' ] then b_files "${REMOTE_USER}@${REMOTE_HOST}::${MYSQL_DUMP_DIR}" "$BACKUP_DIR_CONTAINERS/${MYSQL_CONTAINER}" else b_files "${REMOTE_USER}@${REMOTE_HOST}::${MYSQL_DUMP_DIR}" "${BACKUP_DIR_FILES}/${MYSQL_DUMP_DIR}" fi # die SQL-Dateien vom remote host wieder löschen [ "$MYSQL_DUMP_DIR" != "" ] && [ "$MYSQL_DUMP_DIR" != "/" ] && ssh ${REMOTE_USER}@${REMOTE_HOST} "rm -rf \"$MYSQL_DUMP_DIR/\"*.sql" fi # SCHRITT 2: # die Sicherung der Ordner (inklusive der SQL-Dump) for dir in "${FOLDERS[@]}" do # die eigentliche Sicherung ... b_files "${REMOTE_USER}@${REMOTE_HOST}::${dir}" "${BACKUP_DIR_FILES}/${dir}" # Liste der Sicherungen anzeigen if [ "$2" == "--list" ]; then rdiff-backup -l "${BACKUP_DIR_FILES}/${dir}" fi echo done echo Done backup $1 echo } ## Einzelne Restore-Jobs r_files(){ ## einzelne Dateien und Ordner mit rdiff-backup wiederherstellen echo restore file[s]: "$1" "$3" if [ "$3" != "" ]; then rdiff-backup --force -r "$3" "$1" "$2" else rdiff-backup --force -r now "$1" "$2" fi } import_sql(){ ## Import einer MySQL-DB von einem SQL-Script aus einem vorher (!) wiederherstellen Ordner if [ "$MYSQL_CONTAINER" != '' ] then FROM_FILE=${BACKUP_DIR_CONTAINERS}/${MYSQL_CONTAINER}/${1}.sql else FROM_FILE=${BACKUP_DIR_FILES}/${MYSQL_DUMP_DIR}/${1}.sql fi r_files "$FROM_FILE" "${REMOTE_USER}@${REMOTE_HOST}::${MYSQL_DUMP_DIR}/${1}.sql" "$2" if [ "$MYSQL_CONTAINER" != '' ] then ssh ${REMOTE_USER}@${REMOTE_HOST} "docker exec -i \"$MYSQL_CONTAINER\" mysql -u \"$MYSQL_USER\" \"-p$MYSQL_PASS\" < \"$MYSQL_DUMP_DIR/${1}.sql\"" else ssh ${REMOTE_USER}@${REMOTE_HOST} "mysql -u \"$MYSQL_USER\" \"-p$MYSQL_PASS\" < \"$MYSQL_DUMP_DIR/${1}.sql\"" fi [ "$MYSQL_DUMP_DIR" != "" ] && [ "$MYSQL_DUMP_DIR" != "/" ] && ssh ${REMOTE_USER}@${REMOTE_HOST} "rm -rf \"$MYSQL_DUMP_DIR/${1}.sql\"" } r_vol(){ ## Docker volume mit rdiff-backup wiederherstellen sleep 1 } r_mysql_cont(){ ## Import einer MySQL-DB von einem SQL-Script aus einem vorher (!) wiederherstellen Ordner in ein Container sleep 1 } restore(){ read_config "$1" echo Start restore $1 to $2 echo ================================================== # SCHRITT 1: # Alle Dateien und Ordner aus dem letzten Backup wiederherstellen if [ ${#MYSQL_DB[@]} -gt 0 ] then #FOLDERS+=("$MYSQL_DUMP_DIR") ## jede SQL-Datei einzeln hochladen for db in "${MYSQL_DB[@]}" do echo restore database: "$db" import_sql "$db" "$2" done fi for dir in "${FOLDERS[@]}" do # die eigentliche Wiederherstellung ... r_files "${BACKUP_DIR_FILES}/${dir}" "${REMOTE_USER}@${REMOTE_HOST}::${dir}" "$2" done echo Done restore $1 echo } test_function(){ read_config "$1" echo $REMOTE_HOST } list(){ read_config "$1" echo Show backups of $1 echo ================================================== # neue Konfiguration lesen #source "$CONFIG_DIR/$1" if [ ${#MYSQL_DB[@]} -gt 0 ] then FOLDERS+=("$MYSQL_DUMP_DIR") fi for dir in "${FOLDERS[@]}" do echo show backups for file[s]: "$dir" rdiff-backup -l "${BACKUP_DIR_FILES}/${dir}" echo done echo Done show $1 echo } if [ "$1" == "--gen-config" ]; then gen_config elif [ "$1" == "--backup" ]; then shift backup "$@" elif [ "$1" == "--restore" ]; then shift restore "$@" elif [ "$1" == "--list" ]; then shift list "$@" elif [ "$1" == "--bash" ]; then shift /bin/bash "$@" elif [ "$1" == "--testit" ]; then shift test_function "$@" else echo "usage ?" fi