Merge "updating licensing information for the BGS components"
[genesis.git] / foreman / ci / build.sh
1 #!/bin/bash
2 set -e
3 ##############################################################################
4 # Copyright (c) 2015 Ericsson AB and others.
5 # stefan.k.berg@ericsson.com
6 # jonas.bjurel@ericsson.com
7 # dradez@redhat.com
8 # All rights reserved. This program and the accompanying materials
9 # are made available under the terms of the Apache License, Version 2.0
10 # which accompanies this distribution, and is available at
11 # http://www.apache.org/licenses/LICENSE-2.0
12 ##############################################################################
13
14 trap 'echo "Exiting ..."; \
15 if [ -f ${LOCK_FILE} ]; then \
16    if [ $(cat ${LOCK_FILE}) -eq $$ ]; then \
17       rm -f ${LOCK_FILE}; \
18    fi; \
19 fi;' EXIT
20
21 ############################################################################
22 # BEGIN of usage description
23 #
24 usage ()
25 {
26 cat << EOF
27 $0 Builds the Foreman OPNFV Deployment ISO
28
29 usage: $0 [-s spec-file] [-c cache-URI] [-l log-file] [-f Flags] build-directory
30
31 OPTIONS:
32   -s spec-file ($BUILD_SPEC), define the build-spec file, default ../build/config.mk
33   -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
35   -l log-file ($BUILD_LOG), specifies the output log-file (stdout and stderr), if not specified logs are output to console as normal
36   -v version tag to be applied to the build result
37   -r alternative remote access method script/program. curl is default.
38   -t run small build-script unit test.
39   -T run large build-script unit test.
40   -f build flags ($BUILD_FLAGS):
41      o s: Do nothing, succeed
42      o f: Do nothing, fail
43      o t: run build unit tests
44      o i: run interactive (-t flag to docker run)
45      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
46      o d: Detatch - NOT YET SUPPORTED
47
48   build-directory ($BUILD_DIR), specifies the directory for the output artifacts (.iso file).
49
50   -h help, prints this help text
51
52 Description:
53 build.sh builds opnfv .iso artifact.
54 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:
55 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.
56 2) If the cache is invalidated by one of the following conditions:
57    - The config spec md5sum does not compare to the md5sum for the spec which the cache was built.
58    - 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.
59 3) A valid cache does not exist on the specified -c cache-base-URI.
60
61 The cache URI object name is foreman_cache-"md5sum(spec file)"
62
63 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
65 Built in unit testing of components is enabled by adding the t(est) flag.
66
67 Return codes:
68  - 0 Success!
69  - 1-99 Unspecified build error
70  - 100-199 Build system internal error (not build it self)
71    o 101 Build system instance busy
72  - 200 Build failure
73
74 Examples:
75 build -c http://opnfv.org/artifactory/foreman/cache -d ~/jenkins/genesis/foreman/ci/output -f ti
76 NOTE: At current the build scope is set to the git root of the repository, -d destination locations outside that scope will not work
77 EOF
78 }
79 #
80 # END of usage description
81 ############################################################################
82
83 ############################################################################
84 # BEGIN of variables to customize
85 #
86 BUILD_BASE=$(readlink -e ../build/)
87 RESULT_DIR="${BUILD_BASE}/release"
88 BUILD_SPEC="${BUILD_BASE}/config.mk"
89 CACHE_DIR="cache"
90 LOCAL_CACHE_ARCH_NAME="foreman-cache"
91 REMOTE_CACHE_ARCH_NAME="foreman_cache-$(md5sum ${BUILD_SPEC}| cut -f1 -d " ")"
92 REMOTE_ACCESS_METHD=curl
93 INCLUDE_DIR=../include
94 #
95 # END of variables to customize
96 ############################################################################
97
98 ############################################################################
99 # BEGIN of script assigned variables
100 #
101 SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
102 LOCK_FILE="${SCRIPT_DIR}/.build.lck"
103 CACHE_TMP="${SCRIPT_DIR}/tmp"
104 TEST_SUCCEED=0
105 TEST_FAIL=0
106 UNIT_TEST=0
107 UPDATE_CACHE=0
108 POPULATE_CACHE=0
109 RECURSIV=0
110 DETACH=0
111 DEBUG=0
112 INTEGRATION_TEST=0
113 FULL_INTEGRATION_TEST=0
114 INTERACTIVE=0
115 BUILD_CACHE_URI=
116 BUILD_SPEC=
117 BUILD_DIR=
118 BUILD_LOG=
119 BUILD_VERSION=
120 MAKE_ARGS=
121 #
122 # END of script assigned variables
123 ############################################################################
124
125 ############################################################################
126 # BEGIN of include pragmas
127 #
128 source ${INCLUDE_DIR}/build.sh.debug
129 #
130 # END of include
131 ############################################################################
132
133 ############################################################################
134 # BEGIN of main
135 #
136 while getopts "s:c:d:v:f:l:r:RtTh" OPTION
137 do
138     case $OPTION in
139         h)
140             usage
141             rc=0
142             exit $rc
143             ;;
144
145         s)
146             BUILD_SPEC=${OPTARG}
147             ;;
148
149         c)
150             BUILD_CACHE_URI=${OPTARG}
151             ;;
152
153         d)
154             BUILD_DIR=${OPTARG}
155             ;;
156
157         l)
158             BUILD_LOG=${OPTARG}
159             ;;
160
161         v)
162             BUILD_VERSION=${OPTARG}
163             ;;
164
165         f)
166             BUILD_FLAGS=${OPTARG}
167             ;;
168
169         r)  REMOTE_ACCESS_METHD=${OPTARG}
170             ;;
171
172         R)
173             RECURSIVE=1
174             ;;
175
176         t)
177             INTEGRATION_TEST=1
178             ;;
179
180         T)
181             INTEGRATION_TEST=1
182             FULL_INTEGRATION_TEST=1
183             ;;
184
185         *)
186             echo "${OPTION} is not a valid argument"
187             rc=100
188             exit $rc
189             ;;
190     esac
191 done
192
193 if [ -z $BUILD_DIR ]; then
194     BUILD_DIR=$(echo $@ | cut -d ' ' -f ${OPTIND})
195 fi
196
197 for ((i=0; i<${#BUILD_FLAGS};i++)); do
198     case ${BUILD_FLAGS:$i:1} in
199         s)
200             rc=0
201             exit $rc
202             ;;
203
204         f)
205             rc=1
206             exit $rc
207             ;;
208
209         t)
210             UNIT_TEST=1
211             ;;
212
213         i)
214             INTERACTIVE=1
215             ;;
216
217         P)
218             POPULATE_CACHE=1
219             ;;
220
221         d)
222             DETACH=1
223             echo "Detach is not yet supported - exiting ...."
224             rc=100
225             exit $rc
226             ;;
227
228         D)
229             DEBUG=1
230             ;;
231
232         *)
233             echo "${BUILD_FLAGS:$i:1} is not a valid build flag - exiting ...."
234             rc=100
235             exit $rc
236             ;;
237     esac
238 done
239
240 shift $((OPTIND-1))
241
242 if [ ${INTEGRATION_TEST} -eq 1 ]; then
243     integration-test
244     rc=0
245     exit $rc
246 fi
247
248 if [ ! -f ${BUILD_SPEC} ]; then
249     echo "spec file does not exist: $BUILD_SPEC - exiting ...."
250     rc=100
251     exit $rc
252 fi
253
254 if [ -z ${BUILD_DIR} ]; then
255     echo "Missing build directory - exiting ...."
256     rc=100
257     exit $rc
258 fi
259
260 if [ ! -z ${BUILD_LOG} ]; then
261     if [[ ${RECURSIVE} -ne 1 ]]; then
262         set +e
263         eval $0 -R $@ > ${BUILD_LOG} 2>&1
264         rc=$?
265         set -e
266         if [ $rc -ne 0]; then
267             exit $rc
268         fi
269     fi
270 fi
271
272 if [ ${TEST_SUCCEED} -eq 1 ]; then
273     sleep 1
274     rc=0
275     exit $rc
276 fi
277
278 if [ ${TEST_FAIL} -eq 1 ]; then
279     sleep 1
280     rc=1
281     exit $rc
282 fi
283
284 if [ -e ${LOCK_FILE} ]; then
285     echo "A build job is already running, exiting....."
286     rc=101
287     exit $rc
288 fi
289
290 echo $$ > ${LOCK_FILE}
291
292 if [ ! -z ${BUILD_CACHE_URI} ]; then
293     if [ ${POPULATE_CACHE} -ne 1 ]; then
294         rm -rf ${CACHE_TMP}/cache
295         mkdir -p ${CACHE_TMP}/cache
296         echo "Downloading cach file ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME} ..."
297         set +e
298         ${REMOTE_ACCESS_METHD} -o ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
299         tar -tzf ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz >/dev/null
300         rc=$?
301         set -e
302         if [ $rc -ne 0 ]; then
303                 echo "Remote cache does not exist, or is not accessible - a new cache will be built ..."
304                 POPULATE_CACHE=1
305         else
306             echo "Unpacking cache file ..."
307             tar -C ${CACHE_TMP}/cache -xvf ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
308             cp ${CACHE_TMP}/cache/cache/.versions ${BUILD_BASE}/.
309             set +e
310             make -C ${BUILD_BASE} validate-cache;
311             rc=$?
312             set -e
313
314             if [ $rc -ne 0 ]; then
315                 echo "Cache invalid - a new cache will be built "
316                 POPULATE_CACHE=1
317             else
318                 cp -rf ${CACHE_TMP}/cache/cache/. ${BUILD_BASE}
319             fi
320             rm -rf ${CACHE_TMP}/cache
321         fi
322     fi
323 fi
324
325 if [ ${POPULATE_CACHE} -eq 1 ]; then
326     if [ ${DEBUG} -eq 0 ]; then
327         set +e
328         cd ${BUILD_BASE} && make clean
329         rc=$?
330         set -e
331         if [ $rc -ne 0 ]; then
332             echo "Build - make clean failed, exiting ..."
333             rc=100
334             exit $rc
335         fi
336     fi
337 fi
338
339 if [ ! -z ${BUILD_VERSION} ]; then
340     MAKE_ARGS+="REVSTATE=${BUILD_VERSION} "
341 fi
342
343 if [ ${UNIT_TEST} -eq 1 ]; then
344     MAKE_ARGS+="UNIT_TEST=TRUE "
345 else
346     MAKE_ARGS+="UNIT_TEST=FALSE "
347 fi
348
349 if [ ${INTERACTIVE} -eq 1 ]; then
350     MAKE_ARGS+="INTERACTIVE=TRUE "
351 else
352     MAKE_ARGS+="INTERACTIVE=FALSE "
353 fi
354
355 MAKE_ARGS+=all
356
357 if [ ${DEBUG} -eq 0 ]; then
358     set +e
359     cd ${BUILD_BASE} && make ${MAKE_ARGS}
360     rc=$?
361     set -e
362     if [ $rc -gt 0 ]; then
363         echo "Build: make all failed, exiting ..."
364         rc=200
365         exit $rc
366     fi
367 else
368 debug_make
369 fi
370 set +e
371 make -C ${BUILD_BASE} prepare-cache
372 rc=$?
373 set -e
374
375 if [ $rc -gt 0 ]; then
376     echo "Build: make prepare-cache failed - exiting ..."
377     rc=100
378     exit $rc
379 fi
380 echo "Copying built OPNFV .iso file to target directory ${BUILD_DIR} ..."
381 rm -rf ${BUILD_DIR}
382 mkdir -p ${BUILD_DIR}
383 cp ${BUILD_BASE}/.versions ${BUILD_DIR}
384 cp ${RESULT_DIR}/*.iso* ${BUILD_DIR}
385
386 if [ $POPULATE_CACHE -eq 1 ]; then
387     if [ ! -z ${BUILD_CACHE_URI} ]; then
388         echo "Building cache ..."
389         tar --dereference -C ${BUILD_BASE} -caf ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${CACHE_DIR}
390         echo "Uploading cache ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}"
391         ${REMOTE_ACCESS_METHD} -T ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
392         rm ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz
393     fi
394 fi
395 echo "Success!!!"
396 exit 0
397 #
398 # END of main
399 ############################################################################