ci/deploy.sh: Allow non-root deploys
[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    The default is pxebr.
72 -h Print this message and exit
73 -l Lab name as defined in the configuration directory, e.g. lf
74 -p POD name as defined in the configuration directory, e.g. pod-1
75 -s Deployment-scenario, this points to a short deployment scenario name, which
76    has to be defined in config directory (e.g. os-odl_l2-nofeature-noha).
77
78 $(notify "Disabled input parameters (not yet supported with MCP):" 3)
79 -d (disabled) Dry-run - Produce deploy config files, but do not execute deploy
80 -f (disabled) Deploy on existing Salt master
81 -e (disabled) Do not launch environment deployment
82 -F (disabled) Do only create a Salt master
83 -L (disabled) Deployment log path and name, eg. -L /home/jenkins/job.log.tar.gz
84 -S (disabled) Storage dir for VM images, default is fuel/deploy/images
85 -T (disabled) Timeout, in minutes, for the deploy.
86    It defaults to using the DEPLOY_TIMEOUT environment variable when defined.
87 -i (disabled) .iso image to be deployed (needs to be provided in a URI
88    style, it can be a local resource: file:// or a remote resource http(s)://)
89
90 $(notify "[NOTE] sudo & virsh priviledges are needed for this script to run" 3)
91
92 Example:
93
94 $(notify "sudo $(basename "$0") \\
95   -b file:///home/jenkins/lab-config \\
96   -l lf -p pod1 \\
97   -s os-odl_l2-nofeature-noha" 2)
98 EOF
99 }
100
101 #
102 # END of usage description
103 ##############################################################################
104
105 ##############################################################################
106 # BEGIN of colored notification wrapper
107 #
108 notify() {
109     tput setaf "${2:-1}" || true
110     echo -en "${1:-"[WARN] Unsupported opt arg: $3\\n"}"
111     tput sgr0
112 }
113 #
114 # END of colored notification wrapper
115 ##############################################################################
116
117 ##############################################################################
118 # BEGIN of deployment clean-up
119 #
120 clean() {
121     echo "Cleaning up deploy tmp directories"
122 }
123 #
124 # END of deployment clean-up
125 ##############################################################################
126
127 ##############################################################################
128 # BEGIN of variables to customize
129 #
130 SCRIPT_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
131 DEPLOY_DIR=$(cd "${SCRIPT_PATH}/../mcp/scripts"; pwd)
132 OPNFV_BRIDGES=('pxe' 'mgmt' 'internal' 'public')
133 URI_REGEXP='(file|https?|ftp)://.*'
134
135 export SSH_KEY=${SSH_KEY:-mcp.rsa}
136 export SALT_MASTER=${SALT_MASTER_IP:-192.168.10.100}
137 export SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${SSH_KEY}"
138
139 # Variables below are disabled for now, to be re-introduced or removed later
140 set +x
141 USE_EXISTING_FUEL=''
142 FUEL_CREATION_ONLY=''
143 NO_DEPLOY_ENVIRONMENT=''
144 STORAGE_DIR=''
145 DRY_RUN=0
146 if ! [ -z "${DEPLOY_TIMEOUT}" ]; then
147     DEPLOY_TIMEOUT="-dt ${DEPLOY_TIMEOUT}"
148 else
149     DEPLOY_TIMEOUT=""
150 fi
151 set -x
152 #
153 # END of variables to customize
154 ##############################################################################
155
156 ##############################################################################
157 # BEGIN of main
158 #
159 set +x
160 OPNFV_BRIDGE_IDX=0
161 while getopts "b:B:dfFl:L:p:s:S:T:i:he" OPTION
162 do
163     case $OPTION in
164         b)
165             BASE_CONFIG_URI=${OPTARG}
166             if [[ ! $BASE_CONFIG_URI =~ ${URI_REGEXP} ]]; then
167                 notify "[ERROR] -b $BASE_CONFIG_URI - invalid URI\n"
168                 usage
169                 exit 1
170             fi
171             ;;
172         B)
173             OIFS=${IFS}
174             IFS=','
175             OPT_BRIDGES=($OPTARG)
176             for bridge in "${OPT_BRIDGES[@]}"; do
177                 if [ -n "${bridge}" ]; then
178                     OPNFV_BRIDGES[${OPNFV_BRIDGE_IDX}]="${bridge}"
179                 fi
180                 OPNFV_BRIDGE_IDX=$[OPNFV_BRIDGE_IDX + 1]
181             done
182             IFS=${OIFS}
183             ;;
184         d)
185             notify '' 3 "${OPTION}"; continue
186             DRY_RUN=1
187             ;;
188         f)
189             notify '' 3 "${OPTION}"; continue
190             USE_EXISTING_FUEL='-nf'
191             ;;
192         F)
193             notify '' 3 "${OPTION}"; continue
194             FUEL_CREATION_ONLY='-fo'
195             ;;
196         e)
197             notify '' 3 "${OPTION}"; continue
198             NO_DEPLOY_ENVIRONMENT='-nde'
199             ;;
200         l)
201             TARGET_LAB=${OPTARG}
202             ;;
203         L)
204             notify '' 3 "${OPTION}"; continue
205             DEPLOY_LOG="-log ${OPTARG}"
206             ;;
207         p)
208             TARGET_POD=${OPTARG}
209             ;;
210         s)
211             DEPLOY_SCENARIO=${OPTARG}
212             ;;
213         S)
214             notify '' 3 "${OPTION}"; continue
215             if [[ ${OPTARG} ]]; then
216                 STORAGE_DIR="-s ${OPTARG}"
217             fi
218             ;;
219         T)
220             notify '' 3 "${OPTION}"; continue
221             DEPLOY_TIMEOUT="-dt ${OPTARG}"
222             ;;
223         i)
224             notify '' 3 "${OPTION}"; continue
225             ISO=${OPTARG}
226             if [[ ! $ISO =~ ${URI_REGEXP} ]]; then
227                 notify "[ERROR] -i $ISO - invalid URI\n"
228                 usage
229                 exit 1
230             fi
231             ;;
232         h)
233             usage
234             exit 0
235             ;;
236         *)
237             notify "[ERROR] Arguments not according to new argument style\n"
238             exit 1
239             ;;
240     esac
241 done
242
243 if [[ "$(sudo whoami)" != 'root' ]]; then
244     notify "This script requires sudo rights\n" 1>&2
245     exit 1
246 fi
247
248 if ! virsh list >/dev/null 2>&1; then
249     notify "This script requires hypervisor access\n" 1>&2
250     exit 1
251 fi
252
253 # Validate mandatory arguments are set
254 # FIXME(armband): Bring back support for BASE_CONFIG_URI
255 if [ -z "${TARGET_LAB}" ] || [ -z "${TARGET_POD}" ] || \
256    [ -z "${DEPLOY_SCENARIO}" ]; then
257     notify "[ERROR] At least one of the mandatory args is missing!\n" 1>&2
258     usage
259     exit 1
260 fi
261
262 set -x
263
264 # Enable the automatic exit trap
265 trap do_exit SIGINT SIGTERM EXIT
266
267 # Set no restrictive umask so that Jenkins can removeeee any residuals
268 umask 0000
269
270 clean
271
272 pushd "${DEPLOY_DIR}" > /dev/null
273 # Prepare the deploy config files based on lab/pod information, deployment
274 # scenario, etc.
275
276 # Install required packages
277 [ -n "$(command -v apt-get)" ] && sudo apt-get install -y \
278   git make rsync mkisofs curl virtinst cpu-checker qemu-kvm
279 [ -n "$(command -v yum)" ] && sudo yum install -y \
280   git make rsync genisoimage curl virt-install qemu-kvm
281
282 # Check scenario file existence
283 if [[ ! -f  ../config/${DEPLOY_SCENARIO}.yaml ]]; then
284     notify "[WARN] ${DEPLOY_SCENARIO}.yaml not found! \
285             Setting simplest scenario (os-nosdn-nofeature-noha)\n" 3
286     DEPLOY_SCENARIO='os-nosdn-nofeature-noha'
287 fi
288
289 # Get required infra deployment data
290 source lib.sh
291 eval "$(parse_yaml "../config/defaults.yaml")"
292 eval "$(parse_yaml "../config/${DEPLOY_SCENARIO}.yaml")"
293
294 export CLUSTER_DOMAIN=${cluster_domain}
295
296 declare -A virtual_nodes_ram virtual_nodes_vcpus
297 for node in "${virtual_nodes[@]}"; do
298     virtual_custom_ram="virtual_${node}_ram"
299     virtual_custom_vcpus="virtual_${node}_vcpus"
300     virtual_nodes_ram[$node]=${!virtual_custom_ram:-$virtual_default_ram}
301     virtual_nodes_vcpus[$node]=${!virtual_custom_vcpus:-$virtual_default_vcpus}
302 done
303
304 # Infra setup
305 generate_ssh_key
306 prepare_vms virtual_nodes "${base_image}"
307 create_networks OPNFV_BRIDGES
308 create_vms virtual_nodes virtual_nodes_ram virtual_nodes_vcpus OPNFV_BRIDGES
309 update_pxe_network OPNFV_BRIDGES
310 start_vms virtual_nodes
311 check_connection
312
313 ./salt.sh
314
315 # Openstack cluster setup
316 for state in "${cluster_states[@]}"; do
317     notify "STATE: ${state}\n" 2
318     # shellcheck disable=SC2086,2029
319     ssh ${SSH_OPTS} "ubuntu@${SALT_MASTER}" \
320         sudo "/root/fuel/mcp/config/states/${state}"
321 done
322
323 popd > /dev/null
324
325 #
326 # END of main
327 ##############################################################################