603d6e562877b277bc82eb68c798c8482572c561
[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     [-S storage-dir] [-L /path/to/log/file.tar.gz]
37
38 $(notify "OPTIONS:" 2)
39   -b  Base-uri for the stack-configuration structure
40   -B  Bridge(s): 1st usage = PXE, 2nd = Mgmt, 3rd = Internal, 4th = Public
41   -h  Print this message and exit
42   -l  Lab-name
43   -p  Pod-name
44   -s  Deploy-scenario short-name
45   -S  Storage dir for VM images
46   -L  Deployment log path and file name
47
48 $(notify "DISABLED OPTIONS (not yet supported with MCP):" 3)
49   -d  (disabled) Dry-run
50   -e  (disabled) Do not launch environment deployment
51   -f  (disabled) Deploy on existing Salt master
52   -F  (disabled) Do only create a Salt master
53   -i  (disabled) iso url
54   -T  (disabled) Timeout, in minutes, for the deploy.
55
56 $(notify "Description:" 2)
57 Deploys the Fuel@OPNFV stack on the indicated lab resource.
58
59 This script provides the Fuel@OPNFV deployment abstraction.
60 It depends on the OPNFV official configuration directory/file structure
61 and provides a fairly simple mechanism to execute a deployment.
62
63 $(notify "Input parameters to the build script are:" 2)
64 -b Base URI to the configuration directory (needs to be provided in a URI
65    style, it can be a local resource: file:// or a remote resource http(s)://)
66 -B Bridges to be used by deploy script. It can be specified several times,
67    or as a comma separated list of bridges, or both: -B br1 -B br2,br3
68    First occurence sets PXE Brige, next Mgmt, then Internal and Public.
69    For an empty value, the deploy script will use virsh to create the default
70    expected network (e.g. -B pxe,,,public will use existing "pxe" and "public"
71    bridges, respectively create "mgmt" and "internal").
72    Note that a virtual network "mcpcontrol" is always created. For virtual
73    deploys, "mcpcontrol" is also used for PXE, leaving the PXE bridge unused.
74    For baremetal deploys, PXE bridge is used for baremetal node provisioning,
75    while "mcpcontrol" is used to provision the infrastructure VMs only.
76    The default is 'pxebr'.
77 -h Print this message and exit
78 -L Deployment log path and name, eg. -L /home/jenkins/job.log.tar.gz
79 -l Lab name as defined in the configuration directory, e.g. lf
80 -p POD name as defined in the configuration directory, e.g. pod-1
81 -s Deployment-scenario, this points to a short deployment scenario name, which
82    has to be defined in config directory (e.g. os-odl-nofeature-ha).
83 -S Storage dir for VM images, default is mcp/deploy/images
84
85 $(notify "Disabled input parameters (not yet supported with MCP):" 3)
86 -d (disabled) Dry-run - Produce deploy config files, but do not execute deploy
87 -f (disabled) Deploy on existing Salt master
88 -e (disabled) Do not launch environment deployment
89 -F (disabled) Do only create a Salt master
90 -T (disabled) Timeout, in minutes, for the deploy.
91    It defaults to using the DEPLOY_TIMEOUT environment variable when defined.
92 -i (disabled) .iso image to be deployed (needs to be provided in a URI
93    style, it can be a local resource: file:// or a remote resource http(s)://)
94
95 $(notify "[NOTE] sudo & virsh priviledges are needed for this script to run" 3)
96
97 Example:
98
99 $(notify "sudo $(basename "$0") \\
100   -b file:///home/jenkins/lab-config \\
101   -l lf -p pod2 \\
102   -s os-odl-nofeature-ha" 2)
103 EOF
104 }
105
106 #
107 # END of usage description
108 ##############################################################################
109
110 ##############################################################################
111 # BEGIN of colored notification wrapper
112 #
113 notify() {
114     tput setaf "${2:-1}" || true
115     echo -en "${1:-"[WARN] Unsupported opt arg: $3\\n"}"
116     tput sgr0
117 }
118 #
119 # END of colored notification wrapper
120 ##############################################################################
121
122 ##############################################################################
123 # BEGIN of deployment clean-up
124 #
125 clean() {
126     echo "Cleaning up deploy tmp directories"
127 }
128 #
129 # END of deployment clean-up
130 ##############################################################################
131
132 ##############################################################################
133 # BEGIN of variables to customize
134 #
135 SCRIPT_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
136 DEPLOY_DIR=$(cd "${SCRIPT_PATH}/../mcp/scripts"; pwd)
137 STORAGE_DIR=$(cd "${SCRIPT_PATH}/../mcp/deploy/images"; pwd)
138 DEPLOY_TYPE='baremetal'
139 OPNFV_BRIDGES=('pxebr' 'mgmt' 'internal' 'public')
140 URI_REGEXP='(file|https?|ftp)://.*'
141
142 export SSH_KEY=${SSH_KEY:-"/var/lib/opnfv/mcp.rsa"}
143 export SALT_MASTER=${INSTALLER_IP:-10.20.0.2}
144 export SALT_MASTER_USER=${SALT_MASTER_USER:-ubuntu}
145 export MAAS_IP=${MAAS_IP:-${SALT_MASTER%.*}.3}
146 export SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${SSH_KEY}"
147 export SSH_SALT="${SALT_MASTER_USER}@${SALT_MASTER}"
148
149 # Variables below are disabled for now, to be re-introduced or removed later
150 set +x
151 USE_EXISTING_FUEL=''
152 FUEL_CREATION_ONLY=''
153 NO_DEPLOY_ENVIRONMENT=''
154 DRY_RUN=0
155 if ! [ -z "${DEPLOY_TIMEOUT}" ]; then
156     DEPLOY_TIMEOUT="-dt ${DEPLOY_TIMEOUT}"
157 else
158     DEPLOY_TIMEOUT=""
159 fi
160 set -x
161 #
162 # END of variables to customize
163 ##############################################################################
164
165 ##############################################################################
166 # BEGIN of main
167 #
168 set +x
169 OPNFV_BRIDGE_IDX=0
170 while getopts "b:B:dfFl:L:p:s:S:T:i:he" OPTION
171 do
172     case $OPTION in
173         b)
174             BASE_CONFIG_URI=${OPTARG}
175             if [[ ! $BASE_CONFIG_URI =~ ${URI_REGEXP} ]]; then
176                 notify "[ERROR] -b $BASE_CONFIG_URI - invalid URI\n"
177                 usage
178                 exit 1
179             fi
180             ;;
181         B)
182             OIFS=${IFS}
183             IFS=','
184             OPT_BRIDGES=($OPTARG)
185             for bridge in "${OPT_BRIDGES[@]}"; do
186                 if [ -n "${bridge}" ]; then
187                     OPNFV_BRIDGES[${OPNFV_BRIDGE_IDX}]="${bridge}"
188                 fi
189                 OPNFV_BRIDGE_IDX=$((OPNFV_BRIDGE_IDX + 1))
190             done
191             IFS=${OIFS}
192             ;;
193         d)
194             notify '' 3 "${OPTION}"; continue
195             DRY_RUN=1
196             ;;
197         f)
198             notify '' 3 "${OPTION}"; continue
199             USE_EXISTING_FUEL='-nf'
200             ;;
201         F)
202             notify '' 3 "${OPTION}"; continue
203             FUEL_CREATION_ONLY='-fo'
204             ;;
205         e)
206             notify '' 3 "${OPTION}"; continue
207             NO_DEPLOY_ENVIRONMENT='-nde'
208             ;;
209         l)
210             TARGET_LAB=${OPTARG}
211             ;;
212         L)
213             DEPLOY_LOG="${OPTARG}"
214             ;;
215         p)
216             TARGET_POD=${OPTARG}
217             if [[ "${TARGET_POD}" =~ "virtual" ]]; then
218                 DEPLOY_TYPE='virtual'
219             fi
220             ;;
221         s)
222             DEPLOY_SCENARIO=${OPTARG}
223             ;;
224         S)
225             if [[ ${OPTARG} ]]; then
226                 STORAGE_DIR="${OPTARG}"
227             fi
228             ;;
229         T)
230             notify '' 3 "${OPTION}"; continue
231             DEPLOY_TIMEOUT="-dt ${OPTARG}"
232             ;;
233         i)
234             notify '' 3 "${OPTION}"; continue
235             ISO=${OPTARG}
236             if [[ ! $ISO =~ ${URI_REGEXP} ]]; then
237                 notify "[ERROR] -i $ISO - invalid URI\n"
238                 usage
239                 exit 1
240             fi
241             ;;
242         h)
243             usage
244             exit 0
245             ;;
246         *)
247             notify "[ERROR] Arguments not according to new argument style\n"
248             exit 1
249             ;;
250     esac
251 done
252
253 if [[ "$(sudo whoami)" != 'root' ]]; then
254     notify "This script requires sudo rights\n" 1>&2
255     exit 1
256 fi
257
258 if ! virsh list >/dev/null 2>&1; then
259     notify "This script requires hypervisor access\n" 1>&2
260     exit 1
261 fi
262
263 # Validate mandatory arguments are set
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 remove 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 SCENARIO_DIR="../config/scenario"
299 if [ ! -f  "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
300     notify "[WARN] ${DEPLOY_SCENARIO}.yaml not found! \
301             Setting simplest scenario (os-nosdn-nofeature-noha)\n" 3
302     DEPLOY_SCENARIO='os-nosdn-nofeature-noha'
303     if [ ! -f  "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
304         notify "[ERROR] Scenario definition file is missing!\n" 1>&2
305         exit 1
306     fi
307 fi
308
309 # Check defaults file existence
310 if [ ! -f  "${SCENARIO_DIR}/defaults-$(uname -i).yaml" ]; then
311     notify "[ERROR] Scenario defaults file is missing!\n" 1>&2
312     exit 1
313 fi
314
315 # Get required infra deployment data
316 source lib.sh
317 eval "$(parse_yaml "${SCENARIO_DIR}/defaults-$(uname -i).yaml")"
318 eval "$(parse_yaml "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml")"
319
320 export CLUSTER_DOMAIN=${cluster_domain}
321
322 declare -A virtual_nodes_ram virtual_nodes_vcpus
323 for node in "${virtual_nodes[@]}"; do
324     virtual_custom_ram="virtual_${node}_ram"
325     virtual_custom_vcpus="virtual_${node}_vcpus"
326     virtual_nodes_ram[$node]=${!virtual_custom_ram:-$virtual_default_ram}
327     virtual_nodes_vcpus[$node]=${!virtual_custom_vcpus:-$virtual_default_vcpus}
328 done
329
330 # Infra setup
331 generate_ssh_key
332 prepare_vms virtual_nodes "${base_image}" "${STORAGE_DIR}"
333 create_networks OPNFV_BRIDGES
334 create_vms virtual_nodes virtual_nodes_ram virtual_nodes_vcpus \
335   OPNFV_BRIDGES "${STORAGE_DIR}"
336 update_mcpcontrol_network
337 start_vms virtual_nodes
338 check_connection
339
340 ./salt.sh
341
342 # Openstack cluster setup
343 for state in "${cluster_states[@]}"; do
344     notify "STATE: ${state}\n" 2
345     # shellcheck disable=SC2086,2029
346     ssh ${SSH_OPTS} "ubuntu@${SALT_MASTER}" \
347         sudo "/root/fuel/mcp/config/states/${state} || true"
348 done
349
350 ./log.sh "${DEPLOY_LOG}"
351
352 popd > /dev/null
353
354 #
355 # END of main
356 ##############################################################################