代码扫描工具 SonarQube Scanner 配置 & Jenkins 集成
试了一下,觉得不太好用,但还是记录一下过程,以备不时之需
我遇到的问题较多的是版本匹配问题,详情如下:
- 下载 & 配置
- 启动
- 扫描代码生成可视化
- 集成 Jenkins
一 下载
1 Java
- 下载后解压,我用的是 jdk1.8.0_191
- 配置环境变量 /etc/profile
-
java -version java version "1.8.0_191" Java(TM) SE Runtime Environment (build 1.8.0_191-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
- 检查 java -version 不报错即表示配置成功
2 Sonar & Sonar-Scan
- https://www.sonarqube.org/downloads/ 选择对应版本下载 sonar
- https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/ 选择对应版本下载sonar scan
- 解压 unizp **.zip
- 环境变量
-
# sonar 变量 export SONAR_RUNNER_HOME=/opt/sonar-scanner-4.4.0.2170-linux export PATH=$SONAR_RUNNER_HOME/bin:$PATH ulimit -SHn 65536
注:此处最终使用的是 sonarqube-6.5,先写正常流程,使用其他版本的问题会放在之后问题总结里。
二 配置&启动
1 MySQL 配置
注意 :此处使用的版本是 5.6.44; 使用 root 账号登录完成授权
启动 sonarqube 时会在对应的 sonar 数据库中生成一系列相关表和数据
CREATE USER sonar@'%' IDENTIFIED BY 'sonar'; //sonor - 用户名; ‘sonar’-密码;% - 任意 ip 可访问,也可以执行为启动 sonar 的机器 ip create sonar default character set utf8 collate utf8_general_ci; //创建数据库 GRANT ALL ON sonar.* TO sonar; // 给 sonar 用户对数据库 sonar 的操作权限 flush privileges ;--立即启用修改
2 Sonar 配置
1 vim sonarqube-6.5/conf/wrapper.conf 配置java
1 # Path to JVM executable. By default it must be available in PATH. 2 # Can be an absolute path, for example: 3 wrapper.java.command=/opt/jdk1.8.0_191/bin/java # 更改为自己的 java 全路径 4 #wrapper.java.command=java
2 vim sonarqube-6.5/conf/sonar.properties
配置要访问的数据库ip 端口用户名及密码,在1 MySQL 中配置过的,注意 sonar 部署的机器对 mysql 机器有访问权限
14 sonar.jdbc.username=sonar 15 sonar.jdbc.password=sonar 16 23 sonar.jdbc.url=jdbc:mysql://ip:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
...
109 #sonar.web.port=9000 //这个是启动后 web 访问端口,如果9000已经使用可更换
3 sonar-scanner 配置
sonar-scanner-4.4.0.2170-linux/conf/sonar-scanner.properties
#Configure here general information about the environment, such as SonarQube server connection details for example #No information about specific project should appear here #----- Default SonarQube server #sonar.host.url=http://localhost:9000 #----- Default source code encoding #sonar.sourceEncoding=UTF-8 sonar.host.url=http://sonar_ip:9000 #sonar 要用的 ip 和端口 sonar.jdbc.username=sonar # 数据库配置,同sonar一致就可以 sonar.jdbc.password=sonar sonar.jdbc.url=jdbc:mysql://mysql_ip:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false sonar.login=admin # 登录用户名及密码 sonar.password=admin
4 启动
我一开始用的sonarqube高阶版本,里面有 elasticsearch,要求不能用 root 账号启动。如果你已经不是 root 就正好,如果是需要新建一个用户,具体可百度。
注意新建完成用户后,
1 要更改 sonarqube 的可操作用户未 chown -R sonar:sonar sonarqube-6.6
2 要保证 java 所在目录新用户有访问权限
启动命令如下,表示启动成功
su sonar //切换到非 root 用户 cd sonarqube-6.5/bin/linux-x86-64 sonar linux-x86-64 $ ./sonar.sh start Starting SonarQube... Started SonarQube.
访问 web 地址 http://ip:9000 即可,如下表示启动成功,登录用户名默认 admin / admin
三 统计
启动成功后就可以使用 sonar 来进行代码检测了。检测需要源码。
1 在对应的源码工程目录下,添加文件 sonar-project.properties,内容如下:
# must be unique in a given SonarQube instance sonar.projectKey=my:project # this is the name displayed in the SonarQube UI sonar.projectName=MyProject # 随便起名字,一般跟项目名一致 sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. # Since SonarQube 4.2, this property is optional if sonar.modules is set. # If not set, SonarQube starts looking for source code from the directory containing # the sonar-project.properties file. sonar.sources=. #也可以写绝对路径, . 表示当前文件夹 # Encoding of the source code. Default is default system encoding #sonar.sourceEncoding=UTF-8
2 执行命令 即开始扫描并展示在 sonar 平台上
# source /etc/profile # sonar-scanner INFO: Scanner configuration file: /opt/sonar-scanner-4.4.0.2170-linux/conf/sonar-scanner.properties ...... INFO: Task total time: 20.657 s INFO: ------------------------------------------------------------------------ INFO: EXECUTION SUCCESS
四 Jenkins 集成
1 在 sonarqube 中生成一个token My Account-> Security ->随便输入 Name,生成一个 Token 记住它,因为没有地方可以查看。
(PS:用token代替输入用户名和密码)
2 下载插件 SonarQube Scanner SonarQube Scanner for Jenkins CodeSonar Plugin
3 配置 Jenkins 全局变量 SonarQube servers
4 配置 全局工具配置 -- 注意如果不准备使用节点的话,需要在master机器上部署一个sonar-scanner,指明路径,不然会报找不到
5 配置 job 如下,不知道为什么我配置成 token 会提示没权限,改成用户名密码就可以了,奇奇怪怪。
配置了jenkins之后,感觉就不走 服务器上的 sonar-scanner.配置文件了。
6 查看报告如下,点击 SonarQube 跳转到 sonar 的部署机器打开可视化报告。整个配置流程完成。
五 分析应用
在应用这块我不是特别懂,后面了解清楚了再来完善,据说微博在用 sonar 做代码分析。官网 https://github.com/SonarSource/sonar-php
https://blog.csdn.net/qq_32447301/article/details/90731314
Rules 对应的报错类型
1 block 类报错:无需修改
2 remove unreachable code :可清理优化
六 问题及解决
主要问题都是因为版本导致的 以下部分问题基于 sonar 版本 8.x,部分是 7.7
1 问题:启动 sonar,报错:Unable to start JVM: No such file or directory
原因:sonar 没指定到可执行的 java 文件
解决:1 更改warpper.conf 文件权限,2 配置 2.1 warpper.conf 中的 java 路径
2 sonar 8.x 版本, 问题:
WrapperSimpleApp: Encountered an error running main: java.lang.IllegalStateException: SonarQube requires Java 11 to run
java.lang.IllegalStateException: SonarQube requires Java 11 to run
原因:如 https://www.cnblogs.com/qianjinyan/p/11303195.html 所说,SonarQube 真的是有点飘啊,不想下载jdk11,因此跟该文作者一样下载了 SonarQube 的旧版本。之后的问题都是基于 7.7 的
3 更换版本后的新报错
root@my logs # vi es.log 2020.07.20 14:19:59 ERROR es[][o.e.b.Bootstrap] Exception java.lang.RuntimeException: can not run elasticsearch as root at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:106) ~[elasticsearch-5.6.3.jar:5.6.3] at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:195) ~[elasticsearch-5.6.3.jar:5.6.3] at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:342) [elasticsearch-5.6.3.jar:5.6.3]
解决:见 2.4 启动中,新建非 root 用户,设置权限后, su 新用户 进行启动操作
4 启动 ES 还是报错 https://blog.csdn.net/u012246178/article/details/63253531
2020.07.20 15:26:21 WARN es[][o.e.b.JNANatives] unable to install syscall filter: java.lang.UnsupportedOperationException: seccomp unavailable: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed at org.elasticsearch.bootstrap.SystemCallFilter.linuxImpl(SystemCallFilter.java:364) ~[elasticsearch-5.6.3.jar:5.6.3] at org.elasticsearch.bootstrap.SystemCallFilter.init(SystemCallFilter.java:639) ~[elasticsearch-5.6.3.jar:5.6.3] at org.elasticsearch.bootstrap.JNANatives.tryInstallSystemCallFilter(JNANatives.java:258) [elasticsearch-5.6.3.jar:5.6.3]
原因:因为Centos6不支持SecComp,而ES5.2.1默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动。详见 :https://github.com/elastic/elasticsearch/issues/22899
解决:在elasticsearch.yml中配置bootstrap.system_call_filter为false,注意要在Memory下面:
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
5 基于以上的衍生问题:conf/sonar.properties 中打开 sonar.jdbc.url=jdbc:mysql: localhost:3306/ 时,无法忽略 call_back 报错,启动失败。注释掉可以启动成功
解决:在 elasticsearch/bin/elasticsearch 中更改 ES_JAVA_OPTS 增加参数 -E.enforce.bootstrap.checks=true,(-Des 参数已过期废弃)
https://www.elastic.co/guide/en/elasticsearch/reference/current/jvm-options.html
再次启动,还是报错。在 elasticsearch 下生成 hs_err_pid26890.log文件
# There is insufficient memory for the Java Runtime Environment to continue. # Cannot create GC thread. Out of system resources. # Possible reasons: # The system is out of physical RAM or swap space # In 32 bit mode, the process size limit was hit # Possible solutions: # Reduce memory load on the system
解决:试了下手动释放内存和设置更大连接数,操作如下,https://www.cnblogs.com/kangoroo/p/7375604.html
# 先查看一下释放cache信令值, 此时应该是0 $ cat /proc/sys/vm/drop_caches 0 # 将缓冲区写入磁盘, 当需要停止系统的时候, 保证文件系统的完整性 $ sync # 释放cache, 这个命令可能要花费一点时间, 请耐心等待 $ echo 3 > /proc/sys/vm/drop_caches # 再看一眼 $ cat /proc/sys/vm/drop_caches
6 又报错了,如下:
[2020-07-21T14:00:13,928][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main] org.elasticsearch.bootstrap.StartupException: java.lang.IllegalArgumentException: unknown setting [.enforce.bootstrap.checks] please check that any required plugins are installed, or check the breaking changes documentation for removed settings at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:136) ~[elasticsearch-5.6.3.jar:5.6.3] ...... at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-5.6.3.jar:5.6.3] Caused by: java.lang.IllegalArgumentException: unknown setting [.enforce.bootstrap.checks] please check that any required plugins are installed, or check the breaking changes documentation for removed settings
解决:去掉bin/ela...中的参数,加到 elasticsearch/config/elasticsearch.yml 中如下
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
enforce.bootstrap.checks: true
7 如上操作后可以启动了,但是会有一个web报错如下
2020.07.21 14:30:15 INFO web[][o.s.p.ProcessEntryPoint] Starting web 2020.07.21 14:30:26 WARN web[][o.s.p.ProcessEntryPoint] Fail to start web org.sonar.api.utils.MessageException: Value of 'sonar.web.context' must start with a forward slash: 'sonarqube'
原因:百度说要加一个斜杠,可以加了斜杠后又开始报 call_back 那个错误
解决:有点烦了,机器不能随我搞,就换成了5.6版本,5.6里连 elasticsearch 文件夹都没有,啥都不用配了
8 问题:统计完成后,点击bugs数跳转到 问题页面显示无结果
原因:点击分析失败的后台任务,有报错如下,猜测是这个问题
java.lang.IllegalStateException: Unrecoverable indexation failures: 1 errors among 1 requests at org.sonar.server.es.IndexingListener$1.onFinish(IndexingListener.java:39) at org.sonar.server.es.BulkIndexer.stop(BulkIndexer.java:122) at org.sonar.server.measure.index.ProjectMeasuresIndexer.doIndex(ProjectMeasuresIndexer.java:158) at org.sonar.server.measure.index.ProjectMeasuresIndexer.indexOnAnalysis(ProjectMeasuresIndexer.java:82) at org.sonar.ce.task.projectanalysis.step.IndexAnalysisStep.execute(IndexAnalysisStep.java:45) at org.sonar.ce.task.step.ComputationStepExecutor.executeStep(ComputationStepExecutor.java:81)
google 让检查 es 日志,果然发现 WARN 提示磁盘空间不够
解决:清理磁盘,并重启 sonarqube(但是我没有操作,因为出问题的部署机器我不敢动)