Highly Available and Scalable Information System
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
12 KiB

  1. #!/bin/bash
  2. #EuryBOX vm functions file
  3. #Desc: rename a VM through libvirt
  4. #1 arg required: vm_name
  5. eurybox_vm_rename ()
  6. {
  7. local NAME=$1
  8. local STATUS
  9. local DISKS
  10. local DISKS_NUM
  11. local NOW=$(date +"%Y_%m_%d@%H_%M_%S")
  12. local TMP_DESC="${EURYBOX_TMP_FOLDER}/${NAME}_${NOW}"
  13. local RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list --all | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  14. STATUS=$?
  15. if [[ $STATUS -eq 0 ]]
  16. then
  17. if [[ $RENAME_OUT == "" ]]
  18. then
  19. eurybox_display_message warning VM "Rename not possible on non-present vm: $NAME"
  20. else
  21. RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  22. if [[ !($RENAME_OUT == "") ]]
  23. then
  24. eurybox_display_message warning VM "Forcing stop of running vm: $NAME"
  25. RENAME_OUT=`sudo sh -c "virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME" 2>&1`
  26. fi
  27. eurybox_export_vm_config $NAME $TMP_DESC
  28. DISKS=( $(sudo virsh $EURYBOX_VIRSH_OPTIONS domblklist $NAME | awk '($2 != "-") {print $2}') )
  29. STATUS=$?
  30. if [[ !($STATUS -eq 0) ]]
  31. then
  32. eurybox_display_message error VM "Error on VM description dump: $NAME - error: $STATUS:\n$DISKS"
  33. else
  34. if [[ !($DISKS = "") ]]
  35. then
  36. DISKS_NUM=${#DISKS[@]}
  37. eurybox_display_message message VM "VM $NAME - $DISKS_NUM disk(s) found"
  38. for (( DISK_NUM=0;DISK_NUM<$DISKS_NUM;DISK_NUM++ ))
  39. do
  40. RENAME_OUT=`sudo mv ${DISKS[DISK_NUM]} ${DISKS[DISK_NUM]}_${NOW} 2>&1`
  41. STATUS=$?
  42. if [[ !($STATUS -eq 0) ]]
  43. then
  44. eurybox_display_message error VM "Error on VM disk rename: $NAME - ${DISKS[DISK_NUM]} - error $STATUS:\n$RENAME_OUT"
  45. else
  46. eurybox_display_message debug VM "VM $NAME - disk renamed: ${DISKS[DISK_NUM]} -> ${DISKS[DISK_NUM]}_${NOW}"
  47. RENAME_OUT=`sudo cat $TMP_DESC | awk '{ if($NF == "file=" sq disk_name sq "/>") { for(i=1; i<(NF); i++) { if(i==1) { disk=$i } else { disk=disk" "$i } } ; disk=disk" file=" sq disk_new_name sq "/>" ; print disk } else { print $0 } }' disk_name=${DISKS[DISK_NUM]} disk_new_name=${DISKS[DISK_NUM]}_${NOW} sq=\' 2>&1`
  48. STATUS=$?
  49. if [[ !($STATUS -eq 0) ]]
  50. then
  51. eurybox_display_message error VM "Error on VM disk description update: $NAME - ${DISKS[DISK_NUM]} - error $STATUS:\n$RENAME_OUT"
  52. else
  53. sudo sh -c "echo \"$RENAME_OUT\" > $TMP_DESC"
  54. eurybox_display_message debug VM "VM $NAME - disk description renamed: ${DISKS[DISK_NUM]} -> ${DISKS[DISK_NUM]}_${NOW}"
  55. fi
  56. fi
  57. done
  58. else
  59. eurybox_display_message warning VM "No domain disk detected for VM $NAME"
  60. fi
  61. fi
  62. RENAME_OUT=`sudo sh -c "cat $TMP_DESC | awk '{ if (\\\$NF == \"<name>\"name\"</name>\") {print \"<name>\"new_name\"</name>\"} else { if (\\\$0 !~ /<uuid>/) {print \\\$0} } }' name=$NAME new_name=${NAME}_${NOW}" 2>&1`
  63. STATUS=$?
  64. if [[ !($STATUS -eq 0) ]]
  65. then
  66. eurybox_display_message error VM "Error on VM domain name description updated: $NAME - error $STATUS:\n$RENAME_OUT"
  67. else
  68. RENAME_OUT=`sudo sh -c "echo \"$RENAME_OUT\" > $TMP_DESC" 2>&1`
  69. STATUS=$?
  70. if [[ !($STATUS -eq 0) ]]
  71. then
  72. eurybox_display_message error RENAME "VM $NAME - domain name description update failed - error $STATUS:\n$RENAME_OUT"
  73. else
  74. eurybox_display_message debug RENAME "VM $NAME - domain name description updated: $NAME -> ${NAME}_${NOW}"
  75. fi
  76. RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS undefine $NAME 2>&1`
  77. STATUS=$?
  78. if [[ !($STATUS -eq 0) ]]
  79. then
  80. eurybox_display_message error VM "Error on VM domain name undefine: $NAME - error $STATUS:\n$RENAME_OUT"
  81. else
  82. RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS define $TMP_DESC 2>&1`
  83. STATUS=$?
  84. if [[ !($STATUS -eq 0) ]]
  85. then
  86. eurybox_display_message error VM "Error on VM domain name define: $TMP_DESC - error $STATUS:\n$RENAME_OUT"
  87. else
  88. eurybox_display_message message VM "VM renamed $NAME -> ${NAME}_${NOW}"
  89. fi
  90. fi
  91. fi
  92. fi
  93. else
  94. eurybox_display_message error VM "Virsh call issue - error $STATUS:\$RENAME_OUT"
  95. fi
  96. }
  97. #Desc: shutdown a VM through libvirt ACPI emulation (doesn't work for OS without ACPI support)
  98. #1 arg required: vm_name
  99. eurybox_vm_shutdown_acpi ()
  100. {
  101. local NAME=$1
  102. local STATUS
  103. local VIRSH_OUT
  104. #Waiting for the VM to be stopped
  105. local EURYBOX_VM_NAME
  106. local EURYBOX_VM_STATE=1
  107. local EURYBOX_VM_STOPPED=0
  108. local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  109. while [[ ( $EURYBOX_VM_STATE -eq 1 ) && !( $NB_TRY_LEFT -eq 0 ) ]]
  110. do
  111. EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  112. if [[ -z "$EURYBOX_VM_NAME" ]]
  113. then
  114. EURYBOX_VM_STATE=0
  115. else
  116. if [[ $EURYBOX_VM_STOPPED -eq 0 ]]
  117. then
  118. VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS shutdown $NAME 2>&1`
  119. STATUS=$?
  120. if [[ !($STATUS -eq 0) ]]
  121. then
  122. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  123. eurybox_display_message debug VM "VM $NAME - stop failed - error $STATUS:\n$VIRSH_OUT\nTrying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds / $NB_TRY_LEFT left"
  124. else
  125. EURYBOX_VM_STOPPED=1
  126. eurybox_display_message message VM "Successfully initiated VM $NAME stop - waiting for vm poweroff"
  127. NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  128. fi
  129. else
  130. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  131. eurybox_display_message debug VM "VM $NAME - still running - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds / $NB_TRY_LEFT left"
  132. fi
  133. sleep ${EURYBOX_ERROR_TEMPORISATION_TIME}
  134. fi
  135. done
  136. if [[ $NB_TRY_LEFT -eq 0 ]]
  137. then
  138. eurybox_display_message warning VM "VM $NAME - ACPI stop failed - VM still running after $EURYBOX_MAX_RETRY_ON_FAILURE:\n$EURYBOX_VM_NAME\n error $STATUS:\n$VIRSH_OUT\nForcing stop"
  139. VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME 2>&1`
  140. STATUS=$?
  141. if [[ !($STATUS -eq 0) ]]
  142. then
  143. eurybox_display_message error VM "VM $NAME - forced stop failed - error $STATUS:\n$VIRSH_OUT"
  144. else
  145. eurybox_display_message message VM "Successfully initiated VM $NAME forced stop"
  146. EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  147. if [[ -z "$EURYBOX_VM_NAME" ]]
  148. then
  149. eurybox_display_message message VM "VM $NAME - forced stop OK"
  150. else
  151. eurybox_display_message error VM "VM $NAME - forced stop failed - VM still running:\n$EURYBOX_VM_NAME"
  152. fi
  153. fi
  154. else
  155. eurybox_display_message message VM "VM $NAME - ACPI stop OK"
  156. fi
  157. }
  158. #Desc: shutdown a VM through ssh connection
  159. #4 arg required: vm_name vm_host vm_user vm_port
  160. eurybox_vm_shutdown_ssh ()
  161. {
  162. local NAME=$1
  163. local HOST=$2
  164. local USER=$3
  165. local PORT=$4
  166. local EURYBOX_VM_STATE=1
  167. local EURYBOX_VM_STOPPED=0
  168. local STATUS
  169. local EURYBOX_VM_NAME
  170. local SSH_OUT
  171. local VIRSH_OUT
  172. local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  173. while [[ ( $EURYBOX_VM_STATE -eq 1 ) && !( $NB_TRY_LEFT -eq 0 ) ]]
  174. do
  175. EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  176. if [[ -z "$EURYBOX_VM_NAME" ]]
  177. then
  178. EURYBOX_VM_STATE=0
  179. else
  180. if [[ $EURYBOX_VM_STOPPED -eq 0 ]]
  181. then
  182. SSH_OUT=`ssh $EURYBOX_SSH_OPTIONS -p $PORT $USER@$HOST "halt -p >/dev/null &" 2>&1`
  183. STATUS=$?
  184. if [[ !($STATUS -eq 0) ]]
  185. then
  186. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  187. eurybox_display_message debug VM "VM $NAME - SSH stop failed - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds:\n$SSH_OUT\n$NB_TRY_LEFT left"
  188. else
  189. EURYBOX_VM_STOPPED=1
  190. eurybox_display_message debug VM "Successfully initiated vm $NAME stop - waiting for vm poweroff"
  191. NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  192. fi
  193. else
  194. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  195. eurybox_display_message debug VM "VM $NAME - still running - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds:\n$EURYBOX_VM_NAME\n$NB_TRY_LEFT left"
  196. fi
  197. sleep ${EURYBOX_ERROR_TEMPORISATION_TIME}
  198. fi
  199. done
  200. if [[ $NB_TRY_LEFT -eq 0 ]]
  201. then
  202. eurybox_display_message warning VM "VM $NAME - SSH stop failed - VM still running after $EURYBOX_MAX_RETRY_ON_FAILURE\nForcing stop"
  203. VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME 2>&1`
  204. STATUS=$?
  205. if [[ !($STATUS -eq 0) ]]
  206. then
  207. eurybox_display_message error VM "VM $NAME - forced stop failed - error $STATUS:\n$VIRSH_OUT"
  208. else
  209. eurybox_display_message message VM "Successfully initiated VM $NAME forced stop"
  210. EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  211. if [[ -z "$EURYBOX_VM_NAME" ]]
  212. then
  213. eurybox_display_message message VM "VM $NAME - forced stop OK"
  214. else
  215. eurybox_display_message error VM "VM $NAME - forced stop failed - VM still running:\n$EURYBOX_VM_NAME"
  216. fi
  217. fi
  218. else
  219. eurybox_display_message message VM "VM $NAME - SSH stop OK"
  220. fi
  221. }
  222. #Desc: start a VM through libvirt and check via ssh startup success
  223. #4 arg required: vm_name vm_host vm_user vm_port
  224. eurybox_vm_start ()
  225. {
  226. local NAME=$1
  227. local HOST=$2
  228. local USER=$3
  229. local PORT=$4
  230. local STATUS
  231. local VM_OUT
  232. local EURYBOX_VM_AVAILABLE
  233. local VIRSH_OUT
  234. #Check if VM is operationnal (at network level)
  235. local EURYBOX_VM_STATE=0
  236. local EURYBOX_VM_STARTED=0
  237. local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  238. while [[ ( $EURYBOX_VM_STATE -eq 0 ) && !( $NB_TRY_LEFT -eq 0 ) ]]
  239. do
  240. EURYBOX_VM_AVAILABLE=`ssh $EURYBOX_SSH_OPTIONS -p $PORT $USER@$HOST "touch eurybox_check_ssh_ok" 2>&1`
  241. STATUS=$?
  242. if [[ $STATUS -eq 0 ]]
  243. then
  244. EURYBOX_VM_STATE=1
  245. else
  246. if [[ $EURYBOX_VM_STARTED -eq 0 ]]
  247. then
  248. VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS start $NAME 2>&1`
  249. STATUS=$?
  250. if [[ !($STATUS -eq 0) ]]
  251. then
  252. VM_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1`
  253. if [[ -z "$VM_OUT" ]]
  254. then
  255. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  256. eurybox_display_message debug VM "Error on vm $NAME start - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds:\n$VIRSH_OUT\n$NB_TRY_LEFT left"
  257. else
  258. eurybox_display_message debug VM "VM $NAME already running - waiting for network contact"
  259. EURYBOX_VM_STARTED=1
  260. NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  261. fi
  262. else
  263. EURYBOX_VM_STARTED=1
  264. eurybox_display_message debug VM "Successfully initiated vm $NAME start - waiting for network contact"
  265. NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE
  266. fi
  267. else
  268. NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 ))
  269. eurybox_display_message debug VM "VM $NAME - still unreachable - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds\n$EURYBOX_VM_AVAILABLE\n$NB_TRY_LEFT left"
  270. fi
  271. sleep ${EURYBOX_ERROR_TEMPORISATION_TIME}
  272. fi
  273. done
  274. if [[ $NB_TRY_LEFT -eq 0 ]]
  275. then
  276. eurybox_display_message warning VM "VM $NAME - start failed - no network contact after $EURYBOX_MAX_RETRY_ON_FAILURE:\n${EURYBOX_VM_AVAILABLE}"
  277. else
  278. eurybox_display_message message VM "VM $NAME - start OK"
  279. fi
  280. }