515 lines
15 KiB
Bash
Executable File
515 lines
15 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# ==============================================================================
|
||
# Description: Automaticly generating kernel rpm package with specified branch
|
||
# according to HEAD tag.
|
||
#
|
||
# Author: David Shan <davidshan@tencent.com>
|
||
# ===============================================================================
|
||
|
||
#variables
|
||
kernel_full_name=""
|
||
kernel_version=""
|
||
tlinux_branch=""
|
||
tlinux_release=""
|
||
curdir=`pwd`
|
||
build_specdir="/usr/src/packages/SPECS"
|
||
build_srcdir="/usr/src/packages/SOURCES"
|
||
kernel_type="default"
|
||
spec_file_name=""
|
||
make_jobs=""
|
||
nosign_suffix=""
|
||
build_src_only=0
|
||
strip_sign_token=0
|
||
raw_tagged_name=""
|
||
kasan=0
|
||
# to control wheter to build rpm for xen domU
|
||
isXenU=""
|
||
build_perf=""
|
||
kernel_default_types=(default)
|
||
|
||
#funcitons
|
||
usage()
|
||
{
|
||
echo "generate-rpms [-t \$tag_name ] [-j \$jobs ] [-k \$config_type][-h]"
|
||
echo " -t tag_name"
|
||
echo " Tagged name in the git tree."
|
||
echo " -j jobs"
|
||
echo " Specifies the number of jobs (threads) to run make."
|
||
echo " -d"
|
||
echo " disable module digital signature."
|
||
echo " -p"
|
||
echo " build perf rpm only."
|
||
echo " -c"
|
||
echo " enable kabi check."
|
||
echo " -k config_type"
|
||
echo " build kasan or nosign config, config type is 'kasan' or 'nosign'."
|
||
|
||
echo -e "\n"
|
||
echo " Note:By default, we only generate latest tag kernel for standard kernels"
|
||
echo " without -t and -k option."
|
||
echo " So, if you hope to get certain tag kernel, please use -t."
|
||
echo " Also, only for state type kernel, please use -k option with state value."
|
||
}
|
||
|
||
get_kernel_version()
|
||
{
|
||
local makefile="$1/Makefile"
|
||
|
||
if [ ! -e $makefile ]; then
|
||
echo "Error: No Makefile found."
|
||
exit 1
|
||
fi
|
||
|
||
kernel_version+=`grep "^VERSION" ${makefile} | head -1 | awk -F "=" '{print $2}' | tr -d ' '`
|
||
kernel_version+="."
|
||
kernel_version+=`grep "^PATCHLEVEL" ${makefile} | head -1 | awk -F "=" '{print $2}' | tr -d ' '`
|
||
kernel_version+="."
|
||
kernel_version+=`grep "^SUBLEVEL" ${makefile} | head -1 | awk -F "=" '{print $2}' | tr -d ' '`
|
||
#kernel_version+=`grep "^EXTRAVERSION" ${makefile} | head -1 | awk -F "=" '{print $2}' | tr -d ' '`
|
||
|
||
echo "kernel version: $kernel_version"
|
||
}
|
||
|
||
get_tlinux_name()
|
||
{
|
||
if [ -n "$tag_name" ]; then
|
||
raw_tagged_name="$tag_name"
|
||
else
|
||
raw_tagged_name=`git describe --tags`
|
||
fi
|
||
|
||
if [ -z "${raw_tagged_name}" ];then
|
||
echo "Error:Can't get kernel version from git tree."
|
||
exit 1
|
||
fi
|
||
|
||
#if [[ $raw_tagged_name != private-x86-* ]]; then
|
||
# echo "$raw_tagged_name not valid tag name for private-x86"
|
||
# exit 11
|
||
#fi
|
||
|
||
tagged_name=${raw_tagged_name}
|
||
|
||
echo "${tagged_name}" | grep 'kvm_guest'
|
||
if [ $? -eq 0 ]; then
|
||
echo "start kvm guest build"
|
||
kvm_guest="yes"
|
||
fi
|
||
|
||
echo "${tagged_name}" | grep 'xen_guest'
|
||
if [ $? -eq 0 ]; then
|
||
echo "start xen guest build"
|
||
xen_guest="yes"
|
||
fi
|
||
|
||
echo "${tagged_name}" | grep 'ec'
|
||
if [ $? -eq 0 ]; then
|
||
echo "start ECkernel build"
|
||
ec="yes"
|
||
fi
|
||
|
||
if [ -n "$disable_sign" ]; then
|
||
echo "${tagged_name}" | grep 'nosign'
|
||
if [ $? -ne 0 ]; then
|
||
echo "digital signature disabled ,but tag name didn't contains nosign"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$disable_sign" ]; then
|
||
disable_sign="no"
|
||
fi
|
||
|
||
echo "${tagged_name}" | grep 'kasan'
|
||
if [ $? -eq 0 ]; then
|
||
kasan=1
|
||
disable_sign=yes
|
||
fi
|
||
|
||
# if [ $kasan -eq 1 -a -n "$disable_sign" ]; then
|
||
# echo "${tagged_name}" | grep 'nosign'
|
||
# if [ $? -ne 0 -a $kasan -eq 0 ]; then
|
||
# echo "digital signature disabled ,but tag name didn't contains nosign"
|
||
# exit 1
|
||
# fi
|
||
# fi
|
||
|
||
|
||
#if [ "${tagged_name#*-*-*}" != ${tagged_name} ];then
|
||
#echo "Error: bad tag name:$tagged_name."
|
||
#exit 1
|
||
#fi
|
||
|
||
tlinux_branch=`echo $tagged_name|cut -d- -f3`
|
||
if [ -n "$isXenU" ]; then
|
||
tlinux_branch+="_xenU"
|
||
fi
|
||
if [ "$build_perf" = "yes" ]; then
|
||
rpm_name="perf"
|
||
else
|
||
rpm_name="kernel"-${tlinux_branch}
|
||
fi
|
||
#tlinux_release=${tagged_name#*-}
|
||
tlinux_release=`echo $tagged_name|cut -d- -f2`.`echo $tagged_name|cut -d- -f4`
|
||
kernel_full_name=${rpm_name}-${kernel_version}
|
||
}
|
||
|
||
prepare_tlinux_spec()
|
||
{
|
||
local sign_token
|
||
spec_file_name=${build_specdir}/${kernel_full_name}.spec
|
||
spec_contents="%define name ${rpm_name} \n"
|
||
spec_contents+="%define version ${kernel_version} \n"
|
||
spec_contents+="%define release_os ${tlinux_release} \n"
|
||
spec_contents+="%define title ${tlinux_branch} \n"
|
||
spec_contents+="%define disable_sign ${disable_sign} \n"
|
||
spec_contents+="%define tagged_name ${tagged_name} \n"
|
||
|
||
if [ "${check_kabi}" = "yes" ]; then
|
||
check_kabi=1
|
||
else
|
||
check_kabi=0
|
||
fi
|
||
spec_contents+="%define with_kabichk ${check_kabi} \n"
|
||
|
||
sign_token=`cat /etc/t_os_sign_token`
|
||
if [ "$sign_token" = "" ]; then
|
||
sign_token=0
|
||
fi
|
||
spec_contents+="%define sign_token ${sign_token} \n"
|
||
|
||
|
||
if [ -z "${kernel_type}" ];then
|
||
spec_contents+="%define kernel_all_types ${kernel_default_types[@]} \n"
|
||
else
|
||
spec_contents+="%define kernel_all_types ${kernel_type} \n"
|
||
fi
|
||
|
||
if [ -n "${make_jobs}" ];then
|
||
spec_contents+="%define jobs ${make_jobs} \n\n"
|
||
fi
|
||
|
||
if [ -e /etc/redhat-release ];then
|
||
spec_contents+="%define debug_package %{nil}\n"
|
||
spec_contents+="%define __os_install_post %{nil}\n"
|
||
|
||
fi
|
||
|
||
if [[ $isXenU == "32" && `uname -m` == "x86_64" ]];then
|
||
spec_contents+="%define make_flag \"ARCH=i386\" \n"
|
||
fi
|
||
|
||
echo -e "${spec_contents}" > $spec_file_name
|
||
|
||
if [ "$kvm_guest" = "yes" ] ; then
|
||
cat $curdir/kvm_guest/kernel-tlinux.spec >> $spec_file_name
|
||
|
||
# Add specail patches into spec file
|
||
patch_list=`ls -1 $curdir/kvm_guest/*.patch`
|
||
let i=1
|
||
patch_str2="cd %{name}-%{version}\n"
|
||
for patch in $patch_list
|
||
do
|
||
patch=`basename $patch`
|
||
patch_str1="${patch_str1}Patch$i: $patch\n"
|
||
patch_str2="${patch_str2}%patch$i -p1\n"
|
||
i=`expr $i + 1`
|
||
echo "kvm guest: find patch $patch"
|
||
done
|
||
sed -i "/^URL/i\\${patch_str1}" $spec_file_name
|
||
sed -i "/^%setup/a\\${patch_str2}" $spec_file_name
|
||
elif [ "$xen_guest" = "yes" ] ; then
|
||
cat $curdir/xen_guest/kernel-tlinux.spec >> $spec_file_name
|
||
|
||
# Add specail patches into spec file
|
||
patch_list=`ls -1 $curdir/xen_guest/*.patch`
|
||
let i=1
|
||
patch_str2="cd %{name}-%{version}\n"
|
||
for patch in $patch_list
|
||
do
|
||
patch=`basename $patch`
|
||
patch_str1="${patch_str1}Patch$i: $patch\n"
|
||
patch_str2="${patch_str2}%patch$i -p1\n"
|
||
i=`expr $i + 1`
|
||
echo "xen guest: find patch $patch"
|
||
done
|
||
sed -i "/^URL/i\\${patch_str1}" $spec_file_name
|
||
sed -i "/^%setup/a\\${patch_str2}" $spec_file_name
|
||
|
||
elif [ "$ec" = "yes" ] ; then
|
||
cat $curdir/kernel-tlinux.spec >> $spec_file_name
|
||
|
||
# Add specail patches into spec file
|
||
patch_list=`ls -1 $curdir/ec/*.patch`
|
||
let i=1
|
||
patch_str2="cd %{name}-%{version}\n"
|
||
for patch in $patch_list
|
||
do
|
||
patch=`basename $patch`
|
||
patch_str1="${patch_str1}Patch$i: $patch\n"
|
||
patch_str2="${patch_str2}%patch$i -p1\n"
|
||
i=`expr $i + 1`
|
||
echo "EC: find patch $patch"
|
||
done
|
||
sed -i "/^URL/i\\${patch_str1}" $spec_file_name
|
||
sed -i "/^%setup/a\\${patch_str2}" $spec_file_name
|
||
|
||
else
|
||
if [ "$build_perf" = "yes" ]; then
|
||
cat $curdir/perf-tlinux.spec >> $spec_file_name
|
||
else
|
||
cat $curdir/kernel-tlinux.spec >> $spec_file_name
|
||
fi
|
||
fi
|
||
}
|
||
|
||
build_kasan_config()
|
||
{
|
||
# 默认配置路径
|
||
default_file="./config.default"
|
||
default_kasan_file="./config.default_kasan"
|
||
|
||
# 如果默认配置不存在,则直接退出
|
||
if [ ! -f "${default_file}" ]; then
|
||
echo "Please confirm that ${default_file} exists !"
|
||
exit 1
|
||
fi
|
||
|
||
# 如果kasan配置已存在,则直接删除
|
||
if [ -f "${default_kasan_file}" ]; then
|
||
mv ${default_kasan_file} ${default_kasan_file}.bak.$(date +"%Y-%m-%d")
|
||
fi
|
||
|
||
# 复制默认配置为kasan配置
|
||
cp ${default_file} ${default_kasan_file}
|
||
# 删除已有的KASAN配置
|
||
sed -i '/KASAN\w*=/d' ${default_kasan_file}
|
||
# 删除KASAN配置开关项
|
||
sed -i '/^# CONFIG_KASAN is not set/d' ${default_kasan_file}
|
||
|
||
# 加载kasan配置项
|
||
source ./kasan_parameters.cnf
|
||
|
||
# kasan配置添加kasan配置项
|
||
for tmp_item in ${kasan_parameters[@]}
|
||
do
|
||
item=(${tmp_item//#/ })
|
||
next_key=`awk -F'=' "/^${item[0]}=/{getline ;print \\\$1}" ${default_kasan_file}`
|
||
if [ "${item[1]}" != "${next_key}" ]
|
||
then
|
||
sed -i "/^${item[0]}=/a\\${item[1]}=${item[2]}" ${default_kasan_file}
|
||
else
|
||
sed -i "s/${item[1]}=\w*/${item[1]}=${item[2]}/g" ${default_kasan_file}
|
||
fi
|
||
done
|
||
|
||
# 特殊添加kasan配置注释项
|
||
sed -i "/CONFIG_KASAN_OUTLINE=/a\\\# CONFIG_KASAN_INLINE is not set" ${default_kasan_file}
|
||
sed -i "/CONFIG_KASAN_STACK=/a\\\# CONFIG_TEST_KASAN is not set" ${default_kasan_file}
|
||
}
|
||
|
||
#main function
|
||
|
||
#Parse Parameters
|
||
while getopts ":t:j:hdcpx:k:" option "$@"
|
||
do
|
||
case $option in
|
||
"t" )
|
||
tag_name=$OPTARG
|
||
;;
|
||
"j" )
|
||
make_jobs=$OPTARG
|
||
;;
|
||
"h" )
|
||
usage
|
||
exit 0
|
||
;;
|
||
"d" )
|
||
disable_sign="yes"
|
||
;;
|
||
"p" )
|
||
build_perf="yes"
|
||
;;
|
||
"c" )
|
||
echo "-c kabi check enabled!"
|
||
check_kabi="yes"
|
||
;;
|
||
"k" )
|
||
case ${OPTARG} in
|
||
"kasan" )
|
||
echo "build kasan config."
|
||
cd ../../ ; ./package/update_tkconfig.sh 1>/dev/null 2>&1 ; cd -
|
||
build_kasan_config
|
||
;;
|
||
"nosign" )
|
||
echo "build nosign config."
|
||
echo "function to be developed !"
|
||
;;
|
||
* )
|
||
echo "[-k \$config_type] config type is 'kasan' or 'nosign'."
|
||
;;
|
||
esac
|
||
exit 0
|
||
;;
|
||
"?" )
|
||
usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
#test if parameter of kernel type is valid
|
||
if [ -n "${kernel_type}" ] && [ ! -e config."${kernel_type}" ]
|
||
then
|
||
echo "Error: bad kernel type name. Config file for ${kernel_type} does not exist."
|
||
usage
|
||
exit 1
|
||
elif [ -n "${kernel_type}" ] && [ -n "$isXenU" ] && [ ! -e config."${kernel_type}".xenU ]
|
||
then
|
||
echo "Error: bad kernel type name. Config file for ${kernel_type}.xenU does not exist."
|
||
usage
|
||
exit 1
|
||
|
||
fi
|
||
|
||
|
||
if [ -e /etc/SuSE-release ];then
|
||
build_specdir="/usr/src/packages/SPECS"
|
||
build_srcdir="/usr/src/packages/SOURCES"
|
||
elif [ -e /etc/redhat-release ];then
|
||
build_specdir="$HOME/rpmbuild/SPECS"
|
||
build_srcdir="$HOME/rpmbuild/SOURCES"
|
||
else
|
||
echo "Error: Compile on unknown system."
|
||
exit 1
|
||
fi
|
||
|
||
|
||
if [ ! -e "${build_srcdir}" ]; then
|
||
mkdir $build_srcdir
|
||
[ $? == 1 ] && exit 1
|
||
fi
|
||
|
||
if [ ! -e "${build_specdir}" ]; then
|
||
mkdir $build_specdir
|
||
[ $? == 1 ] && exit 1
|
||
fi
|
||
|
||
cd ../../
|
||
origsrc=`pwd`
|
||
|
||
|
||
if [ $kasan -eq 1 ]; then
|
||
nosign_suffix="_kasan"
|
||
#elif [ "$disable_sign" = "yes" ]; then
|
||
# nosign_suffix="_nosign"
|
||
else
|
||
nosign_suffix=""
|
||
fi
|
||
|
||
get_kernel_version $origsrc
|
||
get_tlinux_name
|
||
echo "Prepare $kernel_full_name source."
|
||
prepare_tlinux_spec
|
||
|
||
cp package/default/tlinux_cciss_link.modules $build_srcdir
|
||
if [ "$kvm_guest" = "yes" ] ; then
|
||
cp package/default/kvm_guest/*.patch $build_srcdir
|
||
fi
|
||
|
||
if [ "$ec" = "yes" ] ; then
|
||
cp package/default/ec/*.patch $build_srcdir
|
||
fi
|
||
|
||
if test -e ${build_srcdir}/${kernel_full_name}; then
|
||
rm -fr ${build_srcdir}/${kernel_full_name}
|
||
fi
|
||
|
||
#tagged_name is a confirmed tag name and will be used for final source.
|
||
git archive --format=tar --prefix=${kernel_full_name}/ ${raw_tagged_name} | (cd ${build_srcdir} && tar xf -)
|
||
if [ $? -ne 0 ];then
|
||
echo "Error:can't prepare $kernel_full_name source with git archive!"
|
||
exit 1
|
||
fi
|
||
|
||
cd ${build_srcdir}/${kernel_full_name}
|
||
./package/update_tkconfig.sh 1>/dev/null 2>&1
|
||
|
||
if [[ $isXenU == "32" ]]
|
||
then
|
||
config_suffix="xenU32"
|
||
target="--target i686"
|
||
elif [[ $isXenU == "64" ]]
|
||
then
|
||
config_suffix="xenU"
|
||
fi
|
||
echo $config_suffix
|
||
|
||
if [ -z "${kernel_type}" ];then
|
||
for type_name in "${kernel_default_types[@]}"
|
||
do
|
||
if [ -n "$isXenU" ]; then
|
||
echo mv -f ${build_srcdir}/${kernel_full_name}/package/default/config.$type_name.$config_suffix${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$type_name{nosign_suffix}
|
||
mv -f ${build_srcdir}/${kernel_full_name}/package/default/config.$type_name.$config_suffix${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$type_name${nosign_suffix}
|
||
fi
|
||
done
|
||
else
|
||
if [ -n "$isXenU" ]; then
|
||
echo mv -f ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type.$config_suffix${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
mv -f ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type.$config_suffix${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
|
||
elif [ "$kvm_guest" = "yes" ] ; then
|
||
echo \
|
||
cp -f ${build_srcdir}/${kernel_full_name}/package/default/kvm_guest/config.${kernel_type}${config_suffix}${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
cp -f ${build_srcdir}/${kernel_full_name}/package/default/kvm_guest/config.${kernel_type}${config_suffix}${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
elif [ "$xen_guest" = "yes" ] ; then
|
||
echo \
|
||
cp -f ${build_srcdir}/${kernel_full_name}/package/default/xen_guest/config.${kernel_type}${config_suffix}${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
cp -f ${build_srcdir}/${kernel_full_name}/package/default/xen_guest/config.${kernel_type}${config_suffix}${nosign_suffix} ${build_srcdir}/${kernel_full_name}/package/default/config.$kernel_type${nosign_suffix}
|
||
fi
|
||
fi
|
||
|
||
cd ..
|
||
tar -zcf ${kernel_full_name}.tar.gz ${kernel_full_name}
|
||
rm -fr ${kernel_full_name}
|
||
|
||
#if [ -n "$tag_name" ];then
|
||
# cd $origsrc
|
||
# git checkout $local_valid_branch > /dev/null
|
||
#fi
|
||
|
||
|
||
echo "Build kernel rpm package."
|
||
if [ $build_src_only -eq 0 ]; then
|
||
rpmbuild -bb ${target} ${spec_file_name}
|
||
sed -i 's/^%define sign_token.*/%define sign_token please_enter_your_token_here/' ${spec_file_name}
|
||
else
|
||
if [ $strip_sign_token -ne 0 ]; then
|
||
sed -i 's/^%define sign_token.*/%define sign_token please_enter_your_token_here/' ${spec_file_name}
|
||
fi
|
||
fi
|
||
|
||
echo "Build kernel source rpm package."
|
||
pwd
|
||
tar -zxf ${kernel_full_name}.tar.gz
|
||
|
||
if [ $build_src_only -eq 0 ]; then
|
||
sed -i "/CONFIG_TCPA/d" ${kernel_full_name}/net/Makefile
|
||
sed -i "/CONFIG_TCPA/d" ${kernel_full_name}/package/default/config.default
|
||
sed -i "/CONFIG_TCPA/d" ${kernel_full_name}/package/default/config.default_nosign
|
||
#sed -i "/CONFIG_TCPA/d" ${kernel_full_name}/package/default/kvm_guest/config.default
|
||
#sed -i "/CONFIG_TCPA/d" ${kernel_full_name}/package/default/kvm_guest/config.default_nosign
|
||
sed -i "/tcpa/Id" ${kernel_full_name}/include/net/sock.h
|
||
sed -i "/tcpa/Id" ${kernel_full_name}/include/linux/skbuff.h
|
||
sed -i "/tcpa/Id" ${kernel_full_name}/net/Kconfig
|
||
|
||
rm -fr ${kernel_full_name}/net/tcpa_engine
|
||
fi
|
||
|
||
rm -fr ${kernel_full_name}/package/default/generate-rpms.sh
|
||
tar -zcf ${kernel_full_name}.tar.gz ${kernel_full_name}
|
||
|
||
rpmbuild -bs ${target} ${spec_file_name}
|
||
|