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