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