Splitting out overcloud functions to lib files
[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 reset=$(tput sgr0 || echo "")
21 blue=$(tput setaf 4 || echo "")
22 red=$(tput setaf 1 || echo "")
23 green=$(tput setaf 2 || echo "")
24
25 interactive="FALSE"
26 ping_site="8.8.8.8"
27 ntp_server="pool.ntp.org"
28 net_isolation_enabled="TRUE"
29 post_config="TRUE"
30 debug="FALSE"
31
32 declare -i CNT
33 declare UNDERCLOUD
34 declare -A deploy_options_array
35 declare -a performance_options
36 declare -A NET_MAP
37
38 SSH_OPTIONS=(-o StrictHostKeyChecking=no -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=/dev/null -o LogLevel=error)
39 DEPLOY_OPTIONS=""
40 CONFIG=${CONFIG:-'/var/opt/opnfv'}
41 RESOURCES=${RESOURCES:-"$CONFIG/images"}
42 LIB=${LIB:-"$CONFIG/lib"}
43 OPNFV_NETWORK_TYPES="admin_network private_network public_network storage_network api_network"
44
45 VM_CPUS=4
46 VM_RAM=8
47 VM_COMPUTES=2
48
49 # Netmap used to map networks to OVS bridge names
50 NET_MAP['admin_network']="br-admin"
51 NET_MAP['private_network']="br-private"
52 NET_MAP['public_network']="br-public"
53 NET_MAP['storage_network']="br-storage"
54 NET_MAP['api_network']="br-api"
55 ext_net_type="interface"
56 ip_address_family=4
57
58 # Libraries
59 lib_files=(
60 $LIB/common-functions.sh
61 $LIB/configure-deps-functions.sh
62 $LIB/parse-functions.sh
63 $LIB/virtual-setup-functions.sh
64 $LIB/undercloud-functions.sh
65 $LIB/overcloud-deploy-functions.sh
66 $LIB/utility-functions.sh
67 $LIB/installer/onos/onos_gw_mac_update.sh
68 )
69 for lib_file in ${lib_files[@]}; do
70   if ! source $lib_file; then
71     echo -e "${red}ERROR: Failed to source $lib_file${reset}"
72     exit 1
73   fi
74 done
75
76 ##FUNCTIONS
77 ##checks if prefix exists in string
78 ##params: string, prefix
79 ##usage: contains_prefix "deploy_setting_launcher=1" "deploy_setting"
80 contains_prefix() {
81   local mystr=$1
82   local prefix=$2
83   if echo $mystr | grep -E "^$prefix.*$" > /dev/null; then
84     return 0
85   else
86     return 1
87   fi
88 }
89
90 ##verify internet connectivity
91 #params: none
92 function verify_internet {
93   if ping -c 2 $ping_site > /dev/null; then
94     if ping -c 2 www.google.com > /dev/null; then
95       echo "${blue}Internet connectivity detected${reset}"
96       return 0
97     else
98       echo "${red}Internet connectivity detected, but DNS lookup failed${reset}"
99       return 1
100     fi
101   else
102     echo "${red}No internet connectivity detected${reset}"
103     return 1
104   fi
105 }
106
107 ##Post configuration after install
108 ##params: none
109 function configure_post_install {
110   local opnfv_attach_networks ovs_ip ip_range net_cidr tmp_ip
111   opnfv_attach_networks="admin_network public_network"
112
113   echo -e "${blue}INFO: Post Install Configuration Running...${reset}"
114
115   echo -e "${blue}INFO: Configuring ssh for root to overcloud nodes...${reset}"
116   # copy host key to instack
117   scp ${SSH_OPTIONS[@]} /root/.ssh/id_rsa.pub "stack@$UNDERCLOUD":jumphost_id_rsa.pub
118
119   # add host key to overcloud nodes authorized keys
120   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" << EOI
121 source stackrc
122 nodes=\$(nova list | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
123 for node in \$nodes; do
124 cat ~/jumphost_id_rsa.pub | ssh -T ${SSH_OPTIONS[@]} "heat-admin@\$node" 'cat >> ~/.ssh/authorized_keys'
125 done
126 EOI
127
128   if [ "${deploy_options_array['dataplane']}" == 'ovs_dpdk' ]; then
129     echo -e "${blue}INFO: Bringing up br-phy and ovs-agent for dpdk compute nodes...${reset}"
130     compute_nodes=$(undercloud_connect stack "source stackrc; nova list | grep compute | wc -l")
131     i=0
132     while [ "$i" -lt "$compute_nodes" ]; do
133       overcloud_connect compute${i} "sudo ifup br-phy; sudo systemctl restart neutron-openvswitch-agent"
134       i=$((i + 1))
135     done
136   fi
137
138   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
139 source overcloudrc
140 set -o errexit
141 echo "Configuring Neutron external network"
142 neutron net-create external --router:external=True --tenant-id \$(openstack project show service | grep id | awk '{ print \$4 }')
143 neutron subnet-create --name external-net --tenant-id \$(openstack project show service | grep id | awk '{ print \$4 }') --disable-dhcp external --gateway ${public_network_gateway} --allocation-pool start=${public_network_floating_ip_range%%,*},end=${public_network_floating_ip_range##*,} ${public_network_cidr}
144
145 echo "Removing sahara endpoint and service"
146 sahara_service_id=\$(openstack service list | grep sahara | cut -d ' ' -f 2)
147 sahara_endpoint_id=\$(openstack endpoint list | grep sahara | cut -d ' ' -f 2)
148 openstack endpoint delete \$sahara_endpoint_id
149 openstack service delete \$sahara_service_id
150
151 echo "Removing swift endpoint and service"
152 swift_service_id=\$(openstack service list | grep swift | cut -d ' ' -f 2)
153 swift_endpoint_id=\$(openstack endpoint list | grep swift | cut -d ' ' -f 2)
154 openstack endpoint delete \$swift_endpoint_id
155 openstack service delete \$swift_service_id
156
157 if [ "${deploy_options_array['congress']}" == 'True' ]; then
158     for s in nova neutronv2 ceilometer cinder glancev2 keystone; do
159         openstack congress datasource create \$s "\$s" \\
160             --config username=\$OS_USERNAME \\
161             --config tenant_name=\$OS_TENANT_NAME \\
162             --config password=\$OS_PASSWORD \\
163             --config auth_url=\$OS_AUTH_URL
164     done
165 fi
166 EOI
167
168   echo -e "${blue}INFO: Checking if OVS bridges have IP addresses...${reset}"
169   for network in ${opnfv_attach_networks}; do
170     ovs_ip=$(find_ip ${NET_MAP[$network]})
171     tmp_ip=''
172     if [ -n "$ovs_ip" ]; then
173       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} has IP address ${ovs_ip}${reset}"
174     else
175       echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} missing IP, will configure${reset}"
176       # use last IP of allocation pool
177       eval "ip_range=\${${network}_usable_ip_range}"
178       ovs_ip=${ip_range##*,}
179       eval "net_cidr=\${${network}_cidr}"
180       sudo ip addr add ${ovs_ip}/${net_cidr##*/} dev ${NET_MAP[$network]}
181       sudo ip link set up ${NET_MAP[$network]}
182       tmp_ip=$(find_ip ${NET_MAP[$network]})
183       if [ -n "$tmp_ip" ]; then
184         echo -e "${blue}INFO: OVS Bridge ${NET_MAP[$network]} IP set: ${tmp_ip}${reset}"
185         continue
186       else
187         echo -e "${red}ERROR: Unable to set OVS Bridge ${NET_MAP[$network]} with IP: ${ovs_ip}${reset}"
188         return 1
189       fi
190     fi
191   done
192
193   # for virtual, we NAT public network through Undercloud
194   if [ "$virtual" == "TRUE" ]; then
195     if ! configure_undercloud_nat ${public_network_cidr}; then
196       echo -e "${red}ERROR: Unable to NAT undercloud with external net: ${public_network_cidr}${reset}"
197       exit 1
198     else
199       echo -e "${blue}INFO: Undercloud VM has been setup to NAT Overcloud public network${reset}"
200     fi
201   fi
202
203   # for sfc deployments we need the vxlan workaround
204   if [ "${deploy_options_array['sfc']}" == 'True' ]; then
205       ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
206 source stackrc
207 set -o errexit
208 for node in \$(nova list | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"); do
209 ssh -T ${SSH_OPTIONS[@]} "heat-admin@\$node" <<EOF
210 sudo ifconfig br-int up
211 sudo ip route add 123.123.123.0/24 dev br-int
212 EOF
213 done
214 EOI
215   fi
216
217   # Collect deployment logs
218   ssh -T ${SSH_OPTIONS[@]} "stack@$UNDERCLOUD" <<EOI
219 mkdir -p ~/deploy_logs
220 rm -rf deploy_logs/*
221 source stackrc
222 set -o errexit
223 for node in \$(nova list | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"); do
224  ssh -T ${SSH_OPTIONS[@]} "heat-admin@\$node" <<EOF
225  sudo cp /var/log/messages /home/heat-admin/messages.log
226  sudo chown heat-admin /home/heat-admin/messages.log
227 EOF
228 scp ${SSH_OPTIONS[@]} heat-admin@\$node:/home/heat-admin/messages.log ~/deploy_logs/\$node.messages.log
229 if [ "$debug" == "TRUE" ]; then
230     nova list --ip \$node
231     echo "---------------------------"
232     echo "-----/var/log/messages-----"
233     echo "---------------------------"
234     cat ~/deploy_logs/\$node.messages.log
235     echo "---------------------------"
236     echo "----------END LOG----------"
237     echo "---------------------------"
238 fi
239  ssh -T ${SSH_OPTIONS[@]} "heat-admin@\$node" <<EOF
240  sudo rm -f /home/heat-admin/messages.log
241 EOF
242 done
243
244 # Print out the undercloud IP and dashboard URL
245 source stackrc
246 echo "Undercloud IP: $UNDERCLOUD, please connect by doing 'opnfv-util undercloud'"
247 echo "Overcloud dashboard available at http://\$(heat output-show overcloud PublicVip | sed 's/"//g')/dashboard"
248 EOI
249
250 }
251
252 display_usage() {
253   echo -e "Usage:\n$0 [arguments] \n"
254   echo -e "   -d|--deploy-settings : Full path to deploy settings yaml file. Optional.  Defaults to null"
255   echo -e "   -i|--inventory : Full path to inventory yaml file. Required only for baremetal"
256   echo -e "   -n|--net-settings : Full path to network settings file. Optional."
257   echo -e "   -p|--ping-site : site to use to verify IP connectivity. Optional. Defaults to 8.8.8.8"
258   echo -e "   -v|--virtual : Virtualize overcloud nodes instead of using baremetal."
259   echo -e "   --flat : disable Network Isolation and use a single flat network for the underlay network."
260   echo -e "   --no-post-config : disable Post Install configuration."
261   echo -e "   --debug : enable debug output."
262   echo -e "   --interactive : enable interactive deployment mode which requires user to confirm steps of deployment."
263   echo -e "   --virtual-cpus : Number of CPUs to use per Overcloud VM in a virtual deployment (defaults to 4)."
264   echo -e "   --virtual-ram : Amount of RAM to use per Overcloud VM in GB (defaults to 8)."
265 }
266
267 ##translates the command line parameters into variables
268 ##params: $@ the entire command line is passed
269 ##usage: parse_cmd_line() "$@"
270 parse_cmdline() {
271   echo -e "\n\n${blue}This script is used to deploy the Apex Installer and Provision OPNFV Target System${reset}\n\n"
272   echo "Use -h to display help"
273   sleep 2
274
275   while [ "${1:0:1}" = "-" ]
276   do
277     case "$1" in
278         -h|--help)
279                 display_usage
280                 exit 0
281             ;;
282         -d|--deploy-settings)
283                 DEPLOY_SETTINGS_FILE=$2
284                 echo "Deployment Configuration file: $2"
285                 shift 2
286             ;;
287         -i|--inventory)
288                 INVENTORY_FILE=$2
289                 shift 2
290             ;;
291         -n|--net-settings)
292                 NETSETS=$2
293                 echo "Network Settings Configuration file: $2"
294                 shift 2
295             ;;
296         -p|--ping-site)
297                 ping_site=$2
298                 echo "Using $2 as the ping site"
299                 shift 2
300             ;;
301         -v|--virtual)
302                 virtual="TRUE"
303                 echo "Executing a Virtual Deployment"
304                 shift 1
305             ;;
306         --flat )
307                 net_isolation_enabled="FALSE"
308                 echo "Underlay Network Isolation Disabled: using flat configuration"
309                 shift 1
310             ;;
311         --no-post-config )
312                 post_config="FALSE"
313                 echo "Post install configuration disabled"
314                 shift 1
315             ;;
316         --debug )
317                 debug="TRUE"
318                 echo "Enable debug output"
319                 shift 1
320             ;;
321         --interactive )
322                 interactive="TRUE"
323                 echo "Interactive mode enabled"
324                 shift 1
325             ;;
326         --virtual-cpus )
327                 VM_CPUS=$2
328                 echo "Number of CPUs per VM set to $VM_CPUS"
329                 shift 2
330             ;;
331         --virtual-ram )
332                 VM_RAM=$2
333                 echo "Amount of RAM per VM set to $VM_RAM"
334                 shift 2
335             ;;
336         --virtual-computes )
337                 VM_COMPUTES=$2
338                 echo "Virtual Compute nodes set to $VM_COMPUTES"
339                 shift 2
340             ;;
341         *)
342                 display_usage
343                 exit 1
344             ;;
345     esac
346   done
347
348   if [[ ! -z "$NETSETS" && "$net_isolation_enabled" == "FALSE" ]]; then
349     echo -e "${red}INFO: Single flat network requested. Only admin_network settings will be used!${reset}"
350   elif [[ -z "$NETSETS" ]]; then
351     echo -e "${red}ERROR: You must provide a network_settings file with -n.${reset}"
352     exit 1
353   fi
354
355   if [[ -n "$virtual" && -n "$INVENTORY_FILE" ]]; then
356     echo -e "${red}ERROR: You should not specify an inventory with virtual deployments${reset}"
357     exit 1
358   fi
359
360   if [[ -z "$DEPLOY_SETTINGS_FILE" || ! -f "$DEPLOY_SETTINGS_FILE" ]]; then
361     echo -e "${red}ERROR: Deploy Settings: ${DEPLOY_SETTINGS_FILE} does not exist! Exiting...${reset}"
362     exit 1
363   fi
364
365   if [[ ! -z "$NETSETS" && ! -f "$NETSETS" ]]; then
366     echo -e "${red}ERROR: Network Settings: ${NETSETS} does not exist! Exiting...${reset}"
367     exit 1
368   fi
369
370   if [[ ! -z "$INVENTORY_FILE" && ! -f "$INVENTORY_FILE" ]]; then
371     echo -e "{$red}ERROR: Inventory File: ${INVENTORY_FILE} does not exist! Exiting...${reset}"
372     exit 1
373   fi
374
375   if [[ -z "$virtual" && -z "$INVENTORY_FILE" ]]; then
376     echo -e "${red}ERROR: You must specify an inventory file for baremetal deployments! Exiting...${reset}"
377     exit 1
378   fi
379
380   if [[ "$net_isolation_enabled" == "FALSE" && "$post_config" == "TRUE" ]]; then
381     echo -e "${blue}INFO: Post Install Configuration will be skipped.  It is not supported with --flat${reset}"
382     post_config="FALSE"
383   fi
384
385 }
386
387 ##END FUNCTIONS
388
389 main() {
390   parse_cmdline "$@"
391   echo -e "${blue}INFO: Parsing network settings file...${reset}"
392   parse_network_settings
393   if ! configure_deps; then
394     echo -e "${red}Dependency Validation Failed, Exiting.${reset}"
395     exit 1
396   fi
397   if [ -n "$DEPLOY_SETTINGS_FILE" ]; then
398     echo -e "${blue}INFO: Parsing deploy settings file...${reset}"
399     parse_deploy_settings
400   fi
401   setup_undercloud_vm
402   if [ "$virtual" == "TRUE" ]; then
403     setup_virtual_baremetal $VM_CPUS $VM_RAM
404   elif [ -n "$INVENTORY_FILE" ]; then
405     parse_inventory_file
406   fi
407   configure_undercloud
408   overcloud_deploy
409   if [ "$post_config" == "TRUE" ]; then
410     if ! configure_post_install; then
411       echo -e "${red}ERROR:Post Install Configuration Failed, Exiting.${reset}"
412       exit 1
413     else
414       echo -e "${blue}INFO: Post Install Configuration Complete${reset}"
415     fi
416   fi
417   if [[ "${deploy_options_array['sdn_controller']}" == 'onos' ]]; then
418     if ! onos_update_gw_mac ${public_network_cidr} ${public_network_gateway}; then
419       echo -e "${red}ERROR:ONOS Post Install Configuration Failed, Exiting.${reset}"
420       exit 1
421     else
422       echo -e "${blue}INFO: ONOS Post Install Configuration Complete${reset}"
423     fi
424   fi
425 }
426
427 main "$@"