Whamcloud - gitweb
- fix .config file not found false error message
[fs/lustre-release.git] / build / lbuild
1 #!/bin/sh
2
3 TOPDIR=$PWD
4
5 # CVSROOT is inherited from the environment
6 KERNELDIR=
7 LUSTRE=
8 PUBLISH=0
9 RELEASE=0
10 DO_SRC=1
11 TAG=
12 TARGET=
13 TARGET_ARCHS=
14 CONFIGURE_FLAGS=
15 EXTERNAL_PATCHES=
16 EXTRA_VERSION=
17
18 # from target file
19 KERNEL=
20 SERIES=
21 CONFIG=
22 VERSION=
23
24 RHBUILD=0
25 SUSEBUILD=0
26 LINUX26=0
27 SUSEBUILD=0
28
29 BASE_ARCHS=
30 BIGMEM_ARCHS=
31 BOOT_ARCHS=
32 JENSEN_ARCHS=
33 SMP_ARCHS=
34 BIGSMP_ARCHS=
35 UP_ARCHS=
36
37 DATE=$(date)
38
39 USE_DATESTAMP=1
40 RPMBUILD=
41
42 cleanup()
43 {
44     true
45 }
46
47 error()
48 {
49     [ "$1" ] && echo -e "\n${0##*/}: $1"
50 }
51
52 fatal()
53 {
54     cleanup
55     error "$2"
56     exit $1
57 }
58
59 publishing()
60 {
61     (( $PUBLISH )) || return 0
62 }
63
64 is_release()
65 {
66     (( $RELEASE )) || return 0
67 }
68
69 list_targets()
70 {
71     echo -n "Available targets:"
72     for target in $TOPDIR/lustre/lustre/kernel_patches/targets/*.target ; do
73         target_file=${target##*/}
74         echo -n " ${target_file%%.target}"
75     done
76     echo
77 }
78
79 usage()
80 {
81     cat <<EOF
82 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
83
84   -d CVSROOT
85     Specifies the CVS Root to use when pulling files from CVS.  The
86     environment variable \$CVSROOT is used if this option is not
87     present.
88
89   --external-patches=EXTERNAL_PATCHES
90     Directory similar to lustre/lustre/kernel_patches/ that lbuild should
91     look for seres and config files in before looking in the lustre
92     tree.
93
94   --extraversion=EXTRAVERSION
95     Text to use for the rpm release and kernel extraversion.
96
97   --kerneldir=KERNELDIR
98     Directory containing Linux source tarballs referenced by target
99     files.
100
101   --lustre=LUSTRE
102     Path to an existing lustre source tarball to use instead of
103     pulling from CVS.
104
105   --nosrc
106     Do not build a .src.rpm, a full kernel patch, or a patched kernel
107     tarball.
108
109   --publish
110     Publish the packages, patches, and tarballs on the ftp server.
111
112   --release
113     Specifies that the files generated do not include timestamps, and
114     that this is an official release.
115
116   --tag=TAG
117     A CVS branch/tag name to build from when pulling from CVS.
118
119   --target=TARGET
120     The name of the target to build.  The available targets are listed
121     below.
122
123   --target-archs=TARGET_ARCHS
124     A (space delimited) list of architectures to build.  By default,
125     all of the archs supported by the TARGET will be built, in
126     addition to a .src.rpm.  This option can limit those, for machines
127     that can only build certain archs or if you only want a certain
128     arch built (for testing, or a one-off kernel).
129
130     Also note that by using a non-"base" arch (eg, i386) only kernels
131     will be built - there will be no lustre-lite-utils package.
132
133   --disable-datestamp
134     Prevents the datestamp flag (-D) from being passed to cvs for 
135     checkouts. This is a workaround for a problem encountered when 
136     using lbuild with tinderbox.
137
138 EOF
139
140 #   list_targets
141
142     fatal "$1" "$2"
143 }
144
145 check_options()
146 {
147     if [ "$LUSTRE" ] ; then
148         [ -r "$LUSTRE" ] || \
149             usage 1 "Could not find Lustre source tarball '$LUSTRE'."
150     else
151         [ "$CVSROOT" ] || \
152             usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
153         [ "$TAG" ] || \
154             usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
155     fi
156
157     [ "$KERNELDIR" ] || \
158         usage 1 "A kernel directory must be specified with --kerneldir."
159
160     [ -d "$KERNELDIR" ] || \
161         usage 1 "$KERNELDIR is not a directory."
162
163     if ! (( $RELEASE )) ; then
164         [ "$TAG" ] || \
165             usage 1 "When building a snapshot, a tag name must be used."
166     fi
167
168     TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M")
169
170     [ "$TARGET" ] || usage 1 "A target must be specified with --target."
171 #    TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
172 #    [ -r "$TARGET_FILE" ] || \
173 #       usage 1 "Target '$TARGET' was not found."
174
175     RPMBUILD=$(which rpmbuild 2>/dev/null | head -1)
176     if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
177         RPMBUILD=$(which rpm 2>/dev/null | head -1)
178         if [ ! "$RPMBUILD" -o "$RPMBUILD" == "" ]; then
179             usage 1 "Could not find binary for making rpms (tried rpmbuild and rpm)."
180         fi
181     fi
182 }
183
184 uniqify()
185 {
186     echo $(echo "$*" | xargs -n 1 | sort -u)
187 }
188
189 load_target()
190 {
191     EXTRA_VERSION_save="$EXTRA_VERSION"
192     for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
193         TARGET_FILE="$patchesdir/targets/$TARGET.target"
194         [ -r "$TARGET_FILE" ] && break
195     done
196     [ -r "$TARGET_FILE" ] || \
197         fatal 1 "Target $TARGET was not found."
198
199     echo "Loading target config file $TARGET.target..." 
200
201     . "$TARGET_FILE"
202
203     [ "$KERNEL"  ] || fatal 1 "Target $TARGET did not specify a kernel."
204 #    [ "$SERIES"  ] || fatal 1 "Target $TARGET did not specify a kernel patch series."
205 #    [ "$CONFIG"  ] || fatal 1 "Target $TARGET did not specify a kernel config."
206     [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify a kernel version."
207
208     if [ "$KERNELDIR" ] ; then
209         KERNEL_FILE="$KERNELDIR/$KERNEL"
210         [ -r "$KERNELDIR/$KERNEL" ] || \
211             fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
212     fi
213
214     if [ "$SERIES" ] ; then
215         for series in $SERIES ; do
216             for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
217                 [ -r "$patchesdir/series/$series" ] && continue 2
218             done
219             fatal 1 "Target $TARGET's series $SERIES could not be found.\nSearched:\n\t$EXTERNAL_PATCHES/series\n\t$TOPDIR/lustre/lustre/kernel_patches/series."
220         done
221     fi
222
223     CONFIG_FILE="$TOPDIR/lustre/lustre/kernel_patches/kernel_configs/$CONFIG"
224     [ -r "$CONFIG_FILE" ] || \
225         fatal 1 "Target $TARGET's config file $CONFIG missing from $TOPDIR/lustre/lustre/kernel_patches/kernel_configs/."
226
227     if [ "$EXTRA_VERSION_save" ] ; then
228         EXTRA_VERSION="$EXTRA_VERSION_save"
229     elif ! (( $RELEASE )) ; then
230         EXTRA_VERSION="${EXTRA_VERSION}-${TAG}.${TIMESTAMP}"
231     fi
232     # EXTRA_VERSION=${EXTRA_VERSION//-/_}
233
234     ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $BIGSMP_ARCHS $UP_ARCHS"
235
236     BUILD_ARCHS=
237     for arch in $(uniqify "$ALL_ARCHS") ; do
238         if [ -z "$TARGET_ARCHS" ] || echo "$TARGET_ARCHS" | grep "$arch" >/dev/null 2>/dev/null ; then
239             BUILD_ARCHS="$BUILD_ARCHS $arch"
240         fi
241     done
242     [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
243     echo "Building for: $BUILD_ARCHS"
244 }
245
246 tarflags()
247 {
248     case "$1" in
249         '')
250             fatal 1 "tarflags(): File name argument missing."
251             ;;
252         *.tar.gz)
253             echo 'zxf'
254             ;;
255         *.tar.bz2)
256             echo 'jxf'
257             ;;
258         *)
259             fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
260             ;;
261     esac
262 }
263
264 untar()
265 {
266     echo "Untarring ${1##*/}..."
267     tar $(tarflags "$1") "$1"
268 }
269
270 unpack_lustre()
271 {
272     DIRNAME="lustre-$TAG-$TIMESTAMP"
273     if [ "$LUSTRE" ] ; then
274         untar "$LUSTRE"
275         [ -d lustre ] || ln -sf lustre* lustre
276     else
277         if [ "$USE_DATESTAMP" ]; then
278             DATESTAMP="-D '$DATE'"
279         else
280             DATESTAMP=""
281         fi          
282
283         cvs -d "$CVSROOT" -qz3 co $DATESTAMP -d "$DIRNAME" lustre || \
284             fatal 1 "There was an error checking out toplevel Lustre from CVS."
285         pushd "$DIRNAME" > /dev/null
286         ./lustrecvs "$TAG" || \
287             fatal 1 "There was an error checking out Lustre/Portals/Build from CVS."
288         echo "Creating lustre tarball..."
289         sh autogen.sh || fatal 1 "There was an error running autogen.sh."
290         ./configure --disable-{modules,utils,liblustre,tests,doc} || \
291             fatal 1 "There was an error running ./configure to create makefiles."
292         make dist || fatal 1 "There was an error running 'make dist'."
293         popd > /dev/null
294         fname=`basename $DIRNAME/lustre-*.tar.gz`
295         cp $DIRNAME/$fname . || fatal 1 "There was an error copying lustre tarball."
296         LUSTRE="$PWD/$fname"
297         ln -sf "$DIRNAME" lustre
298     fi
299 }
300
301 unpack_linux()
302 {
303     untar "$KERNEL_FILE"
304     [ -d linux ] || ln -sf linux* linux
305 }
306
307 patch_linux()
308 {
309     [ "$SERIES" ] || return 0
310     FULL_PATCH="$PWD/lustre-kernel-${TARGET}-${EXTRA_VERSION}.patch"
311     [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
312     pushd linux >/dev/null
313     for series in $SERIES ; do
314         echo -n "Applying series $series:"
315         for patchesdir in "$EXTERNAL_PATCHES" "$TOPDIR/lustre/lustre/kernel_patches" ; do
316             [ -r "$patchesdir/series/$series" ] || continue
317             SERIES_FILE="$patchesdir/series/$series"
318             for patch in $(<"$SERIES_FILE") ; do
319                 echo -n " $patch"
320                 PATCH_FILE="$patchesdir/patches/$patch"
321                 [ -r "$PATCH_FILE" ] || \
322                     fatal 1 "Patch $patch does not exist in Lustre tree."
323                 cat "$PATCH_FILE" >> "$FULL_PATCH" || \
324                     fatal 1 "Error adding patch $patch to full patch."
325                 patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
326             done
327             break
328         done
329         echo
330     done
331     popd >/dev/null
332     echo "Full patch has been saved in ${FULL_PATCH##*/}."
333     echo "Replacing .config files..."
334     [ -d linux/configs ] || mkdir linux/configs || \
335         fatal 1 "Error creating configs directory."
336     rm -f linux/configs/*
337     copysuccess=0
338     for patchesdir in "$EXTERNAL_PATCHES" "lustre/lustre/kernel_patches" ; do
339         [ "$patchesdir" ] && \
340             cp -v $patchesdir/kernel_configs/kernel-${VERSION}-${TARGET}*.config linux/configs/ >/dev/null && copysuccess=1
341     done
342     [ "$copysuccess" = "1" ] || \
343         fatal 1 "Error copying in kernel configs."
344 }
345
346 pack_linux()
347 {
348     TARBALL="$(readlink linux)-$EXTRA_VERSION.tar.gz"
349     echo "Creating patched linux tarball $TARBALL..."
350     tar zcf "$TARBALL" "$(readlink linux)" \
351         --exclude "CVS" --exclude ".cvsignore" || \
352         --exclude "*.orig" --exclude "*~" --exclude "*.rej" || \
353         fatal 1 "Error creating patched Linux tarball."
354 }
355
356 clean_linux()
357 {
358     [ -d linux ] || return 0
359     echo "Cleaning linux..."
360     [ -L linux ] && rm -rf $(readlink linux)
361     rm -rf linux
362 }
363
364 prep_build()
365 {
366     # make .spec file
367     if [ -f /etc/init.d/functions -a -f /etc/sysconfig/network ] ; then
368         ENABLE_INIT_SCRIPTS=""
369     else
370         ENABLE_INIT_SCRIPTS="# "
371     fi
372     sed \
373         -e "s^@BASE_ARCHS@^$BASE_ARCHS^g" \
374         -e "s^@BIGMEM_ARCHS@^$BIGMEM_ARCHS^g" \
375         -e "s^@BIGSMP_ARCHS@^$BIGSMP_ARCHS^g" \
376         -e "s^@BOOT_ARCHS@^$BOOT_ARCHS^g" \
377         -e "s^@CONFIGURE_FLAGS@^$CONFIGURE_FLAGS^g" \
378         -e "s^@ENABLE_INIT_SCRIPTS@^$ENABLE_INIT_SCRIPTS^g" \
379         -e "s^@JENSEN_ARCHS@^$BOOT_ARCHS^g" \
380         -e "s^@KERNEL_EXTRA_VERSION@^$EXTRA_VERSION^g" \
381         -e "s^@KERNEL_RELEASE@^${EXTRA_VERSION//-/_}^g" \
382         -e "s^@KERNEL_SOURCE@^$KERNEL^g" \
383         -e "s^@KERNEL_VERSION@^$VERSION^g" \
384         -e "s^@LINUX26@^$LINUX26^g" \
385         -e "s^@LUSTRE_SOURCE@^${LUSTRE##*/}^g" \
386         -e "s^@LUSTRE_TARGET@^$TARGET^g" \
387         -e "s^@RHBUILD@^$RHBUILD^g" \
388         -e "s^@SMP_ARCHS@^$SMP_ARCHS^g" \
389         -e "s^@SUSEBUILD@^$SUSEBUILD^g" \
390         -e "s^@SUSEBUILD@^$SUSEBUILD^g" \
391         -e "s^@UP_ARCHS@^$UP_ARCHS^g" \
392         < $TOPDIR/lustre/build/lustre-kernel-2.4.spec.in \
393         > lustre-kernel-2.4.spec
394     [ -d SRPMS ] || mkdir SRPMS
395     [ -d RPMS ] || mkdir RPMS
396     [ -d BUILD ] || mkdir BUILD
397     [ -d SOURCES ] || mkdir SOURCES
398     for script in linux-{rhconfig.h,merge-config.awk,merge-modules.awk} \
399         suse-{functions.sh,post.sh,postun.sh,trigger-script.sh.in} ; do
400         cp $TOPDIR/lustre/build/$script SOURCES
401     done
402     cp "$LUSTRE" "$KERNEL_FILE" SOURCES
403     if [ "$EXTERNAL_PATCHES" -a -d "$EXTERNAL_PATCHES" ] ; then
404         tar zcf SOURCES/external-patches.tar.gz -C "$EXTERNAL_PATCHES" series targets patches kernel_configs
405     else
406         touch SOURCES/external-patches.tar.gz
407     fi
408 }
409
410 clean_lustre()
411 {
412     [ -d lustre ] || return 0
413     echo "Cleaning lustre..."
414     [ -L lustre ] && rm -rf $(readlink lustre)
415     rm -rf lustre
416 }
417
418 build()
419 {
420     echo "Building rpms for: $BUILD_ARCHS..."
421     targets=
422     for arch in $BUILD_ARCHS ; do
423         targets="--target $arch $targets"
424     done
425
426     $RPMBUILD $targets -bb lustre-kernel-2.4.spec \
427         --define "_topdir $TOPDIR" || \
428         fatal 1 "Error building rpms for $arch."
429
430     if (( $DO_SRC )) ; then
431         $RPMBUILD -bs lustre-kernel-2.4.spec \
432             --define "_topdir $TOPDIR" || \
433             fatal 1 "Error building .src.rpm."
434     fi
435 }
436
437 publish()
438 {
439     publishing || return 0
440 }
441
442 [ -r ~/.lbuildrc ] && . ~/.lbuildrc
443
444 options=$(getopt -o d:D:h -l external-patches:,extraversion:,kerneldir:,lustre:,nosrc,publish,release,tag:,target:,target-archs:,disable-datestamp -- "$@")
445
446 eval set -- "$options"
447     
448 while [ "$1" ] ; do
449     case "$1" in
450         '')
451             usage 1
452             ;;
453         -d)
454             CVSROOT=$2
455             shift 2
456             ;;
457         -D)
458             DATE=$2
459             shift 2
460             ;;
461         --external-patches)
462             EXTERNAL_PATCHES=$2
463             shift 2
464             ;;
465         --extraversion)
466             EXTRA_VERSION=$2
467             shift 2
468             ;;
469         --help | -h)
470             usage 0
471             ;;
472         --kerneldir)
473             KERNELDIR=$2
474             shift 2
475             ;;
476         --lustre)
477             LUSTRE=$2
478             shift 2
479             ;;
480         --nosrc)
481             DO_SRC=0
482             shift 1
483             ;;
484         --publish)
485             PUBLISH=1
486             shift
487             ;;
488         --release)
489             RELEASE=1
490             shift
491             ;;
492         --tag)
493             TAG=$2
494             shift 2
495             ;;
496         --target)
497             TARGET=$2
498             shift 2
499             ;;
500         --target-archs)
501             TARGET_ARCHS=$2
502             shift 2
503             ;;
504         --disable-datestamp)
505             USE_DATESTAMP=
506             shift
507             ;;
508         --)
509             shift
510             CONFIGURE_FLAGS=$@
511             break
512             ;; 
513         *)
514             usage 1 "Unrecognized option: $1"
515             ;;
516     esac
517 done
518
519 check_options
520
521 unpack_lustre
522 load_target
523
524 if (( $DO_SRC )) ; then
525     unpack_linux
526     patch_linux
527     pack_linux
528     clean_linux
529 fi
530
531 # prep_build needs the .spec.in from the lustre source
532 prep_build
533 clean_lustre
534
535 build
536 publish