--- /dev/null
+#!/bin/sh
+
+TOPDIR=$PWD
+
+# CVSROOT is inherited from the environment
+KERNELDIR=
+LUSTRE=
+PUBLISH=0
+RELEASE=0
+DO_SRC=1
+TAG=
+TARGET=
+TARGET_ARCHS=
+CONFIGURE_FLAGS=
+EXTRA_VERSION=
+
+# from target file
+KERNEL=
+SERIES=
+CONFIG=
+VERSION=
+
+BASE_ARCH=
+BIGMEM_ARCHS=
+BOOT_ARCHS=
+JENSEN_ARCHS=
+SMP_ARCHS=
+UP_ARCHS=
+
+DATE=$(date)
+
+cleanup()
+{
+ true
+}
+
+fatal()
+{
+ cleanup
+ [ "$2" ] && echo
+ [ "$2" ] && echo "${0##*/}: $2"
+ exit $1
+}
+
+publishing()
+{
+ (( $PUBLISH )) || return 0
+}
+
+is_release()
+{
+ (( $RELEASE )) || return 0
+}
+
+list_targets()
+{
+ echo -n "Available targets:"
+ for target in $TOPDIR/lustre/kernel_patches/targets/*.target ; do
+ target_file=${target##*/}
+ echo -n " ${target_file%%.target}"
+ done
+ echo
+}
+
+usage()
+{
+ cat <<EOF
+Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
+
+ -d CVSROOT
+ Specifies the CVS Root to use when pulling files from CVS. The
+ environment variable \$CVSROOT is used if this option is not
+ present.
+
+ --extraversion=EXTRAVERSION
+ Text to use for the rpm release and kernel extraversion.
+
+ --kerneldir=KERNELDIR
+ Directory containing Linux source tarballs referenced by target
+ files.
+
+ --lustre=LUSTRE
+ Path to an existing lustre source tarball to use instead of
+ pulling from CVS.
+
+ --nosrc
+ Do not build a .src.rpm, a full kernel patch, or a patched kernel
+ tarball.
+
+ --publish
+ Publish the packages, patches, and tarballs on the ftp server.
+
+ --release
+ Specifies that the files generated do not include timestamps, and
+ that this is an official release.
+
+ --tag=TAG
+ A CVS branch/tag name to build from when pulling from CVS.
+
+ --target=TARGET
+ The name of the target to build. The available targets are listed
+ below.
+
+ --target-archs=TARGET_ARCHS
+ A (space delimited) list of architectures to build. By default,
+ all of the archs supported by the TARGET will be built, in
+ addition to a .src.rpm. This option can limit those, for machines
+ that can only build certain archs or if you only want a certain
+ arch built (for testing, or a one-off kernel).
+
+ Also note that by using a non-"base" arch (eg, i386) only kernels
+ will be built - there will be no lustre-lite-utils package.
+
+EOF
+
+# list_targets
+
+ fatal "$1" "$2"
+}
+
+check_options()
+{
+ if [ "$LUSTRE" ] ; then
+ [ -r "$LUSTRE" ] || \
+ usage 1 "Could not find Lustre source tarball '$LUSTRE'."
+ else
+ [ "$CVSROOT" ] || \
+ usage 1 "Either specify a CVS Root with -d, or a Lustre source tarball with --lustre."
+ [ "$TAG" ] || \
+ usage 1 "A branch/tag name must be specified with --tag when not building from a tarball."
+ fi
+
+ [ "$KERNELDIR" ] || \
+ usage 1 "A kernel directory must be specified with --kerneldir."
+
+ [ -d "$KERNELDIR" ] || \
+ usage 1 "$KERNELDIR is not a directory."
+
+ if [ "$RELEASE" = "no" ] ; then
+ [ "$TAG" ] || \
+ usage 1 "When building a snapshot, a tag name must be used."
+ fi
+
+ TIMESTAMP=$(date -d "$DATE" "+%Y%m%d%H%M")
+
+ [ "$TARGET" ] || usage 1 "A target must be specified with --target."
+# TARGET_FILE="$TOPDIR/kernel_patches/targets/$TARGET.target"
+# [ -r "$TARGET_FILE" ] || \
+# usage 1 "Target '$TARGET' was not found."
+}
+
+uniqify()
+{
+ echo $(echo "$*" | xargs -n 1 | sort -u)
+}
+
+load_target()
+{
+ EXTRA_VERSION_save="$EXTRA_VERSION"
+ TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
+ [ -r "$TARGET_FILE" ] || \
+ fatal 1 "Target $TARGET was not found."
+
+ echo "Loading target config file $TARGET.target..."
+
+ . "$TARGET_FILE"
+
+ [ "$KERNEL" ] || fatal 1 "Target $TARGET did not specify a kernel."
+ [ "$SERIES" ] || fatal 1 "Target $TARGET did not specify a kernel patch series."
+# [ "$CONFIG" ] || fatal 1 "Target $TARGET did not specify a kernel config."
+ [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify a kernel version."
+
+ if [ "$KERNELDIR" ] ; then
+ KERNEL_FILE="$KERNELDIR/$KERNEL"
+ [ -r "$KERNELDIR/$KERNEL" ] || \
+ fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
+ fi
+
+ SERIES_FILE="$TOPDIR/lustre/kernel_patches/series/$SERIES"
+ [ -r "$SERIES_FILE" ] || \
+ fatal 1 "Target $TARGET's series $SERIES missing from $TOPDIR/lustre/kernel_patches/series."
+
+ CONFIG_FILE="$TOPDIR/lustre/kernel_patches/kernel_configs/$CONFIG"
+ [ -r "$CONFIG_FILE" ] || \
+ fatal 1 "Target $TARGET's config file $CONFIG missing from $TOPDIR/lustre/kernel_patches/kernel_configs/configs."
+
+ if [ "$EXTRA_VERSION_save" ] ; then
+ EXTRA_VERSION="$EXTRA_VERSION_save"
+ else
+ EXTRA_VERSION="${EXTRA_VERSION}_${TAG//_/}.${TIMESTAMP}"
+ fi
+ EXTRA_VERSION=${EXTRA_VERSION//-/_/}
+
+ ALL_ARCHS="$BASE_ARCHS $BIGMEM_ARCHS $BOOT_ARCHS $JENSEN_ARCHS $SMP_ARCHS $UP_ARCHS"
+
+ BUILD_ARCHS=
+ for arch in $(uniqify "$ALL_ARCHS") ; do
+ if [ -z "$TARGET_ARCHS" ] || echo "$TARGET_ARCHS" | grep -s "$arch" ; then
+ BUILD_ARCHS="$BUILD_ARCHS $arch"
+ fi
+ done
+ [ "$BUILD_ARCHS" ] || usage 1 "No available target archs to build."
+ echo "Building for: $BUILD_ARCHS"
+}
+
+tarflags()
+{
+ case "$1" in
+ '')
+ fatal 1 "tarflags(): File name argument missing."
+ ;;
+ *.tar.gz)
+ echo 'zxf'
+ ;;
+ *.tar.bz2)
+ echo 'jxf'
+ ;;
+ *)
+ fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
+ ;;
+ esac
+}
+
+untar()
+{
+ echo "Untarring ${1##*/}..."
+ tar $(tarflags "$1") "$1"
+}
+
+unpack_lustre()
+{
+ DIRNAME="lustre-$TAG-$TIMESTAMP"
+ if [ "$LUSTRE" ] ; then
+ untar "$LUSTRE"
+ [ -d lustre ] || ln -sf lustre* lustre
+ else
+ cvs -d "$CVSROOT" -qz3 co -D "$DATE" "-r$TAG" -d "$DIRNAME" lustre || \
+ fatal 1 "There was an error checking out Lustre from CVS."
+ echo "Creating lustre tarball..."
+ tar zcf "$DIRNAME.tar.gz" "$DIRNAME" \
+ --exclude "CVS" --exclude "*~" --exclude ".cvsignore" || \
+ fatal 1 "Could not create Lustre tarball."
+ LUSTRE="$PWD/$DIRNAME.tar.gz"
+ ln -sf "$DIRNAME" lustre
+ fi
+}
+
+unpack_linux()
+{
+ untar "$KERNEL_FILE"
+ [ -d linux ] || ln -sf linux* linux
+}
+
+patch_linux()
+{
+ FULL_PATCH="$PWD/lustre-kernel-${target}-${EXTRA_VERSION}.patch"
+ [ -f "$FULL_PATCH" ] && rm -f "$FULL_PATCH"
+ pushd linux >/dev/null
+ echo -n "Applying patches:"
+ for patch in $(<"$SERIES_FILE") ; do
+ echo -n " $patch"
+ PATCH_FILE="$TOPDIR/lustre/kernel_patches/patches/$patch"
+ [ -r "$PATCH_FILE" ] || \
+ fatal 1 "Patch $patch does not exist in Lustre tree."
+ cat "$PATCH_FILE" >> "$FULL_PATCH" || \
+ fatal 1 "Error adding patch $patch to full patch."
+ patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
+ done
+ echo
+ popd >/dev/null
+ echo "Full patch has been saved in ${FULL_PATCH##*/}."
+ echo "Replacing .config files..."
+ rm -f linux/configs/*
+ cp -v lustre/kernel_patches/kernel_configs/kernel-${VERSION}-${TARGET}*.config linux/configs/
+}
+
+pack_linux()
+{
+ TARBALL="$(readlink linux)-$EXTRA_VERSION.tar.gz"
+ echo "Creating patched linux tarball $TARBALL..."
+ tar zcf "$TARBALL" "$(readlink linux)" \
+ --exclude "CVS" --exclude ".cvsignore" || \
+ --exclude "*.orig" --exclude "*~" --exclude "*.rej" || \
+ fatal 1 "Error creating patched Linux tarball."
+}
+
+clean_linux()
+{
+ [ -d linux ] || return 0
+ echo "Cleaning linux..."
+ [ -L linux ] && rm -rf $(readlink linux)
+ rm -rf linux
+}
+
+prep_build()
+{
+ # make .spec file
+ sed -e s/@KERNEL_VERSION@/$VERSION/g \
+ -e s/@KERNEL_RELEASE@/$EXTRA_VERSION/g \
+ -e s/@KERNEL_SOURCE@/$KERNEL/g \
+ -e s/@LUSTRE_SOURCE@/${LUSTRE##*/}/g \
+ -e s/@LUSTRE_TARGET@/$TARGET/g \
+ -e s/@CONFIGURE_FLAGS@/$CONFIGURE_FLAGS/g \
+ -e s/@BASE_ARCHS@/$BASE_ARCHS/g \
+ -e s/@BIGMEM_ARCHS@/$BIGMEM_ARCHS/g \
+ -e s/@BOOT_ARCHS@/$BOOT_ARCHS/g \
+ -e s/@JENSEN_ARCHS@/$BOOT_ARCHS/g \
+ -e s/@SMP_ARCHS@/$SMP_ARCHS/g \
+ -e s/@UP_ARCHS@/$UP_ARCHS/g \
+ < $TOPDIR/lustre/scripts/lustre-kernel-2.4.spec.in \
+ > lustre-kernel-2.4.spec
+ [ -d SRPMS ] || mkdir SRPMS
+ [ -d RPMS ] || mkdir RPMS
+ [ -d BUILD ] || mkdir BUILD
+ [ -d SOURCES ] || mkdir SOURCES
+ cp $TOPDIR/lustre/scripts/linux-merge-config.awk SOURCES
+ cp $TOPDIR/lustre/scripts/linux-merge-modules.awk SOURCES
+ cp "$LUSTRE" "$KERNEL_FILE" SOURCES
+}
+
+clean_lustre()
+{
+ [ -d lustre ] || return 0
+ echo "Cleaning lustre..."
+ [ -L lustre ] && rm -rf $(readlink lustre)
+ rm -rf lustre
+}
+
+build()
+{
+ echo "Building rpms for: $BUILD_ARCHS..."
+ targets=
+ for arch in $BUILD_ARCHS ; do
+ targets="--target $arch $targets"
+ done
+
+ rpmbuild $targets -bb lustre-kernel-2.4.spec \
+ --define "_topdir $TOPDIR" \
+ fatal 1 "Error building rpms for $arch."
+
+ (( $DO_SRC )) && rpmbuild -bs lustre-kernel-2.4.spec \
+ --define "_topdir $TOPDIR" \
+ fatal 1 "Error building .src.rpm."
+}
+
+publish()
+{
+ publishing || return 0
+}
+
+[ -r ~/.lbuildrc ] && . ~/.lbuildrc
+
+options=$(getopt -o d:D:h -l extraversion:,kerneldir:,lustre:,nosrc,publish,release,tag:,target:,target-archs: -- "$@")
+
+eval set -- "$options"
+
+while [ "$1" ] ; do
+ case "$1" in
+ '')
+ usage 1
+ ;;
+ -d)
+ CVSROOT=$2
+ shift 2
+ ;;
+ -D)
+ DATE=$2
+ shift 2
+ ;;
+ --extraversion)
+ EXTRA_VERSION=$2
+ shift 2
+ ;;
+ --help | -h)
+ usage 0
+ ;;
+ --kerneldir)
+ KERNELDIR=$2
+ shift 2
+ ;;
+ --lustre)
+ LUSTRE=$2
+ shift 2
+ ;;
+ --nosrc)
+ DO_SRC=0
+ shift 1
+ ;;
+ --publish)
+ PUBLISH=1
+ shift
+ ;;
+ --release)
+ RELEASE=1
+ shift
+ ;;
+ --tag)
+ TAG=$2
+ shift 2
+ ;;
+ --target)
+ TARGET=$2
+ shift 2
+ ;;
+ --target-archs)
+ TARGET_ARCHS=$2
+ shift 2
+ ;;
+ --)
+ shift
+ CONFIGURE_FLAGS=$@
+ break
+ ;;
+ *)
+ usage 1 "Unrecognized option: $1"
+ ;;
+ esac
+done
+
+check_options
+
+unpack_lustre
+load_target
+
+if (( $DO_SRC )) ; then
+ unpack_linux
+ patch_linux
+ pack_linux
+ clean_linux
+fi
+
+# prep_build needs the .spec.in from the lustre source
+prep_build
+clean_lustre
+
+build
+publish