Adds ODL L3 and external network support on compute nodes
[apex.git] / ci / deploy.sh
1 #!/bin/bash
2
3 # Deploy script to install provisioning server for OPNFV Apex
4 # author: Dan Radez (dradez@redhat.com)
5 # author: Tim Rozet (trozet@redhat.com)
6 #
7 # Based on RDO Manager http://www.rdoproject.org
8
9 set -e
10
11 ##VARIABLES
12 if [ "$TERM" != "unknown" ]; then
13   reset=$(tput sgr0)
14   blue=$(tput setaf 4)
15   red=$(tput setaf 1)
16   green=$(tput setaf 2)
17 else
18   reset=""
19   blue=""
20   red=""
21   green=""
22 fi
23
24 vm_index=4
25 ha_enabled="TRUE"
26 ping_site="8.8.8.8"
27 ntp_server="pool.ntp.org"
28 net_isolation_enabled="TRUE"
29 post_config="TRUE"
30
31 declare -i CNT
32 declare UNDERCLOUD
33 declare -A deploy_options_array
34 declare -A NET_MAP
35
36 SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
37 DEPLOY_OPTIONS=""
38 RESOURCES=/var/opt/opnfv/stack
39 CONFIG=/var/opt/opnfv
40 INSTACKENV=$CONFIG/instackenv.json
41 OPNFV_NETWORK_TYPES="admin_network private_network public_network storage_network"
42 # Netmap used to map networks to OVS bridge names
43 NET_MAP['admin_network']="brbm"
44 NET_MAP['private_network']="brbm1"
45 NET_MAP['public_network']="brbm2"
46 NET_MAP['storage_network']="brbm3"
47
48 ##LIBRARIES
49 source $CONFIG/lib/common-functions.sh
50 source $CONFIG/lib/installer/onos/onos_gw_mac_update.sh
51
52 ##FUNCTIONS
53 ##translates yaml into variables
54 ##params: filename, prefix (ex. "config_")
55 ##usage: parse_yaml opnfv_ksgen_settings.yml "config_"
56 parse_yaml() {
57    local prefix=$2
58    local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
59    sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
60         -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
61    awk -F$fs '{
62       indent = length($1)/2;
63       vname[indent] = $2;
64       for (i in vname) {if (i > indent) {delete vname[i]}}
65       if (length($3) > 0) {
66          vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
67          printf("%s%s%s=%s\n", "'$prefix'",vn, $2, $3);
68       }
69    }'
70 }
71
72 ##checks if prefix exists in string
73 ##params: string, prefix
74 ##usage: contains_prefix "deploy_setting_launcher=1" "deploy_setting"
75 contains_prefix() {
76   local mystr=$1
77   local prefix=$2
78   if echo $mystr | grep -E "^$prefix.*$" > /dev/null; then
79     return 0
80   else
81     return 1
82   fi
83 }
84 ##parses variable from a string with '='
85 ##and removes global prefix
86 ##params: string, prefix
87 ##usage: parse_setting_var 'deploy_myvar=2' 'deploy_'
88 parse_setting_var() {
89   local mystr=$1
90   local prefix=$2
91   if echo $mystr | grep -E "^.+\=" > /dev/null; then
92     echo $(echo $mystr | grep -Eo "^.+\=" | tr -d '=' |  sed 's/^'"$prefix"'//')
93   else
94     return 1
95   fi
96 }
97 ##parses value from a string with '='
98 ##params: string
99 ##usage: parse_setting_value
100 parse_setting_value() {
101   local mystr=$1
102   echo $(echo $mystr | grep -Eo "\=.*$" | tr -d '=')
103 }
104 ##parses network settings yaml into globals
105 parse_network_settings() {
106   local required_network_settings="cidr"
107   local common_optional_network_settings="usable_ip_range"
108   local admin_network_optional_settings="provisioner_ip dhcp_range introspection_range"
109   local public_network_optional_settings="floating_ip_range gateway provisioner_ip"
110   local nic_value cidr
111
112   eval $(parse_yaml ${NETSETS})
113   for network in ${OPNFV_NETWORK_TYPES}; do
114     if [[ $(eval echo \${${network}_enabled}) == 'true' ]]; then
115       enabled_network_list+="${network} "
116     elif [ "${network}" == 'admin_network' ]; then
117       echo -e "${red}ERROR: You must enable admin_network and configure it explicitly or use auto-detection${reset}"
118       exit 1
119     elif [ "${network}" == 'public_network' ]; then
120       echo -e "${red}ERROR: You must enable public_network and configure it explicitly or use auto-detection${reset}"
121       exit 1
122     else
123       echo -e "${blue}INFO: Network: ${network} is disabled, will collapse into admin_network"
124     fi
125   done
126
127   # check for enabled network values
128   for enabled_network in ${enabled_network_list}; do
129     # detect required settings first to continue
130     echo -e "${blue}INFO: Detecting Required settings for: ${enabled_network}${reset}"
131     for setting in ${required_network_settings}; do
132       eval "setting_value=\${${enabled_network}_${setting}}"
133       if [ -z "${setting_value}" ]; then
134         # if setting is missing we try to autodetect
135         eval "nic_value=\${${enabled_network}_bridged_interface}"
136         if [ -n "$nic_value" ]; then
137           setting_value=$(eval find_${setting} ${nic_value})
138           if [ -n "$setting_value" ]; then
139             eval "${enabled_network}_${setting}=${setting_value}"
140             echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
141           else
142             echo -e "${red}ERROR: Auto-detection failed: ${setting} not found using interface: ${nic_value}${reset}"
143             exit 1
144           fi
145         else
146           echo -e "${red}ERROR: Required setting: ${setting} not found, and bridge interface not provided\
147 for Auto-detection${reset}"
148           exit 1
149         fi
150       else
151         echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
152       fi
153     done
154     echo -e "${blue}INFO: Detecting Common settings for: ${enabled_network}${reset}"
155     # detect optional common settings
156     # these settings can be auto-generated if missing
157     for setting in ${common_optional_network_settings}; do
158       eval "setting_value=\${${enabled_network}_${setting}}"
159       if [ -z "${setting_value}" ]; then
160         if [ -n "$nic_value" ]; then
161           setting_value=$(eval find_${setting} ${nic_value})
162         else
163           setting_value=''
164           echo -e "${blue}INFO: Skipping Auto-detection, NIC not specified for ${enabled_network}.  Attempting Auto-generation...${reset}"
165         fi
166         if [ -n "$setting_value" ]; then
167           eval "${enabled_network}_${setting}=${setting_value}"
168           echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
169         else
170           # if Auto-detection fails we can auto-generate with CIDR
171           eval "cidr=\${${enabled_network}_cidr}"
172           if [ -n "$cidr" ]; then
173             echo -e "${blue}INFO: Auto-generating: ${setting}${reset}"
174             setting_value=$(eval generate_${setting} ${cidr})
175           else
176             setting_value=''
177             echo -e "${red}ERROR: Auto-generation failed: required parameter CIDR missing for network ${enabled_network}${reset}"
178           fi
179           if [ -n "$setting_value" ]; then
180             eval "${enabled_network}_${setting}=${setting_value}"
181             echo -e "${blue}INFO: Auto-generated: ${enabled_network}_${setting}: ${setting_value}${reset}"
182           else
183             echo -e "${red}ERROR: Auto-generation failed: ${setting} not found${reset}"
184             exit 1
185           fi
186         fi
187       else
188         echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
189       fi
190     done
191     echo -e "${blue}INFO: Detecting Network Specific settings for: ${enabled_network}${reset}"
192     # detect network specific settings
193     if [ -n $(eval echo \${${network}_optional_settings}) ]; then
194       eval "network_specific_settings=\${${enabled_network}_optional_settings}"
195       for setting in ${network_specific_settings}; do
196         eval "setting_value=\${${enabled_network}_${setting}}"
197         if [ -z "${setting_value}" ]; then
198           if [ -n "$nic_value" ]; then
199             setting_value=$(eval find_${setting} ${nic_value})
200           else
201             setting_value=''
202             echo -e "${blue}INFO: Skipping Auto-detection, NIC not specified for ${enabled_network}.  Attempting Auto-generation...${reset}"
203           fi
204           if [ -n "$setting_value" ]; then
205             eval "${enabled_network}_${setting}=${setting_value}"
206             echo -e "${blue}INFO: Auto-detection: ${enabled_network}_${setting}: ${setting_value}${reset}"
207           else
208             eval "cidr=\${${enabled_network}_cidr}"
209             if [ -n "$cidr" ]; then
210               setting_value=$(eval generate_${setting} ${cidr})
211             else
212               setting_value=''
213               echo -e "${red}ERROR: Auto-generation failed: required parameter CIDR missing for network ${enabled_network}${reset}"
214             fi
215             if [ -n "$setting_value" ]; then
216               eval "${enabled_network}_${setting}=${setting_value}"
217               echo -e "${blue}INFO: Auto-generated: ${enabled_network}_${setting}: ${setting_value}${reset}"
218             else
219               echo -e "${red}ERROR: Auto-generation failed: ${setting} not found${reset}"
220               exit 1
221             fi
222           fi
223         else
224           echo -e "${blue}INFO: ${enabled_network}_${setting}: ${setting_value}${reset}"
225         fi
226       done
227     fi
228   done
229 }
230 ##parses deploy settings yaml into globals and options array
231 ##params: none
232 ##usage:  parse_deploy_settings
233 parse_deploy_settings() {
234   local global_prefix="deploy_global_params_"
235   local options_prefix="deploy_deploy_options_"
236   local myvar myvalue
237   local settings=$(parse_yaml $DEPLOY_SETTINGS_FILE "deploy_")
238
239   for this_setting in $settings; do
240     if contains_prefix $this_setting $global_prefix; then
241       myvar=$(parse_setting_var $this_setting $global_prefix)
242       if [ -z "$myvar" ]; then
243         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
244       fi
245       myvalue=$(parse_setting_value $this_setting)
246       # Do not override variables set by cmdline
247       if [ -z "$(eval echo \$$myvar)" ]; then
248         eval "$myvar=\$myvalue"
249         echo -e "${blue}Global parameter set: ${myvar}:${myvalue}${reset}"
250       else
251         echo -e "${blue}Global parameter already set: ${myvar}${reset}"
252       fi
253     elif contains_prefix $this_setting $options_prefix; then
254       myvar=$(parse_setting_var $this_setting $options_prefix)
255       if [ -z "$myvar" ]; then
256         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
257       fi
258       myvalue=$(parse_setting_value $this_setting)
259       deploy_options_array[$myvar]=$myvalue
260       echo -e "${blue}Deploy option set: ${myvar}:${myvalue}${reset}"
261     fi
262   done
263 }
264 ##parses baremetal yaml settings into compatible json
265 ##writes the json to $CONFIG/instackenv_tmp.json
266 ##params: none
267 ##usage: parse_inventory_file
268 parse_inventory_file() {
269   local inventory=$(parse_yaml $INVENTORY_FILE)
270   local node_list
271   local node_prefix="node"
272   local node_count=0
273   local node_total
274   local inventory_list
275
276   # detect number of nodes
277   for entry in $inventory; do
278     if echo $entry | grep -Eo "^nodes_node[0-9]+_" > /dev/null; then
279       this_node=$(echo $entry | grep -Eo "^nodes_node[0-9]+_")
280       if [[ $inventory_list != *"$this_node"* ]]; then
281         inventory_list+="$this_node "
282       fi
283     fi
284   done
285
286   inventory_list=$(echo $inventory_list | sed 's/ $//')
287
288   for node in $inventory_list; do
289     ((node_count+=1))
290   done
291
292   node_total=$node_count
293
294   if [[ "$node_total" -lt 5 && ha_enabled == "TRUE" ]]; then
295     echo -e "${red}ERROR: You must provide at least 5 nodes for HA baremetal deployment${reset}"
296     exit 1
297   elif [[ "$node_total" -lt 2 ]]; then
298     echo -e "${red}ERROR: You must provide at least 2 nodes for non-HA baremetal deployment${reset}"
299     exit 1
300   fi
301
302   eval $(parse_yaml $INVENTORY_FILE)
303
304   instack_env_output="
305 {
306  \"nodes\" : [
307
308 "
309   node_count=0
310   for node in $inventory_list; do
311     ((node_count+=1))
312     node_output="
313         {
314           \"pm_password\": \"$(eval echo \${${node}ipmi_pass})\",
315           \"pm_type\": \"pxe_ipmitool\",
316           \"mac\": [
317             \"$(eval echo \${${node}mac_address})\"
318           ],
319           \"cpu\": \"$(eval echo \${${node}cpus})\",
320           \"memory\": \"$(eval echo \${${node}memory})\",
321           \"disk\": \"$(eval echo \${${node}disk})\",
322           \"arch\": \"$(eval echo \${${node}arch})\",
323           \"pm_user\": \"$(eval echo \${${node}ipmi_user})\",
324           \"pm_addr\": \"$(eval echo \${${node}ipmi_ip})\",
325           \"capabilities\": \"$(eval echo \${${node}capabilities})\"
326 "
327     instack_env_output+=${node_output}
328     if [ $node_count -lt $node_total ]; then
329       instack_env_output+="        },"
330     else
331       instack_env_output+="        }"
332     fi
333   done
334
335   instack_env_output+='
336   ]
337 }
338 '
339   #Copy instackenv.json to undercloud for baremetal
340   echo -e "{blue}Parsed instackenv JSON:\n${instack_env_output}${reset}"
341   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
342 cat > instackenv.json << EOF
343 $instack_env_output
344 EOF
345 EOI
346
347 }
348 ##verify internet connectivity
349 #params: none
350 function verify_internet {
351   if ping -c 2 $ping_site > /dev/null; then
352     if ping -c 2 www.google.com > /dev/null; then
353       echo "${blue}Internet connectivity detected${reset}"
354       return 0
355     else
356       echo "${red}Internet connectivity detected, but DNS lookup failed${reset}"
357       return 1
358     fi
359   else
360     echo "${red}No internet connectivity detected${reset}"
361     return 1
362   fi
363 }
364
365 ##download dependencies if missing and configure host
366 #params: none
367 function configure_deps {
368   if ! verify_internet; then
369     echo "${red}Will not download dependencies${reset}"
370     internet=false
371   fi
372
373   # verify ip forwarding
374   if sysctl net.ipv4.ip_forward | grep 0; then
375     sudo sysctl -w net.ipv4.ip_forward=1
376     sudo sh -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
377   fi
378
379   # ensure no dhcp server is running on jumphost
380   if ! sudo systemctl status dhcpd | grep dead; then
381     echo "${red}WARN: DHCP Server detected on jumphost, disabling...${reset}"
382     sudo systemctl stop dhcpd
383     sudo systemctl disable dhcpd
384   fi
385
386   # ensure networks are configured
387   systemctl start openvswitch
388
389   # If flat we only use admin network
390   if [[ "$net_isolation_enabled" == "FALSE" ]]; then
391     virsh_enabled_networks="admin_network"
392   # For baremetal we only need to create/attach instack to admin and public
393   elif [ "$virtual" == "FALSE" ]; then
394     virsh_enabled_networks="admin_network public_network"
395   else
396     virsh_enabled_networks=$enabled_network_list
397   fi
398
399   for network in ${OPNFV_NETWORK_TYPES}; do
400     ovs-vsctl list-br | grep ${NET_MAP[$network]} > /dev/null || ovs-vsctl add-br ${NET_MAP[$network]}
401     virsh net-list --all | grep ${NET_MAP[$network]} > /dev/null || virsh net-create $CONFIG/${NET_MAP[$network]}-net.xml
402     virsh net-list | grep -E "${NET_MAP[$network]}\s+active" > /dev/null || virsh net-start ${NET_MAP[$network]}
403   done
404
405   echo -e "${blue}INFO: Bridges set: ${reset}"
406   ovs-vsctl list-br
407   echo -e "${blue}INFO: virsh networks set: ${reset}"
408   virsh net-list
409
410   if [[ -z "$virtual" || "$virtual" == "FALSE" ]]; then
411     # bridge interfaces to correct OVS instances for baremetal deployment
412     for network in ${enabled_network_list}; do
413       if [[ "$network" != "admin_network" && "$network" != "public_network" ]]; then
414         continue
415       fi
416       this_interface=$(eval echo \${${network}_bridged_interface})
417       # check if this a bridged interface for this network
418       if [[ ! -z "$this_interface" || "$this_interface" != "none" ]]; then
419         if ! attach_interface_to_ovs ${NET_MAP[$network]} ${this_interface} ${network}; then
420           echo -e "${red}ERROR: Unable to bridge interface ${this_interface} to bridge ${NET_MAP[$network]} for enabled network: ${network}${reset}"
421           exit 1
422         else
423           echo -e "${blue}INFO: Interface ${this_interface} bridged to bridge ${NET_MAP[$network]} for enabled network: ${network}${reset}"
424         fi
425       else
426         echo "${red}ERROR: Unable to determine interface to bridge to for enabled network: ${network}${reset}"
427         exit 1
428       fi
429     done
430   fi
431
432   # ensure storage pool exists and is started
433   virsh pool-list --all | grep default > /dev/null || virsh pool-create $CONFIG/default-pool.xml
434   virsh pool-list | grep -Eo "default\s+active" > /dev/null || virsh pool-start default
435
436   if virsh net-list | grep default > /dev/null; then
437     num_ints_same_subnet=$(ip addr show | grep "inet 192.168.122" | wc -l)
438     if [ "$num_ints_same_subnet" -gt 1 ]; then
439       virsh net-destroy default
440       ##go edit /etc/libvirt/qemu/networks/default.xml
441       sed -i 's/192.168.122/192.168.123/g' /etc/libvirt/qemu/networks/default.xml
442       sed -i 's/192.168.122/192.168.123/g' instackenv-virt.json
443       sleep 5
444       virsh net-start default
445       virsh net-autostart default
446     fi
447   fi
448
449   if ! egrep '^flags.*(vmx|svm)' /proc/cpuinfo > /dev/null; then
450     echo "${red}virtualization extensions not found, kvm kernel module insertion may fail.\n  \
451 Are you sure you have enabled vmx in your bios or hypervisor?${reset}"
452   fi
453
454   if ! lsmod | grep kvm > /dev/null; then modprobe kvm; fi
455   if ! lsmod | grep kvm_intel > /dev/null; then modprobe kvm_intel; fi
456
457   if ! lsmod | grep kvm > /dev/null; then
458     echo "${red}kvm kernel modules not loaded!${reset}"
459     return 1
460   fi
461
462   ##sshkeygen for root
463   if [ ! -e ~/.ssh/id_rsa.pub ]; then
464     ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
465   fi
466
467   echo "${blue}All dependencies installed and running${reset}"
468 }
469
470 ##verify vm exists, an has a dhcp lease assigned to it
471 ##params: none
472 function setup_instack_vm {
473   if ! virsh list --all | grep instack > /dev/null; then
474       #virsh vol-create default instack.qcow2.xml
475       virsh define $CONFIG/instack.xml
476
477       #Upload instack image
478       #virsh vol-create default --file instack.qcow2.xml
479       virsh vol-create-as default instack.qcow2 30G --format qcow2
480
481       ### this doesn't work for some reason I was getting hangup events so using cp instead
482       #virsh vol-upload --pool default --vol instack.qcow2 --file $CONFIG/stack/instack.qcow2
483       #2015-12-05 12:57:20.569+0000: 8755: info : libvirt version: 1.2.8, package: 16.el7_1.5 (CentOS BuildSystem <http://bugs.centos.org>, 2015-11-03-13:56:46, worker1.bsys.centos.org)
484       #2015-12-05 12:57:20.569+0000: 8755: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
485       #2015-12-05 12:57:20.569+0000: 8756: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
486       #error: cannot close volume instack.qcow2
487       #error: internal error: received hangup / error event on socket
488       #error: Reconnected to the hypervisor
489
490       instack_dst=/var/lib/libvirt/images/instack.qcow2
491       cp -f $RESOURCES/instack.qcow2 $instack_dst
492
493       # resize instack machine
494       echo "Checking if instack needs to be resized..."
495       instack_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $instack_dst |grep device | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
496       if [ "$instack_size" -lt 30 ]; then
497         qemu-img resize /var/lib/libvirt/images/instack.qcow2 +25G
498         LIBGUESTFS_BACKEND=direct virt-resize --expand /dev/sda1 $RESOURCES/instack.qcow2 $instack_dst
499         LIBGUESTFS_BACKEND=direct virt-customize -a $instack_dst --run-command 'xfs_growfs -d /dev/sda1 || true'
500         new_size=$(LIBGUESTFS_BACKEND=direct virt-filesystems --long -h --all -a $instack_dst |grep filesystem | grep -Eo "[0-9\.]+G" | sed -n 's/\([0-9][0-9]*\).*/\1/p')
501         if [ "$new_size" -lt 30 ]; then
502           echo "Error resizing instack machine, disk size is ${new_size}"
503           exit 1
504         else
505           echo "instack successfully resized"
506         fi
507       else
508         echo "skipped instack resize, upstream is large enough"
509       fi
510
511   else
512       echo "Found Instack VM, using existing VM"
513   fi
514
515   # if the VM is not running update the authkeys and start it
516   if ! virsh list | grep instack > /dev/null; then
517     echo "Injecting ssh key to instack VM"
518     virt-customize -c qemu:///system -d instack --run-command "mkdir -p /root/.ssh/" \
519         --upload ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
520         --run-command "chmod 600 /root/.ssh/authorized_keys && restorecon /root/.ssh/authorized_keys" \
521         --run-command "cp /root/.ssh/authorized_keys /home/stack/.ssh/" \
522         --run-command "chown stack:stack /home/stack/.ssh/authorized_keys && chmod 600 /home/stack/.ssh/authorized_keys"
523     virsh start instack
524   fi
525
526   sleep 3 # let DHCP happen
527
528   CNT=10
529   echo -n "${blue}Waiting for instack's dhcp address${reset}"
530   while ! grep instack /var/lib/libvirt/dnsmasq/default.leases > /dev/null && [ $CNT -gt 0 ]; do
531       echo -n "."
532       sleep 3
533       CNT=CNT-1
534   done
535
536   # get the instack VM IP
537   UNDERCLOUD=$(grep instack /var/lib/libvirt/dnsmasq/default.leases | awk '{print $3}' | head -n 1)
538   if [ -z "$UNDERCLOUD" ]; then
539     #if not found then dnsmasq may be using leasefile-ro
540     instack_mac=$(virsh domiflist instack | grep default | \
541                   grep -Eo "[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+")
542     UNDERCLOUD=$(/usr/sbin/arp -e | grep ${instack_mac} | awk {'print $1'})
543
544     if [ -z "$UNDERCLOUD" ]; then
545       echo "\n\nNever got IP for Instack. Can Not Continue."
546       exit 1
547     else
548       echo -e "${blue}\rInstack VM has IP $UNDERCLOUD${reset}"
549     fi
550   else
551      echo -e "${blue}\rInstack VM has IP $UNDERCLOUD${reset}"
552   fi
553
554   CNT=10
555   echo -en "${blue}\rValidating instack VM connectivity${reset}"
556   while ! ping -c 1 $UNDERCLOUD > /dev/null && [ $CNT -gt 0 ]; do
557       echo -n "."
558       sleep 3
559       CNT=$CNT-1
560   done
561   if [ "$CNT" -eq 0 ]; then
562       echo "Failed to contact Instack. Can Not Continue"
563       exit 1
564   fi
565   CNT=10
566   while ! ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "echo ''" 2>&1> /dev/null && [ $CNT -gt 0 ]; do
567       echo -n "."
568       sleep 3
569       CNT=$CNT-1
570   done
571   if [ "$CNT" -eq 0 ]; then
572       echo "Failed to connect to Instack. Can Not Continue"
573       exit 1
574   fi
575
576   # extra space to overwrite the previous connectivity output
577   echo -e "${blue}\r                                                                 ${reset}"
578
579   #add the instack public interface if net isolation is enabled (more than just admin network)
580   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
581     virsh attach-interface --domain instack --type network --source ${NET_MAP['public_network']} --model rtl8139 --config --live
582     sleep 1
583     ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "if ! ip a s eth2 | grep ${public_network_provisioner_ip} > /dev/null; then ip a a ${public_network_provisioner_ip}/${public_network_cidr##*/} dev eth2; ip link set up dev eth2; fi"
584   fi
585   # ssh key fix for stack user
586   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "restorecon -r /home/stack"
587 }
588
589 ##Create virtual nodes in virsh
590 ##params: none
591 function setup_virtual_baremetal {
592   for i in $(seq 0 $vm_index); do
593     if ! virsh list --all | grep baremetalbrbm_brbm1_brbm2_brbm3_${i} > /dev/null; then
594       if [ ! -e $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml ]; then
595         define_virtual_node baremetalbrbm_brbm1_brbm2_brbm3_${i}
596       fi
597       # Fix for ramdisk using wrong pxeboot interface
598       # TODO: revisit this and see if there's a more proper fix
599       sed -i "/^\s*<source network='brbm2'\/>/{
600         N
601         s/^\(.*\)virtio\(.*\)$/\1rtl8139\2/
602         }" $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml
603       virsh define $CONFIG/baremetalbrbm_brbm1_brbm2_brbm3_${i}.xml
604     else
605       echo "Found Baremetal ${i} VM, using existing VM"
606     fi
607     virsh vol-list default | grep baremetalbrbm_brbm1_brbm2_brbm3_${i} 2>&1> /dev/null || virsh vol-create-as default baremetalbrbm_brbm1_brbm2_brbm3_${i}.qcow2 40G --format qcow2
608   done
609
610 }
611
612 ##Set network-environment settings
613 ##params: network-environment file to edit
614 function configure_network_environment {
615   local tht_dir nic_ext
616   tht_dir=/usr/share/openstack-tripleo-heat-templates/network
617   nic_ext=''
618
619   sed -i '/ControlPlaneSubnetCidr/c\\  ControlPlaneSubnetCidr: "'${admin_network_cidr##*/}'"' $1
620   sed -i '/ControlPlaneDefaultRoute/c\\  ControlPlaneDefaultRoute: '${admin_network_provisioner_ip}'' $1
621   sed -i '/ExternalNetCidr/c\\  ExternalNetCidr: '${public_network_cidr}'' $1
622   sed -i "/ExternalAllocationPools/c\\  ExternalAllocationPools: [{'start': '${public_network_usable_ip_range%%,*}', 'end': '${public_network_usable_ip_range##*,}'}]" $1
623   sed -i '/ExternalInterfaceDefaultRoute/c\\  ExternalInterfaceDefaultRoute: '${public_network_gateway}'' $1
624   sed -i '/EC2MetadataIp/c\\  EC2MetadataIp: '${admin_network_provisioner_ip}'' $1
625
626   # check for private network
627   if [[ ! -z "$private_network_enabled" && "$private_network_enabled" == "true" ]]; then
628       sed -i 's#^.*Network::Tenant.*$#  OS::TripleO::Network::Tenant: '${tht_dir}'/tenant.yaml#' $1
629       sed -i 's#^.*Controller::Ports::TenantPort:.*$#  OS::TripleO::Controller::Ports::TenantPort: '${tht_dir}'/ports/tenant.yaml#' $1
630       sed -i 's#^.*Compute::Ports::TenantPort:.*$#  OS::TripleO::Compute::Ports::TenantPort: '${tht_dir}'/ports/tenant.yaml#' $1
631       sed -i "/TenantAllocationPools/c\\  TenantAllocationPools: [{'start': '${private_network_usable_ip_range%%,*}', 'end': '${private_network_usable_ip_range##*,}'}]" $1
632       sed -i '/TenantNetCidr/c\\  TenantNetCidr: '${private_network_cidr}'' $1
633       nic_ext+=_private
634   else
635       sed -i 's#^.*Network::Tenant.*$#  OS::TripleO::Network::Tenant: '${tht_dir}'/noop.yaml#' $1
636       sed -i 's#^.*Controller::Ports::TenantPort:.*$#  OS::TripleO::Controller::Ports::TenantPort: '${tht_dir}'/ports/noop.yaml#' $1
637       sed -i 's#^.*Compute::Ports::TenantPort:.*$#  OS::TripleO::Compute::Ports::TenantPort: '${tht_dir}'/ports/noop.yaml#' $1
638   fi
639
640   # check for storage network
641   if [[ ! -z "$storage_network_enabled" && "$storage_network_enabled" == "true" ]]; then
642       sed -i 's#^.*Network::Storage.*$#  OS::TripleO::Network::Storage: '${tht_dir}'/storage.yaml#' $1
643       sed -i 's#^.*Controller::Ports::StoragePort:.*$#  OS::TripleO::Controller::Ports::StoragePort: '${tht_dir}'/ports/storage.yaml#' $1
644       sed -i 's#^.*Compute::Ports::StoragePort:.*$#  OS::TripleO::Compute::Ports::StoragePort: '${tht_dir}'/ports/storage.yaml#' $1
645       sed -i "/StorageAllocationPools/c\\  StorageAllocationPools: [{'start': '${storage_network_usable_ip_range%%,*}', 'end': '${storage_network_usable_ip_range##*,}'}]" $1
646       sed -i '/StorageNetCidr/c\\  StorageNetCidr: '${storage_network_cidr}'' $1
647       nic_ext+=_storage
648   else
649       sed -i 's#^.*Network::Storage.*$#  OS::TripleO::Network::Storage: '${tht_dir}'/noop.yaml#' $1
650       sed -i 's#^.*Controller::Ports::StoragePort:.*$#  OS::TripleO::Controller::Ports::StoragePort: '${tht_dir}'/ports/noop.yaml#' $1
651       sed -i 's#^.*Compute::Ports::StoragePort:.*$#  OS::TripleO::Compute::Ports::StoragePort: '${tht_dir}'/ports/noop.yaml#' $1
652   fi
653
654   # check for ODL L3
655   if [ ${deploy_options_array['sdn_l3']} == 'true' ]; then
656       nic_ext+=_br-ex
657   fi
658
659   # set nics appropriately
660   sed -i 's#^.*Compute::Net::SoftwareConfig:.*$#  OS::TripleO::Compute::Net::SoftwareConfig: nics/compute'${nic_ext}'.yaml#' $1
661   sed -i 's#^.*Controller::Net::SoftwareConfig:.*$#  OS::TripleO::Controller::Net::SoftwareConfig: nics/controller'${nic_ext}'.yaml#' $1
662 }
663 ##Copy over the glance images and instack json file
664 ##params: none
665 function configure_undercloud {
666
667   echo
668   echo "Copying configuration file and disk images to instack"
669   scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.qcow2 "stack@$UNDERCLOUD":
670   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
671     configure_network_environment $CONFIG/network-environment.yaml
672     echo -e "${blue}Network Environment set for Deployment: ${reset}"
673     cat $CONFIG/network-environment.yaml
674     scp ${SSH_OPTIONS[@]} $CONFIG/network-environment.yaml "stack@$UNDERCLOUD":
675   fi
676   scp ${SSH_OPTIONS[@]} -r $CONFIG/nics/ "stack@$UNDERCLOUD":
677
678   # ensure stack user on instack machine has an ssh key
679   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"
680
681   if [ "$virtual" == "TRUE" ]; then
682
683       # copy the instack vm's stack user's pub key to
684       # root's auth keys so that instack can control
685       # vm power on the hypervisor
686       ssh ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
687
688       # fix MACs to match new setup
689       for i in $(seq 0 $vm_index); do
690         pyscript="import json
691 data = json.load(open('$CONFIG/instackenv-virt.json'))
692 print data['nodes'][$i]['mac'][0]"
693
694         old_mac=$(python -c "$pyscript")
695         new_mac=$(virsh dumpxml baremetalbrbm_brbm1_brbm2_brbm3_$i | grep "mac address" | cut -d = -f2 | grep -Eo "[0-9a-f:]+")
696         # this doesn't work with multiple vnics on the vms
697         #if [ "$old_mac" != "$new_mac" ]; then
698         #  echo "${blue}Modifying MAC for node from $old_mac to ${new_mac}${reset}"
699         #  sed -i 's/'"$old_mac"'/'"$new_mac"'/' $CONFIG/instackenv-virt.json
700         #fi
701       done
702
703       DEPLOY_OPTIONS+=" --libvirt-type qemu"
704       INSTACKENV=$CONFIG/instackenv-virt.json
705
706       # upload instackenv file to Instack for virtual deployment
707       scp ${SSH_OPTIONS[@]} $INSTACKENV "stack@$UNDERCLOUD":instackenv.json
708   fi
709
710   # allow stack to control power management on the hypervisor via sshkey
711   # only if this is a virtual deployment
712   if [ "$virtual" == "TRUE" ]; then
713       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
714 while read -r line; do
715   stack_key=\${stack_key}\\\\\\\\n\${line}
716 done < <(cat ~/.ssh/id_rsa)
717 stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
718 sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
719 EOI
720   fi
721
722   # copy stack's ssh key to this users authorized keys
723   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
724
725   # disable requiretty for sudo
726   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "sed -i 's/Defaults\s*requiretty//'" /etc/sudoers
727
728   # configure undercloud on Undercloud VM
729   echo "Running undercloud configuration."
730   echo "Logging undercloud configuration to instack:/home/stack/apex-undercloud-install.log"
731   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
732 if [[ "$net_isolation_enabled" == "TRUE" ]]; then
733   sed -i 's/#local_ip/local_ip/' undercloud.conf
734   sed -i 's/#network_gateway/network_gateway/' undercloud.conf
735   sed -i 's/#network_cidr/network_cidr/' undercloud.conf
736   sed -i 's/#dhcp_start/dhcp_start/' undercloud.conf
737   sed -i 's/#dhcp_end/dhcp_end/' undercloud.conf
738   sed -i 's/#inspection_iprange/inspection_iprange/' undercloud.conf
739   sed -i 's/#undercloud_debug/undercloud_debug/' undercloud.conf
740
741   openstack-config --set undercloud.conf DEFAULT local_ip ${admin_network_provisioner_ip}/${admin_network_cidr##*/}
742   openstack-config --set undercloud.conf DEFAULT network_gateway ${admin_network_provisioner_ip}
743   openstack-config --set undercloud.conf DEFAULT network_cidr ${admin_network_cidr}
744   openstack-config --set undercloud.conf DEFAULT dhcp_start ${admin_network_dhcp_range%%,*}
745   openstack-config --set undercloud.conf DEFAULT dhcp_end ${admin_network_dhcp_range##*,}
746   openstack-config --set undercloud.conf DEFAULT inspection_iprange ${admin_network_introspection_range}
747   openstack-config --set undercloud.conf DEFAULT undercloud_debug false
748
749 fi
750
751 sudo sed -i '/CephClusterFSID:/c\\  CephClusterFSID: \\x27$(cat /proc/sys/kernel/random/uuid)\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
752 sudo sed -i '/CephMonKey:/c\\  CephMonKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
753 sudo sed -i '/CephAdminKey:/c\\  CephAdminKey: \\x27'"\$(ceph-authtool --gen-print-key)"'\\x27' /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
754
755 openstack undercloud install &> apex-undercloud-install.log
756 sleep 30
757 sudo systemctl restart openstack-glance-api
758 sudo systemctl restart openstack-nova-conductor
759 sudo systemctl restart openstack-nova-compute
760 EOI
761 # WORKAROUND: must restart the above services to fix sync problem with nova compute manager
762 # TODO: revisit and file a bug if necessary. This should eventually be removed
763 # as well as glance api problem
764 echo -e "${blue}INFO: Sleeping 15 seconds while services come back from restart${reset}"
765 sleep 15
766
767 }
768
769 ##preping it for deployment and launch the deploy
770 ##params: none
771 function undercloud_prep_overcloud_deploy {
772   if [[ ${#deploy_options_array[@]} -eq 0 || ${deploy_options_array['sdn_controller']} == 'opendaylight' ]]; then
773     if [ ${deploy_options_array['sdn_l3']} == 'true' ]; then
774       DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight_l3.yaml"
775     else
776       DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight.yaml"
777     fi
778   elif [ ${deploy_options_array['sdn_controller']} == 'opendaylight-external' ]; then
779     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight-external.yaml"
780   elif [ ${deploy_options_array['sdn_controller']} == 'onos' ]; then
781     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/onos.yaml"
782   elif [ ${deploy_options_array['sdn_controller']} == 'opencontrail' ]; then
783     echo -e "${red}ERROR: OpenContrail is currently unsupported...exiting${reset}"
784     exit 1
785   fi
786
787   # make sure ceph is installed
788   DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml"
789
790   # check if HA is enabled
791   if [[ "$ha_enabled" == "TRUE" ]]; then
792      DEPLOY_OPTIONS+=" --control-scale 3 --compute-scale 2"
793      DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/puppet-pacemaker.yaml"
794   fi
795
796   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
797      #DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/network-isolation.yaml"
798      DEPLOY_OPTIONS+=" -e network-environment.yaml"
799   fi
800
801   if [[ "$ha_enabled" == "TRUE" ]] || [[ "$net_isolation_enabled" == "TRUE" ]]; then
802      DEPLOY_OPTIONS+=" --ntp-server $ntp_server"
803   fi
804
805   if [[ ! "$virtual" == "TRUE" ]]; then
806      DEPLOY_OPTIONS+=" --control-flavor control --compute-flavor compute"
807   fi
808
809   echo -e "${blue}INFO: Deploy options set:\n${DEPLOY_OPTIONS}${reset}"
810
811   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
812 source stackrc
813 set -o errexit
814 echo "Uploading overcloud glance images"
815 openstack overcloud image upload
816 echo "Configuring undercloud and discovering nodes"
817 openstack baremetal import --json instackenv.json
818 openstack baremetal configure boot
819 openstack baremetal introspection bulk start
820 echo "Configuring flavors"
821 for flavor in baremetal control compute; do
822   echo -e "${blue}INFO: Updating flavor: \${flavor}${reset}"
823   if openstack flavor list | grep \${flavor}; then
824     openstack flavor delete \${flavor}
825   fi
826   openstack flavor create --id auto --ram 4096 --disk 39 --vcpus 1 \${flavor}
827   if ! openstack flavor list | grep \${flavor}; then
828     echo -e "${red}ERROR: Unable to create flavor \${flavor}${reset}"
829   fi
830 done
831 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" baremetal
832 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="control" control
833 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="compute" compute
834 echo "Configuring nameserver on ctlplane network"
835 neutron subnet-update \$(neutron subnet-list | grep -v id | grep -v \\\\-\\\\- | awk {'print \$2'}) --dns-nameserver 8.8.8.8
836 echo "Executing overcloud deployment, this should run for an extended period without output."
837 sleep 60 #wait for Hypervisor stats to check-in to nova
838 # save deploy command so it can be used for debugging
839 cat > deploy_command << EOF
840 openstack overcloud deploy --templates $DEPLOY_OPTIONS
841 EOF
842 openstack overcloud deploy --templates $DEPLOY_OPTIONS
843 EOI
844
845 }
846
847 ##Post configuration after install
848 ##params: none
849 function configure_post_install {
850   local opnfv_attach_networks ovs_ip ip_range net_cidr tmp_ip
851   opnfv_attach_networks="admin_network public_network"
852
853   echo -e "${blue}INFO: Post Install Configuration Running...${reset}"
854
855   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
856 source overcloudrc
857 set -o errexit
858 echo "Configuring Neutron external network"
859 neutron net-create external --router:external=True
860 neutron subnet-create --name external-net --disable-dhcp external --gateway ${public_network_gateway} --allocation-pool start=${public_network_floating_ip_range%%,*},end=${public_network_floating_ip_range##*,} ${public_network_cidr}
861 EOI
862
863   echo -e "${blue}INFO: Checking if OVS bridges have IP addresses...${reset}"
864   for network in ${opnfv_attach_networks}; do
865     ovs_ip=$(find_ip ${NET_MAP[$network]})
866     tmp_ip=''
867     if [ -n "$ovs_ip" ]; then
868       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} has IP address ${ovs_ip}${reset}"
869     else
870       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} missing IP, will configure${reset}"
871       # use last IP of allocation pool
872       eval "ip_range=\${${network}_usable_ip_range}"
873       ovs_ip=${ip_range##*,}
874       eval "net_cidr=\${${network}_cidr}"
875       sudo ip addr add ${ovs_ip}/${net_cidr##*/} dev ${NET_MAP[$network]}
876       sudo ip link set up ${NET_MAP[$network]}
877       tmp_ip=$(find_ip ${NET_MAP[$network]})
878       if [ -n "$tmp_ip" ]; then
879         echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} IP set: ${tmp_ip}${reset}"
880         continue
881       else
882         echo -e "${red}ERROR: Unable to set OVS Bridge ${NET_MAP[$network]} with IP: ${ovs_ip}${reset}"
883         return 1
884       fi
885     fi
886   done
887
888   # for virtual, we NAT public network through instack
889   if [ "$virtual" == "TRUE" ]; then
890     if ! configure_undercloud_nat ${public_network_cidr}; then
891       echo -e "${red}ERROR: Unable to NAT undercloud with external net: ${public_network_cidr}${reset}"
892       exit 1
893     else
894       echo -e "${blue}INFO: Undercloud (instack VM) has been setup to NAT Overcloud public network${reset}"
895     fi
896   fi
897 }
898
899 display_usage() {
900   echo -e "Usage:\n$0 [arguments] \n"
901   echo -e "   -c|--config : Directory to configuration files. Optional.  Defaults to /var/opt/opnfv/ \n"
902   echo -e "   -d|--deploy-settings : Full path to deploy settings yaml file. Optional.  Defaults to null \n"
903   echo -e "   -i|--inventory : Full path to inventory yaml file. Required only for baremetal \n"
904   echo -e "   -n|--net-settings : Full path to network settings file. Optional. \n"
905   echo -e "   -p|--ping-site : site to use to verify IP connectivity. Optional. Defaults to 8.8.8.8 \n"
906   echo -e "   -r|--resources : Directory to deployment resources. Optional.  Defaults to /var/opt/opnfv/stack \n"
907   echo -e "   -v|--virtual : Virtualize overcloud nodes instead of using baremetal. \n"
908   echo -e "   --no-ha : disable High Availability deployment scheme, this assumes a single controller and single compute node \n"
909   echo -e "   --flat : disable Network Isolation and use a single flat network for the underlay network.\n"
910   echo -e "   --no-post-config : disable Post Install configuration."
911 }
912
913 ##translates the command line parameters into variables
914 ##params: $@ the entire command line is passed
915 ##usage: parse_cmd_line() "$@"
916 parse_cmdline() {
917   echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
918   echo "Use -h to display help"
919   sleep 2
920
921   while [ "${1:0:1}" = "-" ]
922   do
923     case "$1" in
924         -h|--help)
925                 display_usage
926                 exit 0
927             ;;
928         -c|--config)
929                 CONFIG=$2
930                 echo "Deployment Configuration Directory Overridden to: $2"
931                 shift 2
932             ;;
933         -d|--deploy-settings)
934                 DEPLOY_SETTINGS_FILE=$2
935                 echo "Deployment Configuration file: $2"
936                 shift 2
937             ;;
938         -i|--inventory)
939                 INVENTORY_FILE=$2
940                 shift 2
941             ;;
942         -n|--net-settings)
943                 NETSETS=$2
944                 echo "Network Settings Configuration file: $2"
945                 shift 2
946             ;;
947         -p|--ping-site)
948                 ping_site=$2
949                 echo "Using $2 as the ping site"
950                 shift 2
951             ;;
952         -r|--resources)
953                 RESOURCES=$2
954                 echo "Deployment Resources Directory Overridden to: $2"
955                 shift 2
956             ;;
957         -v|--virtual)
958                 virtual="TRUE"
959                 echo "Executing a Virtual Deployment"
960                 shift 1
961             ;;
962         --no-ha )
963                 ha_enabled="FALSE"
964                 echo "HA Deployment Disabled"
965                 shift 1
966             ;;
967         --flat )
968                 net_isolation_enabled="FALSE"
969                 echo "Underlay Network Isolation Disabled: using flat configuration"
970                 shift 1
971             ;;
972         --no-post-config )
973                 post_config="FALSE"
974                 echo "Post install configuration disabled"
975                 shift 1
976             ;;
977         *)
978                 display_usage
979                 exit 1
980             ;;
981     esac
982   done
983
984   if [[ ! -z "$NETSETS" && "$net_isolation_enabled" == "FALSE" ]]; then
985     echo -e "${red}INFO: Single flat network requested. Ignoring any network settings!${reset}"
986   elif [[ -z "$NETSETS" && "$net_isolation_enabled" == "TRUE" ]]; then
987     echo -e "${red}ERROR: You must provide a network_settings file with -n or use --flat to force a single flat network${reset}"
988     exit 1
989   fi
990
991   if [[ -n "$virtual" && -n "$INVENTORY_FILE" ]]; then
992     echo -e "${red}ERROR: You should not specify an inventory with virtual deployments${reset}"
993     exit 1
994   fi
995
996   if [[ ! -z "$DEPLOY_SETTINGS_FILE" && ! -f "$DEPLOY_SETTINGS_FILE" ]]; then
997     echo -e "${red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
998     exit 1
999   fi
1000
1001   if [[ ! -z "$NETSETS" && ! -f "$NETSETS" ]]; then
1002     echo -e "${red}ERROR: ${NETSETS} does not exist! Exiting...${reset}"
1003     exit 1
1004   fi
1005
1006   if [[ ! -z "$INVENTORY_FILE" && ! -f "$INVENTORY_FILE" ]]; then
1007     echo -e "{$red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
1008     exit 1
1009   fi
1010
1011   if [[ -z "$virtual" && -z "$INVENTORY_FILE" ]]; then
1012     echo -e "${red}ERROR: You must specify an inventory file for baremetal deployments! Exiting...${reset}"
1013     exit 1
1014   fi
1015
1016   if [[ "$net_isolation_enabled" == "FALSE" && "$post_config" == "TRUE" ]]; then
1017     echo -e "${blue}INFO: Post Install Configuration will be skipped.  It is not supported with --flat${reset}"
1018     post_config="FALSE"
1019   fi
1020 }
1021
1022 ##END FUNCTIONS
1023
1024 main() {
1025   parse_cmdline "$@"
1026   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
1027     echo -e "${blue}INFO: Parsing network settings file...${reset}"
1028     parse_network_settings
1029   fi
1030   if ! configure_deps; then
1031     echo -e "${red}Dependency Validation Failed, Exiting.${reset}"
1032     exit 1
1033   fi
1034   if [ -n "$DEPLOY_SETTINGS_FILE" ]; then
1035     parse_deploy_settings
1036   fi
1037   setup_instack_vm
1038   if [ "$virtual" == "TRUE" ]; then
1039     setup_virtual_baremetal
1040   elif [ -n "$INVENTORY_FILE" ]; then
1041     parse_inventory_file
1042   fi
1043   configure_undercloud
1044   undercloud_prep_overcloud_deploy
1045   if [ "$post_config" == "TRUE" ]; then
1046     if ! configure_post_install; then
1047       echo -e "${red}ERROR:Post Install Configuration Failed, Exiting.${reset}"
1048       exit 1
1049     else
1050       echo -e "${blue}INFO: Post Install Configuration Complete${reset}"
1051     fi
1052   fi
1053   if [[ ${deploy_options_array['sdn_controller']} == 'onos' ]]; then
1054     if ! onos_update_gw_mac ${public_network_cidr} ${public_network_gateway}; then
1055       echo -e "${red}ERROR:ONOS Post Install Configuration Failed, Exiting.${reset}"
1056       exit 1
1057     else
1058       echo -e "${blue}INFO: ONOS Post Install Configuration Complete${reset}"
1059     fi
1060   fi
1061 }
1062
1063 main "$@"