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