Gitlab與Sonarqube整合-代碼提交自動檢測


概述

系統環境與軟件版本

  • docker 19.03.6
  • docker image: postgres:12
  • docker image: sonarqube:8.1-community
  • docker image: gitlab/gitlab-ce:latest 實際版本(12.8.1)
  • docker image: gitlab/gitlab-runner:latest 實際版本(12.8.0)
  • docker image: sonarsource/sonar-scanner-cli:latest

不涉及具體理論,關於各個組件詳細理論可以查看官方文檔。

實現目標:gitlab中項目的master分支每次合並和提交都會自動運行sonar-scanner檢測代碼。

實現原理:通過安裝啟用gitlab-runner,配置項目ci/cd觸發指定操作,使sonar-scanner掃描代碼到sonarqube server完成代碼檢測分析操作。

以下所有組件通過docker進行安裝:

  • postgres
  • sonarqube
  • gitlab
  • gitlab-runner

准備工作

默認bridge網絡內的容器無法解析對方容器的host,通過新建一個docker網絡,可以簡單解決此問題。在創建目錄時,有些容器可能內部需要普通用戶運行,注意目錄權限問題。

# 創建docker network
docker network create project1_net

# 創建各容器所需目錄
mkdir -p /data/docker-volume
cd /data/docker-volume
mkdir postgres
mkdir -p sonarqube/{data,extensions,logs}
mkdir -p gitlab/{config,logs,data}
mkdir -p gitlab-runner/config

# sonarqube內部用戶uid/gid,否則啟動會出現權限問題。容器鏡像版本不同可能有差異,具體可看官方文檔或docker run --rm -it sonarqube:[TAG] bash進入容器查看所使用目錄的屬主屬組
chown -R 999.999 sonarqube

postgres

啟動postgres,並為sonarqube創建一個數據庫。sonarqube數據庫需要使用字符編碼為UTF8,postgres默認創建的則為UTF8,如果你的版本不是,那在創建時需要特別指定。

Note:postgres在本地進行訪問時,不需要密碼驗證,從遠端主機訪問則是需要的。

# 啟動postgres容器
docker run -d --name postgres --net=project1_net \
-e POSTGRES_PASSWORD=pgpasswd \
-v /data/docker-volume/postgres:/var/lib/postgresql/data \
postgres:12

# 創建sonarqube數據庫
docker exec -it postgres psql -U postgres
> create database sonarqube;
> \l # 列出所有數據庫
> \q # 退出

sonarqube

創建sonarqube容器,指定使用postgresql數據庫,且指定連接至postgres的賬號和密碼。

sonarqube容器啟動時,若出現無法連接數據庫問題,則很大程度上是連接到數據庫的網絡或賬號問題,先確認sonarqube容器所在的網絡能否連接到postgres這個名稱的主機,再確認postgres中是否有sonarqube數據庫。

若出現文件權限問題,則按照准備工作章節中的操作確認一遍。

# 啟動sonarqube容器
docker run -d --name sonarqube --net=project1_net \
-p 9000:9000 \
-e SONAR_JDBC_URL=jdbc:postgresql://postgres/sonarqube \
-e SONAR_JDBC_USERNAME=postgres \
-e SONAR_JDBC_PASSWORD=pgpasswd \
-v /data/docker-volume/sonarqube/data:/opt/sonarqube/data \
-v /data/docker-volume/sonarqube/extensions:/opt/sonarqube/extensions \
-v /data/docker-volume/sonarqube/logs:/opt/sonarqube/logs \
sonarqube:8.1-community

gitlab

gitlab鏡像比較大,其中包含了postgres,redis,nginx,gitlab等多個組件,啟動、初始化配置等時間也比較長,具體根據機器配置,耐心等待觀察日志啟動完成即可訪問。

docker run -d --name gitlab --net=project1_net \
--hostname gitlab \
-p 443:443 -p 80:80 -p 2222:22 \
--restart always \
--volume /data/docker-volume/gitlab/config:/etc/gitlab \
--volume /data/docker-volume/gitlab/logs:/var/log/gitlab \
--volume /data/docker-volume/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:latest

gitlab-runner

gitlab-ci是gitlab的持續集成服務,gitlab-runner用於運行gitlab-ci的任務。

gitlab-runner支持很多種運行任務的方式(稱為Executors),目前支持:SSH、Shell、Parallels、VirtualBox、Docker、Docker Machine(auto-scaling)、Kubernetes、Custom。本文選用Docker方式。

參考鏈接-Gitlab持續集成的各種方式選擇參考

參考鏈接-在Gitlab使用Docker持續集成的方式

Gitlab-runner容器

現在開始創建gitlab-runner容器。

# 啟動gitlab-runner容器
docker run -d --name gitlab-runner --net=project1_net \
--restart always \
-v /data/docker-volume/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

注冊Gitlab-runner

注冊gitlab-runner。Admin Area -> Overview -> Runners

docker exec -it gitlab-runner gitlab-runner register -n \
--url GITLAB-REGISTER-URL \
--registration-token GITLAB-REGISTER-TOKEN \
--executor docker \
--description "Docker Runner" \
--docker-image "sonarsource/sonar-scanner-cli:latest" \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock

Sonarqube gitlab integration

使用gitlab進行認證

配置gitlab OAuth

登錄Gitlab,地址為Docker宿主機80端口。默認賬號為root,密碼為初次打開頁面時設置的密碼。

登錄后,如果沒有需求,建議先將Continuous Integration and Deployment Auto DevOps關閉。

Admin Area -> Settings -> CI/CD -> Expand -> Default to Auto DevOps pipeline for all projects選項去掉並記得保存

中文語言設置點擊個人頭像下拉框、Settings、Preferences、Localization。

下面開始設置Gitlab OAuth:

Admin Area -> Applications -> New Application

Name:字面意思

Redirect URI:回調地址。HTTP://SONAR_ADDRES + /oauth2/callback/gitlab;如果版本不同或許可能存在差異,具體可以看官方文檔。

Scopes:僅啟用委托認證勾選read_user,需要組同步則同時勾選api。

其他選項根據需求勾選。

提交后保存Application IDSecret

配置sonarqube ALM Integrations

sonarqube地址為docker宿主機地址+9000端口,默認賬號密碼為admin。

首先在通用設置中配置好Server base URL,此地址必須和Gitlab Redirect URI(回調地址)的協議+主機域名(或IP)是一致的,或者先在這里配置好之后再去配置或修改Gitlab Redirect URI。

配置 -> 通用配置 -> 通用

Server base URL:sonarqube的公共訪問地址。

配置ALM Integrations

配置 -> 通用配置 -> ALM Integrations -> Gitlab

Enabled:啟用。

GitLab URL:Gitlab地址。

Application ID:在Gitlab applications中創建的application id。

Secret:在Gitlab applications中創建的application Secret。

其他選項根據需求勾選。

確認無誤后退出賬號,點擊登錄后則會看到使用gitlab登錄。

創建sonarqube project

語言包和語言分析規則

安裝本地化語言包如以下同樣步驟,在應用市場中搜索chinese

分析語言首先需要安裝一個分析語言規則插件。

配置 -> 應用市場(marketplace)-> 搜索項目用到的主要語言並安裝

基於網絡原因,可能會需要一定時間。安裝完如果無法啟動,可能是下載的插件包不完整,可以手動下載將插件包放到/data/docker-volume/sonarqube/extensions/plugins目錄下重啟docker容器即可。

手動下載地址:sonarplugins

創建分析項目

在sonarqube web界面中點擊新建項目,輸入項目標識(例如:myproject)和顯示名稱(例如:myproject),創建一個TOKEN、輸入TOKEN名稱(例如:myproject)后點擊創建會生成TOKEN串、保存TOKEN串。

然后配置gitlab-ci。

Gitlab-ci

通過以上配置之后則在Gitlab中能夠看到已經有一個注冊的Runner。

現在新創建一個項目,創建完成后在Project overview、Details頁面中,可以看到有一個CI/CD configuretion選項,點擊按鈕添加.gitlab-ci.yml文件配置內容:

image:
  name: sonarsource/sonar-scanner-cli:latest
  entrypoint: [""]
variables:
  SONAR_TOKEN: "6d119e3e0798302753b652e06d52d2356ee9001d"  # 在sonarqube中創建項目時生成的TOKEN
  SONAR_HOST_URL: "http://172.16.0.12:9000"
  GIT_DEPTH: 0
sonarqube-check:
  stage: test
  script:
    - sonar-scanner -X -Dsonar.qualitygate.wait=true -Dsonar.projectKey=myproject # sonarqube中項目的標識
  allow_failure: true
  only: # 僅檢測master合並請求和master分支代碼提交,sonarqube-ce版本只支持分析master分支
    - merge_requests
    - master

之后提交代碼至master,在gitlab的項目詳情界面、CI/CD選項、Jobs中可以看到以前和現在的任務。

點擊任務的Status列中任務狀態的passedfailed可以看到任務運行情況以及輸出的信息或錯誤,從而進行調整。

任務運行情況

任務運行詳情:

任務詳情1

任務運行完成之后,則可以在sonarqube中看到代碼檢測情況:

任務詳情2

如果代碼有問題,則可以點擊項目進行詳細查看,進而改正不規范的地方或修復錯誤。

可能出現的問題

gitlab-ci任務運行詳情中出現錯誤

ERROR: Error during SonarQube Scanner execution
QUALITY GATE STATUS: FAILED - View details on http://xxxx/dashboard?id=myproject

正常錯誤。代表檢測的代碼有問題,具體查看sonarqube中的分析報告,然后修改代碼,如果代碼修改的符合了檢測規范、則提交之后會顯示檢測通過(Passed)。

sonar-scanner-cli無法連接到sonarqube

  • 出現類似Caused by: java.net.SocketTimeoutException: connect timed out錯誤

sonar-scanner-cli無法連接到sonarqube主機或服務,檢查服務是否正常、是否有防火牆、等。

  • 出現類似Caused by: java.net.UnknownHostException: sonar.ioops.net: Name or service not known錯誤

sonar-scanner-cli無法無法解析配置的sonarqube的域名地址。可以在gitlab-runner中注冊runner時指定--dokcer-dns,此dns需要能夠解析sonarqube域名。

docker exec -it gitlab-runner gitlab-runner register -n \
--url GITLAB-REGISTER-URL \
--registration-token GITLAB-REGISTER-TOKEN \
--executor docker \
--description "Docker Runner" \
--docker-image "sonarsource/sonar-scanner-cli:latest" \
--dokcer-dns 172.16.0.253 \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock
  • 出現類似No route to host(Host unreachable)問題

參考鏈接頁面中搜索跳轉至#Networking標題,其中有關於Network的相關說明。

參考鏈接-Docker Executor

如果以上幫助不能解決你的問題:

  1. 嘗試在gitlab項目中修改.gitlab-ci.yml文件中sonarqube服務的連接地址為sonarqube容器地址(默認為自動分配的容器地址),即可測試出網絡問題。

  2. 嘗試在gitlab-runen注冊時使用--docker-network-mode等參數指定網絡。

  3. 嘗試將gitlab-runner部署到其他Docker主機然后注冊(配置sonar-scanner-cli),連接當前主機通過nginx代理暴露或通過docker -p參數暴露的sonarqube服務。

缺少語言分析插件

  • 出現類似Caused by: java.lang.ClassNotFoundException: org.sonarsource.analyzer.commons.RuleMetadataLoader錯誤

下載的語言分析插件包不完整,刪除重新下載或前往sonarplugins手動下載。

/data/docker-volume/sonarqube/extensions/plugins為插件目錄,刪除目錄內對應的插件重啟docker容器即可。

  • 缺少語言分析插件
Unable to load component class org.sonar.scanner.report.MetadataPublisher

該段錯誤最后已經告知了原因:No quality profiles have been found, you probably don't have any language plugin installed.

安裝你要分析的語言插件即可。

由於編碼引起的問題

ERROR: Caused by: File [...] can't be indexed twice. Please check that inclusion/exclusion patterns produce disjoint sets for main and test files

此問題可能是由於編碼引起。

參數sonar.sourceEncoding:

Encoding of the source files. Ex: UTF-8, MacRoman, Shift_JIS. This property can be replaced by the standard property project.build.sourceEncoding in Maven projects. The list of available encodings depends on your JVM.

默認使用系統編碼。

可以在gitlab-ci配置文件中sonar-scanner選項處添加-Dsonar.sourceEncoding=UTF-8,使檢測時使用指定編碼。

如果指定編碼無效,那需要編譯sonar-scanner-cli鏡像,制作新的容器鏡像:

FROM sonarsource/sonar-scanner-cli:latest
ENV LANG C.UTF-8

編譯Dockerfile。

docker build -t ioops/sonar-scanner-cli .

接着在gitlab-runner容器中取消之前注冊的runner。鑒於我們只注冊了一個runner,直接--all-runners參數取消所有注冊的runner。

然后重新注冊runners注冊Gitlab-runner注意注冊的時候記得把image改為剛才編譯的鏡像(ioops/sonar-scanner-cli)

docker exec -it gitlab-runner \
gitlab-runner unregister \
--all-runners

然后在gitlab項目中.gitlab-ci.yml配置文件中指定使用剛才編譯的鏡像

最后保存提交.gitlab-ci.yml則會解決此問題。

參考鏈接-參數配置

不想檢測某些類型的文件

直接在sonarqube web頁面 配置->通用配置->排除 中進行設置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM