Merge "Move mcp.rsa to /var/lib/opnfv"
[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]
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
47 $(notify "DISABLED OPTIONS (not yet supported with MCP):" 3)
48   -d  (disabled) Dry-run
49   -e  (disabled) Do not launch environment deployment
50   -f  (disabled) Deploy on existing Salt master
51   -F  (disabled) Do only create a Salt master
52   -i  (disabled) iso url
53   -L  (disabled) Deployment log path and file name
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 Lab name as defined in the configuration directory, e.g. lf
79 -p POD name as defined in the configuration directory, e.g. pod-1
80 -s Deployment-scenario, this points to a short deployment scenario name, which
81    has to be defined in config directory (e.g. os-odl-nofeature-ha).
82 -S Storage dir for VM images, default is mcp/deploy/images
83
84 $(notify "Disabled input parameters (not yet supported with MCP):" 3)
85 -d (disabled) Dry-run - Produce deploy config files, but do not execute deploy
86 -f (disabled) Deploy on existing Salt master
87 -e (disabled) Do not launch environment deployment
88 -F (disabled) Do only create a Salt master
89 -L (disabled) Deployment log path and name, eg. -L /home/jenkins/job.log.tar.gz
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=${SALT_MASTER_IP:-192.168.10.100}
144 export MAAS_IP=${MAAS_IP:-192.168.10.3}
145 export SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${SSH_KEY}"
146
147 # Variables below are disabled for now, to be re-introduced or removed later
148 set +x
149 USE_EXISTING_FUEL=''
150 FUEL_CREATION_ONLY=''
151 NO_DEPLOY_ENVIRONMENT=''
152 DRY_RUN=0
153 if ! [ -z "${DEPLOY_TIMEOUT}" ]; then
154     DEPLOY_TIMEOUT="-dt ${DEPLOY_TIMEOUT}"
155 else
156     DEPLOY_TIMEOUT=""
157 fi
158 set -x
159 #
160 # END of variables to customize
161 ##############################################################################
162
163 ##############################################################################
164 # BEGIN of main
165 #
166 set +x
167 OPNFV_BRIDGE_IDX=0
168 while getopts "b:B:dfFl:L:p:s:S:T:i:he" OPTION
169 do
170     case $OPTION in
171         b)
172             BASE_CONFIG_URI=${OPTARG}
173             if [[ ! $BASE_CONFIG_URI =~ ${URI_REGEXP} ]]; then
174                 notify "[ERROR] -b $BASE_CONFIG_URI - invalid URI\n"
175                 usage
176                 exit 1
177             fi
178             ;;
179         B)
180             OIFS=${IFS}
181             IFS=','
182             OPT_BRIDGES=($OPTARG)
183             for bridge in "${OPT_BRIDGES[@]}"; do
184                 if [ -n "${bridge}" ]; then
185                     OPNFV_BRIDGES[${OPNFV_BRIDGE_IDX}]="${bridge}"
186                 fi
187                 OPNFV_BRIDGE_IDX=$[OPNFV_BRIDGE_IDX + 1]
188             done
189             IFS=${OIFS}
190             ;;
191         d)
192             notify '' 3 "${OPTION}"; continue
193             DRY_RUN=1
194             ;;
195         f)
196             notify '' 3 "${OPTION}"; continue
197             USE_EXISTING_FUEL='-nf'
198             ;;
199         F)
200             notify '' 3 "${OPTION}"; continue
201             FUEL_CREATION_ONLY='-fo'
202             ;;
203         e)
204             notify '' 3 "${OPTION}"; continue
205             NO_DEPLOY_ENVIRONMENT='-nde'
206             ;;
207         l)
208             TARGET_LAB=${OPTARG}
209             ;;
210         L)
211             notify '' 3 "${OPTION}"; continue
212             DEPLOY_LOG="-log ${OPTARG}"
213             ;;
214         p)
215             TARGET_POD=${OPTARG}
216             if [[ "${TARGET_POD}" =~ "virtual" ]]; then
217                 DEPLOY_TYPE='virtual'
218             fi
219             ;;
220         s)
221             DEPLOY_SCENARIO=${OPTARG}
222             ;;
223         S)
224             if [[ ${OPTARG} ]]; then
225                 STORAGE_DIR="${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 if [ -z "${TARGET_LAB}" ] || [ -z "${TARGET_POD}" ] || \
264    [ -z "${DEPLOY_SCENARIO}" ]; then
265     notify "[ERROR] At least one of the mandatory args is missing!\n" 1>&2
266     usage
267     exit 1
268 fi
269
270 set -x
271
272 # Enable the automatic exit trap
273 trap do_exit SIGINT SIGTERM EXIT
274
275 # Set no restrictive umask so that Jenkins can remove any residuals
276 umask 0000
277
278 clean
279
280 pushd "${DEPLOY_DIR}" > /dev/null
281 # Prepare the deploy config files based on lab/pod information, deployment
282 # scenario, etc.
283
284 # Install required packages
285 [ -n "$(command -v apt-get)" ] && sudo apt-get install -y \
286   git make rsync mkisofs curl virtinst cpu-checker qemu-kvm
287 [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken \
288   git make rsync genisoimage curl virt-install qemu-kvm
289
290 if [ "$(uname -i)" = "aarch64" ]; then
291   [ -n "$(command -v apt-get)" ] && sudo apt-get install -y vgabios && \
292   sudo ln -sf /usr/share/vgabios/vgabios.bin /usr/share/qemu/vgabios-stdvga.bin
293   [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken vgabios
294 fi
295
296 # Check scenario file existence
297 if [ ! -f  "../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
298     notify "[WARN] ${DEPLOY_SCENARIO}.yaml not found! \
299             Setting simplest scenario (os-nosdn-nofeature-noha)\n" 3
300     DEPLOY_SCENARIO='os-nosdn-nofeature-noha'
301     if [ ! -f  "../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
302         notify "[ERROR] Scenario definition file is missing!\n" 1>&2
303         exit 1
304     fi
305 fi
306
307 # Get required infra deployment data
308 source lib.sh
309 eval "$(parse_yaml "../config/scenario/${DEPLOY_TYPE}/defaults.yaml")"
310 eval "$(parse_yaml "../config/scenario/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml")"
311
312 export CLUSTER_DOMAIN=${cluster_domain}
313
314 declare -A virtual_nodes_ram virtual_nodes_vcpus
315 for node in "${virtual_nodes[@]}"; do
316     virtual_custom_ram="virtual_${node}_ram"
317     virtual_custom_vcpus="virtual_${node}_vcpus"
318     virtual_nodes_ram[$node]=${!virtual_custom_ram:-$virtual_default_ram}
319     virtual_nodes_vcpus[$node]=${!virtual_custom_vcpus:-$virtual_default_vcpus}
320 done
321
322 # Infra setup
323 generate_ssh_key
324 prepare_vms virtual_nodes "${base_image}" "${STORAGE_DIR}"
325 create_networks OPNFV_BRIDGES
326 create_vms virtual_nodes virtual_nodes_ram virtual_nodes_vcpus \
327   OPNFV_BRIDGES "${STORAGE_DIR}"
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} || true"
340 done
341
342 popd > /dev/null
343
344 #
345 # END of main
346 ##############################################################################