Advertisement
Guest User

Untitled

a guest
Nov 20th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.49 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3.  
  4. ####################################################################
  5. # #
  6. # WARNING - PLEASE CONSIDER THIS A WORK IN PROGRESS. I HAVE TESTED #
  7. # IT ON MY SERVER AND THERE WAS NO ISSUE BUT THAT DOESNT MEAN IN #
  8. # ANY WAY IT IS FREE FROM BUGS/ISSUS SO PLEASE USE AT YOUR OWN #
  9. # RISK UNTIL IT HAS BEEN TESTED FURTHER - WARNING #
  10. # #
  11. ####################################################################
  12.  
  13.  
  14. ####################################################################
  15. # #
  16. # unraid-autovmbackup copyright 2015-2016, Daniel Jackson (danioj) #
  17. # #
  18. ####################################################################
  19.  
  20.  
  21. # for support please goto script support page:
  22. #
  23. # https://lime-technology.com/forum/index.php?topic=47986
  24.  
  25.  
  26. # what is the scripts' official name.
  27.  
  28. official_script_name="script"
  29.  
  30.  
  31. # default 0 but set the master switch to 1 if you want to enable the script otherwise it will not run.
  32.  
  33. enabled="1"
  34.  
  35.  
  36. # set the name of the script to a variable so it can be used.
  37.  
  38. me=`basename "$0"`
  39.  
  40.  
  41. # this script has been created to automate the backup of unRAID vm's vdisks(s) to a specified location.
  42. # this script does not yet run using variables passed from the cli as yet but there is intention to do so if there is interest.
  43. # for now the variables below are what are needed to be ammended to have the script run.
  44.  
  45.  
  46. # Change Log
  47.  
  48. # v0.1 20160330.
  49. # initial release.
  50. #
  51. # notes: initial realease is more concept and to see if there is a need for it. it lacks basic error handling and recovery.
  52. # which could be developed later.
  53.  
  54. # v0.2 20160330.
  55. # bug fixes.
  56. #
  57. # changed how the bash script is recognising the failed shutdown flag as after testing even a failed shutdown would start a backup.
  58. # changed default mins to wait for shutdown to 6.
  59.  
  60. # v0.3 20160415.
  61. # bug fixes and enhancements.
  62. #
  63. # applied strickter naming conventions to variables.
  64. # cleaned up the code, added comments, removed unecessary 'do' loops.
  65. # added input validation and verification.
  66. # added addition status messages. applied a bit more consistency.
  67. # added ability to deal with vm's with names that have spaces in them.
  68. # vms now seperated by "new line" not space.
  69. # added rsync copy over standard nix cp command.
  70. # added backup of vm xml configuration.
  71. # added option to add timestamps to backup files.
  72. # added script name check for version control.
  73. # added option to enable / disable the script.
  74. # added option to start vm after failure.
  75. # added option to "dry-run" copy operation - note all other functionality is enabled.
  76. # added ability to ignore vm's which are not installed on the system.
  77. # set defaults for all options to 0.
  78. # added guidence for options and inputs.
  79. # added constraint to only backup .img vdisks so to skip installation media etc.
  80. # changed method of obtaining vdisks list.
  81. # fixed issue which had script fail if no vdisks were present.
  82.  
  83. # v0.4 20160416.
  84. # administration.
  85. #
  86. # script name changed to facilitate code being added to github.
  87.  
  88. # bug tracker (order by severity)
  89.  
  90. # <reference> <description> <link to post> <severity> <date added> <by whome> <accepted/refected> <comment>
  91.  
  92.  
  93. # to do list
  94.  
  95. # core
  96. # error capturing and handling -- started (v0.3).
  97. # apply stricter naming conventions -- done (v0.3).
  98. # code clean up -- ongoing (v0.3)
  99. # input validation and verification -- done (v0.3).
  100. # logging.
  101. # clean up status messages -- done (v0.3).
  102. # deal with vm's named with spaces -- done (v0.3).
  103.  
  104. # possible improvements
  105. # use rsync to copy the vdisks instead of copy -- done (v0.3).
  106.  
  107. # possible future features
  108. # backup vm xml file -- done (v0.3).
  109. # have the script run from variables passed in from the cli.
  110. # add timestamps to files -- done (v0.3).
  111. # add iterations of backups and number of backups to maintain at any given time.
  112. # plugin -- started (v0.3).
  113.  
  114. # plugin to-do's
  115. # basic structure and requirements -- done (v0.3)
  116. # git-hub account
  117. # ui validation via menus
  118. # .... much much more ....
  119.  
  120.  
  121. ##################################################### change these variables ###################################################
  122.  
  123.  
  124. # script variables
  125.  
  126.  
  127. # backup location to put vdisks.
  128. # e.g backup_location="/mnt/user/share/backup_folder/"
  129.  
  130. backup_location="/mnt/user/Backups/VM Auto Backups"
  131.  
  132.  
  133. # list of domains that will be backed up seperated by a new line.
  134. # e.g.:
  135. # vms_to_backup="
  136. # windows 10
  137. # ubuntu_main
  138. # mac_OSXv3
  139. # vm that doesnt exist on system"
  140.  
  141. vms_to_backup="
  142. Chicago-VPN
  143. London-VPN
  144. Sweden-VPN
  145. USEast-VPN
  146. macOS
  147. Windows10
  148. "
  149.  
  150.  
  151. # default is 0 but set this to 1 if you would like to actually copy and backup files.
  152.  
  153. actually_copy_files="1"
  154.  
  155.  
  156. # default is 0 but set this to 1 if you would like to add a timestamp to the backed up files.
  157.  
  158. timestamp_files="0"
  159.  
  160.  
  161. # default is 10. set this to the number of times you would like to check if a clean shutdown of a vm has been successfull.
  162.  
  163. clean_shutdown_checks="10"
  164.  
  165.  
  166. # default is 60. set this to the number of seconds to wait in between checks to see if a clean shutdown has been successfull.
  167.  
  168. seconds_to_wait="60"
  169.  
  170.  
  171. # default is 0 but set this to 1 if you would like to kill a vm if it cant be shutdown cleanly.
  172.  
  173. kill_vm_if_cant_shutdown="0"
  174.  
  175.  
  176. # default is 0 but set this to 1 if you would like to start a vm after it has successfully been backed up.
  177.  
  178. start_vm_after_backup="0"
  179.  
  180.  
  181. # default is 0 but set this to 1 if you would like to start a vm after it has failed to have been backed up.
  182.  
  183. start_vm_after_failure="0"
  184.  
  185.  
  186. ################################################## end of variables section #####################################################
  187.  
  188.  
  189.  
  190. ################################################### dont edit below here #######################################################
  191.  
  192.  
  193. # start of script.
  194.  
  195.  
  196. # check the name of the script is as it should be. if yes, continue. if no, exit.
  197.  
  198.  
  199. if [ "$me" == "$official_script_name" ]; then
  200.  
  201.  
  202. echo "information: official_script_name is $official_script_name. script name is valid. continuing."
  203.  
  204.  
  205. elif [ ! "$me" == "$official_script_name" ]; then
  206.  
  207.  
  208. echo "failure: official_script_name is $official_script_name. script name is invalid. exiting."
  209.  
  210. exit 1
  211.  
  212.  
  213. fi
  214.  
  215.  
  216. # check to see if the script has been enabled or disabled by the user. if yes, continue if no, exit. if input invalid, exit.
  217.  
  218.  
  219. if [[ "$enabled" =~ ^(0|1)$ ]]; then
  220.  
  221.  
  222. if [ "$enabled" -eq 1 ]; then
  223.  
  224.  
  225. echo "information: enabled is $enabled. script is enabled. continuing."
  226.  
  227.  
  228. elif [ ! "$enabled" -eq 1 ]; then
  229.  
  230.  
  231. echo "failure: enabled is $enabled. script is disabled. exiting."
  232.  
  233. exit 1
  234.  
  235. fi
  236.  
  237. else
  238.  
  239.  
  240. echo "failure: enabled is $enabled. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  241.  
  242. exit 1
  243.  
  244. fi
  245.  
  246.  
  247. # check to see if the backup_location specified by the user exists. if yes, continue if no, exit. if exists check if writable, if yes continue, if not exit. if input invalid, exit.
  248.  
  249.  
  250. if [ -d "$backup_location" ]; then
  251.  
  252.  
  253. echo "information: backup_location is $backup_location. this location exists. continuing."
  254.  
  255.  
  256. # if backup_location does exist check to see if the backup_location is writable.
  257.  
  258.  
  259. if [ -w "$backup_location" ]; then
  260.  
  261.  
  262. echo "information: backup_location is $backup_location. this location is writable. continuing."
  263.  
  264.  
  265. else
  266.  
  267.  
  268. echo "failure: backup_location is $backup_location. this location is not writable. exiting."
  269.  
  270. exit 1
  271.  
  272.  
  273. fi
  274.  
  275.  
  276. else
  277.  
  278.  
  279. echo "failure: backup_location is $backup_location. this location does not exist. exiting."
  280.  
  281. exit 1
  282.  
  283.  
  284. fi
  285.  
  286.  
  287. # validate the actually_copy_files option. if yes the rsync command line option for dry-run. if input invalid, exit.
  288.  
  289.  
  290. if [[ "$actually_copy_files" =~ ^(0|1)$ ]]; then
  291.  
  292.  
  293. if [ "$actually_copy_files" -eq 0 ]; then
  294.  
  295.  
  296. echo "information: actually_copy_files flag is 0. no files will be coppied."
  297.  
  298.  
  299. # create a variable which tells rsync to do a dry-run.
  300.  
  301. rsync_dry_run_option="n"
  302.  
  303.  
  304. elif [ "$actually_copy_files" -eq 1 ]; then
  305.  
  306.  
  307. echo "warning: actually_copy_files is 1. files will be coppied."
  308.  
  309.  
  310. fi
  311.  
  312.  
  313. else
  314.  
  315.  
  316. echo "failure: actually_copy_files is $actually_copy_files. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  317.  
  318. exit 1
  319.  
  320.  
  321. fi
  322.  
  323.  
  324. # check to see if i should add a timestamp to backed up files or not. if yes, continue if no, continue. if input invalid, exit.
  325.  
  326.  
  327. if [[ "$timestamp_files" =~ ^(0|1)$ ]]; then
  328.  
  329.  
  330. if [ "$timestamp_files" -eq 0 ]; then
  331.  
  332.  
  333. echo "information: timestamp_files is $timestamp_files. timestamp will not be added to backup files."
  334.  
  335.  
  336. elif [ "$timestamp_files" -eq 1 ]; then
  337.  
  338.  
  339. echo "information: timestamp_files is $timestamp_files. timestamp will be added to backup files."
  340.  
  341. # create a variable which is only used in rsync commands
  342.  
  343. timestamp=`date '+%m%d%Y_%H%M%p'`"_"
  344.  
  345. fi
  346.  
  347. else
  348.  
  349.  
  350. echo "failure: timestamp_files is $timestamp_files. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  351.  
  352. exit 1
  353.  
  354.  
  355. fi
  356.  
  357.  
  358. # check to see how many times i should check for vm shutdown. if yes, continue if no, continue if input invalid, exit.
  359.  
  360.  
  361. if [[ "$clean_shutdown_checks" =~ ^[0-9]+$ ]]; then
  362.  
  363.  
  364. if [ "$clean_shutdown_checks" -lt 5 ]; then
  365.  
  366.  
  367. echo "warning: clean_shutdown_checks is $clean_shutdown_checks. this is potentially an insufficient number of shutdown checks."
  368.  
  369.  
  370. elif [ "$clean_shutdown_checks" -gt 50 ]; then
  371.  
  372.  
  373. echo "warning: clean_shutdown_checks is $clean_shutdown_checks. this is a vast number of shutdown checks."
  374.  
  375.  
  376. elif [ "$clean_shutdown_checks" -ge 5 -a "$clean_shutdown_checks" -le 50 ]; then
  377.  
  378.  
  379. echo "information: clean_shutdown_checks is $clean_shutdown_checks. this is probably a sufficient number of shutdown checks."
  380.  
  381.  
  382. fi
  383.  
  384.  
  385. else
  386.  
  387.  
  388. echo "failure: clean_shutdown_checks is $clean_shutdown_checks. this is not a valid format. expecting a number between [0 - 1000000]. exiting."
  389.  
  390. exit 1
  391.  
  392.  
  393. fi
  394.  
  395.  
  396. # check to see how long i should wait between checks for vm shutdown. messages to user only. if input invalid, exit.
  397.  
  398.  
  399. if [[ "$seconds_to_wait" =~ ^[0-9]+$ ]]; then
  400.  
  401.  
  402. if [ "$seconds_to_wait" -lt 60 ]; then
  403.  
  404.  
  405. echo "warning: seconds_to_wait is $seconds_to_wait. this is potentially an insufficient number of seconds to wait between shutdown checks."
  406.  
  407.  
  408. elif [ "$seconds_to_wait" -gt 3000 ]; then
  409.  
  410.  
  411. echo "warning: seconds_to_wait is seconds_to_wait. this is a vast number of seconds to wait between shutdown checks."
  412.  
  413.  
  414. elif [ "$seconds_to_wait" -ge 60 -a "$seconds_to_wait" -le 3000 ]; then
  415.  
  416.  
  417. echo "information: seconds_to_wait is $seconds_to_wait. this is probably a sufficent number of seconds to wait between shutdown checks."
  418.  
  419. fi
  420.  
  421.  
  422. else
  423.  
  424.  
  425. echo "failure: seconds_to_wait is $seconds_to_wait. this is not a valid format. expecting a number between [0 - 1000000]. exiting."
  426.  
  427. exit 1
  428.  
  429.  
  430. fi
  431.  
  432.  
  433. # check to see if i should force kill the vm if i cant do a clean shutdown. if yes, continue if no, continue. if input invalid, exit.
  434.  
  435.  
  436. if [[ "$kill_vm_if_cant_shutdown" =~ ^(0|1)$ ]]; then
  437.  
  438.  
  439. if [ "$kill_vm_if_cant_shutdown" -eq 0 ]; then
  440.  
  441.  
  442. echo "warning: kill_vm_if_cant_shutdown is $kill_vm_if_cant_shutdown. vms will be forced to shutdown if a clean shutdown can not be detected."
  443.  
  444.  
  445. elif [ "$actually_copy_files" -eq 1 ]; then
  446.  
  447.  
  448. echo "information: kill_vm_if_cant_shutdown is $kill_vm_if_cant_shutdown. vms will not be forced to shutdown if a clean shutdown can not be detected."
  449.  
  450.  
  451. fi
  452.  
  453.  
  454. else
  455.  
  456.  
  457. echo "failure: kill_vm_if_cant_shutdown is $kill_vm_if_cant_shutdown. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  458.  
  459. exit 1
  460.  
  461.  
  462. fi
  463.  
  464.  
  465. # check to see if i should start vms after a successfull backup. if yes, continue if no, continue. if input invalid, exit.
  466.  
  467.  
  468. if [[ "$start_vm_after_backup" =~ ^(0|1)$ ]]; then
  469.  
  470.  
  471. if [ "$start_vm_after_backup" -eq 0 ]; then
  472.  
  473.  
  474. echo "warning: start_vm_after_backup is $start_vm_after_backup. vms will be started following successfull backup."
  475.  
  476.  
  477. elif [ "$actually_copy_files" -eq 1 ]; then
  478.  
  479.  
  480. echo "information: start_vm_after_backup is $start_vm_after_backup vms will not be started following a successfull backup."
  481.  
  482.  
  483. fi
  484.  
  485.  
  486. else
  487.  
  488.  
  489. echo "failure: start_vm_after_backup is $start_vm_after_backup. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  490.  
  491. exit 1
  492.  
  493.  
  494. fi
  495.  
  496.  
  497. # check to see if i should start vms after an unsuccessfull backup. if yes, continue if no, continue. if input invalid, exit.
  498.  
  499.  
  500. if [[ "$start_vm_after_failure" =~ ^(0|1)$ ]]; then
  501.  
  502.  
  503. if [ "$start_vm_after_failure" -eq 0 ]; then
  504.  
  505.  
  506. echo "warning: start_vm_after_failure is $start_vm_after_failure. vms will be started following an unsuccessfull backup."
  507.  
  508.  
  509. elif [ "$actually_copy_files" -eq 1 ]; then
  510.  
  511.  
  512. echo "information: start_vm_after_failure is $start_vm_after_failure. vms will not be started following an unsuccessfull backup."
  513.  
  514.  
  515. fi
  516.  
  517.  
  518. else
  519.  
  520.  
  521. echo "failure: start_vm_after_failure is $start_vm_after_failure. this is not a valid format. expecting [0 - no] or [1 - yes]. exiting."
  522.  
  523. exit 1
  524.  
  525.  
  526. fi
  527.  
  528.  
  529. echo "information: started attempt to backup "$vms_to_backup" to $backup_location"
  530.  
  531.  
  532. # set this to force the for loop to split on new lines and not spaces.
  533.  
  534.  
  535. IFS=$'\n'
  536.  
  537.  
  538. # loop through the vms in the list and try and back up thier associated xml configurations and vdisk(s).
  539.  
  540.  
  541. for vm in $vms_to_backup
  542.  
  543. do
  544.  
  545.  
  546. # get a list of the vm names installed on the system.
  547.  
  548.  
  549. vm_exists=$(virsh list --all --name)
  550.  
  551.  
  552. # assume the vm is not going to be backed up until it is found on the system
  553.  
  554. skip_vm="y"
  555.  
  556.  
  557. # check to see if the vm exists on the system to backup.
  558.  
  559.  
  560. for vmname in $vm_exists
  561.  
  562. do
  563.  
  564. # if the vm doesnt match then set the skip flag to y.
  565.  
  566.  
  567. if [ "$vm" == "$vmname" ] ; then
  568.  
  569.  
  570. # set a flag i am going to check later to indicate if i should skip this vm or not.
  571.  
  572. skip_vm="n"
  573.  
  574.  
  575. # skips current loop
  576.  
  577.  
  578. continue
  579.  
  580.  
  581. fi
  582.  
  583. done
  584.  
  585.  
  586. # if the skip flag was set in the previous section then we have to exit and move onto the next vm in the list.
  587.  
  588.  
  589. if [ "$skip_vm" == "y" ]; then
  590.  
  591.  
  592. echo "warning: $vm can not be found on the system. skipping vm."
  593.  
  594. skip_vm="n"
  595.  
  596.  
  597. # skips current loop.
  598.  
  599.  
  600. continue
  601.  
  602.  
  603. else
  604.  
  605.  
  606. echo "information: $vm can be found on the system. attempting backup."
  607.  
  608.  
  609. fi
  610.  
  611.  
  612. # lets create a directory named after the vm within backup_location to store the backup files.
  613.  
  614.  
  615. if [ ! -d $backup_location/$vm ] ; then
  616.  
  617.  
  618. echo "action: backup_location/$vm does not exist. creating it."
  619.  
  620.  
  621. # make the directory as it doesnt exist. added -v option to give a confirmation message to command line.
  622.  
  623.  
  624. mkdir -vp $backup_location/$vm
  625.  
  626.  
  627. else
  628.  
  629.  
  630. echo "information: $backup_location/$vm exists. continuing."
  631.  
  632.  
  633. fi
  634.  
  635.  
  636. # get the state of the vm.
  637.  
  638.  
  639. vm_state=$(virsh domstate "$vm")
  640.  
  641.  
  642. # resume the vm if it is suspended, based on testing this should be instant but will trap later if it has not resumed.
  643.  
  644.  
  645. if [ "$vm_state" == "paused" ]; then
  646.  
  647.  
  648. echo "action: $vm is $vm_state. resuming."
  649.  
  650.  
  651. # resume the vm.
  652.  
  653.  
  654. virsh resume "$vm"
  655.  
  656.  
  657. fi
  658.  
  659.  
  660. # get the state of the vm.
  661.  
  662.  
  663. vm_state=$(virsh domstate "$vm")
  664.  
  665.  
  666. # if the vm is running try and shut it down.
  667.  
  668.  
  669. if [ "$vm_state" == "running" ]; then
  670.  
  671.  
  672. echo "action: $vm is $vm_state. shutting down."
  673.  
  674.  
  675. # attempt to cleanly shutdown the vm.
  676.  
  677.  
  678. virsh shutdown "$vm"
  679.  
  680.  
  681. echo "information: performing $clean_shutdown_checks $seconds_to_wait second cycles waiting for $vm to shutdown cleanly"
  682.  
  683.  
  684. # the shutdown of the vm may last a while so we are going to check periodically based on global input variables.
  685.  
  686.  
  687. for (( i=1; i<=$clean_shutdown_checks; i++ ))
  688.  
  689. do
  690.  
  691. echo "information: clycle $i of $clean_shutdown_checks: waiting $seconds_to_wait seconds before checking if the vm has shutdown"
  692.  
  693.  
  694. # wait x seconds based on how many seconds the user wants to wait between checks for a clean shutdown.
  695.  
  696.  
  697. sleep $seconds_to_wait
  698.  
  699.  
  700. # get the state of the vm.
  701.  
  702.  
  703. vm_state=$(virsh domstate "$vm")
  704.  
  705.  
  706. # if the vm is running decide what to do.
  707.  
  708.  
  709. if [ "$vm_state" == "running" ]; then
  710.  
  711.  
  712. echo "information: $vm is $vm_state"
  713.  
  714.  
  715. # if we have already exhausted our wait time set by the script variables then its time to do soemthing else.
  716.  
  717.  
  718. if [ $i = "$clean_shutdown_checks" ] ; then
  719.  
  720.  
  721. # check if the user wants to kill the vm on failure of unclean shutdown.
  722.  
  723.  
  724. if [ "$kill_vm_if_cant_shutdown" -eq 1 ]; then
  725.  
  726.  
  727. echo "action: kill_vm_if_cant_shutdown is $kill_vm_if_cant_shutdown. killing vm."
  728.  
  729.  
  730. # destroy vm, based on testing this should be instant and without failure.
  731.  
  732. virsh destroy "$vm"
  733.  
  734.  
  735. # get the state of the vm.
  736.  
  737.  
  738. vm_state=$(virsh domstate "$vm")
  739.  
  740.  
  741. # if the vm is shut off then proceed or give up.
  742.  
  743.  
  744. if [ "$vm_state" == "shut off" ]; then
  745.  
  746.  
  747. # set a flag to check later to indicate whether to backup this vm or not.
  748.  
  749.  
  750. can_backup_vm="y"
  751.  
  752.  
  753. echo "information: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  754.  
  755.  
  756. break
  757.  
  758.  
  759. else
  760.  
  761.  
  762. # set a flag to check later to indicate whether to backup this vm or not.
  763.  
  764. can_backup_vm="n"
  765.  
  766. echo "failure: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  767.  
  768.  
  769. fi
  770.  
  771.  
  772. # if the user doesnt want to force a shutdown then there is nothing more to do so i cannot backup the vm.
  773.  
  774.  
  775. else
  776.  
  777. # set a flag to check later to indicate whether to backup this vm or not.
  778.  
  779. can_backup_vm="n"
  780.  
  781.  
  782. echo "failure: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  783.  
  784.  
  785. fi
  786.  
  787.  
  788. fi
  789.  
  790.  
  791. # if the vm is shut off then go onto backing it up.
  792.  
  793.  
  794. elif [ "$vm_state" == "shut off" ]; then
  795.  
  796.  
  797. # set a flag to check later to indicate whether to backup this vm or not.
  798.  
  799. can_backup_vm="y"
  800.  
  801.  
  802. echo "information: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  803.  
  804.  
  805. break
  806.  
  807.  
  808. # if the vm is in a state that is not explicitly defined then do nothing as it is unknown how to handle it.
  809.  
  810.  
  811. else
  812.  
  813.  
  814. # set a flag to check later to indicate whether to backup this vm or not.
  815.  
  816.  
  817. can_backup_vm="n"
  818.  
  819.  
  820. echo "failure: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  821.  
  822.  
  823.  
  824. fi
  825.  
  826.  
  827. done
  828.  
  829.  
  830. # if the vm is shut off then go straight onto backing it up.
  831.  
  832.  
  833. elif [ "$vm_state" == "shut off" ]; then
  834.  
  835.  
  836. # set a flag to check later to indicate whether to backup this vm or not.
  837.  
  838.  
  839. can_backup_vm="y"
  840.  
  841.  
  842. echo "information: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  843.  
  844.  
  845. # if the vm is suspended then something went wrong with the attempt to recover it earlier so do not attempt to backup.
  846.  
  847.  
  848. elif [ "$vm_state" == "suspended" ]; then
  849.  
  850.  
  851. # set a flag to check later to indicate whether to backup this vm or not.
  852.  
  853.  
  854. can_backup_vm="n"
  855.  
  856.  
  857. echo "failure: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  858.  
  859.  
  860. # if the vm is in a state that has not been explicitly defined then do nothing as it is unknown how to handle it.
  861.  
  862.  
  863. else
  864.  
  865.  
  866. # set a flag to check later to indicate whether to backup this vm or not.
  867.  
  868.  
  869. can_backup_vm="n"
  870.  
  871.  
  872. echo "failure: $vm is $vm_state. can_backup_vm set to $can_backup_vm"
  873.  
  874.  
  875. fi
  876.  
  877.  
  878. # check whether to backup the vm or not.
  879.  
  880.  
  881. if [[ "$can_backup_vm" == "y" ]]; then
  882.  
  883.  
  884. echo "action: can_backup_vm flag is $can_backup_vm. starting backup of $vm xml configuration and vdisk(s)."
  885.  
  886.  
  887. # dump the vm xml configuration locally first.
  888.  
  889.  
  890. virsh dumpxml "$vm" > "$vm.xml"
  891.  
  892.  
  893. echo "action: actually_copy_files is $actually_copy_files."
  894.  
  895.  
  896. # copy or pretend to copy the vdisk to the backup location specified by the user.
  897.  
  898.  
  899. rsync -av$rsync_dry_run_option "$vm.xml" "$backup_location/$vm/$timestamp$vm.xml"
  900.  
  901.  
  902. # delete the local copy of the xml configuration.
  903.  
  904.  
  905. rm "$vm.xml"
  906.  
  907.  
  908. # send a message to the user based on whether there was an actual copy or a dry-run.
  909.  
  910.  
  911. if [ "$actually_copy_files" -eq 0 ]; then
  912.  
  913.  
  914. echo "information: dry-run backup of $vm xml configuration to $backup_location/$vm/$timestamp$vm.xml complete."
  915.  
  916.  
  917. else
  918.  
  919.  
  920. echo "information: backup of $vm xml configuration to $backup_location/$vm/$timestamp$vm.xml complete."
  921.  
  922.  
  923. fi
  924.  
  925.  
  926.  
  927. # get the list of the vdisks associated with the vm and address them one by one.
  928.  
  929.  
  930. vdisks=$(virsh domblklist "$vm" --details | grep -v "^$" | grep -v "^Target" | grep -v "\-\-\-\-\-" | awk -F" {2,}" '{print $4}')
  931.  
  932.  
  933. # check for the header in vdisks to see if there are any disks
  934.  
  935.  
  936. if [ "$vdisks" == "Source" ]; then
  937.  
  938.  
  939. echo "warning: there are no vdisk(s) associated with $vm to backup."
  940.  
  941. fi
  942.  
  943.  
  944.  
  945. for disk in $vdisks
  946.  
  947.  
  948. do
  949.  
  950. if [ ! "$disk" == "Source" ]; then
  951.  
  952.  
  953. # get the filename of the disk without the path.
  954.  
  955.  
  956. new_disk=$(basename $disk)
  957.  
  958.  
  959. # check the extension of the disk to ensure only .img disks are coppied.
  960.  
  961.  
  962. if [ ! "${disk##*.}" == "img" ]; then
  963.  
  964.  
  965. echo "warning: $disk of $vm is not a vdisk. skipping."
  966.  
  967.  
  968. continue
  969.  
  970.  
  971. fi
  972.  
  973.  
  974. echo "action: actually_copy_files is $actually_copy_files."
  975.  
  976.  
  977. # copy or pretend to copy the vdisk to the backup location specified by the user.
  978.  
  979.  
  980. rsync -av$rsync_dry_run_option "$disk" "$backup_location/$vm/$timestamp$new_disk"
  981.  
  982.  
  983. # send a message to the user based on whether there was an actual copy or a dry-run.
  984.  
  985.  
  986. if [ "$actually_copy_files" -eq 0 ]; then
  987.  
  988.  
  989. echo "information: dry-run backup of $new_disk vdisk to $backup_location/$vm/$timestamp$new_disk complete."
  990.  
  991.  
  992. else
  993.  
  994.  
  995. echo "information: backup of $new_disk vdisk to $backup_location/$vm/$timestamp$new_disk complete."
  996.  
  997.  
  998. fi
  999.  
  1000. fi
  1001.  
  1002. done
  1003.  
  1004.  
  1005. # if start_vm_after_backup is set to 1 then start the vm but dont check that it has been successfull.
  1006.  
  1007.  
  1008. if [ "$start_vm_after_backup" -eq 1 ]; then
  1009.  
  1010.  
  1011. echo "action: start_vm_after_backup is $start_vm_after_backup. starting $vm."
  1012.  
  1013.  
  1014. # try and start the vm.
  1015.  
  1016. virsh start "$vm"
  1017.  
  1018.  
  1019. fi
  1020.  
  1021.  
  1022. else
  1023.  
  1024.  
  1025. # for whatever reason the backup attempt failed.
  1026.  
  1027.  
  1028. echo "failure: backup of "$vm" to $backup_location/$vm failed."
  1029.  
  1030.  
  1031. # if start_vm_after_failure is set to 1 then start the vm but dont check that it has been successfull.
  1032.  
  1033.  
  1034. if [ "$start_vm_after_failure" -eq 1 ]; then
  1035.  
  1036.  
  1037. echo "action: start_vm_after_failure is $start_vm_after_failure starting $vm."
  1038.  
  1039.  
  1040. # try and start the vm.
  1041.  
  1042. virsh start "$vm"
  1043.  
  1044.  
  1045. fi
  1046.  
  1047.  
  1048. fi
  1049.  
  1050.  
  1051. echo "information: backup of "$vm" to $backup_location/$vm completed."
  1052.  
  1053.  
  1054. done
  1055.  
  1056.  
  1057. echo "information: finished attempt to backup "$vms_to_backup" to $backup_location."
  1058.  
  1059.  
  1060. exit 0
  1061.  
  1062.  
  1063. # end of script
  1064.  
  1065.  
  1066. ################################################### dont edit above here #######################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement