fuel-main/virtualbox/functions/product.sh

230 lines
7.8 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 for connecting to Fuel VM, checking if the installation process completed
# and Fuel became operational, and also enabling outbound network/internet access for this VM through the
# host system
ssh_options='-oConnectTimeout=5 -oStrictHostKeyChecking=no -oCheckHostIP=no -oUserKnownHostsFile=/dev/null -oRSAAuthentication=no -oPubkeyAuthentication=no'
wait_for_fuel_menu() {
ip=$1
username=$2
password=$3
prompt=$4
echo "Waiting for Fuel Menu so it can be skipped. Please do NOT abort the script..."
# Loop until master node gets successfully installed
maxdelay=3000
while ! skip_fuel_menu $ip $username $password "$prompt"; do
sleep 5
((waited += 5))
if (( waited >= maxdelay )); then
echo "Installation timed out! ($maxdelay seconds)" 1>&2
exit 1
fi
done
}
skip_fuel_menu() {
ip=$1
username=$2
password=$3
prompt=$4
# Log in into the VM, see if Fuel Setup is running or puppet already started
# Looks a bit ugly, but 'end of expect' has to be in the very beginning of the line
result=$(
expect << ENDOFEXPECT
spawn ssh $ssh_options $username@$ip
expect "connect to host" exit
expect "*?assword:*"
send "$password\r"
expect "$prompt"
send "pgrep 'fuelmenu|puppet';echo \"returns $?\"\r"
expect "$prompt"
ENDOFEXPECT
)
if [[ "$result" =~ "returns 0" ]]; then
echo "Skipping Fuel Setup..."
expect << ENDOFEXPECT
spawn ssh $ssh_options $username@$ip
expect "connect to host" exit
expect "*?assword:*"
send "$password\r"
expect "$prompt"
send "killall -w -SIGUSR1 fuelmenu\r"
expect "$prompt"
ENDOFEXPECT
return 0
else
return 1
fi
}
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 $ssh_options $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
IFS="${NIFS}"
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
maxdelay=3000
while ! is_product_vm_operational $ip $username $password "$prompt"; do
sleep 5
((waited += 5))
if (( waited >= maxdelay )); then
echo "Installation timed out! ($maxdelay seconds)" 1>&2
exit 1
fi
done
}
enable_outbound_network_for_product_vm() {
ip=$1
username=$2
password=$3
prompt=$4
interface_id=$(($5-1)) # Subtract one to get ethX index (0-based) from the VirtualBox index (from 1 to 4)
gateway_ip=$6
# Check for internet access on the host system
echo -n "Checking for internet connectivity on the host system... "
if [ "`ping -c 5 google.com || ping -c 5 wikipedia.com`" ]; then
echo "OK"
else
echo "FAIL"
print_no_internet_connectivity_banner
return 1
fi
# Check host nameserver configuration
echo -n "Checking local DNS configuration... "
if [ -f /etc/resolv.conf ]; then
nameserver="$(grep '^nameserver' /etc/resolv.conf | grep -v 'nameserver\s\s*127.' | head -3)"
fi
if [ -z "$nameserver" -a -x /usr/bin/nmcli ]; then
# Get DNS from network manager
if [ -n "`LANG=C nmcli nm | grep \"running\s\+connected\"`" ]; then
nameserver="$(nmcli dev list | grep 'IP[46].DNS' | sed -e 's/IP[46]\.DNS\[[0-9]\+\]:\s\+/nameserver /'| grep -v 'nameserver\s\s*127.' | head -3)"
fi
fi
if [ -z "$nameserver" ]; then
echo "/etc/resolv.conf does not contain a nameserver. Using 8.8.8.8 for DNS."
nameserver="nameserver 8.8.8.8"
else
echo "OK"
fi
# Enable internet access on inside the VMs
echo -n "Enabling outbound network/internet access for the product VM... "
# Log in into the VM, configure and bring up the NAT interface, set default gateway, check internet connectivity
# Looks a bit ugly, but 'end of expect' has to be in the very beginning of the line
result=$(
expect << ENDOFEXPECT
spawn ssh $ssh_options $username@$ip
expect "connect to host" exit
expect "*?assword:*"
send "$password\r"
expect "$prompt"
send "file=/etc/sysconfig/network-scripts/ifcfg-eth$interface_id\r"
expect "$prompt"
send "hwaddr=\\\$(grep HWADDR \\\$file)\r"
expect "$prompt"
send "uuid=\\\$(grep UUID \\\$file)\r"
expect "$prompt"
send "echo -e \"\\\$hwaddr\\n\\\$uuid\\nDEVICE=eth$interface_id\\nTYPE=Ethernet\\nONBOOT=yes\\nNM_CONTROLLED=no\\nBOOTPROTO=dhcp\\nPEERDNS=no\" > \\\$file\r"
expect "$prompt"
send "sed \"s/GATEWAY=.*/GATEWAY=\"$gateway_ip\"/g\" -i /etc/sysconfig/network\r"
expect "$prompt"
send "echo -e \"$nameserver\" > /etc/dnsmasq.upstream\r"
expect "$prompt"
send "service network restart >/dev/null 2>&1\r"
expect "$prompt"
send "service dnsmasq restart >/dev/null 2>&1\r"
expect "$prompt"
send "for i in 1 2 3 4 5; do ping -c 2 google.com || ping -c 2 wikipedia.com || sleep 2; done\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 == *icmp_seq* ]]; then
IFS="${NIFS}"
echo "OK"
return 0;
fi
IFS="${NIFS}"
done
echo "FAIL"
print_no_internet_connectivity_banner
return 1
}
print_no_internet_connectivity_banner() {
echo "############################################################"
echo "# WARNING: some of the Fuel features will not be supported #"
echo "# (e.g. RHOS/RHEL integration) because there is #"
echo "# no Internet connectivity #"
echo "############################################################"
}