Merge "build: cache: Allow LOCAL_CACHE_ARCH_NAME override"
[fuel.git] / ci / build.sh
1 #!/bin/bash
2 ##############################################################################
3 # Copyright (c) 2015 Ericsson AB and others.
4 # stefan.k.berg@ericsson.com
5 # jonas.bjurel@ericsson.com
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
11
12 ############################################################################
13 # BEGIN of usage description
14 #
15 usage ()
16 {
17 cat | more << EOF
18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
19 `basename $0`: Builds the Fuel@OPNFV stack
20
21 usage: `basename $0` [-s spec-file] [-c cache-URI] [-l log-file] [-f flags]
22        [output-directory]
23
24 OPTIONS:
25   -s spec-file (NOTE! DEPRECATED!)
26       define the build-spec file, default ../build/config.mk. The script only
27       verifies that the spec-file exists.
28   -c cache base URI
29        specifies the base URI to a build cache to be used/updated, supported
30        methods are http://, ftp:// and file://
31   -l log-file
32        specifies the output log-file (stdout and stderr), if not specified
33        logs are output to console as normal
34   -v
35        version tag to be applied to the build result
36   -r
37        alternative remote access method script/program. curl is default.
38   -f flag[...]
39        build flags:
40           s: Do nothing, succeed
41           f: Do nothing, fail
42           D: Debug mode
43           P: Clear the local cache before building. This flag is only
44              valid if the "-c cache-URI" options has been specified and
45              and the  method in the cache-URI is file:// (local cache).
46
47   -h help, prints this help text
48
49   output-directory, specifies the directory for the output artifacts
50   (.iso file). If no output-directory is specified, the current path
51   when calling the script is used.
52
53
54 Description:
55
56 build.sh builds the opnfv .iso artifact.
57 To reduce build time it uses build caches on a local or remote location. A
58 cache is rebuilt and uploaded if either of the below conditions are met:
59 1) The P(opulate) flag is set and the -c cache-base-URI is provided and set
60    to the method file:// , if -c is
61    not provided the cache will stay local.
62 2) If a cache is invalidated by the make system - the exact logic is encoded
63    in the cache.mk of the different parts of the build.
64 3) A valid cache does not exist on the specified -c cache-base-URI.
65
66 A cache has a blob (binary data) and a meta file in the format of:
67    <SHA1>.blob
68    <SHA1>.meta
69
70 Logging is by default to console, but can be directed elsewhere with the -l
71 option in which case both stdout and stderr is redirected to that destination.
72
73 Built in unit testing of components is enabled by adding the t(est) flag.
74
75 Return codes:
76  - 0 Success!
77  - 1-99 Unspecified build error
78  - 100-199 Build system internal error (not build it self)
79      - 101 Build system instance busy
80  - 200 Build failure
81
82 Examples:
83   build -c http://opnfv.org/artifactory/fuel/cache \
84         -d ~/jenkins/genesis/fuel/ci/output -f ti
85
86 NOTE: At current the build scope is set to the git root of the repository, -d
87       destination locations outside that scope will not work!
88 EOF
89 }
90 #
91 # END of usage description
92 ############################################################################
93
94 ############################################################################
95 # BEGIN of function error_exit
96
97 error_exit() {
98     echo "$@" >&2
99     exit 1
100 }
101
102 #
103 # END of function error_exit
104 ############################################################################
105
106
107 ############################################################################
108 # BEGIN of shorthand variables for internal use
109 #
110 SCRIPT_DIR=$(readlink -f $(dirname ${BASH_SOURCE[0]}))
111 BUILD_BASE=$(readlink -e ${SCRIPT_DIR}/../build/)
112 RESULT_DIR="${BUILD_BASE}/release"
113 BUILD_SPEC="${BUILD_BASE}/config.mk"
114 LOCAL_CACHE_ARCH_NAME="${LOCAL_CACHE_ARCH_NAME:-fuel-cache}"
115
116 #
117 # END of variables to customize
118 ############################################################################
119
120 ############################################################################
121 # BEGIN of script assigned default variables
122 #
123 export CACHEBASE="file://$HOME/cache"
124 export CACHETRANSPORT="curl --silent"
125 CLEAR_CACHE=0
126 MAKE_ARGS=""
127
128 #
129 # END of script assigned variables
130 ############################################################################
131
132 build() {
133     echo "CI build parameters:"
134     echo "SCRIPT_DIR = $SCRIPT_DIR"
135     echo "BUILD_BASE = $BUILD_BASE"
136     echo "RESULT_DIR = $RESULT_DIR"
137     echo "BUILD_SPEC = $BUILD_SPEC"
138     echo "LOCAL_CACHE_ARCH_NAME = $LOCAL_CACHE_ARCH_NAME"
139     echo "CLEAR_CACHE = $CLEAR_CACHE"
140     echo "DEBUG = $DEBUG"
141     echo "OUTPUT_DIR = $OUTPUT_DIR"
142     echo "BUILD_LOG = $BUILD_LOG"
143     echo "MAKE_ARGS = $MAKE_ARGS"
144     echo "CACHEBASE = $CACHEBASE"
145     echo "CACHETRANSPORT = $CACHETRANSPORT"
146
147
148     if [ "$CLEAR_CACHE" -eq 1 ]; then
149         echo $CACHEBASE | grep -q '^file://' $CACHE_BASE
150         if [ $? -ne 0 ]; then
151             error_exit "Can't clear a non-local cache!"
152         else
153             CACHEDIR=$(echo $CACHEBASE | sed 's;file://;;')
154             echo "Clearing local cache at $CACHEDIR..."
155             rm -rvf $CACHEDIR/*
156         fi
157     fi
158
159     echo make ${MAKE_ARGS} cache
160
161     cd ${BUILD_BASE}
162     if make ${MAKE_ARGS} cache; then
163         echo "Copying build result into $OUTPUT_DIR"
164         sort ${BUILD_BASE}/gitinfo*.txt > ${OUTPUT_DIR}/gitinfo.txt
165         cp ${RESULT_DIR}/*.iso ${OUTPUT_DIR}
166         cp ${RESULT_DIR}/*.iso.txt ${OUTPUT_DIR}
167     else
168         error_exit "Build failed"
169     fi
170 }
171
172 ############################################################################
173 # BEGIN of main
174 #
175 while getopts "s:c:l:v:f:r:f:h" OPTION
176 do
177     case $OPTION in
178         s)
179             BUILD_SPEC=${OPTARG}
180             if [ ! -f ${BUILD_SPEC} ]; then
181                 echo "spec file does not exist: $BUILD_SPEC - exiting ...."
182                 exit 100
183             fi
184             ;;
185         c)
186             # This value is used by cache.sh
187             export CACHEBASE=${OPTARG}
188             ;;
189         l)
190             BUILD_LOG=$(readlink -f ${OPTARG})
191             ;;
192         v)
193             MAKE_ARGS+="REVSTATE=${OPTARG}"
194             ;;
195         r)
196             # This value is used by cache.sh
197             export CACHETRANSPORT=${OPTARG}
198             ;;
199         h)
200             usage
201             rc=0
202             exit $rc
203             ;;
204         f)
205             BUILD_FLAGS=${OPTARG}
206             for ((i=0; i<${#BUILD_FLAGS};i++)); do
207                 case ${BUILD_FLAGS:$i:1} in
208                     s)
209                         exit 0
210                         ;;
211
212                     f)
213                         exit 1
214                         ;;
215
216                     P)
217                         CLEAR_CACHE=1
218                         ;;
219
220                     D)
221                         DEBUG=1
222                         ;;
223
224                     *)
225                         error_exit "${BUILD_FLAGS:$i:1} is not a valid build flag - exiting ...."
226                         ;;
227                 esac
228             done
229             ;;
230
231         *)
232             echo "${OPTION} is not a valid argument"
233             rc=100
234             exit $rc
235             ;;
236     esac
237 done
238
239 # Get output directory
240 shift $[$OPTIND - 1]
241 case $# in
242     0)
243         # No directory on command line
244         OUTPUT_DIR=$(pwd)
245         ;;
246     1)
247         # Directory on command line
248         OUTPUT_DIR=$(readlink -f $1)
249         ;;
250     *)
251         error_exit "Too many arguments"
252         ;;
253 esac
254 mkdir -p $OUTPUT_DIR || error_exit "Could not access output directory $OUTPUT_DIR"
255
256
257 if [ -n "${BUILD_LOG}" ]; then
258     touch ${BUILD_LOG} || error_exit "Could not write to log file ${BUILD_LOG}"
259     build 2>&1 | tee ${BUILD_LOG}
260 else
261     build
262 fi
263
264 rc=$?
265 exit $rc
266
267 #
268 # END of main
269 ############################################################################