Proper Windows 7/8/10 support

This commit adds enchantments and proper support for Windows 7/8/10:
 * more verbose messages.
 * by default all network interfaces will be removed.
 * some code cleanup and regexp fixes.
 * added sleeps for some network operations.
 * proper support for windows full filenames.

Change-Id: Ic56f8d114bdaf83dd12b76dd6cc46eaa8d74da52
Closes-Bug: #1524558
Closes-Bug: #1496042
This commit is contained in:
Maksim Malchuk 2015-12-29 21:06:32 +03:00
parent c72ba0c289
commit 85e5cf4817
12 changed files with 76 additions and 73 deletions

View File

@ -45,3 +45,4 @@ else
exit 1 exit 1
fi fi
fi fi
echo "Done."

View File

@ -26,3 +26,4 @@ source ./functions/network.sh
# Delete all VMs from the previous Mirantis OpenStack installation # Delete all VMs from the previous Mirantis OpenStack installation
delete_vms_multiple $vm_name_prefix delete_vms_multiple $vm_name_prefix
echo "Done."

View File

@ -25,12 +25,13 @@ source ./config.sh
source ./functions/vm.sh source ./functions/vm.sh
source ./functions/network.sh source ./functions/network.sh
# Delete host-only interfaces echo "Deleting old interfaces if exists..."
if [[ "$rm_network" == "0" ]]; then if [[ "$rm_network" == "0" ]]; then
delete_fuel_ifaces delete_fuel_ifaces
else else
delete_all_hostonly_interfaces delete_all_hostonly_interfaces
fi fi
echo
# Create the required host-only interfaces # Create the required host-only interfaces
for ip in $fuel_master_ips; do for ip in $fuel_master_ips; do

View File

@ -32,8 +32,8 @@ get_fuel_name_ifaces
name="${vm_name_prefix}master" name="${vm_name_prefix}master"
# Create master node VM
create_vm $name "${host_nic_name[0]}" $vm_master_cpu_cores $vm_master_memory_mb $vm_master_disk_mb create_vm $name "${host_nic_name[0]}" $vm_master_cpu_cores $vm_master_memory_mb $vm_master_disk_mb
echo
# Add additional NICs # Add additional NICs
add_hostonly_adapter_to_vm $name 2 "${host_nic_name[1]}" add_hostonly_adapter_to_vm $name 2 "${host_nic_name[1]}"
@ -49,7 +49,7 @@ if [ ${headless} -eq 1 ]; then
enable_vrde $name ${RDPport} enable_vrde $name ${RDPport}
fi fi
if [ "$skipfuelmenu" = "yes" ]; then if [ "${skipfuelmenu}" = "yes" ]; then
cmdline="$(grep 'append initrd' ../iso/isolinux/isolinux.cfg -m1 2> /dev/null | sed -e 's/^[ ]*append//')" cmdline="$(grep 'append initrd' ../iso/isolinux/isolinux.cfg -m1 2> /dev/null | sed -e 's/^[ ]*append//')"
cmdline="${cmdline:- initrd=initrd.img net.ifnames=0 biosdevname=0 ks=hd:sr0:/ks.cfg ip=10.20.0.2::10.20.0.1:255.255.255.0:fuel.domain.tld:eth0:off::: dns1=10.20.0.1 selinux=0}" cmdline="${cmdline:- initrd=initrd.img net.ifnames=0 biosdevname=0 ks=hd:sr0:/ks.cfg ip=10.20.0.2::10.20.0.1:255.255.255.0:fuel.domain.tld:eth0:off::: dns1=10.20.0.1 selinux=0}"
boot_line="$(translate "$cmdline showmenu=no"$'\n')" boot_line="$(translate "$cmdline showmenu=no"$'\n')"

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
# Copyright 2013 Mirantis, Inc. # Copyright 2013 Mirantis, Inc.
# #

View File

@ -140,4 +140,4 @@ esac
echo "OK" echo "OK"
# Report success # Report success
echo "Setup is done." echo "Done."

View File

@ -26,13 +26,10 @@ pxe_path=`ls -1t drivers/*.*rom 2>/dev/null | head -1`
# Every Mirantis OpenStack machine name will start from this prefix # Every Mirantis OpenStack machine name will start from this prefix
vm_name_prefix=fuel- vm_name_prefix=fuel-
# By default, all available network interfaces vboxnet won't be removed, # By default, all available vbox network interfaces will be removed.
# if their IP addresses don't match with fuel_master_ips (10.20.0.1 172.16.0.254
# 172.16.1.1)
# If you want to remove all existing vbox interfaces, then use rm_network=1
# 0 - don't remove all vbox networks. Remove only fuel networks if they exist # 0 - don't remove all vbox networks. Remove only fuel networks if they exist
# 1 - remove all vbox networks # 1 - remove all vbox networks
rm_network=0 rm_network=1
# Please add the IPs accordingly if you going to create non-default NICs number # Please add the IPs accordingly if you going to create non-default NICs number
# 10.20.0.1/24 - Mirantis OpenStack Admin network # 10.20.0.1/24 - Mirantis OpenStack Admin network

View File

@ -19,7 +19,8 @@
source ./functions/shell.sh source ./functions/shell.sh
get_hostonly_interfaces() { get_hostonly_interfaces() {
echo -e `execute VBoxManage list hostonlyifs | grep '^Name' | sed 's/^Name\:[ \t]*//' | uniq | tr "\\n" ","` local ifaces=`execute VBoxManage list hostonlyifs | egrep '^Name' | sed 's/^Name\:\s*//' | uniq | tr "\\n" ","`
echo -e "${ifaces}"
} }
get_fuel_ifaces() { get_fuel_ifaces() {
@ -32,7 +33,7 @@ get_fuel_ifaces() {
fuel_networks+="$fuel_network " fuel_networks+="$fuel_network "
done done
for ip in $fuel_networks; do for ip in $fuel_networks; do
fuel_iface=`execute VBoxManage list hostonlyifs | grep -B5 $ip | grep '^Name' | sed 's/^Name\:[ \t]*//' | uniq | tr "\\n" ","` fuel_iface=`execute VBoxManage list hostonlyifs | egrep -B3 $ip | egrep '^Name' | sed 's/^Name\:\s*//' | uniq | tr "\\n" ","`
fuel_ifaces+="$fuel_iface" fuel_ifaces+="$fuel_iface"
done done
echo $fuel_ifaces echo $fuel_ifaces
@ -64,7 +65,7 @@ is_hostonly_interface_present() {
;; ;;
esac esac
# Call VBoxManage directly instead of function, due to changed IFS # Call VBoxManage directly instead of function, due to changed IFS
local found_iface=(`execute VBoxManage list hostonlyifs | grep -E "Name: + $name\$" | awk '/Name/ { $1 = ""; print substr($0, 2) }'`) local found_iface=(`execute VBoxManage list hostonlyifs | egrep "Name: + $name\$" | awk '/Name/ { $1 = ""; print substr($0, 2) }'`)
# Change default divider back # Change default divider back
case "$(execute uname)" in case "$(execute uname)" in
CYGWIN*) CYGWIN*)
@ -86,26 +87,21 @@ check_if_iface_settings_applied() {
ip=$2 ip=$2
mask=$3 mask=$3
echo "Verifying interface $name has IP $ip and mask $mask properly set." echo "Verifying interface $name has IP $ip and mask $mask properly set."
# Please leave 12 spaces in place - these are placed intentionally OIFS=$IFS
case "$(execute uname)" in case "$(execute uname)" in
CYGWIN*) CYGWIN*)
OIFS=$IFS
IFS="," IFS=","
;; ;;
*) *)
;;
esac
local new_name=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: $name\$" | awk '/Name/ { $1 = ""; print substr($0, 2) }'`)
case "$(execute uname)" in
CYGWIN*)
IFS=$OIFS IFS=$OIFS
;; ;;
*)
;;
esac esac
local new_ip=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: $name\$" | awk '/IPAddress:/ {print $2}'`) local new_name=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: + $name\$" | awk '/Name/ { $1 = ""; print substr($0, 2) }'`)
local new_mask=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: $name\$" | awk '/NetworkMask:/ {print $2}'`) IFS=$OIFS
local new_dhcp=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: $name\$" | awk '/DHCP:/ {print $2}'`) sleep 2s
local new_ip=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: + $name\$" | awk '/IPAddress:/ { print $2 }'`)
local new_mask=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: + $name\$" | awk '/NetworkMask:/ { print $2 }'`)
local new_dhcp=(`execute VBoxManage list hostonlyifs | egrep -A9 "Name: + $name\$" | awk '/DHCP:/ { print $2 }'`)
# First verify if we checking correct interface # First verify if we checking correct interface
if [[ "$name" != "$new_name" ]]; then if [[ "$name" != "$new_name" ]]; then
echo "Checking $name but found settings for $new_name" echo "Checking $name but found settings for $new_name"
@ -130,7 +126,7 @@ check_if_iface_settings_applied() {
create_hostonly_interfaces() { create_hostonly_interfaces() {
# Creating host-only interface # Creating host-only interface
local ip=$1 local ip=$1
echo "Creating host-only interface" echo "Creating host-only interface..."
local id=`execute VBoxManage hostonlyif create | sed "s/'/_/g" | cut -d "_" -f2 | sed "s/^_//" | sed "s/_$//"` local id=`execute VBoxManage hostonlyif create | sed "s/'/_/g" | cut -d "_" -f2 | sed "s/^_//" | sed "s/_$//"`
# If it does not exist after creation, let's abort # If it does not exist after creation, let's abort
if ! is_hostonly_interface_present "$id"; then if ! is_hostonly_interface_present "$id"; then
@ -143,14 +139,12 @@ create_hostonly_interfaces() {
echo "Disabling DHCP server on interface: $name..." echo "Disabling DHCP server on interface: $name..."
# These magic 1 second sleeps around DHCP config are required under Windows/Cygwin # These magic 1 second sleeps around DHCP config are required under Windows/Cygwin
# due to VBoxSvc COM server accepts next request before previous one is actually finished. # due to VBoxSvc COM server accepts next request before previous one is actually finished.
sleep 1s sleep 2s
execute VBoxManage dhcpserver remove --ifname "$name" 2>/dev/null execute VBoxManage dhcpserver remove --ifname "$name" 2>/dev/null
sleep 1s sleep 2s
# Set up IP address and network mask # Set up IP address and network mask
echo "Configuring IP address $ip and network mask $mask on interface: $name..." echo "Configuring IP address $ip and network mask $mask on interface: $name..."
set -x
execute VBoxManage hostonlyif ipconfig "$id" --ip $ip --netmask $mask execute VBoxManage hostonlyif ipconfig "$id" --ip $ip --netmask $mask
set +x
# Check what we have created actually. # Check what we have created actually.
# Sometimes VBox occasionally fails to apply settings to the last IFace under Windows # Sometimes VBox occasionally fails to apply settings to the last IFace under Windows
if !(check_if_iface_settings_applied "$id" $ip $mask); then if !(check_if_iface_settings_applied "$id" $ip $mask); then
@ -161,6 +155,7 @@ create_hostonly_interfaces() {
echo "Aborting." echo "Aborting."
exit 1 exit 1
fi fi
echo
} }
# Checking that the interface has been removed # Checking that the interface has been removed
@ -187,18 +182,22 @@ delete_fuel_ifaces() {
check_removed_iface "$interface" check_removed_iface "$interface"
done done
fi fi
echo "Done."
} }
delete_all_hostonly_interfaces() { delete_all_hostonly_interfaces() {
# All the hostonly interfaces will be removed # All the hostonly interfaces will be removed
local all_hostonly_interfaces=$(get_hostonly_interfaces) local all_hostonly_interfaces=$(get_hostonly_interfaces)
# Checking that the running virtual machines don't use removable host-only interfaces # Checking that the running virtual machines don't use removable host-only interfaces
check_running_vms "$all_hostonly_interfaces" check_running_vms $all_hostonly_interfaces
OIFS=$IFS;IFS=",";list=(`execute VBoxManage list hostonlyifs | grep '^Name' | sed 's/^Name\:[ \t]*//' | uniq | tr "\\n" ","`);IFS=$OIFS OIFS=$IFS
IFS=","
# Delete every single hostonly interface in the system # Delete every single hostonly interface in the system
for interface in "${list[@]}"; do for interface in $all_hostonly_interfaces; do
echo "Deleting host-only interface: $interface..." IFS=$OIFS
execute VBoxManage hostonlyif remove "$interface" echo "Deleting host-only interface: ${interface}..."
check_removed_iface "$interface" execute VBoxManage hostonlyif remove "${interface}"
check_removed_iface "${interface}"
done done
echo "Done."
} }

0
functions/shell.sh Normal file → Executable file
View File

0
functions/translate.sh Normal file → Executable file
View File

View File

@ -19,7 +19,7 @@
source ./functions/shell.sh source ./functions/shell.sh
get_vm_base_path() { get_vm_base_path() {
echo `execute VBoxManage list systemproperties | grep '^Default machine folder' | sed 's/^Default machine folder\:[ \t]*//'` echo `execute VBoxManage list systemproperties | egrep '^Default machine folder' | sed 's/^Default machine folder\:\s*//'`
} }
get_vms_running() { get_vms_running() {
@ -36,7 +36,7 @@ is_vm_running() {
# Check that the list of running VMs contains the given VM # Check that the list of running VMs contains the given VM
for name_in_list in $list; do for name_in_list in $list; do
if [[ "$name_in_list" == "$name" ]]; then if [[ "${name_in_list}" == "${name}" ]]; then
return 0 return 0
fi fi
done done
@ -48,7 +48,7 @@ is_vm_present() {
list=$(get_vms_present) list=$(get_vms_present)
for name_in_list in $list; do for name_in_list in $list; do
if [[ "$name_in_list" == "$name" ]]; then if [[ "${name_in_list}" == "${name}" ]]; then
return 0 return 0
fi fi
done done
@ -62,14 +62,14 @@ check_running_vms() {
local list_running_vms=$(execute VBoxManage list runningvms | sed 's/\" {/\",{/g') local list_running_vms=$(execute VBoxManage list runningvms | sed 's/\" {/\",{/g')
for vm_name in $list_running_vms; do for vm_name in $list_running_vms; do
vm_name=$(echo $vm_name | grep "\"" | sed 's/"//g') vm_name=$(echo $vm_name | grep "\"" | sed 's/"//g')
vm_names+="$vm_name," vm_names+="${vm_name},"
done done
for i in $vm_names; do for i in $vm_names; do
for j in $hostonly_interfaces; do for j in $hostonly_interfaces; do
running_vm=`execute VBoxManage showvminfo $i | grep "$j"` running_vm=`execute VBoxManage showvminfo $i | grep "${j}"`
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
echo "The \"$i\" VM uses host-only interface \"$j\" and it cannot be removed...." 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..." 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 exit 1
fi fi
done done
@ -86,9 +86,9 @@ create_vm() {
os='RedHat_64' os='RedHat_64'
# There is a chance that some files are left from previous VM instance # There is a chance that some files are left from previous VM instance
vm_base_path=$(get_vm_base_path) vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
vm_path="$vm_base_path/$name/" vm_path="${vm_base_path}/${name}/"
execute rm -rf "$vm_path" execute rm -rf "${vm_path}"
# Create virtual machine with the right name and type (assuming CentOS) # Create virtual machine with the right name and type (assuming CentOS)
execute VBoxManage createvm --name $name --ostype $os --register execute VBoxManage createvm --name $name --ostype $os --register
@ -99,7 +99,7 @@ create_vm() {
execute VBoxManage modifyvm $name --rtcuseutc on --memory $memory_mb --cpus $cpu_cores --vram 16 execute VBoxManage modifyvm $name --rtcuseutc on --memory $memory_mb --cpus $cpu_cores --vram 16
# Configure main network interface for management/PXE network # Configure main network interface for management/PXE network
add_hostonly_adapter_to_vm $name 1 "$nic" add_hostonly_adapter_to_vm $name 1 "${nic}"
execute VBoxManage modifyvm $name --boot1 disk --boot2 dvd --boot3 net --boot4 none execute VBoxManage modifyvm $name --boot1 disk --boot2 dvd --boot3 net --boot4 none
# Configure storage controllers # Configure storage controllers
@ -117,10 +117,10 @@ add_hostonly_adapter_to_vm() {
name=$1 name=$1
id=$2 id=$2
nic=$3 nic=$3
echo "Adding hostonly adapter to $name and bridging with host NIC $nic..." 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. # 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 \ execute VBoxManage modifyvm $name --nic${id} hostonly --hostonlyadapter${id} "${nic}" --nictype${id} 82540EM \
--cableconnected${id} on --macaddress${id} auto --cableconnected${id} on --macaddress${id} auto
execute VBoxManage modifyvm $name --nicpromisc${id} allow-all execute VBoxManage modifyvm $name --nicpromisc${id} allow-all
} }
@ -129,13 +129,12 @@ add_nat_adapter_to_vm() {
name=$1 name=$1
id=$2 id=$2
nat_network=$3 nat_network=$3
echo "Adding NAT adapter to $name for outbound network access through the host system..." 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. # Add Intel PRO/1000 MT Desktop (82540EM) card to VM. The card is 1Gbps.
execute VBoxManage modifyvm $name --nic${id} nat --nictype${id} 82540EM \ execute VBoxManage modifyvm $name --nic${id} nat --nictype${id} 82540EM \
--cableconnected${id} on --macaddress${id} auto --natnet${id} "${nat_network}" --cableconnected${id} on --macaddress${id} auto --natnet${id} "${nat_network}"
execute VBoxManage modifyvm $name --nicpromisc${id} allow-all execute VBoxManage modifyvm $name --nicpromisc${id} allow-all
execute VBoxManage controlvm $name setlinkstate${id} on
} }
add_disk_to_vm() { add_disk_to_vm() {
@ -143,46 +142,48 @@ add_disk_to_vm() {
port=$2 port=$2
disk_mb=$3 disk_mb=$3
echo "Adding disk to $vm_name, with size $disk_mb Mb..." echo "Adding disk to ${vm_name}, with size ${disk_mb} Mb..."
vm_disk_path="$(get_vm_base_path)/$vm_name/" vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
disk_name="${vm_name}_${port}" vm_disk_path="${vm_base_path}/${vm_name}"
disk_filename="${disk_name}.vdi" vm_disk_file="${vm_disk_path}/${vm_name}_${port}.vdi"
execute VBoxManage createhd --filename "$vm_disk_path/$disk_filename" --size $disk_mb --format VDI
execute VBoxManage storageattach $vm_name --storagectl 'SATA' --port $port --device 0 --type hdd --medium "$vm_disk_path/$disk_filename" 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 # Add serial numbers of disks to slave nodes
echo "Adding serial numbers of disks to $vm_name..." 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" execute VBoxManage setextradata $vm_name "VBoxInternal/Devices/ahci/0/Config/Port${port}/SerialNumber" "VBOX-MIRANTIS-VHD${port}"
} }
delete_vm() { delete_vm() {
name=$1 name=$1
vm_base_path=$(get_vm_base_path)
vm_path="$vm_base_path/$name/" vm_base_path=$(get_vm_base_path | sed 's/\\/\\\\/g')
vm_path="${vm_base_path}/${name}/"
# Power off VM, if it's running # Power off VM, if it's running
count=0 count=0
while is_vm_running $name; do while is_vm_running $name; do
echo "Stopping Virtual Machine $name..." echo "Stopping Virtual Machine ${name}..."
execute VBoxManage controlvm $name poweroff execute VBoxManage controlvm $name poweroff
if [[ "$count" != 5 ]]; then if [[ "${count}" != 5 ]]; then
count=$((count+1)) count=$((count+1))
sleep 5 sleep 5
else else
echo "VirtualBox cannot stop VM $name... Exiting" echo "VirtualBox cannot stop VM ${name}... Exiting"
exit 1 exit 1
fi fi
done done
echo "Deleting existing virtual machine $name..." echo "Deleting existing virtual machine ${name}..."
while is_vm_present $name while is_vm_present $name
do do
execute VBoxManage unregistervm $name --delete execute VBoxManage unregistervm $name --delete
done done
# Virtualbox does not fully delete VM file structure, so we need to delete the corresponding directory with files as well # 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" execute rm -rf "${vm_path}"
} }
delete_vms_multiple() { delete_vms_multiple() {
@ -192,7 +193,7 @@ delete_vms_multiple() {
# Loop over the list of VMs and delete them, if its name matches the given refix # Loop over the list of VMs and delete them, if its name matches the given refix
for name in $list; do for name in $list; do
if [[ $name == $name_prefix* ]]; then if [[ $name == $name_prefix* ]]; then
echo "Found existing VM: $name. Deleting it..." echo "Found existing VM: ${name}. Deleting it..."
delete_vm $name delete_vm $name
fi fi
done done
@ -208,7 +209,7 @@ start_vm() {
execute VBoxManage startvm $name execute VBoxManage startvm $name
fi fi
if [ -n "$boot_line" ]; then if [ -n "${boot_line}" ]; then
sleep 3 sleep 3
# Pressing/releasing escape key # Pressing/releasing escape key
execute VBoxManage controlvm ${name} keyboardputscancode 01 81 execute VBoxManage controlvm ${name} keyboardputscancode 01 81
@ -225,7 +226,7 @@ mount_iso_to_vm() {
iso_path=$2 iso_path=$2
# Mount ISO to the VM # Mount ISO to the VM
execute VBoxManage storageattach $name --storagectl "IDE" --port 0 --device 0 --type dvddrive --medium "$iso_path" execute VBoxManage storageattach $name --storagectl 'IDE' --port 0 --device 0 --type dvddrive --medium "${iso_path}"
} }
enable_network_boot_for_vm() { enable_network_boot_for_vm() {

View File

@ -27,14 +27,17 @@ case "$(execute uname)" in
;; ;;
esac esac
# Prepare the host system echo "Prepare the host system..."
./actions/prepare-environment.sh || exit 1 ./actions/prepare-environment.sh || exit 1
echo
# Check available memory on the host system echo "Check available memory on the host system..."
./actions/check-available-memory.sh || exit 1 ./actions/check-available-memory.sh || exit 1
echo
# Сlean previous installation if exists echo "Сlean previous installation if exists..."
./actions/clean-previous-installation.sh || exit 1 ./actions/clean-previous-installation.sh || exit 1
echo
# Сreate host-only interfaces # Сreate host-only interfaces
./actions/create-interfaces.sh || exit 1 ./actions/create-interfaces.sh || exit 1