release_path=/repo/openeuler/${gitcodeTargetBranch}
src_path=source/Packages
update_src_path=update/source/Packages
hotpatch_update_src_path=hotpatch_update/source/Packages
. ${shell_path}/src/lib/lib.sh
function ver_maintainer(){
if [[ ! ${trustlist} =~ ${comment_user} ]];then
check_result=`curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/'${giteeTargetNamespace}'/'${gitcodeRepoName}'/collaborators?access_token='${token}'&page=1&per_page=100'`
maintainer_list=`echo ${check_result}|jq -r '.[].login'`
echo $maintainer_list
if [[ ! ${maintainer_list[@]} =~ ${comment_user} ]]; then
comment_error_src_pr "你没有制作热补丁的权限,请联系sig maintianer。"
log_error "You do not have the permission to make hotpatch. Only maintianer can make hotpatch."
fi
fi
}
function print_job(){
job_name=`echo $JOB_NAME|sed -e 's#/#/job/#g'`
job_path="https://ci.openeuler.openatom.cn/job/${job_name}/$BUILD_ID/console"
body_str="热补丁制作流程已启动,正在创建热补丁issue和生成热补丁元数据并提交pr至hotpatch_meta仓库,请不要重复提交命令。\n点击链接查看工程进度:${job_path}\n热补丁issue及hotpatch_meta仓作用参考:https://gitee.com/openeuler/hotpatch_meta/blob/master/README.md"
curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/'${giteeTargetNamespace}'/'${gitcodeRepoName}'/pulls/'${gitcodePullRequestId}'/comments' -d '{"access_token":"'"${token}"'","body":"'"${body_str}"'"}' || echo "comment source pr failed"
}
function error_info(){
body_str="makehotpatch命令格式错误,请参考如下格式:\n\
\`\`\`text\n\
/makehotpatch <version> <mode> <patch_name> <patch_type> <issue_id> <os_branch>\n\
version: 源码包版本号,必填\n\
mode: 热补丁包演进方式<ACC/SGL>, 必填\n\
patch_name: 冷补丁包名,支持多个patch包,按顺序传入,以逗号隔开,src-openeuler下的仓库必填;kernel仓库不用填,门禁会自动打包patch文件\n\
patch_type: 修复的问题类型<cve/bugfix/feature>,必填\n\
issue_id: 修复问题的issue id,必填\n\
os_branch: 本次热补丁基于哪个分支做,必填\n\`\`\`"
comment_error_src_pr ${body_str}
log_error "makehotpatch命令格式错误,请参考如下格式:/makehotpatch <version> <mode> <patch_name> <patch_type> <cve_issue_id> <os_branch>"
}
function ver_comment(){
comment_array=(${comment})
if [[ ${#comment_array[@]} -eq 7 || ${#comment_array[@]} -eq 6 ]]; then
version=${comment_array[1]}
mode=${comment_array[2]}
if [[ ${#comment_array[@]} -eq 7 ]]; then
patch_name=${comment_array[3]}
cve_issue=${comment_array[5]}
commet_branch=${comment_array[6]}
elif [[ ${#comment_array[@]} -eq 6 ]]; then
cve_issue=${comment_array[4]}
commet_branch=${comment_array[5]}
fi
if [[ $mode != "SGL" && $mode != "ACC" ]]; then
error_info
fi
else
error_info
fi
echo ${cve_issue}
echo ${mode}
echo ${commet_branch}
echo ${patch_name}
echo ${version}
release_path=/repo/openeuler/${commet_branch}
}
function get_src_rpm(){
log_info "**********get source rpm in release**********"
if [[ mode == "ACC" ]]; then
src_hotpatch_update_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no -o LogLevel=ERROR root@${release_ip} "cd ${release_path}/${hotpatch_update_src_path} && ls | grep ${gitcodeRepoName}-${version} | tail -n 1"`|| echo ""
else
src_hotpatch_update_name=""
fi
if [[ $src_hotpatch_update_name ]]; then
src_url="https://repo.openeuler.org/${commet_branch}/${hotpatch_update_src_path}/${src_hotpatch_update_name}"
else
src_update_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no -o LogLevel=ERROR root@${release_ip} "cd ${release_path}/${update_src_path} && ls | grep ${gitcodeRepoName}-${version}"`|| echo ""
if [[ $src_update_name ]]; then
src_url="https://repo.openeuler.org/${commet_branch}/${update_src_path}/${src_update_name}"
else
src_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no root@${release_ip} "cd ${release_path}/${src_path} && ls | grep ${gitcodeRepoName}-${version}"`|| echo ""
if [[ $src_name ]]; then
src_url="https://repo.openeuler.org/${commet_branch}/${src_path}/${src_name}"
else
comment_error_src_pr "没有找到${gitcodeRepoName}包${version}版本源码包"
log_error "${gitcodeRepoName} not found ${version} source rpm"
fi
fi
fi
echo ${src_url}
}
function get_debuginfo_url(){
arch=$1
log_info "***********get ${arch} debuginfo rpm in release**********"
debuginfo_path=debuginfo/${arch}/Packages
update_debuginfo_path=update/${arch}/Packages
debug_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no root@${release_ip} "cd ${release_path}/${debuginfo_path} && ls | grep ${gitcodeRepoName}-debuginfo-${version}"`|| echo ""
if [[ $debug_name ]]; then
debug_url="https://repo.openeuler.org/${commet_branch}/${debuginfo_path}/${debug_name}"
else
debug_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no root@${release_ip} "cd ${release_path}/${update_debuginfo_path} && ls | grep ${gitcodeRepoName}-debuginfo-${version}"`|| echo ""
if [[ $debug_name ]];then
debug_url="https://repo.openeuler.org/${commet_branch}/${update_debuginfo_path}/${debug_name}"
else
comment_error_src_pr "没有找到${gitcodeRepoName}包${version}版本${arch}架构debuginfo包"
log_error "${gitcodeRepoName} not found ${version} ${arch} debuginfo rpm"
fi
fi
}
function get_debuginfo_rpm(){
get_debuginfo_url "x86_64"
x86_debug_url=$debug_url
echo ${x86_debug_url}
get_debuginfo_url "aarch64"
aarch64_debug_url=$debug_url
echo ${aarch64_debug_url}
}
function get_patch(){
rm -rf $gitcodeRepoName
git clone -b $gitcodeTargetBranch --depth 1 https://gitee.com/$giteeTargetNamespace/$gitcodeRepoName
cd $gitcodeRepoName
if [[ ${openeuler_support} =~ ${gitcodeRepoName} ]]; then
log_info "***********get openeuler pr patch file*********"
wget https://gitcode.com/$giteeTargetNamespace/kernel/pull/$gitcodePullRequestId.patch
patch_list="$gitcodePullRequestId.patch"
else
echo
log_info "**********get src-openeuler ${gitcodeRepoName} patch file**********"
git fetch origin pull/$gitcodePullRequestId/head:pr_$gitcodePullRequestId
git checkout pr_$gitcodePullRequestId
patch_list=`echo ${patch_name}|sed -e 's/,/ /g'`
changed_patch=`git diff --name-status HEAD~1 HEAD~0 | grep ".patch" | awk -F ' ' '{print $2}'`
if [[ $changed_patch ]]; then
for patch in ${patch_list[@]}
do
if [[ ! `echo $changed_patch | grep $patch` ]]; then
comment_error_src_pr "补丁文件:${patch}不存在"
log_error "补丁文件:${patch}不存在"
fi
done
fi
fi
patch_path=`pwd`
cd ..
}
function judge_laster_version_release(){
log_info "**********judge laster version release**********"
curr_version=`cat ${hotmetadata_xml} | grep "<hotpatch version="| sed 's/<hotpatch version=//g' | sed 's/ type=.*$//g'|awk -F " " 'END {print}'|sed 's/\"//g'`
curr_release=`cat ${hotmetadata_xml} | grep "release="| sed 's/.*release=//g' | sed 's/ type=.*$//g'|awk -F " " 'END {print}'|sed 's/\"//g'`
echo "curr_version:$curr_version"
echo "curr_release:$curr_release"
curr_version=$((10#${curr_version}))
curr_release=$((10#${curr_release}))
if [[ func == "update" ]];then
last_release=$curr_release-1
else
last_release=$curr_release
fi
echo $last_release
if [[ $last_release -ge 1 ]];then
src_hotpatch_update_name=`ssh -i ${update_key} -o StrictHostKeyChecking=no -o LogLevel=ERROR root@${release_ip} "cd ${release_path}/${hotpatch_update_src_path} && ls | grep ${repo}-${repo_version} | grep ACC-${curr_version}-${last_release}"`|| echo ""
echo $src_hotpatch_update_name
if [[ ! $src_hotpatch_update_name ]]; then
src_url="https://repo.openeuler.org/${comment_branch}/${hotpatch_update_src_path}/${src_hotpatch_update_name}"
comment_error_src_pr "上一个热补丁版本:${curr_version}-${last_release}未发布,不允许新增version"
log_error "上一个热补丁版本未发布,不允许新增version"
fi
fi
}
function get_pr_patch_file(){
if [[ $open_pr_result ]];then
open_pr_id=${open_pr_result##*/}
if [[ ${open_pr_id} ]]; then
git fetch origin pull/${open_pr_id}/head:pr_${open_pr_id}
git checkout pr_${open_pr_id}
pr_patch_list=`git diff --name-status HEAD~1 HEAD~0 | grep ".patch"| awk -F ' ' '{print $2}'`
echo ${pr_patch_list}
fi
fi
}
function gen_hot_patch_metadata(){
log_info "************generate hotpatch metadata**********"
create_remote_branch
export PYTHONPATH=${shell_path}
python3 ${shell_path}/src/hotpatch/gen_hotmetadata_xml.py -f ${func} -c ${giteeTargetNamespace} -t ${token} -p `echo ${patch_list}|sed -e 's/ /,/g'` -b ${commet_branch} -r ${gitcodeRepoName} -pr ${gitcodePullRequestId} -o ${metadata_path} -i ${hotpatch_issue_file} -m "${comment}" -l "${src_url},${x86_debug_url},${aarch64_debug_url}"
if [ $? -ne 0 ];then
if [[ $(git branch -a | grep ${branch_name}) && !${open_pr_result} ]]; then
git push origin --delete ${branch_name}
fi
else
get_pr_patch_file
git checkout ${branch_name}
pr_patch_list=(${pr_patch_list})
echo ${pr_patch_list}
for patch in ${pr_patch_list[@]}
do
rm -f $patch
done
log_info "copy patch file to hotmetadata"
for patch in ${patch_list[@]}
do
cp ${patch_path}/${patch} ${metadata_path}/${commet_branch}/${gitcodeRepoName}/${version}/patch/
done
ls -l ${metadata_path}/${commet_branch}/${gitcodeRepoName}/${version}
cat ${hotmetadata_xml}
set +e
log_info "git push"
git add .
git commit -m "Hotpatch repair"
git push
set -e
create_pr
fi
}
function create_remote_branch(){
log_info "**********create remote branch for pr**********"
branch_name="hotpatch_${commet_branch}_${gitcodeRepoName}_${version}_${gitcodePullRequestId}"
echo $branch_name
branch_result=`curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/openeuler/hotpatch_meta/branches' -d '{"access_token":"'"${CicdToken}"'","refs":"master","branch_name":"'"${branch_name}"'"}'`
if [[ `echo ${branch_result} | grep "分支名已存在"` ]]; then
branch_exist=`curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/openeuler/hotpatch_meta/branches/'${branch_name}'?access_token='${CicdToken}`
branch_creater=`echo ${branch_exist} | jq -r '.commit.commit.author.name'`
echo ${branch_creater}
if [[ ${branch_creater} != ${GiteeCloneUserName} ]]; then
comment_error_src_pr "私人分支${branch_name}已存在,不能创建分支"
fi
func="update"
pr_result=`curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/openeuler/hotpatch_meta/pulls?access_token='${CicdToken}'&state=open&head='${branch_name}'&sort=created&direction=desc&page=1&per_page=20'` || echo "get source branch open pr failed"
open_pr_result=`echo ${pr_result} | jq -r '.[].html_url'`
echo ${open_pr_result}
if [[ !{open_pr_result} ]]; then
func="add"
fi
else
func="add"
fi
echo ${func}
rm -rf hotpatch_meta
git clone https://${GiteeCloneUserName}:${GiteeClonePassword}@gitee.com/openeuler/hotpatch_meta.git
cd hotpatch_meta
git branch --track ${branch_name} remotes/origin/${branch_name}
git checkout ${branch_name}
metadata_path=`pwd`
if [[ $mode == "SGL" ]]; then
hotmetadata_xml=${metadata_path}/${commet_branch}/${gitcodeRepoName}/${version}/hotmetadata_SGL.xml
else
hotmetadata_xml=${metadata_path}/${commet_branch}/${gitcodeRepoName}/${version}/hotmetadata_ACC.xml
fi
if [[ -e $hotmetadata_xml && $mode == "ACC" ]];then
judge_laster_version_release
fi
}
function create_pr(){
log_info "**********create pr to commit hotmetadata**********"
title="[hotpatch]fix ${cve_issue}"
head=${branch_name}
base="master"
log_info "**********create pr**********"
pr_result=`curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/openeuler/hotpatch_meta/pulls' -d '{"access_token":"'"${CicdToken}"'","title":"'"${title}"'","base":"master","head":"'"${branch_name}"'"}'`
if [[ $(echo ${pr_result}|grep "已存在相同源分支、目标分支的 Pull Request") ]]; then
pr_url=`echo ${pr_result}|jq -r '.message'| sed 's/^.*<a href=//g' | sed 's/>.*$//g'| sed 's/\"//g'`
pr_link="https://gitee.com/${pr_url}"
else
pr_link=`echo ${pr_result}|jq -r '.html_url'`
fi
echo ${pr_link}
comment_src_pr
}
function comment_src_pr(){
log_info "**********comment hotmetadata pr link to source pr********"
hotpatch_issue=`cat ${hotpatch_issue_file}`
echo ${hotpatch_issue}
body_str="In response to this:\n > ${comment} \n\n命令执行结果:\n热补丁issue链接:${hotpatch_issue} \n后续热补丁流程请在hotpatch_meta仓库pr跟踪,链接如下: ${pr_link}"
curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/'${giteeTargetNamespace}'/'${gitcodeRepoName}'/pulls/'${gitcodePullRequestId}'/comments' -d '{"access_token":"'"${token}"'","body":"'"${body_str}"'"}' || echo "comment source pr failed"
}
function comment_error_src_pr(){
log_info "**********comment hotmetadata pr link to source pr********"
body_str="In response to this:\n > ${comment} \n\n命令执行结果:\n $* "
curl -X POST --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/'${giteeTargetNamespace}'/'${gitcodeRepoName}'/pulls/'${gitcodePullRequestId}'/comments' -d '{"access_token":"'"${token}"'","body":"'"${body_str}"'"}' || echo "comment source pr failed"
log_error $1
}
function main(){
echo ${gitcodeRepoName}
echo ${giteeTargetNamespace}
echo ${gitcodeTargetBranch}
curr_path=`pwd`
hotpatch_issue_file=$curr_path/hotpatch_issue
ver_maintainer
print_job
ver_comment
get_src_rpm
get_debuginfo_rpm
get_patch
sudo yum install -y python3-pip
pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple -r ${shell_path}/src/requirements
gen_hot_patch_metadata
}
set -x
main
set +x