cf7b3b35b938d6ec6f5b36842a47f311e6ea07c8
[fuel.git] / ci / deploy.sh
1 #!/bin/bash
2 # shellcheck disable=SC2034,SC2154,SC1091
3 set -ex
4 ##############################################################################
5 # Copyright (c) 2017 Ericsson AB, Mirantis Inc., Enea AB and others.
6 # jonas.bjurel@ericsson.com
7 # All rights reserved. This program and the accompanying materials
8 # are made available under the terms of the Apache License, Version 2.0
9 # which accompanies this distribution, and is available at
10 # http://www.apache.org/licenses/LICENSE-2.0
11 ##############################################################################
12
13 ##############################################################################
14 # BEGIN of Exit handlers
15 #
16 do_exit () {
17     clean
18     echo "Exiting ..."
19 }
20 #
21 # End of Exit handlers
22 ##############################################################################
23
24 ##############################################################################
25 # BEGIN of usage description
26 #
27 usage ()
28 {
29 cat << EOF
30 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
31 $(notify "$(basename "$0"): Deploy the Fuel@OPNFV MCP stack" 3)
32
33 $(notify "USAGE:" 2)
34   $(basename "$0") -b base-uri -l lab-name -p pod-name -s deploy-scenario \\
35     [-B PXE Bridge [-B Mgmt Bridge [-B Internal Bridge [-B Public Bridge]]]]
36
37 $(notify "OPTIONS:" 2)
38   -b  Base-uri for the stack-configuration structure
39   -B  Bridge(s): 1st usage = PXE, 2nd = Mgmt, 3rd = Internal, 4th = Public
40   -h  Print this message and exit
41   -l  Lab-name
42   -p  Pod-name
43   -s  Deploy-scenario short-name
44
45 $(notify "DISABLED OPTIONS (not yet supported with MCP):" 3)
46   -d  (disabled) Dry-run
47   -e  (disabled) Do not launch environment deployment
48   -f  (disabled) Deploy on existing Salt master
49   -F  (disabled) Do only create a Salt master
50   -i  (disabled) iso url
51   -L  (disabled) Deployment log path and file name
52   -S  (disabled) Storage dir for VM images
53   -T  (disabled) Timeout, in minutes, for the deploy.
54
55 $(notify "Description:" 2)
56 Deploys the Fuel@OPNFV stack on the indicated lab resource.
57
58 This script provides the Fuel@OPNFV deployment abstraction.
59 It depends on the OPNFV official configuration directory/file structure
60 and provides a fairly simple mechanism to execute a deployment.
61
62 $(notify "Input parameters to the build script are:" 2)
63 -b Base URI to the configuration directory (needs to be provided in a URI
64    style, it can be a local resource: file:// or a remote resource http(s)://)
65 -B Bridges to be used by deploy script. It can be specified several times,
66    or as a comma separated list of bridges, or both: -B br1 -B br2,br3
67    First occurence sets PXE Brige, next Mgmt, then Internal and Public.
68    For an empty value, the deploy script will use virsh to create the default
69    expected network (e.g. -B pxe,,,public will use existing "pxe" and "public"
70    bridges, respectively create "mgmt" and "internal").
71    Note that a virtual network "mcpcontrol" is always created. For virtual
72    deploys, "mcpcontrol" is also used for PXE, leaving the PXE bridge unused.
73    For baremetal deploys, PXE bridge is used for baremetal node provisioning,
74    while "mcpcontrol" is used to provision the infrastructure VMs only.
75    The default is 'pxebr'.
76 -h Print this message and exit
77 -l Lab name as defined in the configuration directory, e.g. lf
78 -p POD name as defined in the configuration directory, e.g. pod-1
79 -s Deployment-scenario, this points to a short deployment scenario name, which
80    has to be defined in config directory (e.g. os-odl_l2-nofeature-noha).
81
82 $(notify "Disabled input parameters (not yet supported with MCP):" 3)
83 -d (disabled) Dry-run - Produce deploy config files, but do not execute deploy
84 -f (disabled) Deploy on existing Salt master
85 -e (disabled) Do not launch environment deployment
86 -F (disabled) Do only create a Salt master
87 -L (disabled) Deployment log path and name, eg. -L /home/jenkins/job.log.tar.gz
88 -S (disabled) Storage dir for VM images, default is fuel/deploy/images
89 -T (disabled) Timeout, in minutes, for the deploy.
90    It defaults to using the DEPLOY_TIMEOUT environment variable when defined.
91 -i (disabled) .iso image to be deployed (needs to be provided in a URI
92    style, it can be a local resource: file:// or a remote resource http(s)://)
93
94 $(notify "[NOTE] sudo & virsh priviledges are needed for this script to run" 3)
95
96 Example:
97
98 $(notify "sudo $(basename "$0") \\
99   -b file:///home/jenkins/lab-config \\
100   -l lf -p pod1 \\
101   -s os-odl_l2-nofeature-noha" 2)
102 EOF
103 }
104
105 #
106 # END of usage description
107 ##############################################################################
108
109 ##############################################################################
110 # BEGIN of colored notification wrapper
111 #
112 notify() {
113     tput setaf "${2:-1}" || true
114     echo -en "${1:-"[WARN] Unsupported opt arg: $3\\n"}"
115     tput sgr0
116 }
117 #
118 # END of colored notification wrapper
119 ##############################################################################
120
121 ##############################################################################
122 # BEGIN of deployment clean-up
123 #
124 clean() {
125     echo "Cleaning up deploy tmp directories"
126 }
127 #
128 # END of deployment clean-up
129 ##############################################################################
130
131 ##############################################################################
132 # BEGIN of variables to customize
133 #
134 SCRIPT_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
135 DEPLOY_DIR=$(cd "${SCRIPT_PATH}/../mcp/scripts"; pwd)
136 DEPLOY_TYPE='baremetal'
137 OPNFV_BRIDGES=('pxebr' 'mgmt' 'internal' 'public')
138 URI_REGEXP='(file|https?|ftp)://.*'
139
140 export SSH_KEY=${SSH_KEY:-mcp.rsa}
141 export SALT_MASTER=${SALT_MASTER_IP:-192.168.10.100}
142 export MAAS_IP=${MAAS_IP:-192.168.10.3}
143 export SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${SSH_KEY}"
144
145 # Variables below are disabled for now, to be re-introduced or removed later
146 set +x
147 USE_EXISTING_FUEL=''
148 FUEL_CREATION_ONLY=''
149 NO_DEPLOY_ENVIRONMENT=''
150 STORAGE_DIR=''
151 DRY_RUN=0
152 if ! [ -z "${DEPLOY_TIMEOUT}" ]; then
153     DEPLOY_TIMEOUT="-dt ${DEPLOY_TIMEOUT}"
154 else
155     DEPLOY_TIMEOUT=""
156 fi
157 set -x
158 #
159 # END of variables to customize
160 ##############################################################################
161
162 ##############################################################################
163 # BEGIN of main
164 #
165 set +x
166 OPNFV_BRIDGE_IDX=0
167 while getopts "b:B:dfFl:L:p:s:S:T:i:he" OPTION
168 do
169     case $OPTION in
170         b)
171             BASE_CONFIG_URI=${OPTARG}
172             if [[ ! $BASE_CONFIG_URI =~ ${URI_REGEXP} ]]; then
173                 notify "[ERROR] -b $BASE_CONFIG_URI - invalid URI\n"
174                 usage
175                 exit 1
176             fi
177             ;;
178         B)
179             OIFS=${IFS}
180             IFS=','
181             OPT_BRIDGES=($OPTARG)
182             for bridge in "${OPT_BRIDGES[@]}"; do
183                 if [ -n "${bridge}" ]; then
184                     OPNFV_BRIDGES[${OPNFV_BRIDGE_IDX}]="${bridge}"
185                 fi
186                 OPNFV_BRIDGE_IDX=$[OPNFV_BRIDGE_IDX + 1]
187             done
188             IFS=${OIFS}
189             ;;
190         d)
191             notify '' 3 "${OPTION}"; continue
192             DRY_RUN=1
193             ;;
194         f)
195             notify '' 3 "${OPTION}"; continue
196             USE_EXISTING_FUEL='-nf'
197             ;;
198         F)
199             notify '' 3 "${OPTION}"; continue
200             FUEL_CREATION_ONLY='-fo'
201             ;;
202         e)
203             notify '' 3 "${OPTION}"; continue
204             NO_DEPLOY_ENVIRONMENT='-nde'
205             ;;
206         l)
207             TARGET_LAB=${OPTARG}
208             ;;
209         L)
210             notify '' 3 "${OPTION}"; continue
211             DEPLOY_LOG="-log ${OPTARG}"
212             ;;
213         p)
214             TARGET_POD=${OPTARG}
215             if [[ "${TARGET_POD}" =~ "virtual" ]]; then
216                 DEPLOY_TYPE='virtual'
217             fi
218             ;;
219         s)
220             DEPLOY_SCENARIO=${OPTARG}
221             ;;
222         S)
223             notify '' 3 "${OPTION}"; continue
224             if [[ ${OPTARG} ]]; then
225                 STORAGE_DIR="-s ${OPTARG}"
226             fi
227             ;;
228         T)
229             notify '' 3 "${OPTION}"; continue
230             DEPLOY_TIMEOUT="-dt ${OPTARG}"
231             ;;
232         i)
233             notify '' 3 "${OPTION}"; continue
234             ISO=${OPTARG}
235             if [[ ! $ISO =~ ${URI_REGEXP} ]]; then
236                 notify "[ERROR] -i $ISO - invalid URI\n"
237                 usage
238                 exit 1
239             fi
240             ;;
241         h)
242             usage
243             exit 0
244             ;;
245         *)
246             notify "[ERROR] Arguments not according to new argument style\n"
247             exit 1
248             ;;
249     esac
250 done
251
252 if [[ "$(sudo whoami)" != 'root' ]]; then
253     notify "This script requires sudo rights\n" 1>&2
254     exit 1
255 fi
256
257 if ! virsh list >/dev/null 2>&1; then
258     notify "This script requires hypervisor access\n" 1>&2
259     exit 1
260 fi
261
262 # Validate mandatory arguments are set
263 # FIXME(armband): Bring back support for BASE_CONFIG_URI
264 if [ -z "${TARGET_LAB}" ] || [ -z "${TARGET_POD}" ] || \
265    [ -z "${DEPLOY_SCENARIO}" ]; then
266     notify "[ERROR] At least one of the mandatory args is missing!\n" 1>&2
267     usage
268     exit 1
269 fi
270
271 set -x
272
273 # Enable the automatic exit trap
274 trap do_exit SIGINT SIGTERM EXIT
275
276 # Set no restrictive umask so that Jenkins can removeeee any residuals
277 umask 0000
278
279 clean
280
281 pushd "${DEPLOY_DIR}" > /dev/null
282 # Prepare the deploy config files based on lab/pod information, deployment
283 # scenario, etc.
284
285 # Install required packages
286 [ -n "$(command -v apt-get)" ] && sudo apt-get install -y \
287   git make rsync mkisofs curl virtinst cpu-checker qemu-kvm
288 [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken \
289   git make rsync genisoimage curl virt-install qemu-kvm
290
291 if [ "$(uname -i)" = "aarch64" ]; then
292   [ -n "$(command -v apt-get)" ] && sudo apt-get install -y vgabios && \
293   sudo ln -sf /usr/share/vgabios/vgabios.bin /usr/share/qemu/vgabios-stdvga.bin
294   [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken vgabios
295 fi
296
297 # Check scenario file existence
298 if [ ! -f  ../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml ]; then
299     notify "[WARN] ${DEPLOY_SCENARIO}.yaml not found! \
300             Setting simplest scenario (os-nosdn-nofeature-noha)\n" 3
301     DEPLOY_SCENARIO='os-nosdn-nofeature-noha'
302     if [ ! -f  ../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml ]; then
303         notify "[ERROR] Scenario definition file is missing!\n" 1>&2
304         exit 1
305     fi
306 fi
307
308 # Get required infra deployment data
309 source lib.sh
310 eval "$(parse_yaml "../config/scenario/${DEPLOY_TYPE}/defaults.yaml")"
311 eval "$(parse_yaml "../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml")"
312
313 export CLUSTER_DOMAIN=${cluster_domain}
314
315 declare -A virtual_nodes_ram virtual_nodes_vcpus
316 for node in "${virtual_nodes[@]}"; do
317     virtual_custom_ram="virtual_${node}_ram"
318     virtual_custom_vcpus="virtual_${node}_vcpus"
319     virtual_nodes_ram[$node]=${!virtual_custom_ram:-$virtual_default_ram}
320     virtual_nodes_vcpus[$node]=${!virtual_custom_vcpus:-$virtual_default_vcpus}
321 done
322
323 # Infra setup
324 generate_ssh_key
325 prepare_vms virtual_nodes "${base_image}"
326 create_networks OPNFV_BRIDGES
327 create_vms virtual_nodes virtual_nodes_ram virtual_nodes_vcpus OPNFV_BRIDGES
328 update_mcpcontrol_network
329 start_vms virtual_nodes
330 check_connection
331
332 ./salt.sh
333
334 # Openstack cluster setup
335 for state in "${cluster_states[@]}"; do
336     notify "STATE: ${state}\n" 2
337     # shellcheck disable=SC2086,2029
338     ssh ${SSH_OPTS} "ubuntu@${SALT_MASTER}" \
339         sudo "/root/fuel/mcp/config/states/${state}"
340 done
341
342 popd > /dev/null
343
344 #
345 # END of main
346 ##############################################################################