Merge "Adds installation instructions for Foreman/QuickStack"
[genesis.git] / fuel / 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 # 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 ##############################################################################
12
13 trap 'echo "Exiting ..."; \
14 if [ -f ${LOCK_FILE} ]; then \
15    if [ $(cat ${LOCK_FILE}) -eq $$ ]; then \
16       rm -f ${LOCK_FILE}; \
17    fi; \
18 fi;' EXIT
19
20 ############################################################################
21 # BEGIN of usage description
22 #
23 usage ()
24 {
25 cat << EOF
26 $0 Builds the Fuel@OPNFV stack
27
28 usage: $0 [-s spec-file] [-c cache-URI] [-l log-file] [-f Flags] build-directory
29
30 OPTIONS:
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.
33
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
41      o f: Do nothing, fail
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
46
47   build-directory ($BUILD_DIR), specifies the directory for the output artifacts (.iso file).
48
49   -h help, prints this help text
50
51 Description:
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.
59
60 The cache URI object name is fuel_cache-"md5sum(spec file)"
61
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.
63
64 Built in unit testing of components is enabled by adding the t(est) flag.
65
66 Return codes:
67  - 0 Success!
68  - 1-99 Unspecified build error
69  - 100-199 Build system internal error (not build it self)
70    o 101 Build system instance busy
71  - 200 Build failure
72
73 Examples:
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
76 EOF
77 }
78 #
79 # END of usage description
80 ############################################################################
81
82 ############################################################################
83 # BEGIN of variables to customize
84 #
85 BUILD_BASE=$(readlink -e ../build/)
86 RESULT_DIR="${BUILD_BASE}/release"
87 BUILD_SPEC="${BUILD_BASE}/config.mk"
88 CACHE_DIR="cache"
89 LOCAL_CACHE_ARCH_NAME="fuel-cache"
90 REMOTE_CACHE_ARCH_NAME="fuel_cache-$(md5sum ${BUILD_SPEC}| cut -f1 -d " ")"
91 REMOTE_ACCESS_METHD=curl
92 INCLUDE_DIR=../include
93 #
94 # END of variables to customize
95 ############################################################################
96
97 ############################################################################
98 # BEGIN of script assigned variables
99 #
100 SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
101 LOCK_FILE="${SCRIPT_DIR}/.build.lck"
102 CACHE_TMP="${SCRIPT_DIR}/tmp"
103 TEST_SUCCEED=0
104 TEST_FAIL=0
105 UNIT_TEST=0
106 UPDATE_CACHE=0
107 POPULATE_CACHE=0
108 RECURSIVE=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: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         l)
153             BUILD_LOG=${OPTARG}
154             ;;
155
156         v)
157             BUILD_VERSION=${OPTARG}
158             ;;
159
160         f)
161             BUILD_FLAGS=${OPTARG}
162             ;;
163
164         r)  REMOTE_ACCESS_METHD=${OPTARG}
165             ;;
166
167         R)
168             RECURSIVE=1
169             ;;
170
171         t)
172             INTEGRATION_TEST=1
173             ;;
174
175         T)
176             INTEGRATION_TEST=1
177             FULL_INTEGRATION_TEST=1
178             ;;
179
180         *)
181             echo "${OPTION} is not a valid argument"
182             rc=100
183             exit $rc
184             ;;
185     esac
186 done
187
188 if [ -z $BUILD_DIR ]; then
189     BUILD_DIR=$(echo $@ | cut -d ' ' -f ${OPTIND})
190 fi
191
192 for ((i=0; i<${#BUILD_FLAGS};i++)); do
193     case ${BUILD_FLAGS:$i:1} in
194         s)
195             rc=0
196             exit $rc
197             ;;
198
199         f)
200             rc=1
201             exit $rc
202             ;;
203
204         t)
205             UNIT_TEST=1
206             ;;
207
208         i)
209             INTERACTIVE=1
210             ;;
211
212         P)
213             POPULATE_CACHE=1
214             ;;
215
216         d)
217             DETACH=1
218             echo "Detach is not yet supported - exiting ...."
219             rc=100
220             exit $rc
221             ;;
222
223         D)
224             DEBUG=1
225             ;;
226
227         *)
228             echo "${BUILD_FLAGS:$i:1} is not a valid build flag - exiting ...."
229             rc=100
230             exit $rc
231             ;;
232     esac
233 done
234
235 if [ ${INTEGRATION_TEST} -eq 1 ]; then
236     integration-test
237     rc=0
238     exit $rc
239 fi
240
241 if [ ! -f ${BUILD_SPEC} ]; then
242     echo "spec file does not exist: $BUILD_SPEC - exiting ...."
243     rc=100
244     exit $rc
245 fi
246
247 if [ -z ${BUILD_DIR} ]; then
248     echo "Missing build directory - exiting ...."
249     rc=100
250     exit $rc
251 fi
252
253 if [ ! -z ${BUILD_LOG} ]; then
254     if [[ ${RECURSIVE} -ne 1 ]]; then
255         set +e
256         eval $0 -R $@ > ${BUILD_LOG} 2>&1
257         rc=$?
258         set -e
259         if [ $rc -ne 0]; then
260             exit $rc
261         fi
262     fi
263 fi
264
265 if [ ${TEST_SUCCEED} -eq 1 ]; then
266     sleep 1
267     rc=0
268     exit $rc
269 fi
270
271 if [ ${TEST_FAIL} -eq 1 ]; then
272     sleep 1
273     rc=1
274     exit $rc
275 fi
276
277 if [ -e ${LOCK_FILE} ]; then
278     echo "A build job is already running, exiting....."
279     rc=101
280     exit $rc
281 fi
282
283 echo $$ > ${LOCK_FILE}
284
285 if [ ! -z ${BUILD_CACHE_URI} ]; then
286     if [ ${POPULATE_CACHE} -ne 1 ]; then
287         rm -rf ${CACHE_TMP}/cache
288         mkdir -p ${CACHE_TMP}/cache
289         echo "Downloading cach file ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME} ..."
290         set +e
291         ${REMOTE_ACCESS_METHD} -o ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
292         rc=$?
293         set -e
294         if [ $rc -ne 0 ]; then
295                 echo "Remote cache does not exist, or is not accessible - a new cache will be built ..."
296                 POPULATE_CACHE=1
297         else
298             echo "Unpacking cache file ..."
299             tar -C ${CACHE_TMP}/cache -xvf ${CACHE_TMP}/cache/${LOCAL_CACHE_ARCH_NAME}.tgz
300             cp ${CACHE_TMP}/cache/cache/.versions ${BUILD_BASE}/.
301             set +e
302             make -C ${BUILD_BASE} validate-cache;
303             rc=$?
304             set -e
305
306             if [ $rc -ne 0 ]; then
307                 echo "Cache invalid - a new cache will be built "
308                 POPULATE_CACHE=1
309             else
310                 cp -rf ${CACHE_TMP}/cache/cache/. ${BUILD_BASE}
311             fi
312             rm -rf ${CACHE_TMP}/cache
313         fi
314     fi
315 fi
316
317 if [ ${POPULATE_CACHE} -eq 1 ]; then
318     if [ ${DEBUG} -eq 0 ]; then
319         set +e
320         cd ${BUILD_BASE} && make clean
321         rc=$?
322         set -e
323         if [ $rc -ne 0 ]; then
324             echo "Build - make clean failed, exiting ..."
325             rc=100
326             exit $rc
327         fi
328     fi
329 fi
330
331 if [ ! -z ${BUILD_VERSION} ]; then
332     MAKE_ARGS+="REVSTATE=${BUILD_VERSION} "
333 fi
334
335 if [ ${UNIT_TEST} -eq 1 ]; then
336     MAKE_ARGS+="UNIT_TEST=TRUE "
337 else
338     MAKE_ARGS+="UNIT_TEST=FALSE "
339 fi
340
341 if [ ${INTERACTIVE} -eq 1 ]; then
342     MAKE_ARGS+="INTERACTIVE=TRUE "
343 else
344     MAKE_ARGS+="INTERACTIVE=FALSE "
345 fi
346
347 MAKE_ARGS+=all
348
349 if [ ${DEBUG} -eq 0 ]; then
350     set +e
351     cd ${BUILD_BASE} && make ${MAKE_ARGS}
352     rc=$?
353     set -e
354     if [ $rc -gt 0 ]; then
355         echo "Build: make all failed, exiting ..."
356         rc=200
357         exit $rc
358     fi
359 else
360 debug_make
361 fi
362 set +e
363 make -C ${BUILD_BASE} prepare-cache
364 rc=$?
365 set -e
366
367 if [ $rc -gt 0 ]; then
368     echo "Build: make prepare-cache failed - exiting ..."
369     rc=100
370     exit $rc
371 fi
372 echo "Copying built OPNFV .iso file to target directory ${BUILD_DIR} ..."
373 rm -rf ${BUILD_DIR}
374 mkdir -p ${BUILD_DIR}
375 cp ${BUILD_BASE}/.versions ${BUILD_DIR}
376 cp ${RESULT_DIR}/*.iso* ${BUILD_DIR}
377
378 if [ $POPULATE_CACHE -eq 1 ]; then
379     if [ ! -z ${BUILD_CACHE_URI} ]; then
380         echo "Building cache ..."
381         tar --dereference -C ${BUILD_BASE} -caf ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${CACHE_DIR}
382         echo "Uploading cache ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}"
383         ${REMOTE_ACCESS_METHD} -T ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz ${BUILD_CACHE_URI}/${REMOTE_CACHE_ARCH_NAME}.tgz
384         rm ${BUILD_BASE}/${LOCAL_CACHE_ARCH_NAME}.tgz
385     fi
386 fi
387 echo "Success!!!"
388 exit 0
389 #
390 # END of main
391 ############################################################################