2 # shellcheck disable=SC2034,SC2154,SC1091
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 ##############################################################################
13 ##############################################################################
14 # BEGIN of Exit handlers
21 # End of Exit handlers
22 ##############################################################################
24 ##############################################################################
25 # BEGIN of usage description
30 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
31 $(notify "$(basename "$0"): Deploy the Fuel@OPNFV MCP stack" 3)
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]
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
44 -s Deploy-scenario short-name
45 -S Storage dir for VM images
46 -L Deployment log path and file name
48 $(notify "DISABLED OPTIONS (not yet supported with MCP):" 3)
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
54 -T (disabled) Timeout, in minutes, for the deploy.
56 $(notify "Description:" 2)
57 Deploys the Fuel@OPNFV stack on the indicated lab resource.
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.
63 $(notify "Input parameters to the build script are:" 2)
64 -b Base URI to the configuration directory (needs to be provided in URI style,
65 it can be a local resource: file:// or a remote resource http(s)://).
66 A POD Descriptor File (PDF) should be available at:
67 <base-uri>/labs/<lab-name>/<pod-name>.yaml
68 The default is './mcp/config'.
69 -B Bridges to be used by deploy script. It can be specified several times,
70 or as a comma separated list of bridges, or both: -B br1 -B br2,br3
71 First occurence sets PXE Brige, next Mgmt, then Internal and Public.
72 For an empty value, the deploy script will use virsh to create the default
73 expected network (e.g. -B pxe,,,public will use existing "pxe" and "public"
74 bridges, respectively create "mgmt" and "internal").
75 Note that a virtual network "mcpcontrol" is always created. For virtual
76 deploys, "mcpcontrol" is also used for PXE, leaving the PXE bridge unused.
77 For baremetal deploys, PXE bridge is used for baremetal node provisioning,
78 while "mcpcontrol" is used to provision the infrastructure VMs only.
79 The default is 'pxebr'.
80 -h Print this message and exit
81 -L Deployment log path and name, eg. -L /home/jenkins/job.log.tar.gz
82 -l Lab name as defined in the configuration directory, e.g. lf
83 -p POD name as defined in the configuration directory, e.g. pod2
84 -s Deployment-scenario, this points to a short deployment scenario name, which
85 has to be defined in config directory (e.g. os-odl-nofeature-ha).
86 -S Storage dir for VM images, default is mcp/deploy/images
88 $(notify "Disabled input parameters (not yet supported with MCP):" 3)
89 -d (disabled) Dry-run - Produce deploy config files, but do not execute deploy
90 -f (disabled) Deploy on existing Salt master
91 -e (disabled) Do not launch environment deployment
92 -F (disabled) Do only create a Salt master
93 -T (disabled) Timeout, in minutes, for the deploy.
94 It defaults to using the DEPLOY_TIMEOUT environment variable when defined.
95 -i (disabled) .iso image to be deployed (needs to be provided in a URI
96 style, it can be a local resource: file:// or a remote resource http(s)://)
98 $(notify "[NOTE] sudo & virsh priviledges are needed for this script to run" 3)
102 $(notify "sudo $(basename "$0") \\
103 -b file:///home/jenkins/securedlab \\
105 -s os-odl-nofeature-ha" 2)
110 # END of usage description
111 ##############################################################################
113 ##############################################################################
114 # BEGIN of colored notification wrapper
117 tput setaf "${2:-1}" || true
118 echo -en "${1:-"[WARN] Unsupported opt arg: $3\\n"}"
122 # END of colored notification wrapper
123 ##############################################################################
125 ##############################################################################
126 # BEGIN of deployment clean-up
129 echo "Cleaning up deploy tmp directories"
132 # END of deployment clean-up
133 ##############################################################################
135 ##############################################################################
136 # BEGIN of variables to customize
138 REPO_ROOT_PATH=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/..")
139 DEPLOY_DIR=$(cd "${REPO_ROOT_PATH}/mcp/scripts"; pwd)
140 STORAGE_DIR=$(cd "${REPO_ROOT_PATH}/mcp/deploy/images"; pwd)
141 RECLASS_CLUSTER_DIR=$(cd "${REPO_ROOT_PATH}/mcp/reclass/classes/cluster"; pwd)
142 DEPLOY_TYPE='baremetal'
143 OPNFV_BRIDGES=('pxebr' 'mgmt' 'internal' 'public')
144 URI_REGEXP='(file|https?|ftp)://.*'
145 BASE_CONFIG_URI="file://${REPO_ROOT_PATH}/mcp/config"
147 export SSH_KEY=${SSH_KEY:-"/var/lib/opnfv/mcp.rsa"}
148 export SALT_MASTER=${INSTALLER_IP:-10.20.0.2}
149 export SALT_MASTER_USER=${SALT_MASTER_USER:-ubuntu}
150 export MAAS_IP=${MAAS_IP:-${SALT_MASTER%.*}.3}
151 export MAAS_PXE_NETWORK=${MAAS_PXE_NETWORK:-192.168.11.0}
153 # Derivated from above global vars
154 export MCP_CTRL_NETWORK_ROOTSTR=${SALT_MASTER%.*}
155 export MAAS_PXE_NETWORK_ROOTSTR=${MAAS_PXE_NETWORK%.*}
156 export SSH_OPTS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${SSH_KEY}"
157 export SSH_SALT="${SALT_MASTER_USER}@${SALT_MASTER}"
159 # Variables below are disabled for now, to be re-introduced or removed later
162 FUEL_CREATION_ONLY=''
163 NO_DEPLOY_ENVIRONMENT=''
165 if ! [ -z "${DEPLOY_TIMEOUT}" ]; then
166 DEPLOY_TIMEOUT="-dt ${DEPLOY_TIMEOUT}"
172 # END of variables to customize
173 ##############################################################################
175 ##############################################################################
180 while getopts "b:B:dfFl:L:p:s:S:T:i:he" OPTION
184 BASE_CONFIG_URI=${OPTARG}
185 if [[ ! $BASE_CONFIG_URI =~ ${URI_REGEXP} ]]; then
186 notify "[ERROR] -b $BASE_CONFIG_URI - invalid URI\n"
194 OPT_BRIDGES=($OPTARG)
195 for bridge in "${OPT_BRIDGES[@]}"; do
196 if [ -n "${bridge}" ]; then
197 OPNFV_BRIDGES[${OPNFV_BRIDGE_IDX}]="${bridge}"
199 OPNFV_BRIDGE_IDX=$((OPNFV_BRIDGE_IDX + 1))
204 notify '' 3 "${OPTION}"; continue
208 notify '' 3 "${OPTION}"; continue
209 USE_EXISTING_FUEL='-nf'
212 notify '' 3 "${OPTION}"; continue
213 FUEL_CREATION_ONLY='-fo'
216 notify '' 3 "${OPTION}"; continue
217 NO_DEPLOY_ENVIRONMENT='-nde'
223 DEPLOY_LOG="${OPTARG}"
227 if [[ "${TARGET_POD}" =~ "virtual" ]]; then
228 DEPLOY_TYPE='virtual'
232 DEPLOY_SCENARIO=${OPTARG}
235 if [[ ${OPTARG} ]]; then
236 STORAGE_DIR="${OPTARG}"
240 notify '' 3 "${OPTION}"; continue
241 DEPLOY_TIMEOUT="-dt ${OPTARG}"
244 notify '' 3 "${OPTION}"; continue
246 if [[ ! $ISO =~ ${URI_REGEXP} ]]; then
247 notify "[ERROR] -i $ISO - invalid URI\n"
257 notify "[ERROR] Arguments not according to new argument style\n"
263 if [[ "$(sudo whoami)" != 'root' ]]; then
264 notify "This script requires sudo rights\n" 1>&2
268 if ! virsh list >/dev/null 2>&1; then
269 notify "This script requires hypervisor access\n" 1>&2
273 # Validate mandatory arguments are set
274 if [ -z "${TARGET_LAB}" ] || [ -z "${TARGET_POD}" ] || \
275 [ -z "${DEPLOY_SCENARIO}" ]; then
276 notify "[ERROR] At least one of the mandatory args is missing!\n" 1>&2
283 # Enable the automatic exit trap
284 trap do_exit SIGINT SIGTERM EXIT
286 # Set no restrictive umask so that Jenkins can remove any residuals
291 pushd "${DEPLOY_DIR}" > /dev/null
292 # Prepare the deploy config files based on lab/pod information, deployment
295 # Install required packages
296 [ -n "$(command -v apt-get)" ] && sudo apt-get install -y \
297 git make rsync mkisofs curl virtinst cpu-checker qemu-kvm
298 [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken \
299 git make rsync genisoimage curl virt-install qemu-kvm
301 if [ "$(uname -i)" = "aarch64" ]; then
302 [ -n "$(command -v apt-get)" ] && sudo apt-get install -y vgabios && \
303 sudo ln -sf /usr/share/vgabios/vgabios.bin /usr/share/qemu/vgabios-stdvga.bin
304 [ -n "$(command -v yum)" ] && sudo yum install -y --skip-broken vgabios
307 # Clone git submodules and apply our patches
308 make -C "${REPO_ROOT_PATH}/mcp/patches" deepclean patches-import
310 # Convert Pharos-compatible POD Descriptor File (PDF) to reclass model input
311 PHAROS_GEN_CONFIG_SCRIPT="./pharos/config/utils/generate_config.py"
312 PHAROS_INSTALLER_ADAPTER="./pharos/config/installers/fuel/pod_config.yml.j2"
313 BASE_CONFIG_PDF="${BASE_CONFIG_URI}/labs/${TARGET_LAB}/${TARGET_POD}.yaml"
314 LOCAL_PDF="${STORAGE_DIR}/$(basename "${BASE_CONFIG_PDF}")"
315 LOCAL_PDF_RECLASS="${STORAGE_DIR}/pod_config.yml"
316 if ! curl --create-dirs -o "${LOCAL_PDF}" "${BASE_CONFIG_PDF}"; then
317 if [ "${DEPLOY_TYPE}" = 'baremetal' ]; then
318 notify "[ERROR] Could not retrieve PDF (Pod Descriptor File)!\n" 1>&2
321 notify "[WARN] Could not retrieve PDF (Pod Descriptor File)!\n" 3
323 elif ! "${PHAROS_GEN_CONFIG_SCRIPT}" -y "${LOCAL_PDF}" \
324 -j "${PHAROS_INSTALLER_ADAPTER}" > "${LOCAL_PDF_RECLASS}"; then
325 notify "[ERROR] Could not convert PDF to reclass model input!\n" 1>&2
329 # Check scenario file existence
330 SCENARIO_DIR="../config/scenario"
331 if [ ! -f "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
332 notify "[WARN] ${DEPLOY_SCENARIO}.yaml not found! \
333 Setting simplest scenario (os-nosdn-nofeature-noha)\n" 3
334 DEPLOY_SCENARIO='os-nosdn-nofeature-noha'
335 if [ ! -f "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml" ]; then
336 notify "[ERROR] Scenario definition file is missing!\n" 1>&2
341 # Check defaults file existence
342 if [ ! -f "${SCENARIO_DIR}/defaults-$(uname -i).yaml" ]; then
343 notify "[ERROR] Scenario defaults file is missing!\n" 1>&2
347 # Get required infra deployment data
349 eval "$(parse_yaml "${SCENARIO_DIR}/defaults-$(uname -i).yaml")"
350 eval "$(parse_yaml "${SCENARIO_DIR}/${DEPLOY_TYPE}/${DEPLOY_SCENARIO}.yaml")"
352 export CLUSTER_DOMAIN=${cluster_domain}
354 declare -A virtual_nodes_ram virtual_nodes_vcpus
355 for node in "${virtual_nodes[@]}"; do
356 virtual_custom_ram="virtual_${node}_ram"
357 virtual_custom_vcpus="virtual_${node}_vcpus"
358 virtual_nodes_ram[$node]=${!virtual_custom_ram:-$virtual_default_ram}
359 virtual_nodes_vcpus[$node]=${!virtual_custom_vcpus:-$virtual_default_vcpus}
362 # Expand reclass and virsh network templates
363 for tp in "${RECLASS_CLUSTER_DIR}/all-mcp-ocata-common/opnfv/"*.template \
364 net_*.template; do envsubst < "${tp}" > "${tp%.template}"; done
368 prepare_vms virtual_nodes "${base_image}" "${STORAGE_DIR}"
369 create_networks OPNFV_BRIDGES
370 create_vms virtual_nodes virtual_nodes_ram virtual_nodes_vcpus \
371 OPNFV_BRIDGES "${STORAGE_DIR}"
372 update_mcpcontrol_network
373 start_vms virtual_nodes
376 ./salt.sh "${LOCAL_PDF_RECLASS}"
378 # Openstack cluster setup
379 for state in "${cluster_states[@]}"; do
380 notify "STATE: ${state}\n" 2
381 # shellcheck disable=SC2086,2029
382 ssh ${SSH_OPTS} "ubuntu@${SALT_MASTER}" \
383 sudo "/root/fuel/mcp/config/states/${state} || true"
386 ./log.sh "${DEPLOY_LOG}"
392 ##############################################################################