NoPaste

virt_backup

von mig
SNIPPET_DESC:
Bash script to Backup KVM Vms
SNIPPET_CREATION_TIME:
19.11.2021 07:21:15
SNIPPET_PRUNE_TIME:
19.12.2021 07:21:15

SNIPPET_TEXT:
  1. #!/bin/bash
  2.  
  3. unset TRY_RUN
  4. #Uncomment the following line to get a TRY RUN (no actions taken just output)
  5. #TRY_RUN="TRUE"
  6. cmd_eval ()
  7. { if [ ! -z "$TRY_RUN" ]; then
  8.     echo "$*"
  9.     return 0
  10. else
  11.     eval "$*"
  12.     if [ $? -ne 0 ]; then
  13.         loging "Failed to execute $*"
  14.         loging "exiting"
  15.         return 1
  16.     fi
  17.     return 0
  18. fi }
  19.  
  20.  
  21. unset DEBUG
  22. #Uncomment the following line to get debuging ouput
  23. DEBUG="TRUE"
  24. #Use this function to echo text
  25. debugecho ()
  26. { if [ ! -z "$DEBUG" ]; then echo "$*"; fi }
  27.  
  28. if [ ! -z "$DEBUG" ]; then
  29.     RSYNC_OPTION="-avhW --inplace --chmod u=rw,g=rw,o=r  --progress"
  30. else
  31.     RSYNC_OPTION="-ahW --inplace --chmod u=rw,g=rw,o=r"
  32. fi
  33. # Optional add S to options
  34. LOGENTRYNAME=backup_virtual_machines
  35. unset SYSTEMD_LOGING
  36.  
  37. { if [ ! -z "$TRY_RUN" ]; then
  38.     unset SYSTEMD_LOGING="TRUE"
  39. else
  40.     SYSTEMD_LOGING="TRUE"
  41. fi }
  42.  
  43.  
  44. #scriptname for systemd loging
  45. loging ()
  46. { if [ ! -z "$SYSTEMD_LOGING" ]; then systemd-cat -t "$LOGENTRYNAME" echo "$*"; fi }
  47.  
  48. SCRIPTNAME=backup_virtual_machines
  49. #scriptname for systemd logging
  50.  
  51.  
  52. #connect to the right kvm Instance
  53. export LIBVIRT_DEFAULT_URI='qemu:///system'
  54. #debian default connect virsh to qemu:///session for non-root
  55.  
  56. #Path to the Backup
  57. BACKUPPATH="/srv/backup/virtual_machines/autobackup/"
  58.  
  59. # List domains
  60. DOMAINS=$(virsh list --all | tail -n +3 | awk '{print $2}')
  61. debugecho "DOMAINS: $DOMAINS"
  62.  
  63. # Loop over the DOMAINS
  64. for DOMAIN in $DOMAINS; do
  65.  
  66.     debugecho "### STARTING with Domain: $DOMAIN ###"
  67.  
  68.         # Generate the backup folder URI - this is something you should
  69.         # change/check
  70.         BACKUPFOLDER="$BACKUPPATH$DOMAIN/"
  71.         mkdir -p $BACKUPFOLDER
  72.    
  73.         # Get the target disk
  74.         TARGETS=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $3}')
  75.    
  76.         # Get the image page
  77.         IMAGES=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $4}')
  78.  
  79.     #only for running Domains
  80.         STATE=$(virsh dominfo $DOMAIN | grep "State" | cut -d " " -f 11)
  81.         if [ "$STATE" = "running" ]; then
  82.         debugecho "$Domain is running"
  83.         debugecho "Starting backup for running $DOMAIN on $(date +'%d-%m-%Y %H:%M:%S')"
  84.         loging "Starting backup for running $DOMAIN on $(date +'%d-%m-%Y %H:%M:%S')"
  85.    
  86.         # Create the snapshot/disk specification
  87.         DISKSPEC=""
  88.    
  89.         for TARGET in $TARGETS; do
  90.                 DISKSPEC="$DISKSPEC --diskspec $TARGET,snapshot=external"
  91.         done
  92.          
  93.         cmd_eval "virsh snapshot-create-as --domain $DOMAIN --name "backupSNAP-$DOMAIN" --no-metadata --atomic --disk-only $DISKSPEC 1>/dev/null 2>&1"
  94.         if [ $? -ne 0 ]; then
  95.             debugecho "Failed to create snapshot for $DOMAIN --> exiting"
  96.                 loging "Failed to create snapshot for $DOMAIN --> exiting"
  97.                 exit 1
  98.         fi
  99.         debugecho "Snapshot for $DOMAIN created"
  100.    
  101.         # Copy disk image
  102.         for IMAGE in $IMAGES; do
  103.             STARTZEIT=$(date "+%s")
  104.                 NAME=$(basename $IMAGE)
  105.                     # cp $IMAGE $BACKUPFOLDER/$NAMEqem  
  106.                     # pv $IMAGE > $BACKUPFOLDER/$NAME
  107.                 cmd_eval "rsync $RSYNC_OPTION $IMAGE $BACKUPFOLDER/$NAME"
  108.             if [ $? -ne 0 ]; then
  109.                    loging "Failed to copy snapshot for $DOMAIN --> exiting"
  110.                    exit 1
  111.             fi
  112.             ENDZEIT=$(date "+%s")
  113.             debugecho "Backup done: $IMAGE to $BACKUPFOLDER/$NAME in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  114.             loging "Backup done: $IMAGE to $BACKUPFOLDER/$NAME in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  115.         done
  116.        
  117.         # Merge changes back
  118.         BACKUPIMAGES=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $4}')
  119.         STARTZEIT=$(date "+%s")
  120.         for TARGET in $TARGETS; do
  121.                 cmd_eval "virsh blockcommit $DOMAIN $TARGET --active --pivot 1>/dev/null 2>&1"
  122.             if [ $? -ne 0 ]; then
  123.                 loging "Failed to revert snapshot for $DOMAIN  --> exiting"
  124.                 exit 1
  125.             fi
  126.         done
  127.         ENDZEIT=$(date "+%s")
  128.         debugecho "Reverting Snapshot done for $IMAGE in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  129.         loging "Reverting Snapshot done for $IMAGE in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  130.    
  131.         # Cleanup left over backups
  132.         for BACKUP in $BACKUPIMAGES; do
  133.             if [[ $BACKUP =~ .*backupSNAP.* ]]
  134.             then
  135.                 cmd_eval "rm -f $BACKUP"
  136.                 else
  137.                     loging "Filename $DOMAIN snapshot doesent include scurity token  --> exiting"
  138.                     exit 1
  139.                 fi
  140.    
  141.         done
  142.    
  143.         # Dump the configuration information.
  144.         cmd_eval "virsh dumpxml $DOMAIN > $BACKUPFOLDER/$DOMAIN.xml 1>/dev/null 2>&1"
  145.     else
  146.         debugecho "$Domain is not running"
  147.         loging "Starting copy for not running $DOMAIN on $(date +'%d-%m-%Y %H:%M:%S')"
  148.         # For not running Domains just copy the disks
  149.         # no snnapshot and merge needed
  150.         # Copy disk image
  151.         for IMAGE in $IMAGES; do
  152.             STARTZEIT=$(date "+%s")
  153.                 NAME=$(basename $IMAGE)
  154.                     # cp $IMAGE $BACKUPFOLDER/$NAMEqem  
  155.                     # pv $IMAGE > $BACKUPFOLDER/$NAME
  156.                 cmd_eval "rsync $RSYNC_OPTION  $IMAGE $BACKUPFOLDER/$NAME"
  157.             if [ $? -ne 0 ]; then
  158.                    loging "Failed to copy $IMAGE for $DOMAIN --> exiting"
  159.                    exit 1
  160.             fi
  161.             ENDZEIT=$(date "+%s")
  162.             debugecho "Backup done: $IMAGE to $BACKUPFOLDER/$NAME in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  163.             loging "Backup done: $IMAGE to $BACKUPFOLDER/$NAME in: "$(( $ENDZEIT - $STARTZEIT ))" sekunden"
  164.         done
  165.         cmd_eval "virsh dumpxml $DOMAIN > $BACKUPFOLDER/$DOMAIN.xml 1>/dev/null 2>&1"
  166.     fi
  167.     debugecho "### Finished backup of $DOMAIN at $(date +'%d-%m-%Y %H:%M:%S') ###"
  168.     loging "### Finished backup of $DOMAIN at $(date +'%d-%m-%Y %H:%M:%S') ###"
  169. done
  170.  
  171. exit 0

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN