8b5fa539c2a55bf21fe12fe7de6fe0c4838621c8
[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
30 declare -i CNT
31 declare UNDERCLOUD
32 declare -A deploy_options_array
33
34 SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
35 DEPLOY_OPTIONS=""
36 RESOURCES=/var/opt/opnfv/stack
37 CONFIG=/var/opt/opnfv
38 INSTACKENV=$CONFIG/instackenv.json
39 NETENV=$CONFIG/network-environment.yaml
40
41 ##FUNCTIONS
42 ##translates yaml into variables
43 ##params: filename, prefix (ex. "config_")
44 ##usage: parse_yaml opnfv_ksgen_settings.yml "config_"
45 parse_yaml() {
46    local prefix=$2
47    local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
48    sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
49         -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p"  $1 |
50    awk -F$fs '{
51       indent = length($1)/2;
52       vname[indent] = $2;
53       for (i in vname) {if (i > indent) {delete vname[i]}}
54       if (length($3) > 0) {
55          vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
56          printf("%s%s%s=%s\n", "'$prefix'",vn, $2, $3);
57       }
58    }'
59 }
60
61 ##checks if prefix exists in string
62 ##params: string, prefix
63 ##usage: contains_prefix "deploy_setting_launcher=1" "deploy_setting"
64 contains_prefix() {
65   local mystr=$1
66   local prefix=$2
67   if echo $mystr | grep -E "^$prefix.*$" > /dev/null; then
68     return 0
69   else
70     return 1
71   fi
72 }
73 ##parses variable from a string with '='
74 ##and removes global prefix
75 ##params: string, prefix
76 ##usage: parse_setting_var 'deploy_myvar=2' 'deploy_'
77 parse_setting_var() {
78   local mystr=$1
79   local prefix=$2
80   if echo $mystr | grep -E "^.+\=" > /dev/null; then
81     echo $(echo $mystr | grep -Eo "^.+\=" | tr -d '=' |  sed 's/^'"$prefix"'//')
82   else
83     return 1
84   fi
85 }
86 ##parses value from a string with '='
87 ##params: string
88 ##usage: parse_setting_value
89 parse_setting_value() {
90   local mystr=$1
91   echo $(echo $mystr | grep -Eo "\=.*$" | tr -d '=')
92 }
93 ##parses deploy settings yaml into globals and options array
94 ##params: none
95 ##usage:  parse_deploy_settings
96 parse_deploy_settings() {
97   local global_prefix="deploy_global_params_"
98   local options_prefix="deploy_deploy_options_"
99   local myvar myvalue
100   local settings=$(parse_yaml $DEPLOY_SETTINGS_FILE "deploy_")
101
102   for this_setting in $settings; do
103     if contains_prefix $this_setting $global_prefix; then
104       myvar=$(parse_setting_var $this_setting $global_prefix)
105       if [ -z "$myvar" ]; then
106         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
107       fi
108       myvalue=$(parse_setting_value $this_setting)
109       # Do not override variables set by cmdline
110       if [ -z "$(eval echo \$$myvar)" ]; then
111         eval "$myvar=\$myvalue"
112         echo -e "${blue}Global parameter set: ${myvar}:${myvalue}${reset}"
113       else
114         echo -e "${blue}Global parameter already set: ${myvar}${reset}"
115       fi
116     elif contains_prefix $this_setting $options_prefix; then
117       myvar=$(parse_setting_var $this_setting $options_prefix)
118       if [ -z "$myvar" ]; then
119         echo -e "${red}ERROR: while parsing ${DEPLOY_SETTINGS_FILE} for setting: ${this_setting}${reset}"
120       fi
121       myvalue=$(parse_setting_value $this_setting)
122       deploy_options_array[$myvar]=$myvalue
123       echo -e "${blue}Deploy option set: ${myvar}:${myvalue}${reset}"
124     fi
125   done
126 }
127 ##parses baremetal yaml settings into compatible json
128 ##writes the json to $CONFIG/instackenv_tmp.json
129 ##params: none
130 ##usage: parse_inventory_file
131 parse_inventory_file() {
132   local inventory=$(parse_yaml $INVENTORY_FILE)
133   local node_list
134   local node_prefix="node"
135   local node_count=0
136   local node_total
137   local inventory_list
138
139   # detect number of nodes
140   for entry in $inventory; do
141     if echo $entry | grep -Eo "^nodes_node[0-9]+_" > /dev/null; then
142       this_node=$(echo $entry | grep -Eo "^nodes_node[0-9]+_")
143       if [[ $inventory_list != *"$this_node"* ]]; then
144         inventory_list+="$this_node "
145       fi
146     fi
147   done
148
149   inventory_list=$(echo $inventory_list | sed 's/ $//')
150
151   for node in $inventory_list; do
152     ((node_count+=1))
153   done
154
155   node_total=$node_count
156
157   if [[ "$node_total" -lt 5 && ha_enabled == "TRUE" ]]; then
158     echo -e "${red}ERROR: You must provide at least 5 nodes for HA baremetal deployment${reset}"
159     exit 1
160   elif [[ "$node_total" -lt 2 ]]; then
161     echo -e "${red}ERROR: You must provide at least 2 nodes for non-HA baremetal deployment${reset}"
162     exit 1
163   fi
164
165   eval $(parse_yaml $INVENTORY_FILE)
166
167   instack_env_output="
168 {
169  \"nodes\" : [
170
171 "
172   node_count=0
173   for node in $inventory_list; do
174     ((node_count+=1))
175     node_output="
176         {
177           \"pm_password\": \"$(eval echo \${${node}ipmi_pass})\",
178           \"pm_type\": \"pxe_ipmitool\",
179           \"mac\": [
180             \"$(eval echo \${${node}mac_address})\"
181           ],
182           \"cpu\": \"$(eval echo \${${node}cpus})\",
183           \"memory\": \"$(eval echo \${${node}memory})\",
184           \"disk\": \"$(eval echo \${${node}disk})\",
185           \"arch\": \"$(eval echo \${${node}arch})\",
186           \"pm_user\": \"$(eval echo \${${node}ipmi_user})\",
187           \"pm_addr\": \"$(eval echo \${${node}ipmi_ip})\",
188           \"capabilities\": \"$(eval echo \${${node}capabilities})\"
189 "
190     instack_env_output+=${node_output}
191     if [ $node_count -lt $node_total ]; then
192       instack_env_output+="        },"
193     else
194       instack_env_output+="        }"
195     fi
196   done
197
198   instack_env_output+='
199   ]
200 }
201 '
202   #Copy instackenv.json to undercloud for baremetal
203   echo -e "{blue}Parsed instackenv JSON:\n${instack_env_output}${reset}"
204   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
205 cat > instackenv.json << EOF
206 $instack_env_output
207 EOF
208 EOI
209
210 }
211 ##verify internet connectivity
212 #params: none
213 function verify_internet {
214   if ping -c 2 $ping_site > /dev/null; then
215     if ping -c 2 www.google.com > /dev/null; then
216       echo "${blue}Internet connectivity detected${reset}"
217       return 0
218     else
219       echo "${red}Internet connectivity detected, but DNS lookup failed${reset}"
220       return 1
221     fi
222   else
223     echo "${red}No internet connectivity detected${reset}"
224     return 1
225   fi
226 }
227
228 ##download dependencies if missing and configure host
229 #params: none
230 function configure_deps {
231   if ! verify_internet; then
232     echo "${red}Will not download dependencies${reset}"
233     internet=false
234   fi
235
236   # verify ip forwarding
237   if sysctl net.ipv4.ip_forward | grep 0; then
238     sudo sysctl -w net.ipv4.ip_forward=1
239     sudo sh -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"
240   fi
241
242   # ensure brbm networks are configured
243   systemctl start openvswitch
244   ovs-vsctl list-br | grep brbm > /dev/null || ovs-vsctl add-br brbm
245   virsh net-list --all | grep brbm > /dev/null || virsh net-create $CONFIG/brbm-net.xml
246   virsh net-list | grep -E "brbm\s+active" > /dev/null || virsh net-start brbm
247   ovs-vsctl list-br | grep brbm1 > /dev/null || ovs-vsctl add-br brbm1
248   virsh net-list --all | grep brbm1 > /dev/null || virsh net-create $CONFIG/brbm1-net.xml
249   virsh net-list | grep -E "brbm1\s+active" > /dev/null || virsh net-start brbm1
250
251   # ensure storage pool exists and is started
252   virsh pool-list --all | grep default > /dev/null || virsh pool-create $CONFIG/default-pool.xml
253   virsh pool-list | grep -Eo "default\s+active" > /dev/null || virsh pool-start default
254
255   if virsh net-list | grep default > /dev/null; then
256     num_ints_same_subnet=$(ip addr show | grep "inet 192.168.122" | wc -l)
257     if [ "$num_ints_same_subnet" -gt 1 ]; then
258       virsh net-destroy default
259       ##go edit /etc/libvirt/qemu/networks/default.xml
260       sed -i 's/192.168.122/192.168.123/g' /etc/libvirt/qemu/networks/default.xml
261       sed -i 's/192.168.122/192.168.123/g' instackenv-virt.json
262       sleep 5
263       virsh net-start default
264       virsh net-autostart default
265     fi
266   fi
267
268   if ! egrep '^flags.*(vmx|svm)' /proc/cpuinfo > /dev/null; then
269     echo "${red}virtualization extensions not found, kvm kernel module insertion may fail.\n  \
270 Are you sure you have enabled vmx in your bios or hypervisor?${reset}"
271   fi
272
273   if ! lsmod | grep kvm > /dev/null; then modprobe kvm; fi
274   if ! lsmod | grep kvm_intel > /dev/null; then modprobe kvm_intel; fi
275
276   if ! lsmod | grep kvm > /dev/null; then
277     echo "${red}kvm kernel modules not loaded!${reset}"
278     return 1
279   fi
280
281   ##sshkeygen for root
282   if [ ! -e ~/.ssh/id_rsa.pub ]; then
283     ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
284   fi
285
286   echo "${blue}All dependencies installed and running${reset}"
287 }
288
289 ##verify vm exists, an has a dhcp lease assigned to it
290 ##params: none
291 function setup_instack_vm {
292   if ! virsh list --all | grep instack > /dev/null; then
293       #virsh vol-create default instack.qcow2.xml
294       virsh define $CONFIG/instack.xml
295
296       #Upload instack image
297       #virsh vol-create default --file instack.qcow2.xml
298       virsh vol-create-as default instack.qcow2 30G --format qcow2
299
300       ### this doesn't work for some reason I was getting hangup events so using cp instead
301       #virsh vol-upload --pool default --vol instack.qcow2 --file $CONFIG/stack/instack.qcow2
302       #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)
303       #2015-12-05 12:57:20.569+0000: 8755: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
304       #2015-12-05 12:57:20.569+0000: 8756: warning : virKeepAliveTimerInternal:143 : No response from client 0x7ff1e231e630 after 6 keepalive messages in 35 seconds
305       #error: cannot close volume instack.qcow2
306       #error: internal error: received hangup / error event on socket
307       #error: Reconnected to the hypervisor
308
309       cp -f $RESOURCES/instack.qcow2 /var/lib/libvirt/images/instack.qcow2
310
311   else
312       echo "Found Instack VM, using existing VM"
313   fi
314
315   # if the VM is not running update the authkeys and start it
316   if ! virsh list | grep instack > /dev/null; then
317     echo "Injecting ssh key to instack VM"
318     virt-customize -c qemu:///system -d instack --run-command "mkdir /root/.ssh/" \
319         --upload ~/.ssh/id_rsa.pub:/root/.ssh/authorized_keys \
320         --run-command "chmod 600 /root/.ssh/authorized_keys && restorecon /root/.ssh/authorized_keys" \
321         --run-command "cp /root/.ssh/authorized_keys /home/stack/.ssh/" \
322         --run-command "chown stack:stack /home/stack/.ssh/authorized_keys && chmod 600 /home/stack/.ssh/authorized_keys"
323     virsh start instack
324   fi
325
326   sleep 3 # let DHCP happen
327
328   CNT=10
329   echo -n "${blue}Waiting for instack's dhcp address${reset}"
330   while ! grep instack /var/lib/libvirt/dnsmasq/default.leases > /dev/null && [ $CNT -gt 0 ]; do
331       echo -n "."
332       sleep 3
333       CNT=CNT-1
334   done
335
336   # get the instack VM IP
337   UNDERCLOUD=$(grep instack /var/lib/libvirt/dnsmasq/default.leases | awk '{print $3}' | head -n 1)
338   if [ -z "$UNDERCLOUD" ]; then
339     #if not found then dnsmasq may be using leasefile-ro
340     instack_mac=$(virsh domiflist instack | grep default | \
341                   grep -Eo "[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+:[0-9a-f\]+")
342     UNDERCLOUD=$(arp -e | grep ${instack_mac} | awk {'print $1'})
343
344     if [ -z "$UNDERCLOUD" ]; then
345       echo "\n\nNever got IP for Instack. Can Not Continue."
346       exit 1
347     fi
348   else
349      echo -e "${blue}\rInstack VM has IP $UNDERCLOUD${reset}"
350   fi
351
352   CNT=10
353   echo -en "${blue}\rValidating instack VM connectivity${reset}"
354   while ! ping -c 1 $UNDERCLOUD > /dev/null && [ $CNT -gt 0 ]; do
355       echo -n "."
356       sleep 3
357       CNT=$CNT-1
358   done
359   if [ "$CNT" -eq 0 ]; then
360       echo "Failed to contact Instack. Can Not Continue"
361       exit 1
362   fi
363   CNT=10
364   while ! ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "echo ''" 2>&1> /dev/null && [ $CNT -gt 0 ]; do
365       echo -n "."
366       sleep 3
367       CNT=$CNT-1
368   done
369   if [ "$CNT" -eq 0 ]; then
370       echo "Failed to connect to Instack. Can Not Continue"
371       exit 1
372   fi
373
374   # extra space to overwrite the previous connectivity output
375   echo -e "${blue}\r                                                                 ${reset}"
376
377   #add the instack brbm1 interface
378   virsh attach-interface --domain instack --type network --source brbm1 --model rtl8139 --config --live
379   sleep 1
380   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "if ! ip a s eth2 | grep 192.168.37.1 > /dev/null; then ip a a 192.168.37.1/24 dev eth2; ip link set up dev eth2; fi"
381
382   # ssh key fix for stack user
383   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "restorecon -r /home/stack"
384 }
385
386 ##Create virtual nodes in virsh
387 ##params: none
388 function setup_virtual_baremetal {
389   for i in $(seq 0 $vm_index); do
390     if ! virsh list --all | grep baremetalbrbm_brbm1_${i} > /dev/null; then
391       if [ ! -e $CONFIG/baremetalbrbm_brbm1_${i}.xml ]; then
392         define_virtual_node baremetalbrbm_brbm1_${i}
393       fi
394       virsh define $CONFIG/baremetalbrbm_brbm1_${i}.xml
395     else
396       echo "Found Baremetal ${i} VM, using existing VM"
397     fi
398     virsh vol-list default | grep baremetalbrbm_brbm1_${i} 2>&1> /dev/null || virsh vol-create-as default baremetalbrbm_brbm1_${i}.qcow2 40G --format qcow2
399   done
400
401 }
402
403 ##Copy over the glance images and instack json file
404 ##params: none
405 function configure_undercloud {
406
407   echo
408   echo "Copying configuration file and disk images to instack"
409   scp ${SSH_OPTIONS[@]} $RESOURCES/overcloud-full.qcow2 "stack@$UNDERCLOUD":
410   scp ${SSH_OPTIONS[@]} $NETENV "stack@$UNDERCLOUD":
411   scp ${SSH_OPTIONS[@]} -r $CONFIG/nics/ "stack@$UNDERCLOUD":
412
413   # ensure stack user on instack machine has an ssh key
414   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "if [ ! -e ~/.ssh/id_rsa.pub ]; then ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa; fi"
415
416   if [ "$virtual" == "TRUE" ]; then
417
418       # copy the instack vm's stack user's pub key to
419       # root's auth keys so that instack can control
420       # vm power on the hypervisor
421       ssh ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> /root/.ssh/authorized_keys
422
423       # fix MACs to match new setup
424       for i in $(seq 0 $vm_index); do
425         pyscript="import json
426 data = json.load(open('$CONFIG/instackenv-virt.json'))
427 print data['nodes'][$i]['mac'][0]"
428
429         old_mac=$(python -c "$pyscript")
430         new_mac=$(virsh dumpxml baremetalbrbm_brbm1_$i | grep "mac address" | cut -d = -f2 | grep -Eo "[0-9a-f:]+")
431         # this doesn't work with multiple vnics on the vms
432         #if [ "$old_mac" != "$new_mac" ]; then
433         #  echo "${blue}Modifying MAC for node from $old_mac to ${new_mac}${reset}"
434         #  sed -i 's/'"$old_mac"'/'"$new_mac"'/' $CONFIG/instackenv-virt.json
435         #fi
436       done
437
438       DEPLOY_OPTIONS+=" --libvirt-type qemu"
439       INSTACKENV=$CONFIG/instackenv-virt.json
440       NETENV=$CONFIG/network-environment.yaml
441
442       # upload instackenv file to Instack for virtual deployment
443       scp ${SSH_OPTIONS[@]} $INSTACKENV "stack@$UNDERCLOUD":instackenv.json
444   fi
445
446   # allow stack to control power management on the hypervisor via sshkey
447   # only if this is a virtual deployment
448   if [ "$virtual" == "TRUE" ]; then
449       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
450 while read -r line; do
451   stack_key=\${stack_key}\\\\\\\\n\${line}
452 done < <(cat ~/.ssh/id_rsa)
453 stack_key=\$(echo \$stack_key | sed 's/\\\\\\\\n//')
454 sed -i 's~INSERT_STACK_USER_PRIV_KEY~'"\$stack_key"'~' instackenv.json
455 EOI
456   fi
457
458   # copy stack's ssh key to this users authorized keys
459   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "cat /home/stack/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys
460
461   # disable requiretty for sudo
462   ssh -T ${SSH_OPTIONS[@]} "root@$UNDERCLOUD" "sed -i 's/Defaults\s*requiretty//'" /etc/sudoers
463
464   # configure undercloud on Undercloud VM
465   echo "Running undercloud configuration."
466   echo "Logging undercloud configuration to instack:/home/stack/apex-undercloud-install.log"
467   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
468 if [ -n "$DEPLOY_SETTINGS_FILE" ]; then
469   sed -i 's/#local_ip/local_ip/' undercloud.conf
470   sed -i 's/#network_gateway/network_gateway/' undercloud.conf
471   sed -i 's/#network_cidr/network_cidr/' undercloud.conf
472   sed -i 's/#dhcp_start/dhcp_start/' undercloud.conf
473   sed -i 's/#dhcp_end/dhcp_end/' undercloud.conf
474   sed -i 's/#inspection_iprange/inspection_iprange/' undercloud.conf
475   sed -i 's/#undercloud_debug/undercloud_debug/' undercloud.conf
476
477   openstack-config --set undercloud.conf DEFAULT local_ip ${deploy_options_array['instack_ip']}/${deploy_options_array['provisioning_cidr']##*/}
478   openstack-config --set undercloud.conf DEFAULT network_gateway ${deploy_options_array['provisioning_gateway']}
479   openstack-config --set undercloud.conf DEFAULT network_cidr ${deploy_options_array['provisioning_cidr']}
480   openstack-config --set undercloud.conf DEFAULT dhcp_start ${deploy_options_array['provisioning_dhcp_start']}
481   openstack-config --set undercloud.conf DEFAULT dhcp_end ${deploy_options_array['provisioning_dhcp_end']}
482   openstack-config --set undercloud.conf DEFAULT inspection_iprange ${deploy_options_array['provisioning_inspection_iprange']}
483   openstack-config --set undercloud.conf DEFAULT undercloud_debug false
484
485   if [ -n "$net_isolation_enabled" ]; then
486     sed -i '/ControlPlaneSubnetCidr/c\\  ControlPlaneSubnetCidr: "${deploy_options_array['provisioning_cidr']##*/}"' network-environment.yaml
487     sed -i '/ControlPlaneDefaultRoute/c\\  ControlPlaneDefaultRoute: ${deploy_options_array['provisioning_gateway']}' network-environment.yaml
488     sed -i '/ExternalNetCidr/c\\  ExternalNetCidr: ${deploy_options_array['ext_net_cidr']}' network-environment.yaml
489     sed -i '/ExternalAllocationPools/c\\  ExternalAllocationPools: [{'start': '${deploy_options_array['ext_allocation_pool_start']}', 'end': '${deploy_options_array['ext_allocation_pool_end']}'}]' network-environment.yaml
490     sed -i '/ExternalInterfaceDefaultRoute/c\\  ExternalInterfaceDefaultRoute: ${deploy_options_array['ext_gateway']}' network-environment.yaml
491   fi
492 fi
493
494 openstack undercloud install &> apex-undercloud-install.log
495 EOI
496 }
497
498 ##preping it for deployment and launch the deploy
499 ##params: none
500 function undercloud_prep_overcloud_deploy {
501
502   if [[ ${#deploy_options_array[@]} -eq 0 || ${deploy_options_array['sdn_controller']} == 'opendaylight' ]]; then
503     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight.yaml"
504   elif [ ${deploy_options_array['sdn_controller']} == 'opendaylight-external' ]; then
505     DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/opendaylight-external.yaml"
506   elif [ ${deploy_options_array['sdn_controller']} == 'onos' ]; then
507     echo -e "${red}ERROR: ONOS is currently unsupported...exiting${reset}"
508     exit 1
509   elif [ ${deploy_options_array['sdn_controller']} == 'opencontrail' ]; then
510     echo -e "${red}ERROR: OpenContrail is currently unsupported...exiting${reset}"
511     exit 1
512   fi
513
514   # check if HA is enabled
515   if [[ "$ha_enabled" == "TRUE" ]]; then
516      DEPLOY_OPTIONS+=" --control-scale 3 --compute-scale 2"
517      DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/puppet-pacemaker.yaml"
518   fi
519
520   if [[ "$net_isolation_enabled" == "TRUE" ]]; then
521      DEPLOY_OPTIONS+=" -e /usr/share/openstack-tripleo-heat-templates/environments/network-isolation.yaml"
522      DEPLOY_OPTIONS+=" -e network-environment.yaml"
523   fi
524
525   if [[ "$ha_enabled" == "TRUE" ]] || [[ $net_isolation_enabled == "TRUE" ]]; then
526      DEPLOY_OPTIONS+=" --ntp-server $ntp_server"
527   fi
528
529   if [[ ! "$virtual" == "TRUE" ]]; then
530      DEPLOY_OPTIONS+=" --control-flavor control --compute-flavor compute"
531   fi
532
533   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
534 source stackrc
535 set -o errexit
536 echo "Uploading overcloud glance images"
537 openstack overcloud image upload
538 echo "Configuring undercloud and discovering nodes"
539 openstack baremetal import --json instackenv.json
540 openstack baremetal configure boot
541 openstack baremetal introspection bulk start
542 echo "Configuring flavors"
543 for flavor in baremetal control compute; do
544   echo -e "${blue}INFO: Updating flavor: \${flavor}${reset}"
545   if openstack flavor list | grep \${flavor}; then
546     openstack flavor delete \${flavor}
547   fi
548   openstack flavor create --id auto --ram 4096 --disk 39 --vcpus 1 \${flavor}
549   if ! openstack flavor list | grep \${flavor}; then
550     echo -e "${red}ERROR: Unable to create flavor \${flavor}${reset}"
551   fi
552 done
553 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" baremetal
554 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="control" control
555 openstack flavor set --property "cpu_arch"="x86_64" --property "capabilities:boot_option"="local" --property "capabilities:profile"="compute" compute
556 echo "Configuring nameserver on ctlplane network"
557 neutron subnet-update \$(neutron subnet-list | grep -v id | grep -v \\\\-\\\\- | awk {'print \$2'}) --dns-nameserver 8.8.8.8
558 echo "Executing overcloud deployment, this should run for an extended period without output."
559 sleep 60 #wait for Hypervisor stats to check-in to nova
560 openstack overcloud deploy --templates $DEPLOY_OPTIONS
561 EOI
562
563 }
564
565 display_usage() {
566   echo -e "Usage:\n$0 [arguments] \n"
567   echo -e "   -c|--config : Directory to configuration files. Optional.  Defaults to /var/opt/opnfv/ \n"
568   echo -e "   -d|--deploy-settings : Full path to deploy settings yaml file. Optional.  Defaults to null \n"
569   echo -e "   -i|--inventory : Full path to inventory yaml file. Required only for baremetal \n"
570   echo -e "   -n|--netenv : Full path to network environment file. Optional. Defaults to \$CONFIG/network-environment.yaml \n"
571   echo -e "   -p|--ping-site : site to use to verify IP connectivity. Optional. Defaults to 8.8.8.8 \n"
572   echo -e "   -r|--resources : Directory to deployment resources. Optional.  Defaults to /var/opt/opnfv/stack \n"
573   echo -e "   -v|--virtual : Virtualize overcloud nodes instead of using baremetal. \n"
574   echo -e "   --no-ha : disable High Availability deployment scheme, this assumes a single controller and single compute node \n"
575   echo -e "   --flat : disable Network Isolation and use a single flat network for the underlay network."
576 }
577
578 ##translates the command line parameters into variables
579 ##params: $@ the entire command line is passed
580 ##usage: parse_cmd_line() "$@"
581 parse_cmdline() {
582   echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
583   echo "Use -h to display help"
584   sleep 2
585
586   while [ "${1:0:1}" = "-" ]
587   do
588     case "$1" in
589         -h|--help)
590                 display_usage
591                 exit 0
592             ;;
593         -c|--config)
594                 CONFIG=$2
595                 echo "Deployment Configuration Directory Overridden to: $2"
596                 shift 2
597             ;;
598         -d|--deploy-settings)
599                 DEPLOY_SETTINGS_FILE=$2
600                 echo "Deployment Configuration file: $2"
601                 shift 2
602             ;;
603         -i|--inventory)
604                 INVENTORY_FILE=$2
605                 shift 2
606             ;;
607         -n|--netenv)
608                 NETENV=$2
609                 shift 2
610             ;;
611         -p|--ping-site)
612                 ping_site=$2
613                 echo "Using $2 as the ping site"
614                 shift 2
615             ;;
616         -r|--resources)
617                 RESOURCES=$2
618                 echo "Deployment Resources Directory Overridden to: $2"
619                 shift 2
620             ;;
621         -v|--virtual)
622                 virtual="TRUE"
623                 echo "Executing a Virtual Deployment"
624                 shift 1
625             ;;
626         --no-ha )
627                 ha_enabled="FALSE"
628                 echo "HA Deployment Disabled"
629                 shift 1
630             ;;
631         --flat )
632                 net_isolation_enabled="FALSE"
633                 echo "Underlay Network Isolation Disabled: using flat configuration"
634                 shift 1
635             ;;
636         *)
637                 display_usage
638                 exit 1
639             ;;
640     esac
641   done
642
643   if [[ ! -z "$NETENV" && "$net_isolation_enabled" == "FALSE" ]]; then
644     echo -e "${red}INFO: Single flat network requested. Ignoring any netenv settings!${reset}"
645   elif [[ ! -z "$NETENV" && ! -z "$DEPLOY_SETTINGS_FILE" ]]; then
646     echo -e "${red}WARN: deploy_settings and netenv specified.  Ignoring netenv settings! deploy_settings will contain \
647 netenv${reset}"
648   fi
649
650   if [[ -n "$virtual" && -n "$INVENTORY_FILE" ]]; then
651     echo -e "${red}ERROR: You should not specify an inventory with virtual deployments${reset}"
652     exit 1
653   fi
654
655   if [[ ! -z "$DEPLOY_SETTINGS_FILE" && ! -f "$DEPLOY_SETTINGS_FILE" ]]; then
656     echo -e "${red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
657     exit 1
658   fi
659
660   if [[ ! -z "$NETENV" && ! -f "$NETENV" ]]; then
661     echo -e "${red}ERROR: ${NETENV} does not exist! Exiting...${reset}"
662     exit 1
663   fi
664
665   if [[ ! -z "$INVENTORY_FILE" && ! -f "$INVENTORY_FILE" ]]; then
666     echo -e "{$red}ERROR: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
667     exit 1
668   fi
669
670   if [[ -z "$virtual" && -z "$INVENTORY_FILE" ]]; then
671     echo -e "${red}ERROR: You must specify an inventory file for baremetal deployments! Exiting...${reset}"
672     exit 1
673   fi
674 }
675
676 ##END FUNCTIONS
677
678 main() {
679   parse_cmdline "$@"
680   if ! configure_deps; then
681     echo "Dependency Validation Failed, Exiting."
682   fi
683   if [ -n "$DEPLOY_SETTINGS_FILE" ]; then
684     parse_deploy_settings
685   fi
686   setup_instack_vm
687   if [ "$virtual" == "TRUE" ]; then
688     setup_virtual_baremetal
689   elif [ -n "$INVENTORY_FILE" ]; then
690     parse_inventory_file
691   fi
692   configure_undercloud
693   undercloud_prep_overcloud_deploy
694 }
695
696 main "$@"