3 ##############################################################################
4 # Copyright (c) 2015 Ericsson AB and others.
5 # stefan.k.berg@ericsson.com
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 trap 'echo "Exiting ..."; \
14 if [ -f ${LOCK_FILE} ]; then \
15 if [ $(cat ${LOCK_FILE}) -eq $$ ]; then \
20 ############################################################################
21 # BEGIN of usage description
26 $0 Builds the Fuel@OPNFV stack
28 usage: $0 [-s spec-file] [-c cache-URI] [-l log-file] [-f Flags] build-directory
31 -s spec-file ($BUILD_SPEC), define the build-spec file, default ../build/config.mk
32 -c cache base URI ($BUILD_CACHE_URI), specifies the base URI to a build cache to be used/updated - the name is automatically generated from the md5sum of the spec-file, http://, ftp://, file://[absolute path] suported.
34 -l log-file ($BUILD_LOG), specifies the output log-file (stdout and stderr), if not specified logs are output to console as normal
35 -v version tag to be applied to the build result
36 -r alternative remote access method script/program. curl is default.
37 -t run small build-script unit test.
38 -T run large build-script unit test.
39 -f build flags ($BUILD_FLAGS):
40 o s: Do nothing, succeed
42 o t: run build unit tests
43 o i: run interactive (-t flag to docker run)
44 o P: Populate a new local cache and push it to the (-c cache-URI) cache artifactory if -c option is present, currently file://, http:// and ftp:// are supported
45 o d: Detatch - NOT YET SUPPORTED
47 build-directory ($BUILD_DIR), specifies the directory for the output artifacts (.iso file).
49 -h help, prints this help text
52 build.sh builds opnfv .iso artifact.
53 To reduce build time it uses build cache on a local or remote location. The cache is rebuilt and uploaded if either of the below conditions are met:
54 1) The P(opulate) flag is set and the -c cache-base-URI is provided, if -c is not provided the cache will stay local.
55 2) If the cache is invalidated by one of the following conditions:
56 - The config spec md5sum does not compare to the md5sum for the spec which the cache was built.
57 - The git Commit-Id on the remote repos/HEAD defined in the spec file does not correspont with the Commit-Id for what the cache was built with.
58 3) A valid cache does not exist on the specified -c cache-base-URI.
60 The cache URI object name is fuel_cache-"md5sum(spec file)"
62 Logging by default to console, but can be directed elsewhere with the -l option in which case both stdout and stderr is redirected to that destination.
64 Built in unit testing of components is enabled by adding the t(est) flag.
68 - 1-99 Unspecified build error
69 - 100-199 Build system internal error (not build it self)
70 o 101 Build system instance busy
74 build -c http://opnfv.org/artifactory/fuel/cache -d ~/jenkins/genesis/fuel/ci/output -f ti
75 NOTE: At current the build scope is set to the git root of the repository, -d destination locations outside that scope will not work
79 # END of usage description
80 ############################################################################
82 ############################################################################
83 # Begin of string xor function
87 local res=(`echo "$1" | sed "s/../0x& /g"`)
90 local one=(`echo "$1" | sed "s/../0x& /g"`)
91 local count1=${#res[@]}
92 if [ $count1 -lt ${#one[@]} ]
96 for (( i = 0; i < $count1; i++ ))
98 res[$i]=$((${one[$i]:-0} ^ ${res[$i]:-0}))
102 printf "%02x" "${res[@]}"
105 # END of string xor function
106 ############################################################################
108 ############################################################################
109 # BEGIN of variables to customize
111 BUILD_BASE=$(readlink -e ../build/)
112 RESULT_DIR="${BUILD_BASE}/release"
113 BUILD_SPEC="${BUILD_BASE}/config.mk"
115 LOCAL_CACHE_ARCH_NAME="fuel-cache"
117 REMOTE_ACCESS_METHD=curl
118 INCLUDE_DIR=../include
120 # END of variables to customize
121 ############################################################################
123 ############################################################################
124 # BEGIN of script assigned variables
126 SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
127 LOCK_FILE="${SCRIPT_DIR}/.build.lck"
128 CACHE_TMP="${SCRIPT_DIR}/tmp"
138 FULL_INTEGRATION_TEST=0
146 FUEL_GIT_SRC="$(make -f ../build/config.mk get-fuel-repo | cut -d " " -f1)"
147 FUEL_GIT_BRANCH="$(make -f ../build/config.mk get-fuel-repo | cut -d " " -f2)"
148 CACHE_MD5=$(md5sum ../build/cache.mk | cut -f1 -d " ")
149 CONFIG_MD5=$(md5sum ../build/config.mk | cut -f1 -d " ")
150 FUEL_COMMIT_ID=$(git ls-remote $FUEL_GIT_SRC -t $FUEL_GIT_BRANCH | cut -d $'\t' -f1)
151 REMOTE_CACHE_ARCH_HASH_TMP="$(xor $CACHE_MD5 $CONFIG_MD5)"
152 REMOTE_CACHE_ARCH_HASH="$(xor $REMOTE_CACHE_ARCH_HASH_TMP $FUEL_COMMIT_ID)"
153 REMOTE_CACHE_ARCH_NAME="fuel_cache-$REMOTE_CACHE_ARCH_HASH"
155 # END of script assigned variables
156 ############################################################################
158 ############################################################################
159 # BEGIN of include pragmas
161 source ${INCLUDE_DIR}/build.sh.debug
164 ############################################################################
166 ############################################################################
169 while getopts "s:c:v:f:l:r:RtTh" OPTION
183 BUILD_CACHE_URI=${OPTARG}
191 BUILD_VERSION=${OPTARG}
195 BUILD_FLAGS=${OPTARG}
198 r) REMOTE_ACCESS_METHD=${OPTARG}
211 FULL_INTEGRATION_TEST=1
215 echo "${OPTION} is not a valid argument"
222 if [ -z $BUILD_DIR ]; then
223 BUILD_DIR=$(echo $@ | cut -d ' ' -f ${OPTIND})
226 for ((i=0; i<${#BUILD_FLAGS};i++)); do
227 case ${BUILD_FLAGS:$i:1} in
252 echo "Detach is not yet supported - exiting ...."
262 echo "${BUILD_FLAGS:$i:1} is not a valid build flag - exiting ...."
269 if [ ${INTEGRATION_TEST} -eq 1 ]; then
275 if [ ! -f ${BUILD_SPEC} ]; then
276 echo "spec file does not exist: $BUILD_SPEC - exiting ...."
281 if [ -z ${BUILD_DIR} ]; then
282 echo "Missing build directory - exiting ...."
287 if [ ! -z ${BUILD_LOG} ]; then
288 if [[ ${RECURSIVE} -ne 1 ]]; then
290 eval $0 -R $@ > ${BUILD_LOG} 2>&1
293 if [ $rc -ne 0]; then
299 if [ ${TEST_SUCCEED} -eq 1 ]; then
305 if [ ${TEST_FAIL} -eq 1 ]; then
311 if [ -e ${LOCK_FILE} ]; then
312 echo "A build job is already running, exiting....."
317 echo $$ > ${LOCK_FILE}
319 if [ ! -z ${BUILD_CACHE_URI} ]; then
320 if [ ${POPULATE_CACHE} -ne 1 ]; then
321 rm -rf ${CACHE_TMP}/cache
322 mkdir -p ${CACHE_TMP}/cache
323 echo "Downloading cache archive ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME} ..."
325 ${REMOTE_ACCESS_METHD} -o ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
328 if [ $rc -ne 0 ]; then
329 echo "Remote cache does not exist, or is not accessible - a new cache will be built ..."
332 echo "Unpacking cache archive ..."
334 tar -C ${CACHE_TMP}/cache -xvf ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
337 if [ $rc -ne 0 ]; then
338 echo "WARNING: The cache seems to be corrupt or has trailing garbage, will try to use brute force"
339 echo "Info about the cache below:"
341 file ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
342 tar -C ${CACHE_TMP}/cache -tvf ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
344 echo "Current time is: `date`"
346 pushd ${CACHE_TMP}/cache
347 gunzip -dcq ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz | tar -xvf -
351 if [ $rc -ne 0 ]; then
352 echo "ERROR: Not able to resolve the cache corruption"
355 echo "The chache corruption was resolved"
356 cp ${CACHE_TMP}/cache/cache/.versions ${BUILD_BASE}/.
358 make -C ${BUILD_BASE} validate-cache;
361 if [ $rc -ne 0 ]; then
362 echo "Cache invalid - a new cache will be built "
365 echo "Cache is up to date and will be used"
366 cp -rf ${CACHE_TMP}/cache/cache/. ${BUILD_BASE}
370 echo "Cache archive is intact"
371 cp ${CACHE_TMP}/cache/cache/.versions ${BUILD_BASE}/.
373 make -C ${BUILD_BASE} validate-cache;
377 if [ $rc -ne 0 ]; then
378 echo "Cache invalid - a new cache will be built "
381 echo "Cache is up to date and will be used"
382 cp -rf ${CACHE_TMP}/cache/cache/. ${BUILD_BASE}
385 rm -rf ${CACHE_TMP}/cache
390 if [ ${POPULATE_CACHE} -eq 1 ]; then
391 if [ ${DEBUG} -eq 0 ]; then
393 cd ${BUILD_BASE} && make clean
396 if [ $rc -ne 0 ]; then
397 echo "Build - make clean failed, exiting ..."
404 if [ ! -z ${BUILD_VERSION} ]; then
405 MAKE_ARGS+="REVSTATE=${BUILD_VERSION} "
408 if [ ${UNIT_TEST} -eq 1 ]; then
409 MAKE_ARGS+="UNIT_TEST=TRUE "
411 MAKE_ARGS+="UNIT_TEST=FALSE "
414 if [ ${INTERACTIVE} -eq 1 ]; then
415 MAKE_ARGS+="INTERACTIVE=TRUE "
417 MAKE_ARGS+="INTERACTIVE=FALSE "
422 if [ ${DEBUG} -eq 0 ]; then
424 cd ${BUILD_BASE} && make ${MAKE_ARGS}
427 if [ $rc -gt 0 ]; then
428 echo "Build: make all failed, exiting ..."
436 make -C ${BUILD_BASE} prepare-cache
440 if [ $rc -gt 0 ]; then
441 echo "Build: make prepare-cache failed - exiting ..."
445 echo "Copying built OPNFV .iso file to target directory ${BUILD_DIR} ..."
447 mkdir -p ${BUILD_DIR}
448 cp ${BUILD_BASE}/.versions ${BUILD_DIR}
449 cp ${RESULT_DIR}/*.iso* ${BUILD_DIR}
451 if [ $POPULATE_CACHE -eq 1 ]; then
452 if [ ! -z ${BUILD_CACHE_URI} ]; then
453 echo "Building cache ..."
454 tar --dereference -C ${BUILD_BASE} -caf ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${CACHE_DIR}
456 tar -C ${CACHE_TMP}/cache -tvf ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz
459 if [ $rc -ne 0 ]; then
460 echo "WARNING the cache archive generated seems to be corrupt, or containing trailing garbage"
462 echo "The Cache archive build is intact"
464 echo "Uploading cache ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}"
465 ${REMOTE_ACCESS_METHD} -T ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
466 rm ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz
473 ############################################################################