Hi everyone, today I will share a little experience of installing SonarQube on CentOS 7 environment and how to integrate SonarQube on Jenkins to scan source code and create Code Quality Gate.
1. Install SonarQube
I relied on a script from a DEV guy’s gist, but I didn’t save the link for a long time (If you accidentally read this post, if you can comment, let me note the author, thank you ^^) create a script to To install SonarQube, everyone needs to define the version as well as help me install a compatible Java version.
- Install the Java version, please install the openjdk-devel version, please help me
- Install PostgreSQL database
- Remember to change your password information to default 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 |
After the installation is complete, check the status of SonarQube to see if it is active with the command: systemctl status sonarqube
Anyone who wants to check or change the access configuration can follow this path: /opt/sonarqube/conf/sonar.properties
2. Integrating SonarQube Deployment on Jenkins
Install SonarQube Scanner Plugin on Jenkins
Go to Manage Jenkins => Configure System
Go to the SonarQube server section and set the necessary parameters
Note the token part, I took 2 steps to help me: First log in to the SonarQube site to create a token
Step 2: Go to Credentials => System => Gloabl section to generate the secret key from the SonarQube site you just got
Once done, create a SonarQube Job in turn to scan the source code
Configure Pipeline, everyone
Information about my pipeline is attached below
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 } } } } } |
Note the line mvn sonar:sonar to help me is the project everyone created on SonarQube, after creating there will be this scan token line, remember to save it for later use.
Creating a new project will follow the steps below, first I create a manual project and select Localy project
The line of tokens I noticed to everyone is the line when creating this project.
3. Create Webhook for SonarQube Job on Jenkins
Ok, here is the process of completing the installation and setting up a job pipeline on Jenkins, but SonarQube has one final setup, which is to create a webhook to fire an event to let Jenkins know that Sonar has finished scanning, please update the status for the Job. success or failure. In the Project Settings section, choose to go to webhooks.
Note that the webhook path on Jenkins will be http://jenkins-host :port/sonarqube-webhook/ , everyone, when accessing the interface, it will report as shown.
Okie now start to turn on the job and wait for the results. If there is no Webhook, the job will run until the timeout stops, everyone.
On Sonar, everyone, go to Project Settings => Background Tasks to check the status of the scan job
Ah one more note for those who scan Java source code, they should add a configuration to ignore source folders that do not want to be scanned to increase speed. Sample template as shown below.
Thank you everyone for following this line, see you in the next post ^^
Link to my article: https://gociter.wordpress.com/2022/09/29/cai-dat-cau-hinh-sonarqube-tren-jenkins-va-tao-webhook-sonarqube-job/