[TOC]


0x00 基本概述

官网描述: SonarQube 提高您的团队成员的代码质量和安全性,使所有开发人员能够编写更干净、更安全的代码。
官网地址: https://www.sonarqube.org/
帮助文档: https://docs.sonarqube.org/latest/

Q: SonarQube 是什么?

答: SonarQube 是一个开源的代码质量管理平台系统,用于检测各类开发语言(例如: java、php、python、html、C、C#、Groovy)代码中的错误,漏洞和代码规范;
并且现在它可以与现有的Gitlab、Jenkins进行集成,以便在项目拉取后进行连续的代码质量检查;

WeiyiGeek.SonarQube

WeiyiGeek.SonarQube

Q: SonarQube 有何用处?

答: CI/CD integration 和 代码评审反馈;


SonarQube 特性:

  • (1) 检查代码是否遵循编程标准:如命名规范,编写的规范等。
  • (2) 检查设计存在的潜在缺陷:SonarQube 通过插件 Findbugs、Checkstyle 等工具检测代码存在的缺陷。
  • (3) 检测代码的重复代码量:SonarQube 可以展示项目中存在大量复制粘贴的代码。
  • (4) 检测代码中注释的程度:源码注释过多或者太少都不好,影响程序的可读可理解性。
  • (5) 检测代码中包、类之间的关系:分析类之间的关系是否合理,复杂度情况。


SonarQube 版本: Current is 8.6

  • Community Edition(免费) :(在你的CI/CD中采用代码质量的起点) The starting point for adopting code quality in your CI/CD
  • Developer Edition(14 day free trial) : (最大的应用程序安全性,最大的跨分支和PRs值) Maximum Application Security Maximum value across branches & PRs
  • Enterprise Edition :(管理您的应用程序组合,在企业级别上保证代码质量和安全性。) Manage your Application Portfolio, enable Code Quality & Security at an Enterprise level.
  • Data CenterEdition : (高可用性,用于全球部署) High Availability, for global deployments

参考地址: https://www.sonarqube.org/downloads/


SonarQube 组成:
SonarQube 平台是由 4 个部分组成:

  • SonarQube Server
  • SonarQube Database
  • SonarQube Plugins
  • SonarQube Scanner


SonarQube 工作流程:
SonarQube 在进行代码质量管理时,会从下面七个纬度来分析项目的质量:Architecture(架构)、Duplications(段重复)、Unit test(单元测试)、Complexity(复杂程度)、Potential Bugs(潜在的BUG)、Codeding Rules(编码规则)、Comments(注解)

SonarQube 需要数据库的支持用于存储检测项目后的分析数据,同时为了实现可持续监测还需要持续集成工具(如Jenkins)的支持,在构建版本前通过 Jenkins+Sonar 插件执行项目分析指令,最终的结果会通过 SonarQube 服务器的Web 页面展示;

下图是使用 SonarQube 做代码持续审查的流程图:

  • 1.本地项目开发
  • 2.推送开发的项目到 SCM (如果 Gitlab/Github)
  • 3.Jenkins采用自定义的Job进行自动构建
  • 4.并执行代码分析检测命令 (Sonar-Scanner)
  • 5.利用SonarQube接口进行分析项目源码(上面的七个维度)并存储到数据库之中
  • 6.SonarQube Web 前台展现代码分析结果给使用者
WeiyiGeek.SonarQube 工作流程

WeiyiGeek.SonarQube 工作流程


0x01 环境安装

描述: SnoarQube 安装方式有两种您可以使用传统的zip文件安装来评估SonarQube,也可以使用我们的Docker映像来启动一个Docker容器

基础环境需求:

  • (0) 处理器 CPU 建议 4~8U
  • (1) 内存 RAM 最低 1GM 建议至少 大于等于 4G
  • (2) 磁盘空间量将取决于您使用 SonarQube 分析的代码量, 备注读写硬盘性能将对整个 SonarQube 服务器性能产生很大影响。
  • (3) 建议 服务器端扫描端都安装 64 位系统
  • (4) Java 版本 : 甲骨文 JRE / Openjdk 建议都使用 Jdk 11,如果受环境因素较大扫描端可安装 JDK 8;
  • (5) 数据库支持情况: 注意已经缺省弃用 MySQL 数据库
    1
    2
    3
    PostgreSQL	9.3–9.6, 10~12  # 必须配置为使用 UTF-8 字符集
    MsSQL 2014 ~ 2017 (MSSQL 服务器 12~14.0) 与捆绑的微软 JDBC 驱动程序。支持快速版。 # 排序规则必须重写 (CS) 和重音敏感 (AS)(例如:Latin1_General_CS_AS), READ_COMMITTED_SNAPSHOT必须在 SonarQube 数据库上设置,以避免在重负载下出现潜在的死锁
    Oracle XE 版 / 11G / 12 ~ 19 C # 必须配置为使用 UTF8 系列字符集(请参阅NLS_CHARACTERSET) , 驱动程序 ojdbc14.jar 不支持驱动程序, 仅支持精简模式,不支持 OCI

PS : 至sonarqube7.9版本以后就不支持Mysql了(本地试用的话可以使用它内置的数据库),系统运行内存一定要3G以上否则在启动项目时启动会显示ES失败;
PS : 嵌入式数据库应仅用于评估目的, 嵌入式数据库不能伸缩,它不支持升级到SonarQube的新版本,也不支持将数据从其中迁移到另一个数据库引擎。
环境准备(针对于):


基础配置

(0) 字体
描述: 生成执行报告要求在托管 SonarQube 的服务器上安装字体。在 Windows 服务器上这是给定的。但是Linux 服务器的情况并非总是如此。
应确保以下事项:

  • Fontconfig安装在托管 SonarQube 的服务器上
  • 在SonarQube服务器上安装了 FreeType 字体包。确切的可用包将因分发而异,但常用的包是libfreetype6(https://www.freetype.org/)

(1) Linux上虚拟缓存与IO设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Linux 推荐配置
vm.max_map_count 大于或等于 524288
fs.file-max 大于或等于 131072
运行 SonarQube 的用户至少可以打开 131072 个文件描述符
运行 SonarQube 的用户至少可以打开 8192 个线程

# 查看vm.max_map_count、fs.file-max、文件描述符、线程
sysctl vm.max_map_count
sysctl fs.file-max
ulimit -n
ulimit -u

# 临时配置按照需求调整
sysctl -w vm.max_map_count=524288
sysctl -w fs.file-max=131072
ulimit -n 131072
ulimit -u 8192

# 永久配置 更新 /etc/sysctl.d/99-sonarqube.conf 或 /etc/sysctl.conf
# 指定用户 /etc/security/limits.d/99-sonarqube.conf or /etc/security/limits.conf
sonarqube - nofile 131072
sonarqube - nproc 8192

PS : 如果使用systemd启动 SonarQube,则必须在 [服务]部分中的单元文件中指定这些限制:

1
2
3
4
[Service]
...
LimitNOFILE=131072
LimitNPROC=8192


(2) seccomp过滤器
描述: 默认情况下弹性搜索使用seccomp 筛选器,在大多数发行版上,此功能在内核中激活;
针对于 Linux 6 发行版此功能被停用。如果使用没有此功能的发行版,并且无法升级到已激活 seccomp 的较新版本,则必须通过更新 $SONARQUBEHOME/conf/sonar.properties 显式停用此安全层:sonar.search.javaAdditionalOpts

1
2
3
4
5
6
7
8
# 检查 seccomp 在您的内核上是否可用,正常状态下应该是如下;
$ grep SECCOMP /boot/config-$(uname -r)
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_SECCOMP_FILTER=y
CONFIG_SECCOMP=y

# 配置
sonar.search.javaAdditionalOpts=-Dbootstrap.system_call_filter=false


本机安装

描述: 安装SonarQube的本地实例需要下载 SonarQube Zip 文件;

  • Step 1.下载SonarQube社区版zip文件 : https://www.sonarqube.org/downloads/

  • Step 2.作为一个非root用户,解压它比如在C:\sonarqube/app/sonarqube中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 用户与sonarqube目录创建
    sudo useradd -m sonarqube # esadmin、sonar
    sudo mkdir -vp /app/

    # 将sonarqube压缩包解压到/app/sonarqube
    sudo unzip sonarqube-8.6.0.39681.zip -d /app/

    # 创建软连接
    /app$ sudo ln -s /app/sonarqube-8.6.0.39681/ /app/sonarqube
    /app$ ls /app/sonarqube/
    # bin/ COPYING elasticsearch/ lib/ temp/
    # conf/ data/ extensions/ logs/ web/
    /app$sudo ln -s /app/sonarqube/bin/linux-x86-64/sonar.sh /usr/local/bin/sonar.sh

    # 权限设置
    /app$ sudo chown -R sonarqube:sonarqube /app
  • Step 3.SonarQube 简单配置文件/app/sonarqube/conf/sonar.properties

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # (1) 修改Sonarqube连接数据库配置文件
    sonar.jdbc.username=sonarqube
    sonar.jdbc.password=password
    # #----- PostgreSQL 9.3 or greater
    sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube?currentSchema=my_schema
    # #----- Oracle 11g/12c/18c/19c
    sonar.jdbc.url=jdbc:oracle:thin:@localhost:1521/XE
    # #----- Microsoft SQLServer 2014/2016/2017 and SQL Azure
    sonar.jdbc.url=jdbc:sqlserver://localhost;databaseName=sonar;integratedSecurity=true

    # (2) Web Server JVM 设置
    # -Xmx 设置你的应用程序(不是JVM)能够使用的最大内存数(注意不能超过内存数 )
    # -Xms 设置程序初始化的时候内存栈的大小
    sonar.web.javaOpts=-Xmx512m -Xms128m -XX:+HeapDumpOnOutOfMemoryError
    sonar.web.host=0.0.0.0
    sonar.web.port=9000
  • Step 4.注意必须采用非root用户,启动SonarQube服务器:(PS:此处采用内置的数据库,如果是正式项目请采用外置数据库)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # On Windows, execute:
    C:\sonarqube\bin\windows-x86-64\StartSonar.bat

    # On other operating systems, as a non-root user execute:
    # 启动
    su - sonarqube -c "/app/sonarqube/bin/linux-x86-64/sonar.sh console"

    # 查看启动状态
    su sonar ./bin/linux-x86-64/sonar.sh status

    # 跟踪日志
    su sonar tail -f /usr/local/sonarqube-6.7.5/logs/sonar.log

    # 如出现以下四行表示启动成功
    jvm 1 | 2020.12.30 09:39:42 INFO app[][o.s.a.SchedulerImpl] Process[es] is up
    jvm 1 | 2020.12.30 09:39:55 INFO app[][o.s.a.SchedulerImpl] Process[web] is up
    jvm 1 | 2020.12.30 09:39:59 INFO app[][o.s.a.SchedulerImpl] Process[ce] is up
    jvm 1 | 2020.12.30 09:39:59 INFO app[][o.s.a.SchedulerImpl] SonarQube is up
WeiyiGeek.sonar.sh

WeiyiGeek.sonar.sh


容器安装

描述: 采用Docker 容器的安装 SonarQube 非常简单,访问 Find the Community Edition Docker image on Docker Hub:https://hub.docker.com/_/sonarqube/

  • Step 1.docker拉取SonarQube镜像以及运行

    1
    2
    3
    4
    5
    # 指定版本拉取
    docker pull sonarqube:8.6.0-community

    # 运行
    $ docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest
  • Step 2.实例启动并运行后,使用系统管理员凭据登录 http://localhost:9000,账号密码 admin,然后安装参考请看基础使用;


K8s集群安装

环境说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal

Client: Docker Engine - Community
Version: 20.10.3
API version: 1.41
Go version: go1.13.15

$ kubelet --version
Kubernetes v1.19.6

SonarQube 版本:8.6.1-community # https://hub.docker.com/_/sonarqube
Postgrep 版本:13.1 # https://registry.hub.docker.com/_/postgres

Tips : 本集群中kubernetes底层存储使用的是NFS,并且以nfs作为存储创建了storageclass(名称为managed-nfs-storage)便于动态创建pv

1
2
3
$ kubectl get storageclasses  # alias sc
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
# managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 19d


操作流程:

  • Step 1.环境准备之 PostgreSQL 部署,需要将数据库的数据文件持久化,因此需要创建对应的pv,本次安装通过storageclass创建pv。
    描述: SonarQube需要依赖数据库存储数据,且SonarQube7.9及其以后版本将不再支持Mysql,所以这里推荐设置PostgreSQL作为SonarQube的数据库。
    Tips: 由于PostgreSQL只需要集群内部连接,因此采用Headless service(无头服务)来创建数据库对应的svc,数据库的端口是5432,最终的yaml如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
cat > PostgreSQL-Deployment.yaml <<'END'
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-sonar
labels:
app: postgres-sonar
spec:
replicas: 1
selector:
matchLabels:
app: postgres-sonar
template:
metadata:
labels:
app: postgres-sonar
spec:
containers:
- name: postgres-sonar
image: postgres:13.1-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: "sonarDB"
- name: POSTGRES_USER
value: "sonarUser"
- name: POSTGRES_PASSWORD
value: "WeiyiGeek#2021"
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 500m
memory: 1024Mi
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteMany"]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: postgres-sonar
labels:
app: postgres-sonar
spec:
clusterIP: None
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
app: postgres-sonar
END
  • Step 2.执行kubectl apply|create创建资源,并检查对应的pv,pvc以及日志
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~/k8s/sonarqube$ kubectl create -f PostgreSQL-Deployment.yaml -n devops
    # deployment.apps/postgres-sonar created
    # persistentvolumeclaim/postgres-data created
    # service/postgres-sonar created

    ~/k8s/sonarqube$ kubectl get pvc,deployment,svc -n devops | grep "postgres"
    # persistentvolumeclaim/postgres-data Bound pvc-5d6936c4-2999-4f86-8248-8ad784899801 1Gi RWX managed-nfs-storage 71s
    # deployment.apps/postgres-sonar 1/1 1 1 71s
    # service/postgres-sonar ClusterIP None <none> 5432/TCP 71s


  • Step 3.SonarQube 部署的资源清单
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    cat > sonarqube-deployment.yaml <<'END'
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: sonarqube
    labels:
    app: sonarqube
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: sonarqube
    template:
    metadata:
    labels:
    app: sonarqube
    spec:
    initContainers:
    - name: init-sysctl
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["sysctl", "-w", "vm.max_map_count=262144"]
    securityContext:
    privileged: true
    containers:
    - name: sonarqube
    image: sonarqube:8.6.1-community
    ports:
    - containerPort: 9000
    env:
    - name: SONARQUBE_JDBC_USERNAME
    value: "sonarUser"
    - name: SONARQUBE_JDBC_PASSWORD
    value: "WeiyiGeek#2021"
    - name: SONARQUBE_JDBC_URL
    value: "jdbc:postgresql://postgres-sonar:5432/sonarDB"
    livenessProbe:
    httpGet:
    path: /sessions/new
    port: 9000
    initialDelaySeconds: 60
    periodSeconds: 30
    readinessProbe:
    httpGet:
    path: /sessions/new
    port: 9000
    initialDelaySeconds: 60
    periodSeconds: 30
    failureThreshold: 6
    resources:
    limits:
    cpu: 2000m
    memory: 2048Mi
    requests:
    cpu: 1000m
    memory: 1024Mi
    volumeMounts:
    - mountPath: /opt/sonarqube/conf
    name: data
    subPath: conf
    - mountPath: /opt/sonarqube/data
    name: data
    subPath: data
    - mountPath: /opt/sonarqube/extensions
    name: data
    subPath: extensions
    volumes:
    - name: data
    persistentVolumeClaim:
    claimName: sonarqube-data

    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
    name: sonarqube-data
    spec:
    accessModes:
    - ReadWriteMany
    storageClassName: "managed-nfs-storage"
    resources:
    requests:
    storage: 10Gi
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: sonarqube
    labels:
    app: sonarqube
    spec:
    type: NodePort
    ports:
    - name: sonarqube
    port: 9000
    targetPort: 9000
    nodePort: 30002
    protocol: TCP
    selector:
    app: sonarqube
    END

Tips: 通过官方的sonar镜像部署,通过环境变量指定连接数据库的地址信息,同样通过storageclass来提供存储卷,通过NodePort方式暴露服务。

Tips: 与常规部署不同的是,这里对sonar通过init container进行了初始化,执行修改了容器的vm.max_map_count根据内存大小提供;

1
2
3
4
5
6
7
8
9
10
# 修改此权限需要授权能执行系统命令
securityContext:
privileged: true

# 例如,在Linux操作系统下,可以在主机上以root用户运行以下命令来设置当前会话的推荐值:
# For example, on Linux, you can set the recommended values for the current session by running the following commands as root on the host:
sysctl -w vm.max_map_count=262144
sysctl -w fs.file-max=65536
ulimit -n 65536
ulimit -u 4096


  • Step 4.执行部署sonarqube并查看部署状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    ~/k8s/sonarqube$ kubectl create -f sonarqube-deployment.yaml -n devops
    # deployment.apps/sonarqube created
    # persistentvolumeclaim/sonarqube-data created
    # service/sonarqube created

    ~/k8s/sonarqube$ kubectl get deployment,pvc,svc -n devops | grep 'sonarqube'
    # deployment.apps/sonarqube 0/1 1 0 4m57s
    # persistentvolumeclaim/sonarqube-data Bound pvc-5695d2d5-e769-43f4-a91d-7ff0f5ab0b8b 10Gi RWX managed-nfs-storage 4m57s
    # service/sonarqube NodePort 10.100.233.217 <none> 9000:30002/TCP 4m57s
  • Step 5.访问SonarQube UI: http://192.168.12.107:30002/sessions/new?return_to=%2F

WeiyiGeek.K8s-SonarQube

WeiyiGeek.K8s-SonarQube


0x02 基础使用

1.初始化配置

  • Step 1.访问 http://10.10.107.217:9000/ 输入初始密码(admin / admin), 更新初始密码;
WeiyiGeek.登陆成功

WeiyiGeek.登陆成功

WeiyiGeek.界面汉化

WeiyiGeek.界面汉化

  • Step 3.安装代码检测插件默认已经安装了C Java Python PHP js等质量分析工具,并且可以根据项目自行安装其它的代码检测语言比如 Go;

  • Step 4.离线安装插件,由于SonarQube安装可能需要很长的时间,所以可以选择之前已经安装过的插件,直接导入到Plugins目录, 然后重新服务后即可在应用中心查看已安装过的插件;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Plugins 目录
    ~$ ls /app/sonarqube/extensions/plugins/
    README.txt sonar-l10n-zh-plugin-8.5.jar

    # 将下载的插件解压到Plugins目录之中并授予相应的权限;
    tar xf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/plugins/
    sudo shown -R sonarqube.sonarqube /usr/local/sonarqube/extensions/plugins/
    ls /app/sonarqube/extensions/plugins/
    # README.txt sonar-l10n-zh-plugin-8.5.jar sonar-pmd-plugin-3.2.1.jar
  • Step 5.如果在客户端需要分析HTML、PHP、Python等项目,则需要安装一个sonar-scanner(https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/)的工具;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # Client端下载解压
    wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.5.0.2216.zip
    # 2020-12-31 02:34:47 (517 KB/s) - ‘sonar-scanner-cli-4.5.0.2216.zip’ saved [589153/589153]
    unzip sonar-scanner-cli-4.5.0.2216.zip -d sonar-scanner-cli
    ~/sonar/sonar-scanner-4.5.0.2216$ ls
    # bin conf lib

    # 软连接
    sudo ln -s /home/weiyigeek/sonar/sonar-scanner-4.5.0.2216/bin/sonar-scanner /usr/local/bin/
    sonar-scanner -v
    # INFO: Scanner configuration file: /home/weiyigeek/sonar/sonar-scanner-4.5.0.2216/conf/sonar-scanner.properties
    # INFO: Project root configuration file: NONE
    # INFO: SonarScanner 4.5.0.2216
    # INFO: Java 1.8.0_211 Oracle Corporation (64-bit)
    # INFO: Linux 5.4.0-46-generic amd64

    # 客户端 sonar-scanner 基础配置
    ## 域名解析
    sudo tee -a /etc/hosts <<'EOF'
    10.10.107.217 sonar.weiyigeek.top
    EOF


2.静态项目分析实践

描述: 前面已经对SonarQube进行了一个简单的配置, 接下来我们将建立一个代码项目并进行分析;

  • Step 1.创建项目与令牌(Token), 首页创建新项目 -> 手工设置(项目标识/显示名) -> 创建一个令牌 -> 输入HelloWorld -> 获得Token:helloWorld: 1b0b037f06e7990c360d62ce9151aaf978cec155

PS : 此时需要设置服务端开启认证(缺省是开启的),配置 -> Force user authentication|强制用户使用认证 -> 标识: sonar.forceAuthentication

WeiyiGeek.分析项目创建

  • Step 2.在我们客户端机器拉取我们的静态Blog页面代码并进行质量分析;

    1
    2
    3
    4
    5
    6
    7
    8
    ~/code$ git clone [email protected]:ci-cd/blog.git
    ~/code/blog$ git config --list
    # core.repositoryformatversion=0
    # core.filemode=true
    # core.bare=false
    # core.logallrefupdates=true
    # [email protected]:ci-cd/blog.git
    # remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
  • Step 3.客户端 sonar-scanner.properties 全局参数设置,在之后的使用sonar-scanner命令时便可不输入以下参数;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ nano ~/sonar/sonar-scanner-4.5.0.2216/conf/sonar-scanner.properties
    #----- Default SonarQube server
    sonar.host.url=http://sonar.weiyigeek.top:9000

    #----- Token Configure
    sonar.login=1b0b037f06e7990c360d62ce9151aaf978cec155

    #----- Default source code encoding
    sonar.sourceEncoding=UTF-8
  • Step 4.开始在客户端进行代码的质量扫描

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 项目扫描
    sonar-scanner -Dsonar.projectname=Hello-World-Blog -Dsonar.projectKey=Hello-World -Dsonar.sources=.
    # INFO: CPD Executor CPD calculation finished (done) | time=270833ms
    # INFO: Analysis report generated in 10280ms, dir size=159 MB
    # INFO: Analysis report compressed in 44023ms, zip size=39 MB
    # INFO: Analysis report uploaded in 1574ms
    # INFO: ANALYSIS SUCCESSFUL, you can browse http://sonarqube.weiyigeek.top/dashboard?id=html
    # INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
    # INFO: More about the report processing at http://sonarqube.weiyigeek.top/api/ce/task?id=AXa2xmjzr2pPEzGrpOUX
    # INFO: Analysis total time: 6:52.709 s
    # INFO: ------------------------------------------------------------------------
    # INFO: EXECUTION SUCCESS # 分析扫描完成
    # INFO: ------------------------------------------------------------------------
    # INFO: Total time: 6:54.148s
    # INFO: Final Memory: 16M/423M
    # INFO: ------------------------------------------------------------------------
WeiyiGeek.代码质量检测结果

WeiyiGeek.代码质量检测结果


3.Java项目分析实践

描述: Java 项目可以通过Maven进行代码质检而无需使用Sonar-Scanner工具(但是扫描出的结果比官方的工具较少),只需要安装Maven即可

  • Step 1.Linux 下 Maven 安装

    1
    2
    apt install maven
    yum install maven
  • Step 2.手动从Gitlab仓库获取Java代码,进入项目目录并使用MVN进行代码质量扫描

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ~/code/$ git clone [email protected]:ci-cd/java-maven.git
    ~/code/java-maven$ git config --list
    # core.repositoryformatversion=0
    # core.filemode=true
    # core.bare=false
    # core.logallrefupdates=true
    # [email protected]:ci-cd/java-maven.git
    # remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
    # branch.master.remote=origin
    # branch.master.merge=refs/heads/master
  • Step 3.在 Maven 配置文件进行变量的定义配置只需要输入一条命令即可;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # 方式1
    mvn sonar:sonar -Dsonar.host.url=http://sonar.weiyigeek.top:9000 -Dsonar.login=1b0b037f06e7990c360d62ce9151aaf978cec155
    # [INFO] Scanning for projects...
    # Downloading from weiyigeek-maven: http://maven.weiyigeek.top:8081/repository/maven-public/org/apache/maven/plugins/maven-deploy-plugin/2.7/maven-deploy-plugin-2.7.pom
    # ....
    # [INFO] ANALYSIS SUCCESSFUL, you can browse http://sonarqube.weiyigeek.top/dashboard?id=com.weiyigeek.main%3Ahello-world
    # [INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
    # [INFO] More about the report processing at http://sonarqube.weiyigeek.top/api/ce/task?id=AXa2595Cr2pPEzGrpOUp
    # [INFO] Analysis total time: 7.113 s
    # [INFO] ------------------------------------------------------------------------
    # [INFO] BUILD SUCCESS
    # [INFO] ------------------------------------------------------------------------
    # [INFO] Total time: 27.219 s
    # [INFO] Finished at: 2020-12-31T03:46:57Z
    # [INFO] ------------------------------------------------------------------------

    # 方式2.在 Maven 配置文件 文件中定义Token后
    mvn sonar:sonar

    # 方式3.采用 `Sonar-scanner` 方式进行扫描该Maven项目
    sonar-scanner -Dsonar.projectName=Java-maven -Dsonar.projectKey=Hello-World -Dsonar.sources=. -Dsonar.java.binaries=target/
    # INFO: ANALYSIS SUCCESSFUL, you can browse http://sonarqube.weiyigeek.top/dashboard?id=Hello-World
    # INFO: Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report
    # INFO: More about the report processing at http://sonarqube.weiyigeek.top/api/ce/task?id=AXa3PxQNr2pPEzGrpOU1
    # INFO: Analysis total time: 3.467 s
    # INFO: ------------------------------------------------------------------------
    # INFO: EXECUTION SUCCESS
    # INFO: ------------------------------------------------------------------------
    # INFO: Total time: 4.293s
    # INFO: Final Memory: 18M/163M
    # INFO: ------------------------------------------------------------------------
  • Step 4.查看 SonarQube 分析后的结果

WeiyiGeek.SonarQube-Maven

WeiyiGeek.SonarQube-Maven


0x03 插件收集

  • (1) sonar-pdf-report (质量分析报告插件): https://github.com/SonarQubeCommunity/sonar-pdf-report
    1
    2
    3
    4
    5
    6
    # Git拉取编译
    git clone https://github.com/SonarQubeCommunity/sonar-pdf-report.git
    mvn clean package -Dmaven.test.skip=true
    # [INFO] Replacing /home/weiyigeek/code/sonar-pdf-report/target/sonar-pdfreport-plugin-1.5-SNAPSHOT.jar
    $ ls -lh /home/weiyigeek/code/sonar-pdf-report/target/
    # -rw-r--r-- 1 weiyigeek weiyigeek 3.1M Dec 31 02:11 sonar-pdfreport-plugin-1.5-SNAPSHOT.jar

0x04 补充说明

(1) 多种构建技术调用检测

使用Maven执行SonarQube扫描

1
2
3
4
5
# 使用Maven执行SonarQube分析是非常简单的。只需要在你的项目目录下执行如下命令。
mvn sonar:sonar \
-Dsonar.projectKey=Jenkis \
-Dsonar.host.url=http://sonar.weiyigeek.top:9000 \
-Dsonar.login=755eeb453cb28f96aa9d4ea14334da7287c2e840


使用Gradle执行SonarQube扫描

1
2
3
4
5
6
7
8
9
10
# (1) 使用Gradle执行SonarQube分析是非常简单的。只需要在你的<code>build.gradle</code>文件中声明<code>org.sonarqube</code>插件:
plugins {
id "org.sonarqube" version "3.0"
}

# (2) 然后执行如下命令:
./gradlew sonarqube \
-Dsonar.projectKey=Jenkis \
-Dsonar.host.url=http://sonar.weiyigeek.top:9000 \
-Dsonar.login=755eeb453cb28f96aa9d4ea14334da7287c2e840

PS : 你需要查找当前版本的Gradle插件(http://sonar.weiyigeek.top:9000/documentation/analysis/scan/sonarscanner-for-gradle/)


使用MSBuild扫描器执行SonarQube扫描

1
2
3
4
5
6
7
8
9
# (1) 下载并解压SonarQube MSBuild扫描器将可执行程序的目录添加至<code>%PATH%</code>环境变量
# http://sonar.weiyigeek.top:9000/documentation/analysis/scan/sonarscanner-for-msbuild/

# (2) 使用MSBuild执行SonarQube分析是非常简单的。只需要在你的项目目录下执行如下命令。
SonarScanner.MSBuild.exe begin /k:"Jenkis" /d:sonar.host.url="http://sonar.weiyigeek.top:9000" /d:sonar.login="755eeb453cb28f96aa9d4ea14334da7287c2e840"

# (3) 再次
MsBuild.exe /t:Rebuild
SonarScanner.MSBuild.exe end /d:sonar.login="755eeb453cb28f96aa9d4ea14334da7287c2e840"


其他 (比如 JS, TS, Go, Python, PHP, …)执行SonarQube扫描

各大操作系统平台的scanner工具下载地址:

  • Linux/Windows/Mac平台的扫描器:http://sonar.weiyigeek.top:9000/documentation/analysis/scan/sonarscanner/
  • 分析调用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Linux 
    sonar-scanner \
    -Dsonar.projectKey=Jenkis \
    -Dsonar.sources=. \
    -Dsonar.host.url=http://sonar.weiyigeek.top:9000 \
    -Dsonar.login=755eeb453cb28f96aa9d4ea14334da7287c2e840

    # Windows
    sonar-scanner.bat -D"sonar.projectKey=Jenkis" -D"sonar.sources=." -D"sonar.host.url=http://sonar.weiyigeek.top:9000" -D"sonar.login=755eeb453cb28f96aa9d4ea14334da7287c2e840"

0x05 入坑出坑

问题1.ERROR: Error during SonarScanner execution Malformed input or input contains unmappable characters

问题原因: 操作系统字符集不支持中文, 需要安装相关的中文依赖;
解决办法:

1
2
3
4
5
# 以`Ubuntu`为例
- apt-get update && apt-get install -y locales
- locale-gen "en_US.UTF-8"
- update-locale LC_ALL="en_US.UTF-8"
- export LANG="en_US.UTF-8"

参考地址: https://community.sonarsource.com/t/analysis-failed-with-malformed-input-or-input-contains-unmappable-characters/19452

-Dsonar.scm.provider=git

https://blog.csdn.net/huangli1466384630/article/details/85283766

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
ERROR: Error during SonarScanner execution
java.lang.IllegalStateException: Can not execute Findbugs
at org.sonar.plugins.findbugs.FindbugsExecutor.execute(FindbugsExecutor.java:188)
at org.sonar.plugins.findbugs.FindbugsSensor.execute(FindbugsSensor.java:114)
at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:393)
at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:389)
at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:358)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:144)
at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:137)
at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:123)
at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
at com.sun.proxy.$Proxy0.execute(Unknown Source)
at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
at org.sonarsource.scanner.cli.Main.main(Main.java:61)
Caused by: java.lang.IllegalStateException: One (sub)project contains Java source files that are not compiled (/home/jenkins/agent/workspace/zytb_manage_rebuild).
at org.sonar.plugins.findbugs.FindbugsConfiguration.getFindbugsProject(FindbugsConfiguration.java:123)
at org.sonar.plugins.findbugs.FindbugsExecutor.execute(FindbugsExecutor.java:119)
... 31 more
ERROR:
ERROR: Re-run SonarScanner using the -X switch to enable full debug logging.

https://blog.csdn.net/melody_hahaha/article/details/80567624

解决sonar scanner扫描报错Please provide compiled classes of your project with sonar.java.binaries property