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.

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
}