From b92a08787b7e391dae99d8ba687f92b8615e547f Mon Sep 17 00:00:00 2001 From: Tim Rozet Date: Mon, 13 Apr 2015 15:28:24 -0400 Subject: Adds deploy.sh for Foreman/QuickStack PATCHSET2: Fixes whitespace issue and adds default_gw substitution in ksgen settings file Creates a Vagrant VM provisioned with VirtualBox. The Vagrantfile config is modified at runtime with dynamic support for baremetal network setup. IP addresses and other network info are gathered at runtime and passed to the .yaml file which is fed into Khaleesi to install Foreman/QuickStack and provision hosts. For the script usage it is recommended to include the following inside of the yaml file set: - mac_address: "01:23:45:67:89:AB" <-Mac Address of admin interface - bmc_ip: 10.4.17.2 - bmc_mac: "01:23:45:67:88:AB" - bmc_user: root - bmc_pass: root JIRA: BGS-31 Change-Id: I1aa9352d2f5965befabf86119c0c9c5edb82f329 Signed-off-by: Tim Rozet --- foreman/ci/deploy.sh | 402 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) mode change 100644 => 100755 foreman/ci/deploy.sh (limited to 'foreman') diff --git a/foreman/ci/deploy.sh b/foreman/ci/deploy.sh old mode 100644 new mode 100755 index e69de29..d1bb24c --- a/foreman/ci/deploy.sh +++ b/foreman/ci/deploy.sh @@ -0,0 +1,402 @@ +#!/usr/bin/env bash + +#Deploy script to install provisioning server for Foreman/QuickStack +#author: Tim Rozet (trozet@redhat.com) +# +#Uses Vagrant and VirtualBox +#VagrantFile uses bootsrap.sh which Installs Khaleesi +#Khaleesi will install and configure Foreman/QuickStack +# +#Pre-requisties: +#Supports 3 or 4 network interface configuration +#Target system must be RPM based +#Ensure the host's kernel is up to date (yum update) +#Provisioned nodes expected to have following order of network connections (note: not all have to exist, but order is maintained): +#eth0- admin network +#eth1- private network (+storage network in 3 NIC config) +#eth2- public network +#eth3- storage network +#script assumes /24 subnet mask + +##VARS +reset=`tput sgr0` +blue=`tput setaf 4` +red=`tput setaf 1` +green=`tput setaf 2` + +##END VARS + +##FUNCTIONS +display_usage() { + echo -e "\n\n${blue}This script is used to deploy Foreman/QuickStack Installer and Provision OPNFV Target System${reset}\n\n" + echo -e "\n${green}Make sure you have the latest kernel installed before running this script! (yum update kernel +reboot)${reset}\n" + echo -e "\nUsage:\n$0 [arguments] \n" + echo -e "\n -no_parse : No variable parsing into config. Flag. \n" + echo -e "\n -base_config : Full path of settings file to parse. Optional. Will provide a new base settings file rather than the default. Example: -base_config /opt/myinventory.yml \n" +} + +##find ip of interface +##params: interface name +function find_ip { + ip addr show $1 | grep -Eo '^\s+inet\s+[\.0-9]+' | awk '{print $2}' +} + +##increments next IP +##params: ip +##assumes a /24 subnet +function next_ip { + baseaddr="$(echo $1 | cut -d. -f1-3)" + lsv="$(echo $1 | cut -d. -f4)" + if [ "$lsv" -ge 254 ]; then + return 1 + fi + ((lsv++)) + echo $baseaddr.$lsv +} + +##removes the network interface config from Vagrantfile +##params: interface +##assumes you are in the directory of Vagrantfile +function remove_vagrant_network { + sed -i 's/^.*'"$1"'.*$//' Vagrantfile +} + +##check if IP is in use +##params: ip +##ping ip to get arp entry, then check arp +function is_ip_used { + ping -c 5 $1 > /dev/null 2>&1 + arp -n | grep "$1 " | grep -iv incomplete > /dev/null 2>&1 +} + +##find next usable IP +##params: ip +function next_usable_ip { + new_ip=$(next_ip $1) + while [ "$new_ip" ]; do + if ! is_ip_used $new_ip; then + echo $new_ip + return 0 + fi + new_ip=$(next_ip $new_ip) + done + return 1 +} + +##increment ip by value +##params: ip, amount to increment by +##increment_ip $next_private_ip 10 +function increment_ip { + baseaddr="$(echo $1 | cut -d. -f1-3)" + lsv="$(echo $1 | cut -d. -f4)" + incrval=$2 + lsv=$((lsv+incrval)) + if [ "$lsv" -ge 254 ]; then + return 1 + fi + echo $baseaddr.$lsv +} + +##END FUNCTIONS + +if [[ ( $1 == "--help") || $1 == "-h" ]]; then + display_usage + exit 0 +fi + +echo -e "\n\n${blue}This script is used to deploy Foreman/QuickStack Installer and Provision OPNFV Target System${reset}\n\n" +echo "Use -h to display help" +sleep 2 + +while [ "`echo $1 | cut -c1`" = "-" ] +do + echo $1 + case "$1" in + -base_config) + base_config=$2 + shift 2 + ;; + -no_parse) + no_parse="TRUE" + shift 1 + ;; + *) + display_usage + exit 1 + ;; +esac +done + + + +##disable selinux +/sbin/setenforce 0 + +##install EPEL +if ! yum repolist | grep "epel/"; then + if ! rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm; then + printf '%s\n' 'deploy.sh: Unable to configure EPEL repo' >&2 + exit 1 + fi +else + printf '%s\n' 'deploy.sh: Skipping EPEL repo as it is already configured.' +fi + +##install dependencies +if ! yum -y install binutils gcc make patch libgomp glibc-headers glibc-devel kernel-headers kernel-devel dkms; then + printf '%s\n' 'deploy.sh: Unable to install depdency packages' >&2 + exit 1 +fi + +##install VirtualBox repo +if cat /etc/*release | grep -i "Fedora release"; then + vboxurl=http://download.virtualbox.org/virtualbox/rpm/fedora/\$releasever/\$basearch +else + vboxurl=http://download.virtualbox.org/virtualbox/rpm/el/\$releasever/\$basearch +fi + +cat > /etc/yum.repos.d/virtualbox.repo << EOM +[virtualbox] +name=Oracle Linux / RHEL / CentOS-\$releasever / \$basearch - VirtualBox +baseurl=$vboxurl +enabled=1 +gpgcheck=1 +gpgkey=https://www.virtualbox.org/download/oracle_vbox.asc +skip_if_unavailable = 1 +keepcache = 0 +EOM + +##install VirtualBox +if ! yum list installed | grep -i virtualbox; then + if ! yum -y install VirtualBox-4.3; then + printf '%s\n' 'deploy.sh: Unable to install virtualbox package' >&2 + exit 1 + fi +fi + +##install kmod-VirtualBox +if ! lsmod | grep vboxdrv; then + if ! sudo /etc/init.d/vboxdrv setup; then + printf '%s\n' 'deploy.sh: Unable to install kernel module for virtualbox' >&2 + exit 1 + fi +else + printf '%s\n' 'deploy.sh: Skipping kernel module for virtualbox. Already Installed' +fi + +##install Vagrant +if ! rpm -qa | grep vagrant; then + if ! rpm -Uvh https://dl.bintray.com/mitchellh/vagrant/vagrant_1.7.2_x86_64.rpm; then + printf '%s\n' 'deploy.sh: Unable to install vagrant package' >&2 + exit 1 + fi +else + printf '%s\n' 'deploy.sh: Skipping Vagrant install as it is already installed.' +fi + +##add centos 7 box to vagrant +if ! vagrant box list | grep chef/centos-7.0; then + if ! vagrant box add chef/centos-7.0 --provider virtualbox; then + printf '%s\n' 'deploy.sh: Unable to download centos7 box for Vagrant' >&2 + exit 1 + fi +else + printf '%s\n' 'deploy.sh: Skipping Vagrant box add as centos-7.0 is already installed.' +fi + +##install workaround for centos7 +if ! vagrant plugin list | grep vagrant-centos7_fix; then + if ! vagrant plugin install vagrant-centos7_fix; then + printf '%s\n' 'deploy.sh: Warning: unable to install vagrant centos7 workaround' >&2 + fi +else + printf '%s\n' 'deploy.sh: Skipping Vagrant plugin as centos7 workaround is already installed.' +fi + +cd /tmp/ + +##remove bgs vagrant incase it wasn't cleaned up +rm -rf /tmp/bgs_vagrant + +##clone bgs vagrant +##will change this to be opnfv repo when commit is done +if ! git clone https://github.com/trozet/bgs_vagrant.git; then + printf '%s\n' 'deploy.sh: Unable to clone vagrant repo' >&2 + exit 1 +fi + +cd bgs_vagrant + +echo "${blue}Detecting network configuration...${reset}" +##detect host 1 or 3 interface configuration +#output=`ip link show | grep -E "^[0-9]" | grep -Ev ": lo|tun|virbr|vboxnet" | awk '{print $2}' | sed 's/://'` +output=`ifconfig | grep -E "^[a-Z0-9]+:"| grep -Ev "lo|tun|virbr|vboxnet:" | awk '{print $1}' | sed 's/://'` + +if [ ! "$output" ]; then + printf '%s\n' 'deploy.sh: Unable to detect interfaces to bridge to' >&2 + exit 1 +fi + +##find number of interfaces with ip and substitute in VagrantFile +if_counter=0 +for interface in ${output}; do + + if [ "$if_counter" -ge 4 ]; then + break + fi + interface_ip=$(find_ip $interface) + if [ ! "$interface_ip" ]; then + continue + fi + new_ip=$(next_usable_ip $interface_ip) + if [ ! "$new_ip" ]; then + continue + fi + interface_ip_arr[$if_counter]=$new_ip + sed -i 's/^.*eth_replace'"$if_counter"'.*$/ config.vm.network "public_network", ip: '\""$new_ip"\"', bridge: '\'"$interface"\''/' Vagrantfile + ((if_counter++)) +done + +##now remove interface config in Vagrantfile for 1 node +##if 1, 3, or 4 interfaces set deployment type +##if 2 interfaces remove 2nd interface and set deployment type +if [ "$if_counter" == 1 ]; then + deployment_type="single_network" + remove_vagrant_network eth_replace1 + remove_vagrant_network eth_replace2 + remove_vagrant_network eth_replace3 +elif [ "$if_counter" == 2 ]; then + deployment_type="single_network" + second_interface=`echo $output | awk '{print $2}'` + remove_vagrant_network $second_interface + remove_vagrant_network eth_replace2 +elif [ "$if_counter" == 3 ]; then + deployment_type="three_network" + remove_vagrant_network eth_replace3 +else + deployment_type="multi_network" +fi + +echo "${blue}Network detected: ${deployment_type}! ${reset}" + +if route | grep default; then + defaultgw=$(route | grep default | awk '{print $2}') + echo "${blue}Default gateway detected: $defaultgw ${reset}" + sed -i 's/^.*default_gw =.*$/ default_gw = '\""$defaultgw"\"'/' Vagrantfile +else + defaultgw=`echo ${interface_arr_ip[0]} | cut -d. -f1-3` + firstip=.1 + defaultgw=$defaultgw$firstip + echo "${blue}Unable to find default gateway. Assuming it is $defaultgw ${reset}" + sed -i 's/^.*default_gw =.*$/ default_gw = '\""$defaultgw"\"'/' Vagrantfile +fi + +sed -i 's/^.*default_gw:.*$/default_gw:'" $defaultgw"'/' opnfv_ksgen_settings.yml + +if [ $base_config ]; then + if ! cp -f $base_config opnfv_ksgen_settings.yml; then + echo "{red}ERROR: Unable to copy $base_config to opnfv_ksgen_settings.yml${reset}" + exit 1 + fi +fi + +if [ $no_parse ]; then +echo "${blue}Skipping parsing variables into settings file as no_parse flag is set${reset}" + +else + +echo "${blue}Gathering network parameters for Target System...this may take a few minutes${reset}" +##Edit the ksgen settings appropriately +##ksgen settings will be stored in /vagrant on the vagrant machine +##if single node deployment all the variables will have the same ip +##interface names will be enp0s3, enp0s8, enp0s9 in chef/centos7 + +##replace private interface parameter +##private interface will be of hosts, so we need to know the provisioned host interface name +##we add biosdevname=0, net.ifnames=0 to the kickstart to use regular interface naming convention on hosts +##replace IP for parameters with next IP that will be given to controller +if [ "$deployment_type" == "single_network" ]; then + sed -i 's/^.*ovs_tunnel_if:.*$/ ovs_tunnel_if: eth0/' opnfv_ksgen_settings.yml + ##we also need to assign IP addresses to nodes + ##for single node, foreman is managing the single network, so we can't reserve them + ##not supporting single network anymore for now + echo "{blue}Single Network type is unsupported right now. Please check your interface configuration. Exiting. ${reset}" + exit 0 + +elif [[ "$deployment_type" == "multi_network" || "$deployment_type" == "three_network" ]]; then + sed -i 's/^.*ovs_tunnel_if:.*$/ ovs_tunnel_if: eth1/' opnfv_ksgen_settings.yml + + if [ "$deployment_type" == "three_network" ]; then + sed -i 's/^.*storage_iface:.*$/ storage_iface: eth1/' opnfv_ksgen_settings.yml + sed -i 's/^.*network_type:.*$/ network_type: three_network/' opnfv_ksgen_settings.yml + else + sed -i 's/^.*storage_iface:.*$/ storage_iface: eth3/' opnfv_ksgen_settings.yml + fi + + ##get ip addresses for private network on controllers to make dhcp entries + ##required for controllers_ip_array global param + next_private_ip=${interface_ip_arr[1]} + type=_private + for node in controller1 controller2 controller3; do + next_private_ip=$(next_usable_ip $next_private_ip) + if [ ! "$next_private_ip" ]; then + printf '%s\n' 'deploy.sh: Unable to find next ip for private network for control nodes' >&2 + exit 1 + fi + sed -i 's/'"$node$type"'/'"$next_private_ip"'/g' opnfv_ksgen_settings.yml + controller_ip_array=$controller_ip_array$next_private_ip, + done + + ##replace global param for contollers_ip_array + controller_ip_array=${controller_ip_array%?} + sed -i 's/^.*controllers_ip_array:.*$/ controllers_ip_array: '"$controller_ip_array"'/' opnfv_ksgen_settings.yml + + ##now replace all the VIP variables. admin//private can be the same IP + ##we have to use IP's here that won't be allocated to hosts at provisioning time + ##therefore we increment the ip by 10 to make sure we have a safe buffer + next_private_ip=$(increment_ip $next_private_ip 10) + + grep -E '*private_vip|loadbalancer_vip|db_vip|amqp_vip|*admin_vip' opnfv_ksgen_settings.yml | while read -r line ; do + sed -i 's/^.*'"$line"'.*$/ '"$line $next_private_ip"'/' opnfv_ksgen_settings.yml + next_private_ip=$(next_usable_ip $next_private_ip) + if [ ! "$next_private_ip" ]; then + printf '%s\n' 'deploy.sh: Unable to find next ip for private network for vip replacement' >&2 + exit 1 + fi + done + + ##replace public_vips + next_public_ip=${interface_ip_arr[2]} + next_public_ip=$(increment_ip $next_public_ip 10) + grep -E '*public_vip' opnfv_ksgen_settings.yml | while read -r line ; do + sed -i 's/^.*'"$line"'.*$/ '"$line $next_public_ip"'/' opnfv_ksgen_settings.yml + next_public_ip=$(next_usable_ip $next_public_ip) + if [ ! "$next_public_ip" ]; then + printf '%s\n' 'deploy.sh: Unable to find next ip for public network for vip replcement' >&2 + exit 1 + fi + done + + ##replace private_subnet param + network=.0 + baseaddr="$(echo $next_private_ip | cut -d. -f1-3)" + private_subnet=$baseaddr$network + sed -i 's/^.*private_subnet:.*$/ private_subnet:'" $private_subnet"''"\/24"'/' opnfv_ksgen_settings.yml +else + printf '%s\n' 'deploy.sh: Unknown network type: $deployment_type' >&2 + exit 1 +fi + +echo "${blue}Parameters Complete. Settings have been set for Foreman. ${reset}" + +fi + +echo "${blue}Starting Vagrant! ${reset}" + +##stand up vagrant +if ! vagrant up; then + printf '%s\n' 'deploy.sh: Unable to start vagrant' >&2 + exit 1 +fi + + -- cgit 1.2.3-korg