#!/bin/bash
#############################################################################
# Copyright (c) 2003-2009 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com
#############################################################################
# generate a kernel-source rpm package
# if this is SLE11_BRANCH and earlier, hand over to scripts/tar-up-old.sh
if test ! -x rpm/mkspec; then
exec ${0%.sh}-old.sh "$@"
fi
. ${0%/*}/wd-functions.sh
sort()
{
LC_ALL=C command sort "$@"
}
tolerate_unknown_new_config_options=
ignore_kabi=
mkspec_args=()
source $(dirname $0)/config.sh
until [ "$#" = "0" ] ; do
case "$1" in
--dir=*)
build_dir=${1#*=}
shift
;;
-d|--dir)
build_dir=$2
shift 2
;;
--embargo)
# obsolete
shift
;;
-nf|--tolerate-unknown-new-config-options)
tolerate_unknown_new_config_options=1
shift
;;
-i|--ignore-kabi)
ignore_kabi=1
shift
;;
-iu|--ignore-unsupported-deps)
# ignored, set %supported_modules_check in the spec instead
shift
;;
-rs|--release-string)
case "$2" in
*' '*)
echo "$1 option argument must not contain spaces" >&2
exit 1
esac
mkspec_args=("${mkspec_args[@]}" --release "$2")
shift 2
;;
-h|--help|-v|--version)
cat <<EOF
${0##*/} perpares a 'kernel-source' package for submission into autobuild
these options are recognized:
-nf to proceed if a new unknown .config option is found during make oldconfig
-u update generated files in an existing kernel-source dir
-i ignore kabi failures
-d, --dir=DIR create package in DIR instead of default $BUILD_DIR
EOF
exit 1
;;
*)
echo "unknown option '$1'" >&2
exit 1
;;
esac
done
export LANG=POSIX
[ -z "$build_dir" ] && build_dir=$BUILD_DIR
if [ -z "$build_dir" ]; then
echo "Please define the build directory with the --dir option" >&2
exit 1
fi
check_for_merge_conflicts() {
set -- $(grep -lP '^<{7}(?!<)|^>{7}(?!>)' "$@" 2> /dev/null)
if [ $# -gt 0 ]; then
printf "Merge conflicts in %s\n" "$@" >&2
return 1
fi
}
# Dot files are skipped by intention, in order not to break osc working
# copies. The linux tarball is not deleted if it is already there
for f in "$build_dir"/*; do
case "$f" in
*/"linux-$SRCVERSION.tar.bz2")
continue
esac
rm -f "$f"
done
mkdir -p "$build_dir"
if test ! -e "$build_dir/linux-$SRCVERSION.tar.bz2"; then
echo "linux-$SRCVERSION.tar.bz2"
get_tarball "$SRCVERSION" "$build_dir"
fi
# list of patches to include.
install -m 644 series.conf $build_dir/
# All config files and patches used
referenced_files="$( {
$(dirname $0)/guards --list < $build_dir/series.conf
$(dirname $0)/guards --prefix=config --list < config.conf
} | sort -u )"
for file in $referenced_files; do
case $file in
config/* | patches.*/*)
;;
*)
echo "Error: Patches must be placed in the patches.*/ subdirectories: $file" >&2
exit 1
esac
done
inconsistent=false
check_for_merge_conflicts $referenced_files kernel-source.changes{,.old} || \
inconsistent=true
scripts/check-conf || inconsistent=true
scripts/check-cvs-add --committed || inconsistent=true
# FIXME: someone should clean up the mess and make this check fatal
if $inconsistent; then
echo "Inconsistencies found."
echo "Please clean up series.conf and/or the patches directories!"
echo
fi
tsfile=source-timestamp
if ! scripts/cvs-wd-timestamp > $build_dir/$tsfile; then
exit 1
fi
if $using_git; then
# Always include the git revision
echo "GIT Revision: $(git rev-parse HEAD)" >> $build_dir/$tsfile
tag=$(get_branch_name)
if test -n "$tag"; then
echo "GIT Branch: $tag" >>$build_dir/$tsfile
fi
fi
CLEANFILES=()
trap 'if test -n "$CLEANFILES"; then rm -rf "${CLEANFILES[@]}"; fi' EXIT
tmpdir=$(mktemp -dt ${0##*/}.XXXXXX)
CLEANFILES=("${CLEANFILES[@]}" "$tmpdir")
cp -p rpm/* config.conf supported.conf doc/* $build_dir
if test -e misc/extract-modaliases; then
cp misc/extract-modaliases $build_dir
fi
# install this file only if the spec file references it
if grep -q '^Source.*:[[:space:]]*log\.sh[[:space:]]*$' rpm/kernel-source.spec.in; then
cp -p scripts/rpm-log.sh "$build_dir"/log.sh
fi
rm -f "$build_dir/kernel-source.changes.old"
if test -e "$build_dir"/config-options.changes; then
# Rename to avoid triggering a build service rule error
mv "$build_dir"/config-options.changes \
"$build_dir"/config-options.changes.txt
fi
# FIXME: move config-subst out of rpm/
rm "$build_dir/config-subst"
changelog=$build_dir/kernel-source$VARIANT.changes
if test -e kernel-source.changes; then
cat kernel-source.changes{,.old} >"$changelog"
elif $using_git; then
exclude=()
# Exclude commits in the scripts branch, these are rarely interesting for
# users of the rpm packages.
# FIXME: the remote might have a different name than "origin" or there
# might be no remote at all.
if git cat-file -e origin/scripts 2>/dev/null; then
exclude[${#exclude[@]}]=^origin/scripts
fi
if git cat-file -e scripts 2>/dev/null; then
exclude[${#exclude[@]}]=^scripts
fi
if test ${#exclude[@]} -eq 0; then
echo "warning: no scripts or origin/scripts branch found" >&2
echo "warning: rpm changelog will have some useless entries" >&2
fi
changes_stop=$(sed 1q rpm/kernel-source.changes.old)
case "$changes_stop" in
last\ commit:\ *)
exclude[${#exclude[@]}]=^${changes_stop#*: }
;;
*)
echo "expected \"last commit: <commit>\" in rpm/kernel-source.changes.old" >&2
exit 1
esac
scripts/gitlog2changes "${exclude[@]}" HEAD -- >"$changelog"
sed 1d rpm/kernel-source.changes.old >>"$changelog"
else
touch "$changelog"
fi
if [ -e extra-symbols ]; then
install -m 755 \
extra-symbols \
$build_dir
fi
# Usage:
# stable_tar [-t <timestamp>] [-C <dir>] [--exclude=...] <tarball> <files> ...
# if -t is not given, files must be within a git repository
tar_override_works=
stable_tar() {
local tarball mtime=() chdir="." tar_opts=()
while test $# -gt 2; do
case "$1" in
-t)
mtime=(--mtime "$2")
shift 2
;;
-C)
chdir=$2
shift 2
;;
--exclude=*)
tar_opts=("${tar_opts[@]}" "$1")
shift
;;
--exclude)
tar_opts=("${tar_opts[@]}" "$1" "$2")
shift 2
;;
*)
break
esac
done
tarball=$1
shift
if [ -z "$tar_override_works" ]; then
if tar --mtime="Tue, 3 Feb 2009 10:52:55 +0100" --owner=nobody \
--group=nobody --help >/dev/null; then
tar_override_works=true
else
echo "warning: created tarballs will differ between runs" >&2
tar_override_works=false
fi
fi
if $tar_override_works; then
if test -z "$mtime" && $using_git; then
mtime=(--mtime "$(cd "$chdir"
echo "$@" | xargs git log -1 --pretty=tformat:"%ct %cD" -- | \
sort -rn | sed 's/^[^ ]* //; q')")
fi
tar_opts=("${tar_opts[@]}" --owner=nobody --group=nobody "${mtime[@]}")
fi
(
cd "$chdir"
# See 'info xargs' for an explanation of the below construct
printf '%s\n' "$@" | xargs sh -c \
'find "$@" \( -type f -o -type l -o -type d -a -empty \) -print0' \
dummy | \
LC_ALL=C sort -z | \
tar -cf - --null -T - "${tar_opts[@]}"
) | bzip2 -9 >"$tarball"
}
# The first directory level determines the archive name
all_archives="$(
echo "$referenced_files" \
| sed -e 's,/.*,,' \
| uniq )"
for archive in $all_archives; do
echo "$archive.tar.bz2"
case " $IGNORE_ARCHS " in
*" ${archive#patches.} "*)
echo "Ignoring $archive..."
continue ;;
esac
files="$( echo "$referenced_files" \
| sed -ne "\:^${archive//./\\.}/:p" \
| while read patch; do
[ -e "$patch" ] && echo "$patch"
done)"
if [ -n "$files" ]; then
stable_tar $build_dir/$archive.tar.bz2 $files
fi
done
echo "kabi.tar.bz2"
stable_tar $build_dir/kabi.tar.bz2 kabi
if test -d sysctl && \
grep -q '^Source.*\<sysctl\.tar\.bz2' "$build_dir/kernel-source.spec.in"
then
echo "sysctl.tar.bz2"
stable_tar $build_dir/sysctl.tar.bz2 sysctl
fi
# Create empty dummys for any *.tar.bz2 archive mentioned in the spec file
# not already created: patches.addon is empty by intention; others currently
# may contain no patches.
archives=$(sed -ne 's,^Source[0-9]*:.*[ \t/]\([^/]*\)\.tar\.bz2$,\1,p' \
$build_dir/kernel-source.spec.in | sort -u)
for archive in $archives; do
case "$archive" in
*%*)
# skip archive names with macros
continue
esac
if test -e "$build_dir/$archive.tar.bz2"; then
continue
fi
echo "$archive.tar.bz2 (empty)"
tmpdir2=$(mktemp -dt ${0##*/}.XXXXXX)
CLEANFILES=("${CLEANFILES[@]}" "$tmpdir2")
mkdir -p $tmpdir2/$archive
stable_tar -C $tmpdir2 -t "Wed, 01 Apr 2009 12:00:00 +0200" \
$build_dir/$archive.tar.bz2 $archive
done
# Force mbuild to choose build hosts with enough memory available:
echo $((1024*1024)) > $build_dir/minmem
# Force mbuild to choose build hosts with enough disk space available:
echo $((6*1024)) > $build_dir/needed_space_in_mb
if [ -n "$ignore_kabi" ]; then
echo > $build_dir/IGNORE-KABI-BADNESS
fi
if [ -n "$tolerate_unknown_new_config_options" ]; then
echo > $build_dir/TOLERATE-UNKNOWN-NEW-CONFIG-OPTIONS
fi
echo "cd $build_dir; ./mkspec ${mkspec_args[@]}"
patches=$PWD
cd "$build_dir"
./mkspec --patches "$patches" "${mkspec_args[@]}"