一 安装gerrit jenkins sonar
安装步奏略
安装版本
jenkins 2.3
gerrit 2.16
sonar 7.4
postgres latest
jdk 1.8
最新的postgres 数据库要求jdk 11 所以使用docker安装数据库及sonar
二 gerrit 和jenkins联动
1 gerrit 添加 code-scan 标签 及 jekins用户及权限修改
下载All-Projects仓:
$ git init cfg
$ cd cfg
$ git remote add origin ssh://user@address:29418/All-Projects
$ git pull origin refs/meta/config
$ vi project.config
然后在权限配置文件(project.config)末尾添加自定义lable及相关配置:
[label “Compiled-Passed”]
function = MaxWithBlock
value = -1 Fails
value = 0 No score
value = +1 Compiled-Passed
copyAllScoresIfNoCodeChange = true
defaultValue = 0
[label “Code-Scanning”]
function = MaxWithBlock
value = -1 Fails
value = 0 No score
value = +1 Code-Scanning
copyAllScoresIfNoCodeChange = true
defaultValue = 0
最后提交即可生效:
$ git commit -a -m ‘Updated permissions’
$ git push origin HEAD:refs/meta/config
将jenkins添加到用户组 Non-Interactive Users
All-Projects/acess/Reference: refs/heads/*
Global Capabilities /Stream Events
ALLOW Non-Interactive Users
Reference: refs/* /read
ALLOW Non-Interactive Users
在gerrit 中添加jenkins用户 加入Non-Interactive Users用户组
将安装jenkins 的机器公钥添加到gerrit 用户 jenkins中
2 Gerrit Trigger插件安装及配置
插件安装
jenkins 插件管理直接搜索插件名
配置
注意格式ip位置只能为ip或单独域名
私钥为gerrit机器的私钥
密码为生成公钥私钥时的密码 一般无密码
用户名为gerrit用户具有stream event权限 且用户配置jenkins机器的公钥
保存test connect 是否success
3 jenkins 配置
Gerrit event
Trigger on
patchset creat MR创建触发
comment add 加一触发
/ project ** 代表所有 project带/ 则分开显示
ssh -x -p 29418 jenkins@192.168.10.200 gerrit review --project ${GERRIT_PROJECT} --code-scanning -1 ${GERRIT_PATCHSET_REVISION}
命令加一
sonar + jenkins
1 SonarQube Scanner 2.4 插件安装
2 配置
token 首次进入sonar 网页显示或者
执行
Analysis properties
sonar.projectKey=${project_name}-${GERRIT_BRANCH}-${BUILD_NUMBER}
sonar.projectName=${project_name}-${GERRIT_BRANCH}-${BUILD_NUMBER}
sonar.projectVersion=1.0
sonar.sources=${before_merge}
sonar.java.binaries=${before_merge}
sonar.projectBaseDir=${before_merge}
sonar.sourceEncoding=UTF-8
sonar.language=java
Additional arguments
-X
gerrit 带来的参数
echo $GERRIT_PATCHSET_UPLOADER
echo $GERRIT_PATCHSET_REVISION
echo $GERRIT_CHANGE_ID
echo $GERRIT_PATCHSET_NUMBER
echo $GERRIT_EVENT_ACCOUNT_EMAIL
echo $GERRIT_CHANGE_NUMBER
echo $GERRIT_CHANGE_OWNER
echo $GERRIT_REFSPEC
echo $GERRIT_EVENT_TYPE
echo $GERRIT_EVENT_ACCOUNT
echo $GERRIT_CHANGE_SUBJECT
echo $GERRIT_CHANGE_OWNER_NAME
echo $GERRIT_PROJECT
echo $GERRIT_EVENT_HASH
echo $GERRIT_BRANCH
echo $GERRIT_CHANGE_OWNER_EMAIL
echo $GERRIT_PATCHSET_UPLOADER_EMAIL
echo $GERRIT_CHANGE_URL
echo $GERRIT_PATCHSET_UPLOADER_NAME
echo $GERRIT_EVENT_ACCOUNT_NAME
jenkins 参数
echo ${WORKSPACE}
echo ${BUILD_NUMBER}
BUILD_ID
JOB_NAME
NODE_NAME #代理名称
JENKINS_HOME #enkins主节点上分配的目录绝对路径存储数据
JENKINS_URL
BUILD_URL
SVN_URL
git clone ${GERRIT_URL}
git fetch ${GERRIT_URL} ${GERRIT_REFSPEC} && git cherry-pick FETCH_HEAD
下载MR 代码
获取sonar结果并汇总
#!/usr/bin/env python
#--*--coding:utf-8--*--
import requests,json,os,time
import sys
import commands
reload(sys)
sys.setdefaultencoding('utf8')
print "##########################################################################################################################################################################"
print "三、开始执行Python脚本"
#各种变量
build_number = os.getenv("BUILD_NUMBER")
project_name = os.getenv("project_name")
branch = os.getenv("GERRIT_BRANCH")
work_space = os.getenv("work_space")
scanning_space = os.getenv("Scanning_Space")
before_merge = os.getenv("before_merge")
after_merge = os.getenv("after_merge")
sonar_url = "http://192.168.10.200:9090"
report_task_file = "%s/.sonar/report-task.txt"%after_merge
sonar_env_variable = "%s/result_report.sh"%(scanning_space)
dashboard_url = "%s/dashboard?id=%s-%s-%s"%(sonar_url,project_name,branch,build_number)
(status, output) = commands.getstatusoutput("grep 'ceTaskId' %s | awk -F '=' '{print $2}' "%report_task_file )
task_url = "%s/api/ce/task?id=%s"%(sonar_url,output)
component_url = '%s/api/measures/component?component=%s-%s-%s'%(sonar_url,project_name,branch,build_number) + '&metricKeys=vulnerabilities,new_vulnerabilities,bugs,new_bugs,code_smells,new_code_smells,violations,alert_status,new_violations'
def print_global_variable():
print "build_number=%s"%(build_number)
print "project_name=%s"%(project_name)
print "branch=%s"%(branch)
print "work_space=%s"%(work_space)
print "scanning_space=%s"%(scanning_space)
print "before_merge=%s"%(before_merge)
print "after_merge=%s"%(after_merge)
print "sonar_url=%s"%(sonar_url)
print "report_task_file=%s"%(report_task_file)
print "output=%s"%(output)
print "task_url=%s"%(task_url)
print "component_url=%s"%(component_url)
def wirte_sonar_result(result,violation,bug,leak,code_smell,new_bug,new_leak,new_code_smell,new_violation):
os.system("echo '#!/bin/bash' > %s"%(sonar_env_variable))
os.system("echo 'export dashboard_url=%s' > %s"%(dashboard_url,sonar_env_variable))
os.system("echo 'export result=%s' >> %s"%(result,sonar_env_variable))
os.system("echo 'export violation=%s' >> %s"%(str(violation),sonar_env_variable))
os.system("echo 'export bug=%s' >> %s"%(str(bug),sonar_env_variable))
os.system("echo 'export leak=%s' >> %s"%(str(leak),sonar_env_variable))
os.system("echo 'export code_smell=%s' >> %s"%(str(code_smell),sonar_env_variable))
os.system("echo 'export new_violation=%s' >> %s"%(str(new_violation),sonar_env_variable))
os.system("echo 'export new_bug=%s' >> %s"%(str(new_bug),sonar_env_variable))
os.system("echo 'export new_leak=%s' >> %s"%(str(new_leak),sonar_env_variable))
os.system("echo 'export new_code_smell=%s' >> %s"%(str(new_code_smell),sonar_env_variable))
def get_soanr_id_status():
#获取指定id的task
resopnse_task = requests.get(task_url).text
result_task = json.loads(resopnse_task)
print "result_task=%s"%(result_task)
task_status = 'PENDING'
task_status = result_task['task']['status']
print "task_status=%s"%(task_status)
if task_status == 'PENDING' or task_status == 'IN_PROGRESS':
print "PENDING or IN_PROGRESS sleep 30s"
time.sleep(30)
get_soanr_id_status()
elif task_status == 'CANCELED' or task_status == 'FAILED':
print "sonar error exit"
sys.exit(1)
else:
print "task status SUCCESS"
def get_soanr_result():
bug = new_bug = leak = new_leak = code_smell = new_code_smell = violation = new_violation = 0
result = ''
# 获取sonar指定项目结果
resopnse = requests.get(component_url).text
# 转换成josn
result = json.loads(resopnse)
print "result=%s"%(result)
# 解析sonar json结果
for item_compont in result['component']['measures']:
print ('item_compont=', item_compont )
if item_compont['metric']=="new_bugs":
print ('item_compont1=', item_compont['periods'])
for new_bugs_item in item_compont['periods']:
new_bug = new_bugs_item['value']
print ('new_bugs_item=', new_bugs_item['value'])
elif item_compont['metric']=="bugs":
bug = item_compont['value']
print ('bug=', item_compont['value'])
elif item_compont['metric']=="vulnerabilities":
leak = item_compont['value']
print ('leak=', item_compont['value'])
elif item_compont['metric']=="new_vulnerabilities":
print ('item_compont2=', item_compont['periods'])
for new_leak_item in item_compont['periods']:
new_leak = new_leak_item['value']
print ('new_leak_item=', new_leak_item['value'])
elif item_compont['metric']=="code_smells":
code_smell = item_compont['value']
print ('code_smell=', item_compont['value'])
elif item_compont['metric']=='new_code_smells':
print ('item_compont3=', item_compont['periods'])
for new_code_smell_item in item_compont['periods']:
new_code_smell = new_code_smell_item['value']
print ('new_code_smell_item=', new_code_smell_item['value'])
elif item_compont['metric']=='alert_status':
result = item_compont['value']
print ('result=', item_compont['value'])
elif item_compont['metric']=='violations':
violation = item_compont['value']
print ('violation=', item_compont['value'])
elif item_compont['metric']=='new_violations':
print ('item_compont4=', item_compont['periods'])
for new_violations_item in item_compont['periods']:
new_violation = new_violations_item['value']
print ('new_violations_item=', new_violations_item['value'])
else:
pass
wirte_sonar_result(result,violation,bug,leak,code_smell,new_bug,new_leak,new_code_smell,new_violation)
if __name__=="__main__":
print_global_variable()
get_soanr_id_status()
get_soanr_result()
根据结果给gerrit投票
#!/bin/bash
echo "##########################################################################################################################################################################"
echo "四、统计Sonarqube扫描结果"
if [ -f ${Scanning_Space}/result_report.sh ];then
source ${Scanning_Space}/result_report.sh
else
print_message "error" "未发现扫描结果文件${Scanning_Space}/result_report.sh"
fi
function print_message()
{
local type=$1
local message=$2
if [ "${type}" == "warnning" ];then
echo "WARNNING: ${message}"
elif [ "${type}" == "info" ];then
echo "INFO: ${message}"
elif [ "${type}" == "error" ];then
echo "ERROR: ${message}"
exit 1
fi
}
function get_sanning_result()
{
if [ ${result} == "OK" ];then
if [ ${new_bug} -gt 0 ] && [ ${new_leak} -gt 0 ];then
send_data_to_gerrit "-1" "${CHANGE_OWNER_NAME}提交的代码被扫描出bug ${new_bug}个,漏洞${new_leak}个,详见---->"
elif [ ${new_bug} -gt 0 ];then
send_data_to_gerrit "-1" "${CHANGE_OWNER_NAME}提交的代码被扫描出bug ${new_bug}个,详见---->"
elif [ ${new_leak} -gt 0 ];then
send_data_to_gerrit "-1" "${CHANGE_OWNER_NAME}提交的代码被扫描出漏洞${new_leak}个,详见---->"
else
send_data_to_gerrit "1"
fi
else
send_data_to_gerrit "-1" "详见链接--->"
fi
}
function send_data_to_gerrit()
{
local status=$1
local info=$2
if [ ${status} == "1" ];then
message="扫描成功 "
elif [ ${status} == "0" ];then
message="开始扫描 "
elif [ ${status} == "-1" ];then
message="扫描失败:${info}"
fi
print_message "info" "向gerrit服务器发送结果:"
cmd="ssh -x -p 29418 jenkins@192.168.10.200 gerrit review --project ${GERRIT_PROJECT} --code-scanning ${status} ${GERRIT_PATCHSET_REVISION} --message '${message} ${dashboard_url}'"
#ssh -x -p 29418 jenkins@192.168.10.200 gerrit review --project $GERRIT_PROJECT --code-scanning 1 $GERRIT_PATCHSET_REVISION
echo "cmd=${cmd}" && ${cmd};
if [ $? -ne 0 ];then
print_message "error" "向gerrit服务器发送结果失败"
exit 1;
fi
}
get_sanning_result