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.
285 lines
12 KiB
285 lines
12 KiB
#!/bin/bash |
|
#EuryBOX vm functions file |
|
|
|
#Desc: rename a VM through libvirt |
|
#1 arg required: vm_name |
|
eurybox_vm_rename () |
|
{ |
|
local NAME=$1 |
|
local STATUS |
|
local DISKS |
|
local DISKS_NUM |
|
local NOW=$(date +"%Y_%m_%d@%H_%M_%S") |
|
local TMP_DESC="${EURYBOX_TMP_FOLDER}/${NAME}_${NOW}" |
|
local RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list --all | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
STATUS=$? |
|
if [[ $STATUS -eq 0 ]] |
|
then |
|
if [[ $RENAME_OUT == "" ]] |
|
then |
|
eurybox_display_message warning VM "Rename not possible on non-present vm: $NAME" |
|
else |
|
RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ !($RENAME_OUT == "") ]] |
|
then |
|
eurybox_display_message warning VM "Forcing stop of running vm: $NAME" |
|
RENAME_OUT=`sudo sh -c "virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME" 2>&1` |
|
fi |
|
eurybox_export_vm_config $NAME $TMP_DESC |
|
DISKS=( $(sudo virsh $EURYBOX_VIRSH_OPTIONS domblklist $NAME | awk '($2 != "-") {print $2}') ) |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM description dump: $NAME - error: $STATUS:\n$DISKS" |
|
else |
|
if [[ !($DISKS = "") ]] |
|
then |
|
DISKS_NUM=${#DISKS[@]} |
|
eurybox_display_message message VM "VM $NAME - $DISKS_NUM disk(s) found" |
|
for (( DISK_NUM=0;DISK_NUM<$DISKS_NUM;DISK_NUM++ )) |
|
do |
|
RENAME_OUT=`sudo mv ${DISKS[DISK_NUM]} ${DISKS[DISK_NUM]}_${NOW} 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM disk rename: $NAME - ${DISKS[DISK_NUM]} - error $STATUS:\n$RENAME_OUT" |
|
else |
|
eurybox_display_message debug VM "VM $NAME - disk renamed: ${DISKS[DISK_NUM]} -> ${DISKS[DISK_NUM]}_${NOW}" |
|
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` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM disk description update: $NAME - ${DISKS[DISK_NUM]} - error $STATUS:\n$RENAME_OUT" |
|
else |
|
sudo sh -c "echo \"$RENAME_OUT\" > $TMP_DESC" |
|
eurybox_display_message debug VM "VM $NAME - disk description renamed: ${DISKS[DISK_NUM]} -> ${DISKS[DISK_NUM]}_${NOW}" |
|
fi |
|
fi |
|
done |
|
else |
|
eurybox_display_message warning VM "No domain disk detected for VM $NAME" |
|
fi |
|
fi |
|
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` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM domain name description updated: $NAME - error $STATUS:\n$RENAME_OUT" |
|
else |
|
RENAME_OUT=`sudo sh -c "echo \"$RENAME_OUT\" > $TMP_DESC" 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error RENAME "VM $NAME - domain name description update failed - error $STATUS:\n$RENAME_OUT" |
|
else |
|
eurybox_display_message debug RENAME "VM $NAME - domain name description updated: $NAME -> ${NAME}_${NOW}" |
|
fi |
|
RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS undefine $NAME 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM domain name undefine: $NAME - error $STATUS:\n$RENAME_OUT" |
|
else |
|
RENAME_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS define $TMP_DESC 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "Error on VM domain name define: $TMP_DESC - error $STATUS:\n$RENAME_OUT" |
|
else |
|
eurybox_display_message message VM "VM renamed $NAME -> ${NAME}_${NOW}" |
|
fi |
|
fi |
|
fi |
|
fi |
|
else |
|
eurybox_display_message error VM "Virsh call issue - error $STATUS:\$RENAME_OUT" |
|
fi |
|
} |
|
|
|
#Desc: shutdown a VM through libvirt ACPI emulation (doesn't work for OS without ACPI support) |
|
#1 arg required: vm_name |
|
eurybox_vm_shutdown_acpi () |
|
{ |
|
local NAME=$1 |
|
local STATUS |
|
local VIRSH_OUT |
|
#Waiting for the VM to be stopped |
|
local EURYBOX_VM_NAME |
|
local EURYBOX_VM_STATE=1 |
|
local EURYBOX_VM_STOPPED=0 |
|
local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
while [[ ( $EURYBOX_VM_STATE -eq 1 ) && !( $NB_TRY_LEFT -eq 0 ) ]] |
|
do |
|
EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ -z "$EURYBOX_VM_NAME" ]] |
|
then |
|
EURYBOX_VM_STATE=0 |
|
else |
|
if [[ $EURYBOX_VM_STOPPED -eq 0 ]] |
|
then |
|
VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS shutdown $NAME 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
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" |
|
else |
|
EURYBOX_VM_STOPPED=1 |
|
eurybox_display_message message VM "Successfully initiated VM $NAME stop - waiting for vm poweroff" |
|
NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
fi |
|
else |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
eurybox_display_message debug VM "VM $NAME - still running - trying again in ${EURYBOX_ERROR_TEMPORISATION_TIME} seconds / $NB_TRY_LEFT left" |
|
fi |
|
sleep ${EURYBOX_ERROR_TEMPORISATION_TIME} |
|
fi |
|
done |
|
if [[ $NB_TRY_LEFT -eq 0 ]] |
|
then |
|
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" |
|
VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "VM $NAME - forced stop failed - error $STATUS:\n$VIRSH_OUT" |
|
else |
|
eurybox_display_message message VM "Successfully initiated VM $NAME forced stop" |
|
EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ -z "$EURYBOX_VM_NAME" ]] |
|
then |
|
eurybox_display_message message VM "VM $NAME - forced stop OK" |
|
else |
|
eurybox_display_message error VM "VM $NAME - forced stop failed - VM still running:\n$EURYBOX_VM_NAME" |
|
fi |
|
fi |
|
else |
|
eurybox_display_message message VM "VM $NAME - ACPI stop OK" |
|
fi |
|
} |
|
|
|
#Desc: shutdown a VM through ssh connection |
|
#4 arg required: vm_name vm_host vm_user vm_port |
|
eurybox_vm_shutdown_ssh () |
|
{ |
|
local NAME=$1 |
|
local HOST=$2 |
|
local USER=$3 |
|
local PORT=$4 |
|
local EURYBOX_VM_STATE=1 |
|
local EURYBOX_VM_STOPPED=0 |
|
local STATUS |
|
local EURYBOX_VM_NAME |
|
local SSH_OUT |
|
local VIRSH_OUT |
|
local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
while [[ ( $EURYBOX_VM_STATE -eq 1 ) && !( $NB_TRY_LEFT -eq 0 ) ]] |
|
do |
|
EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ -z "$EURYBOX_VM_NAME" ]] |
|
then |
|
EURYBOX_VM_STATE=0 |
|
else |
|
if [[ $EURYBOX_VM_STOPPED -eq 0 ]] |
|
then |
|
SSH_OUT=`ssh $EURYBOX_SSH_OPTIONS -p $PORT $USER@$HOST "halt -p >/dev/null &" 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
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" |
|
else |
|
EURYBOX_VM_STOPPED=1 |
|
eurybox_display_message debug VM "Successfully initiated vm $NAME stop - waiting for vm poweroff" |
|
NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
fi |
|
else |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
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" |
|
fi |
|
sleep ${EURYBOX_ERROR_TEMPORISATION_TIME} |
|
fi |
|
done |
|
if [[ $NB_TRY_LEFT -eq 0 ]] |
|
then |
|
eurybox_display_message warning VM "VM $NAME - SSH stop failed - VM still running after $EURYBOX_MAX_RETRY_ON_FAILURE\nForcing stop" |
|
VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS destroy $NAME 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
eurybox_display_message error VM "VM $NAME - forced stop failed - error $STATUS:\n$VIRSH_OUT" |
|
else |
|
eurybox_display_message message VM "Successfully initiated VM $NAME forced stop" |
|
EURYBOX_VM_NAME=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ -z "$EURYBOX_VM_NAME" ]] |
|
then |
|
eurybox_display_message message VM "VM $NAME - forced stop OK" |
|
else |
|
eurybox_display_message error VM "VM $NAME - forced stop failed - VM still running:\n$EURYBOX_VM_NAME" |
|
fi |
|
fi |
|
else |
|
eurybox_display_message message VM "VM $NAME - SSH stop OK" |
|
fi |
|
} |
|
|
|
#Desc: start a VM through libvirt and check via ssh startup success |
|
#4 arg required: vm_name vm_host vm_user vm_port |
|
eurybox_vm_start () |
|
{ |
|
local NAME=$1 |
|
local HOST=$2 |
|
local USER=$3 |
|
local PORT=$4 |
|
local STATUS |
|
local VM_OUT |
|
local EURYBOX_VM_AVAILABLE |
|
local VIRSH_OUT |
|
#Check if VM is operationnal (at network level) |
|
local EURYBOX_VM_STATE=0 |
|
local EURYBOX_VM_STARTED=0 |
|
local NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
while [[ ( $EURYBOX_VM_STATE -eq 0 ) && !( $NB_TRY_LEFT -eq 0 ) ]] |
|
do |
|
EURYBOX_VM_AVAILABLE=`ssh $EURYBOX_SSH_OPTIONS -p $PORT $USER@$HOST "touch eurybox_check_ssh_ok" 2>&1` |
|
STATUS=$? |
|
if [[ $STATUS -eq 0 ]] |
|
then |
|
EURYBOX_VM_STATE=1 |
|
else |
|
if [[ $EURYBOX_VM_STARTED -eq 0 ]] |
|
then |
|
VIRSH_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS start $NAME 2>&1` |
|
STATUS=$? |
|
if [[ !($STATUS -eq 0) ]] |
|
then |
|
VM_OUT=`sudo virsh $EURYBOX_VIRSH_OPTIONS list | awk '{ if ($2 == name) {print $2} }' name=$NAME 2>&1` |
|
if [[ -z "$VM_OUT" ]] |
|
then |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
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" |
|
else |
|
eurybox_display_message debug VM "VM $NAME already running - waiting for network contact" |
|
EURYBOX_VM_STARTED=1 |
|
NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
fi |
|
else |
|
EURYBOX_VM_STARTED=1 |
|
eurybox_display_message debug VM "Successfully initiated vm $NAME start - waiting for network contact" |
|
NB_TRY_LEFT=$EURYBOX_MAX_RETRY_ON_FAILURE |
|
fi |
|
else |
|
NB_TRY_LEFT=$(( $NB_TRY_LEFT - 1 )) |
|
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" |
|
fi |
|
sleep ${EURYBOX_ERROR_TEMPORISATION_TIME} |
|
fi |
|
done |
|
if [[ $NB_TRY_LEFT -eq 0 ]] |
|
then |
|
eurybox_display_message warning VM "VM $NAME - start failed - no network contact after $EURYBOX_MAX_RETRY_ON_FAILURE:\n${EURYBOX_VM_AVAILABLE}" |
|
else |
|
eurybox_display_message message VM "VM $NAME - start OK" |
|
fi |
|
} |
|
|
|
|