added initial version of scripts for running Fuel Web under VirtualBox

This commit is contained in:
Mirantis 2013-02-05 17:59:19 -08:00 committed by default
parent 95b13f85ec
commit f92493d4ef
9 changed files with 377 additions and 0 deletions

8
virtualbox/README Normal file
View File

@ -0,0 +1,8 @@
In order to successfully run Fuel Web under VirtualBox, you need to:
- download the official release (.iso) and place it under 'iso' directory
- run "./launch.sh". it will automatically pick up the iso, and will spin up master node and slave nodes
If there are any errors, the script will report them and abort.
If you want to change settings (number of OpenStack nodes, CPU, RAM, HDD), please refer to "config.sh".

View File

@ -0,0 +1,27 @@
#!/bin/bash
#
# This script creates a master node for the product, launches its installation,
# and waits for its completion
#
# Include the handy functions to operate VMs and track ISO installation progress
source config.sh
source functions/vm.sh
source functions/product.sh
# Create master node for the product
name="${vm_name_prefix}master"
delete_vm $name
create_vm $name $hostonly_interface_name $vm_master_cpu_cores $vm_master_memory_mb $vm_master_disk_mb
mount_iso_to_vm $name $iso_path
# Start virtual machine with the master node
start_vm $name
# Wait until the machine gets installed and Puppet completes its run
wait_for_product_vm_to_install $vm_master_ip $vm_master_username $vm_master_password "$vm_master_prompt"
# Report success
echo "Master node has been installed."

View File

@ -0,0 +1,46 @@
#!/bin/bash
#
# This script performs initial check and configuration of the host system. It:
# - verifies that all available command-line tools are present on the host system
# - check that there is no previous installation of Fuel Web (if there is one, the script deletes it)
# - creates host-only network interfaces
#
# We are avoiding using 'which' because of http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script
#
# Include the script with handy functions to operate VMs and VirtualBox networking
source config.sh
source functions/vm.sh
source functions/network.sh
# Check for expect
echo -n "Checking for 'expect'... "
expect -v >/dev/null 2>&1 || { echo >&2 "'expect' is not available in the path, but it's required. Aborting."; exit 1; }
echo "OK"
# Check for VirtualBox
echo -n "Checking for 'VBoxManage'... "
VBoxManage -v >/dev/null 2>&1 || { echo >&2 "'VBoxManage' is not available in the path, but it's required. Likely, VirtualBox is not installed. Aborting."; exit 1; }
echo "OK"
# Check for ISO image to be available
echo -n "Checking for Fuel Web ISO image... "
if [ -z $iso_path ]; then
echo "Fuel Web image is not found. Please download it and put under 'iso' directory."
exit 1
fi
echo "OK"
# Delete all VMs from the previous Fuel Web installation
delete_vms_multiple $vm_name_prefix
# Delete all host-only interfaces
delete_all_hostonly_interfaces
# Create the required host-only interface
create_hostonly_interface $hostonly_interface_name $hostonly_interface_ip $hostonly_interface_mask
# Report success
echo "Setup is done."

View File

@ -0,0 +1,25 @@
#!/bin/bash
#
# This script creates slaves node for the product, launches its installation,
# and waits for its completion
#
# Include the handy functions to operate VMs
source config.sh
source functions/vm.sh
# Create and start slave nodes
for idx in $(seq 1 $cluster_size); do
name="${vm_name_prefix}slave-${idx}"
delete_vm $name
create_vm $name $hostonly_interface_name $vm_slave_cpu_cores $vm_slave_memory_mb $vm_slave_disk_mb
enable_network_boot_for_vm $name
start_vm $name
done
# Report success
echo "Slave nodes have been created. They will boot over PXE and get discovered by the master node."
echo "To access master node, please point your browser to:"
echo " http://${vm_master_ip}:8000/"

32
virtualbox/config.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# The number of nodes for installing OpenStack on
# - for minimal non-HA installation, specify 2 (1 controller + 1 compute)
# - for minimal HA installation, specify 4 (3 controllers + 1 compute)
cluster_size=2
# Get the first available ISO from the directory 'iso'
iso_path=`ls -1 iso/*.iso 2>/dev/null | head -1`
# Every Fuel Web machine name will start from this prefix
vm_name_prefix=fuel-web-
# This host-only interface will be created and all networking will be done throught it
hostonly_interface_name=vboxnet0
hostonly_interface_ip=10.20.0.1
hostonly_interface_mask=255.255.255.0
# Master node settings
vm_master_cpu_cores=1
vm_master_memory_mb=1024
vm_master_disk_mb=16384
vm_master_ip=10.20.0.2
vm_master_username=root
vm_master_password=r00tme
vm_master_prompt='root@nailgun ~]#'
# Slave node settings
vm_slave_cpu_cores=1
vm_slave_memory_mb=768 # PXE boot might not work with lower values
vm_slave_disk_mb=16384

60
virtualbox/functions/network.sh Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash
# This file contains the functions to manage host-only interfaces in the system
get_hostonly_interfaces() {
echo -e `VBoxManage list hostonlyifs | grep '^Name' | sed 's/^Name\:[ \t]*//' | uniq`
}
is_hostonly_interface_present() {
name=$1
list=$(get_hostonly_interfaces)
# Check that the list of interfaces contains the given interface
if [[ $list = *$name* ]]; then
return 0
else
return 1
fi
}
create_hostonly_interface() {
name=$1
ip=$2
mask=$3
# Exit if the interface already exists (deleting it here is not safe, as VirtualBox creates hostonly adapters sequentially)
if is_hostonly_interface_present $name; then
echo "Fatal error. Interface $name cannot be created because it already exists. Exiting"
exit 1
fi
# Create the interface
echo "Creating host-only interface: $name..."
VBoxManage hostonlyif create
# If it does not exist after creation, let's abort
if ! is_hostonly_interface_present $name; then
echo "Fatal error. Interface $name does not exist after creation. Exiting"
exit 1
fi
# Disable DHCP
echo "Disabling DHCP server on interface: $name..."
VBoxManage dhcpserver remove --ifname $name 2>/dev/null
# Set up IP address and network mask
echo "Configuring IP address $ip and network mask $mask on interface: $name..."
VBoxManage hostonlyif ipconfig $name --ip $ip --netmask $mask
}
delete_all_hostonly_interfaces() {
list=$(get_hostonly_interfaces)
# Delete every single hostonly interface in the system
for interface in $list; do
echo "Deleting host-only interface: $interface..."
VBoxManage hostonlyif remove $interface
done
}

58
virtualbox/functions/product.sh Executable file
View File

@ -0,0 +1,58 @@
#!/bin/bash
# This file contains the functions to connect to the product VM and see if it became operational
is_product_vm_operational() {
ip=$1
username=$2
password=$3
prompt=$4
# Log in into the VM, see if Puppet has completed its run
# Looks a bit ugly, but 'end of expect' has to be in the very beginning of the line
result=$(
expect << ENDOFEXPECT
spawn ssh -oConnectTimeout=5 -oStrictHostKeyChecking=no -oCheckHostIP=no -oUserKnownHostsFile=/dev/null $username@$ip
expect "connect to host" exit
expect "*?assword:*"
send "$password\r"
expect "$prompt"
send "grep -o 'Finished catalog run' /var/log/puppet/bootstrap_admin_node.log\r"
expect "$prompt"
ENDOFEXPECT
)
# When you are launching command in a sub-shell, there are issues with IFS (internal field separator)
# and parsing output as a set of strings. So, we are saving original IFS, replacing it, iterating over lines,
# and changing it back to normal
#
# http://blog.edwards-research.com/2010/01/quick-bash-trick-looping-through-output-lines/
OIFS="${IFS}"
NIFS=$'\n'
IFS="${NIFS}"
for line in $result; do
IFS="${OIFS}"
if [[ $line = Finished* ]]; then
return 0;
fi
IFS="${NIFS}"
done
return 1
}
wait_for_product_vm_to_install() {
ip=$1
username=$2
password=$3
prompt=$4
echo "Waiting for product VM to install. Please do NOT abort the script..."
# Loop until master node gets successfully installed
while ! is_product_vm_operational $ip $username $password "$prompt"; do
sleep 5
done
}

110
virtualbox/functions/vm.sh Executable file
View File

@ -0,0 +1,110 @@
#!/bin/bash
# This file contains the functions to manage VMs in through VirtualBox CLI
get_vm_base_path() {
echo -e `VBoxManage list systemproperties | grep '^Default machine folder' | sed 's/^Default machine folder\:[ \t]*//'`
}
get_vms_running() {
echo -e `VBoxManage list runningvms | sed 's/[ \t]*{.*}//' | sed 's/^"//' | sed 's/"$//'`
}
get_vms_present() {
echo -e `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
if [[ $list = *$name* ]]; then
return 0
else
return 1
fi
}
create_vm() {
name=$1
main_network_interface=$2
cpu_cores=$3
memory_mb=$4
disk_mb=$5
vm_base_path=$(get_vm_base_path)
vm_disk_path="$vm_base_path/$name/$name.vdi"
# Create virtual machine with the right name and type (assuming CentOS)
VBoxManage createvm --name $name --ostype RedHat_64 --register
# Set the real-time clock (RTC) operate in UTC time
VBoxManage modifyvm $name --rtcuseutc on --memory $memory_mb --cpus $cpu_cores
# Configure network interfaces
VBoxManage modifyvm $name --nic1 hostonly --hostonlyadapter1 $main_network_interface --nictype1 Am79C973 \
--cableconnected1 on --macaddress1 auto
VBoxManage controlvm $name setlinkstate1 on
# Configure storage controllers
VBoxManage storagectl $name --name 'IDE' --add ide
VBoxManage storagectl $name --name 'SATA' --add sata
# Create and attach the main hard drive
VBoxManage createhd --filename "$vm_base_path/$name/$name" --size $disk_mb --format VDI
VBoxManage storageattach $name --storagectl 'SATA' --port 0 --device 0 --type hdd --medium "$vm_disk_path"
}
delete_vm() {
name=$1
vm_base_path=$(get_vm_base_path)
vm_path="$vm_base_path/$name/"
# Power off VM, if it's running
if is_vm_running $name; then
VBoxManage controlvm $name poweroff
fi
# Virtualbox does not fully delete VM file structure, so we need to delete the corresponding directory with files as well
if [ -d "$vm_path" ]; then
echo "Deleting existing virtual machine $name..."
VBoxManage unregistervm $name --delete
rm -rf "$vm_path"
fi
}
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
VBoxManage startvm $name --type headless
}
mount_iso_to_vm() {
name=$1
iso_path=$2
# Mount ISO to the VM
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
VBoxManage modifyvm $name --boot1 disk --boot2 net --boot3 none --boot4 none --nicbootprio1 1
}

11
virtualbox/launch.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
# Prepare the host system
./actions/prepare-environment.sh || exit 1
# Create and launch master node
./actions/master-node-create-and-install.sh || exit 1
# Create and launch slave nodes
./actions/slave-nodes-create-and-boot.sh || exit 1