fuel-virtualbox/functions/vm.sh

244 lines
7.4 KiB
Bash
Executable File

#!/bin/bash
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# This file contains the functions to manage VMs in through VirtualBox CLI
source ./functions/shell.sh
get_vm_base_path() {
echo `execute VBoxManage list systemproperties | egrep '^Default machine folder' | sed 's/^Default machine folder\:[ \t]*//'`
}
get_vms_running() {
echo `execute VBoxManage list runningvms | sed 's/[ \t]*{.*}//' | sed 's/^"//' | sed 's/"$//'`
}
get_vms_present() {
echo `execute VBoxManage list vms | sed 's/[ \t]*{.*}//' | sed 's/^"//' | sed 's/"$//'`
}
is_vm_running() {
name=$1
list=$(get_vms_running)
# Check that the list of running VMs contains the given VM
for name_in_list in $list; do
if [[ "${name_in_list}" == "${name}" ]]; then
return 0
fi
done
return 1
}
is_vm_present() {
name=$1
list=$(get_vms_present)
for name_in_list in $list; do
if [[ "${name_in_list}" == "${name}" ]]; then
return 0
fi
done
return 1
}
check_running_vms() {
OIFS=$IFS
IFS=","
local hostonly_interfaces=$1
local list_running_vms=$(execute VBoxManage list runningvms | sed 's/\" {/\",{/g')
for vm_name in $list_running_vms; do
vm_name=$(echo $vm_name | grep "\"" | sed 's/"//g')
vm_names+="${vm_name},"
done
for i in $vm_names; do
for j in $hostonly_interfaces; do
running_vm=`execute VBoxManage showvminfo $i | grep "${j}"`
if [[ $? -eq 0 ]]; then
echo "The \"${i}\" VM uses host-only interface \"${j}\" and it cannot be removed...."
echo "You should turn off the \"${i}\" virtual machine, run the script again and then the host-only interface will be deleted. Aborting..."
exit 1
fi
done
done
IFS=$OIFS
}
create_vm() {
name=$1
nic=$2
cpu_cores=$3
memory_mb=$4
disk_mb=$5
os='RedHat_64'
# There is a chance that some files are left from previous VM instance
vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
vm_path="${vm_base_path}/${name}/"
execute rm -rf "${vm_path}"
# Create virtual machine with the right name and type (assuming CentOS)
execute VBoxManage createvm --name $name --ostype $os --register
# Set the real-time clock (RTC) operate in UTC time
# Set memory and CPU parameters
# Set video memory to 16MB, so VirtualBox does not complain about "non-optimal" settings in the UI
execute VBoxManage modifyvm $name --rtcuseutc on --memory $memory_mb --cpus $cpu_cores --vram 16
# Configure main network interface for management/PXE network
add_hostonly_adapter_to_vm $name 1 "${nic}"
execute VBoxManage modifyvm $name --boot1 disk --boot2 dvd --boot3 net --boot4 none
# Configure storage controllers
execute VBoxManage storagectl $name --name 'IDE' --add ide --hostiocache on
execute VBoxManage storagectl $name --name 'SATA' --add sata --hostiocache on
# Create and attach the main hard drive
add_disk_to_vm $name 0 $disk_mb
}
add_hostonly_adapter_to_vm() {
name=$1
id=$2
nic=$3
echo "Adding hostonly adapter to ${name} and bridging with host NIC ${nic}..."
# Add Intel PRO/1000 MT Desktop (82540EM) card to VM. The card is 1Gbps.
execute VBoxManage modifyvm $name --nic${id} hostonly --hostonlyadapter${id} "${nic}" --nictype${id} 82540EM \
--cableconnected${id} on --macaddress${id} auto
execute VBoxManage modifyvm $name --nicpromisc${id} allow-all
}
add_nat_adapter_to_vm() {
name=$1
id=$2
nat_network=$3
echo "Adding NAT adapter to ${name} for outbound network access through the host system..."
# Add Intel PRO/1000 MT Desktop (82540EM) card to VM. The card is 1Gbps.
execute VBoxManage modifyvm $name --nic${id} nat --nictype${id} 82540EM \
--cableconnected${id} on --macaddress${id} auto --natnet${id} "${nat_network}"
execute VBoxManage modifyvm $name --nicpromisc${id} allow-all
}
add_disk_to_vm() {
vm_name=$1
port=$2
disk_mb=$3
echo "Adding disk to ${vm_name}, with size ${disk_mb} Mb..."
vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
vm_disk_path="${vm_base_path}/${vm_name}"
vm_disk_file="${vm_disk_path}/${vm_name}_${port}.vdi"
execute VBoxManage createhd --filename "${vm_disk_file}" --size $disk_mb --format VDI
execute VBoxManage storageattach $vm_name --storagectl 'SATA' --port $port --device 0 --type hdd --medium "${vm_disk_file}"
# Add serial numbers of disks to slave nodes
echo "Adding serial numbers of disks to ${vm_name}..."
execute VBoxManage setextradata $vm_name "VBoxInternal/Devices/ahci/0/Config/Port${port}/SerialNumber" "VBOX-MIRANTIS-VHD${port}"
}
delete_vm() {
name=$1
vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
vm_path="${vm_base_path}/${name}/"
# Power off VM, if it's running
count=0
while is_vm_running $name; do
echo "Stopping Virtual Machine ${name}..."
execute VBoxManage controlvm $name poweroff
if [[ "${count}" != 5 ]]; then
count=$((count+1))
sleep 5
else
echo "VirtualBox cannot stop VM ${name}... Exiting"
exit 1
fi
done
echo "Deleting existing virtual machine ${name}..."
while is_vm_present $name
do
execute VBoxManage unregistervm $name --delete
done
# Virtualbox does not fully delete VM file structure, so we need to delete the corresponding directory with files as well
execute rm -rf "${vm_path}"
}
delete_vms_multiple() {
name_prefix=$1
list=$(get_vms_present)
# Loop over the list of VMs and delete them, if its name matches the given refix
for name in $list; do
if [[ $name == $name_prefix* ]]; then
echo "Found existing VM: ${name}. Deleting it..."
delete_vm $name
fi
done
}
start_vm() {
name=$1
# Just start it
if [[ $headless == 1 ]]; then
execute VBoxManage startvm $name --type headless
else
execute VBoxManage startvm $name
fi
if [ -n "${boot_line}" ]; then
sleep 3
# Pressing/releasing escape key
execute VBoxManage controlvm ${name} keyboardputscancode 01 81
for letter in ${boot_line}; do
execute VBoxManage controlvm ${name} keyboardputscancode ${letter}
done
fi
}
mount_iso_to_vm() {
name=$1
iso_path=$2
# Mount ISO to the VM
execute VBoxManage storageattach $name --storagectl 'IDE' --port 0 --device 0 --type dvddrive --medium "${iso_path}"
}
enable_network_boot_for_vm() {
name=$1
# Set the right boot priority
execute VBoxManage modifyvm $name --boot1 net --boot2 disk --boot3 none --boot4 none --nicbootprio1 1
}
enable_vrde(){
name=$1
port=${2:-$RDPport}
# Enable VRDE, set port and address
execute VBoxManage modifyvm $name --vrde on
execute VBoxManage modifyvm $name --vrdeport $port
}