2b7fd9af1d254dcc5a835000140abc430248f23e
[genesis.git] / compass / 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 # chigang@huawei.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 Compass@OPNFV stack
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 compass_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/compass/cache -d ~/jenkins/genesis/compass/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 export RESULT_DIR="${BUILD_BASE}/release"
88 BUILD_SPEC="${BUILD_BASE}/config.mk"
89 CACHE_DIR="cache"
90 LOCAL_CACHE_ARCH_NAME="compass-cache"
91 REMOTE_CACHE_ARCH_NAME="compass_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 export BUILD_CACHE_URI=
116 BUILD_SPEC=
117 BUILD_DIR=
118 BUILD_LOG=
119 export 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 build_prepare
137
138 while getopts "s:c:v:f:l:r:RtTh" OPTION
139 do
140     case $OPTION in
141         h)
142             usage
143             rc=0
144             exit $rc
145             ;;
146
147         s)
148             BUILD_SPEC=${OPTARG}
149             ;;
150
151         c)
152             BUILD_CACHE_URI=${OPTARG}
153             ;;
154
155         l)
156             BUILD_LOG=${OPTARG}
157             ;;
158
159         v)
160             BUILD_VERSION=${OPTARG}
161             ;;
162
163         f)
164             BUILD_FLAGS=${OPTARG}
165             ;;
166
167         r)  REMOTE_ACCESS_METHD=${OPTARG}
168             ;;
169
170         R)
171             RECURSIVE=1
172             ;;
173
174         t)
175             INTEGRATION_TEST=1
176             ;;
177
178         T)
179             INTEGRATION_TEST=1
180             FULL_INTEGRATION_TEST=1
181             ;;
182
183         *)
184             echo "${OPTION} is not a valid argument"
185             rc=100
186             exit $rc
187             ;;
188     esac
189 done
190
191 if [ -z $BUILD_DIR ]; then
192     BUILD_DIR=$(echo $@ | cut -d ' ' -f ${OPTIND})
193 fi
194
195 for ((i=0; i<${#BUILD_FLAGS};i++)); do
196     case ${BUILD_FLAGS:$i:1} in
197         s)
198             rc=0
199             exit $rc
200             ;;
201
202         f)
203             rc=1
204             exit $rc
205             ;;
206
207         t)
208             UNIT_TEST=1
209             ;;
210
211         i)
212             INTERACTIVE=1
213             ;;
214
215         P)
216             POPULATE_CACHE=1
217             ;;
218
219         d)
220             DETACH=1
221             echo "Detach is not yet supported - exiting ...."
222             rc=100
223             exit $rc
224             ;;
225
226         D)
227             DEBUG=1
228             ;;
229
230         *)
231             echo "${BUILD_FLAGS:$i:1} is not a valid build flag - exiting ...."
232             rc=100
233             exit $rc
234             ;;
235     esac
236 done
237
238 if [ ${INTEGRATION_TEST} -eq 1 ]; then
239     integration-test
240     rc=0
241     exit $rc
242 fi
243
244 if [ ! -f ${BUILD_SPEC} ]; then
245     echo "spec file does not exist: $BUILD_SPEC - exiting ...."
246     rc=100
247     exit $rc
248 fi
249
250 if [ -z ${BUILD_DIR} ]; then
251     echo "Missing build directory - exiting ...."
252     rc=100
253     exit $rc
254 fi
255
256 if [ ! -z ${BUILD_LOG} ]; then
257     if [[ ${RECURSIVE} -ne 1 ]]; then
258         set +e
259         eval $0 -R $@ > ${BUILD_LOG} 2>&1
260         rc=$?
261         set -e
262         if [ $rc -ne 0 ]; then
263             exit $rc
264         fi
265     fi
266 fi
267
268 if [ ${TEST_SUCCEED} -eq 1 ]; then
269     sleep 1
270     rc=0
271     exit $rc
272 fi
273
274 if [ ${TEST_FAIL} -eq 1 ]; then
275     sleep 1
276     rc=1
277     exit $rc
278 fi
279
280 if [ -e ${LOCK_FILE} ]; then
281     echo "A build job is already running, exiting....."
282     rc=101
283     exit $rc
284 fi
285
286 echo $$ > ${LOCK_FILE}
287
288 if [ ! -z ${BUILD_CACHE_URI} ]; then
289     if [ ${POPULATE_CACHE} -ne 1 ]; then
290         rm -rf ${CACHE_TMP}/cache
291         mkdir -p ${CACHE_TMP}/cache
292         echo "Downloading cach file ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME} ..."
293         set +e
294         ${REMOTE_ACCESS_METHD} -o ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
295         rc=$?
296         set -e
297         if [ $rc -ne 0 ]; then
298                 echo "Remote cache does not exist, or is not accessible - a new cache will be built ..."
299                 POPULATE_CACHE=1
300         else
301             echo "Unpacking cache file ..."
302             tar -C ${CACHE_TMP}/cache -xvf ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
303             cp ${CACHE_TMP}/cache/cache/.versions ${BUILD_BASE}/.
304             set +e
305             make -C ${BUILD_BASE} validate-cache;
306             rc=$?
307             set -e
308
309             if [ $rc -ne 0 ]; then
310                 echo "Cache invalid - a new cache will be built "
311                 POPULATE_CACHE=1
312             else
313                 cp -rf ${CACHE_TMP}/cache/cache/. ${BUILD_BASE}
314             fi
315             rm -rf ${CACHE_TMP}/cache
316         fi
317     fi
318 fi
319
320 if [ ${POPULATE_CACHE} -eq 1 ]; then
321     if [ ${DEBUG} -eq 0 ]; then
322         set +e
323         cd ${BUILD_BASE} && make clean
324         rc=$?
325         set -e
326         if [ $rc -ne 0 ]; then
327             echo "Build - make clean failed, exiting ..."
328             rc=100
329             exit $rc
330         fi
331     fi
332 fi
333
334 if [ ! -z ${BUILD_VERSION} ]; then
335     MAKE_ARGS+="REVSTATE=${BUILD_VERSION} "
336 fi
337
338 if [ ${UNIT_TEST} -eq 1 ]; then
339     MAKE_ARGS+="UNIT_TEST=TRUE "
340 else
341     MAKE_ARGS+="UNIT_TEST=FALSE "
342 fi
343
344 if [ ${INTERACTIVE} -eq 1 ]; then
345     MAKE_ARGS+="INTERACTIVE=TRUE "
346 else
347     MAKE_ARGS+="INTERACTIVE=FALSE "
348 fi
349
350 MAKE_ARGS+=all
351
352 if [ ${DEBUG} -eq 0 ]; then
353     set +e
354     cd ${BUILD_BASE} && make ${MAKE_ARGS}
355     rc=$?
356     set -e
357     if [ $rc -gt 0 ]; then
358         echo "Build: make all failed, exiting ..."
359         rc=200
360         exit $rc
361     fi
362 else
363 debug_make
364 fi
365 set +e
366 make -C ${BUILD_BASE} prepare-cache
367 rc=$?
368 set -e
369
370 if [ $rc -gt 0 ]; then
371     echo "Build: make prepare-cache failed - exiting ..."
372     rc=100
373     exit $rc
374 fi
375 echo "Copying built OPNFV .iso file to target directory ${BUILD_DIR} ..."
376 rm -rf ${BUILD_DIR}
377 mkdir -p ${BUILD_DIR}
378 cp ${BUILD_BASE}/.versions ${BUILD_DIR}
379 cp ${RESULT_DIR}/*.iso* ${BUILD_DIR}
380
381 #if [ $POPULATE_CACHE -eq 1 ]; then
382 #    if [ ! -z ${BUILD_CACHE_URI} ]; then
383 #       echo "Building cache ..."
384 #       tar --dereference -C ${BUILD_BASE} -caf ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${CACHE_DIR}
385 #       echo "Uploading cache ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}"
386 #       ${REMOTE_ACCESS_METHD} -T ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
387 #       rm ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz
388 #    fi
389 #fi
390 echo "Success!!!"
391 exit 0
392 #
393 # END of main
394 ############################################################################