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