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