Hi mọi người, hôm nay mình sẽ chia sẻ một ít kinh nghiệm cài đặt SonarQube trên môi trường CentOS 7 và cách tích hợp SonarQube trên Jenkins để quét source code và tạo Code Quality Gate.
1. Cài đặt SonarQube
Mình có dựa vào script từ gist của một anh DEV mà lâu quá mình không lưu lại link (Nếu anh có vô tình đọc bài này nếu có thể comment em để em note tác giả nhé, em cảm ơn ^^) tạo một script để cài đặt SonarQube mọi người cần định nghĩa phiên bản cũng như lưu ý giúp mình cài đặt phiên bản Java tương thích.
- Cài đặt phiên bản Java lưu ý cài bản openjdk-devel giúp mình nhé
- Cài đặt database PostgreSQL
- Nhớ đổi thông tin password nhé mình để mặc định xxxxxx
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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <span class="token shebang important">#!/bin/bash</span> <span class="token comment"># This script install sonarqube in your RHEL/Centos7 System.</span> <span class="token keyword">function</span> <span class="token function-name function">install_postgres</span> <span class="token punctuation">{</span> <span class="token comment"># Install PostgreSQL repository</span> yum <span class="token function">install</span> -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm <span class="token comment">#Install PostgreSQL database server </span> yum -y <span class="token function">install</span> yum -y <span class="token function">install</span> postgresql13-server postgresql13 postgresql13-contrib <span class="token comment"># Initialize the database</span> /usr/pgsql-13/bin/postgresql-13-setup initdb <span class="token comment"># Edit the /var/lib/pgsql/13/data/pg_hba.conf to enable MD5-based authentication</span> <span class="token function">cat</span> <span class="token operator">>></span> /var/lib/pgsql/13/data/pg_hba.conf <span class="token operator"><<</span><span class="token string">EOF # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 md5 # IPv6 local connections: host all all ::1/128 md5 EOF</span> <span class="token comment"># Start PostgreSQL server and enable</span> systemctl start postgresql-13 systemctl <span class="token builtin class-name">enable</span> postgresql-13 <span class="token comment">#Change the password for the default PostgreSQL user.</span> <span class="token builtin class-name">echo</span> -e <span class="token string">"xxxxxx<span class="token entity" title="n">n</span>xxxxxx"</span> <span class="token operator">|</span> <span class="token function">passwd</span> postgres <span class="token comment">#Switch to the postgres user.</span> <span class="token function">su</span> - postgres <span class="token comment">#Create a new user by typing</span> createuser sonar <span class="token comment">#Set a password for the newly created user for SonarQube database.</span> psql -c <span class="token string">"ALTER USER sonar WITH ENCRYPTED password 'xxxxxx'"</span><span class="token punctuation">;</span> <span class="token comment"># Create a new database for PostgreSQL database</span> psql -c <span class="token string">"CREATE DATABASE sonar OWNER sonar;"</span> <span class="token comment">#Exit from the psql shel and exit user .</span> <span class="token builtin class-name">exit</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function-name function">update_install_java</span> <span class="token punctuation">{</span> <span class="token comment">#update package</span> yum update -y <span class="token comment">#yum install java</span> yum -y <span class="token function">install</span> java-11-openjdk-devel <span class="token function">wget</span> <span class="token function">unzip</span> <span class="token function">vim</span> net-tools <span class="token function">cp</span> /etc/profile /etc/profile_backup <span class="token builtin class-name">echo</span> <span class="token string">'export JAVA_HOME=/usr/lib/jvm/jre-11-openjdk'</span> <span class="token operator">|</span> <span class="token function">sudo</span> <span class="token function">tee</span> -a /etc/profile <span class="token builtin class-name">echo</span> <span class="token string">'export JRE_HOME=/usr/lib/jvm/jre'</span> <span class="token operator">|</span> <span class="token function">sudo</span> <span class="token function">tee</span> -a /etc/profile <span class="token builtin class-name">source</span> /etc/profile <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function-name function">install_sonar_config</span> <span class="token punctuation">{</span> <span class="token comment"># Use temp folder</span> <span class="token builtin class-name">cd</span> /tmp <span class="token comment"># pull repo sonarqube</span> <span class="token function">wget</span> https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.5.0.56709.zip <span class="token comment"># install SonarQube at /opt/sonarqube</span> <span class="token function">unzip</span> -o -j sonarqube-9.5.0.56709.zip -d /tmp/sonarqube-9.5.0.56709 <span class="token function">mv</span> /tmp/sonarqube-9.5.0.56709/sonarqube-9.5.0.56709 /opt/sonarqube <span class="token comment"># Create sonar user and sonar group</span> <span class="token function">groupadd</span> sonar <span class="token function">useradd</span> -c <span class="token string">"Sonar System User"</span> -d /opt/sonarqube/ -g sonar -s /bin/bash sonar <span class="token function">sudo</span> <span class="token function">chown</span> -R sonar:sonar /opt/sonarqube/ <span class="token comment"># Make a backup configuration file.</span> <span class="token function">cp</span> /opt/sonarqube/conf/sonar.properties /opt/sonarqube/conf/sonar.properties.bka <span class="token function">cat</span> <span class="token operator">>></span> /opt/sonarqube/conf/sonar.properties <span class="token operator"><<</span> <span class="token string">EOF # Database information sonar.jdbc.username=sonar sonar.jdbc.password=xxxxxx sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonar EOF</span> <span class="token comment"># Change user to run Sonar</span> <span class="token function">sed</span> -i <span class="token string">'s/#RUN_AS_USER=/RUN_AS_USER=sonar/g'</span> /opt/sonarqube/bin/linux-x86-64/sonar.sh <span class="token comment"># Make a file to manage Sonar service via systemctl</span> <span class="token function">cat</span> <span class="token operator">></span> /etc/systemd/system/sonar.service <span class="token operator"><<</span> <span class="token string">EOF [Unit] Description=SonarQube service After=syslog.target network.target [Service] Type=forking ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop User=sonar Group=sonar Restart=always LimitNOFILE = 65536 [Install] WantedBy=multi-user.target EOF</span> <span class="token comment">#Allow the required HTTP port through the system firewall.</span> <span class="token comment"># sudo firewall-cmd --add-service=http --permanent</span> <span class="token comment"># sudo firewall-cmd --reload</span> <span class="token comment"># Set vm.max_map_count</span> <span class="token builtin class-name">echo</span> <span class="token string">'vm.max_map_count=262144'</span> <span class="token operator">>></span> /etc/sysctl.conf sysctl -p <span class="token comment"># Stop firewalld</span> systemctl stop firewalld <span class="token comment"># Start sonarqube</span> systemctl start sonar systemctl <span class="token builtin class-name">enable</span> sonar systemctl status sonar <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function-name function">install_auto_sonar</span> <span class="token punctuation">{</span> update_install_java install_postgres install_sonar_config <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function-name function">main</span> <span class="token punctuation">{</span> <span class="token assign-left variable">OS</span><span class="token operator">=</span><span class="token variable"><span class="token variable">$(</span> <span class="token function">cat</span> /etc/*-release <span class="token operator">|</span> <span class="token function">grep</span> <span class="token string">'NAME'</span> <span class="token operator">|</span> <span class="token function">tr</span> <span class="token punctuation">[</span>:upper:<span class="token punctuation">]</span> <span class="token punctuation">[</span>:lower:<span class="token punctuation">]</span> <span class="token operator">|</span> <span class="token function">grep</span> -Poi <span class="token string">'(ubuntu|centos|fedora|amazon)'</span> <span class="token operator">|</span> <span class="token function">uniq</span> <span class="token variable">)</span></span> <span class="token keyword">if</span> <span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token environment constant">$EUID</span> -ne <span class="token number">0</span> <span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span> <span class="token builtin class-name">echo</span> <span class="token string">"This script must be run as root"</span> <span class="token operator"><span class="token file-descriptor important">1</span>></span><span class="token file-descriptor important">&2</span> <span class="token builtin class-name">exit</span> <span class="token number">1</span> <span class="token keyword">fi</span> <span class="token keyword">if</span> <span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token variable">$OS</span> <span class="token operator">==</span> <span class="token string">"centos"</span> <span class="token operator">||</span> <span class="token variable">$OS</span> <span class="token operator">==</span> <span class="token string">"amazon"</span> <span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span> install_auto_sonar <span class="token builtin class-name">echo</span> <span class="token string">"[SUCCESS] Sonar installed complete!"</span> <span class="token keyword">else</span> <span class="token builtin class-name">echo</span> <span class="token string">"[ERROR] This operating system is not supported."</span> <span class="token keyword">fi</span> <span class="token punctuation">}</span> main |
Sau khi cài đặt xong thì check lại status của SonarQube xem đã active chưa nhé bằng câu lệnh: systemctl status sonarqube
Mọi người muốn kiểm tra hoặc thay đổi cấu hình truy cập theo đường dẫn này nhé: /opt/sonarqube/conf/sonar.properties
2. Tích hợp triển khai SonarQube trên Jenkins
Cài đặt Plugin SonarQube Scanner trên Jenkins
Vào phần Manage Jenkins => Configure System
Đến mục SonarQube server và cài đặt các thông số cần thiết
Lưu ý phần token mình thực hiện 2 bước giúp mình: Đầu tiên đăng nhập vào site SonarQube để tạo token nhé
Bước 2: Truy cập phần Credentials => System => Gloabl để tạo ra secret key từ site SonarQube vừa lấy
Sau khi hoàn tất xong thì lần lượt tạo Job SonarQube để quét source code
Cấu hình Pipeline nhé mọi người
Thông tin pipeline mình đính kèm bên dưới
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 | pipeline{ agent any tools { maven 'Maven' jdk 'jdk11' } stages{ stage ('checkout'){ steps{ deleteDir() checkout scm } } stage('Build') { tools { jdk "JDK8" // the name you have given the JDK installation using the JDK manager (Global Tool Configuration) } steps { sh 'mvn compile' sh 'mvn clean' } } stage('SonarQube analysis') { tools { jdk "jdk11" // the name you have given the JDK installation using the JDK manager (Global Tool Configuration) } environment { scannerHome = tool 'SonarQube' // the name you have given the Sonar Scanner (Global Tool Configuration) jdk = tool name: 'jdk11' javahome = "${jdk}/jdk-11.0.2" } steps { withSonarQubeEnv(installationName: 'SonarQube') { // sh 'mvn sonar:sonar' withEnv(["JAVA_HOME=${ tool 'jdk11' }/jdk-11.0.2/","PATH+JAVA=${ tool 'jdk11'}/jdk-11.0.2/bin"]) { sh "echo JDK: ${jdk}" sh "echo JAVA_HOME: $JAVA_HOME" // note that simple quote strings are not evaluated by Groovy // substitution is done by shell script using environment sh '$JAVA_HOME/bin/java -version' sh 'mvn clean package' sh 'mvn sonar:sonar -Dsonar.projectKey=Project_Backend -Dsonar.host.url=http://xx.xx.xx.xx:9000 -Dsonar.login=xxx' } } timeout(time: 60, unit: 'MINUTES') { waitForQualityGate abortPipeline: true } } } } } |
Lưu ý dòng mvn sonar:sonar giúp mình nhé là project mọi người đã tạo trên SonarQube, sau khi tạo sẽ có dòng token scan này nhớ lưu lại cho các lần sử dụng sau này.
Tạo mới project sẽ theo các bước bên dưới, đầu tiên mình tạo manual project và chọn Localy project nhé bà con
Dòng token mình lưu ý với mọi người chính là dòng khi khởi tạo project này.
3. Tạo Webhook cho SonarQube Job trên Jenkins
Ok đến đây là hoàn tất quá trình cài đặt và thiết lập 1 job pipeline trên Jenkins nhưng SonarQube có 1 thiết lập cuối cùng chính là tạo webhook để bắn event cho Jenkins biết là Sonar đã quét xong vui lòng cập nhật trạng thái cho Job là thành công hay thất bại. Trong phần Project Settings mọi người chọn đến webhooks nhé.
Lưu ý đường dẫn webhook trên Jenkins sẽ là http://jenkins-host:port/sonarqube-webhook/ nhé mọi người, khi truy cập trên giao diện sẽ báo như hình
Okie giờ bắt đầu bật job lên và chờ thành quả thui nếu không có Webhook thì job sẽ chạy đến lúc bị timeout mới dừng nhé mọi người.
Trên Sonar mọi người truy cập Project Settings => Background Tasks để check trạng thái job quét nhé
Ah thêm một lưu ý với những ai quét source code Java thì nên thêm cấu hình ignore những thư mục source không muốn quét để tăng tốc độ lên nhé. Sample template như hình bên dưới của mình.
Cảm ơn mọi người đã follow đến dòng này, hẹn gặp mọi người trong bài viết lần sau nhé ^^
Link bài viết của mình: https://gociter.wordpress.com/2022/09/29/cai-dat-cau-hinh-sonarqube-tren-jenkins-va-tao-webhook-sonarqube-job/