6
votes

I configure Jenkins to work with sonarqube scanner. The scan are working fine. The jenkins pipeline is working and I don't have any isssue in the jenkins log.

SonarQube Scanner 3.0.3.778 Jenkins: 2.70 SonarQube Scanner for Jenkins plugin: 2.6.1

I use this code:

    stage('SonarQube analysis') {
        sh 'sed -ie "s|_PROJECT_|${PROJECT_CODE}|g" $WORKSPACE/_pipeline/sonar-project.properties'
        // requires SonarQube Scanner 3.0+
        def scannerHome = '/opt/sonar/bin/sonar-scanner';
        withSonarQubeEnv('mscodeanalysis') {
            sh "${scannerHome}/bin/sonar-scanner -Dproject.settings=$WORKSPACE/_pipeline/sonar-project.properties"
        }
    }
    }
    }
}
    }
    // No need to occupy a node
    stage("Quality Gate"){
        timeout(time: 15, unit: 'MINUTES') { // Just in case something goes wrong, pipeline will be killed after a timeout
        def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
            if (qg.status != 'OK') {
                error "Pipeline aborted due to quality gate failure: ${qg.status}"
            }
        }
    }

My problem come from Quality Gate. It never POST the json payload to jenkins. I don't see a json entry inside jenkins log. But I know the connection between jenkins and sonarqube server is working because I was able to send a POST using curl from the sonarqube VM.

Here the jenkins job output:

Timeout set to expire in 15 min
[Pipeline] {
[Pipeline] waitForQualityGate
Checking status of SonarQube task 'AV3irVJXpvBxXXNJYZkd' on server 'mscodeanalysis'
SonarQube task 'AV3irVJXpvBxXXNJYZkd' status is 'PENDING'
Cancelling nested steps due to timeout

Here is my payload that never reach jenkins pipeline: url: http://sonar-server:9000/api/ce/task?id=AV3irVJXpvBxXXNJYZkd

{"task":{"organization":"default-organization","id":"AV3irVJXpvBxXXNJYZkd","type":"REPORT","componentId":"AV3hrJeCfL_nrF2072FH","componentKey":"POOL-003","componentName":"POOL-003","componentQualifier":"TRK","analysisId":"AV3irVkZszLEB6PsCK9X","status":"SUCCESS","submittedAt":"2017-08-14T21:36:35+0000","submitterLogin":"jenkins","startedAt":"2017-08-14T21:36:37+0000","executedAt":"2017-08-14T21:36:38+0000","executionTimeMs":650,"logs":false,"hasScannerContext":true}}

I can't insert image but the Quality gate is Pass and the analysis task is success.

Let me know if I need to include more information. Thank you

7
To verify: you did configure a webhook to post back to Jenkins at the end of server-side processing, right? - G. Ann - SonarSource Team
Yes, I configure the webhook on this page: sonarqube-servert:9000/settings?category=webhooks Put nameL Jenkins and url: jenkins-int.domain.com/sonarqube-webhook - Marc
And your logs show the webhooks being fired? Also, do you have a proxy or firewall between the two boxes? - G. Ann - SonarSource Team
In which log can I see this? There is nothing in ce.log I do have a firewall between box. But curl -H "Content-Type: application/json" -X POST -d "PAYLOAD I already past" jenkins-int.domain.comt/sonarqube-webhook Reach jenkins server. I can see the POST in jenkins log. Also after the jenkins job run. I am able to see: SonarQube Quality Gate TEST-003 OK server-side processing: Success On jenkins job page - Marc

7 Answers

4
votes

The issue could be that Jenkins is using https with self-signed certificate. Then solution is:

  1. Generate truststore for SonarQube:

    keytool -import -trustcacerts -alias jenkins-host-name -file cert.crt -keystore sonarqube.jks
    

    keystore passw: password

    Where cert.crt - is certificate used for ssl for jenkins, jenkins-host-name - is a hostname of jenkins in the docker network (which is used in webhook)

  2. Add truststore to SonarQube Dockerfile:

    FROM sonarqube
    COPY sonarqube.jks /var/sonar_cert/
    COPY sonar.properties /opt/sonarqube/conf/sonar.properties
    
  3. Update sonar.properties

    sonar.ce.javaAdditionalOpts=-Djavax.net.ssl.trustStore=/var/sonar_cert/sonarqube.jks -Djavax.net.ssl.trustStorePassword=password
    

Then if you have a correct user and password for Jenkins provided in webhook URL everything should work.

Tried: Jenkins 2.107.2, SonarQube 7.1

1
votes

Here is a quick example of what we did to resolve this issue:

SonarQube randomly hangs at "pending" state. Telling it to retry refreshes it. We set it to 10 seconds in this example

maxRetry = 200
forloop (i=0; i<maxRetry; i++){
    try {
        timeout(time: 10, unit: 'SECONDS') {
            waitForQualityGate()
        }
    } catch(Exception e) {
        if (i == maxRetry-1) {
            throw e
        }
    }
}
1
votes

Was surprised to find that @Katone Vi's answer worked so well. Based on their answer we added a quick exit on success and used the DSL for the original request:

    stage('SonarQube') {
      steps {
        withSonarQubeEnv('SonarQube') {
          sh """
            ${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=XXX_${env.STAGE}_lambda
          """
        }

        script {
          Integer waitSeconds = 10
          Integer timeOutMinutes = 10
          Integer maxRetry = (timeOutMinutes * 60) / waitSeconds as Integer
          for (Integer i = 0; i < maxRetry; i++) {
            try {
              timeout(time: waitSeconds, unit: 'SECONDS') {
                def qg = waitForQualityGate()
                if (qg.status != 'OK') {
                  error "Sonar quality gate status: ${qg.status}"
                } else {
                  i = maxRetry
                }
              }
            } catch (Throwable e) {
              if (i == maxRetry - 1) {
                throw e
              }
            }
          }
        }
      }
    }
1
votes

If you have configured SonarQube to use a HTTP(S) proxy, make sure that your jenkins is either reachable through the proxy or is configured as a "non-proxy host". This can be done with the http.nonProxyHosts property or HTTP_NONPROXYHOSTS environment variable. See also the documentation for further information and syntax.

0
votes

If you are using Jenkinsfile, this is workaround:

define creadentials:

 environment { 
  CRED = credentials('jenkins_user_pass') 
 }

then use:

stage("Quality Gate") {
    steps {
         script {
                while(true){
                    sh "sleep 2"
                    def url="http://jenkinsURL/job/${env.JOB_NAME.replaceAll('/','/job/')}/lastBuild/consoleText";
                    def sonarId = sh script: "wget -qO- --content-on-error --no-proxy --auth-no-challenge --http-user=${CRED_USR} --http-password=${CRED_PSW} '${url}'  | grep 'More about the report processing' | head -n1 ",returnStdout:true
                    sonarId = sonarId.substring(sonarId.indexOf("=")+1)
                    echo "sonarId ${sonarId}"
                    def sonarUrl = "http://jenkinsURL/sonar/api/ce/task?id=${sonarId}"
                    def sonarStatus = sh script: "wget -qO- '${sonarUrl}' --no-proxy --content-on-error | jq -r '.task' | jq -r '.status' ",returnStdout:true
                    echo "Sonar status ... ${sonarStatus}"
                    if(sonarStatus.trim() == "SUCCESS"){
                        echo "BREAK";
                        break;
                    }
                    if(sonarStatus.trim() == "FAILED "){
                        echo "FAILED"
                        currentBuild.result = 'FAILED'
                        break;
                    }
                }
            }
        }
    }
0
votes

I have faced similar issue, while the quality Gate back-end activities in Sonar server takes less than 20 sec to complete its analysis.But quality gate fail/success response from sonar-webhook in jenkins job take lot of time and stuck.

 stage('Sonar:QG') {
            steps {
                **sleep(10)  /* Added 10 sec sleep that was suggested in few places*/**
                script{
                    timeout(time: 10, unit: 'MINUTES') {
                        def qg = waitForQualityGate abortPipeline: true
                        if (qg.status != 'OK') {
                            echo "Status: ${qg.status}"
                            error "Pipeline aborted due to quality gate failure: ${qg.status}"
                        }
                    }
                }
            }
        }

Essentially check below thing:- Webhook is configured in sonar or not :- SonarQube -> Administration -> Webhooks http://:/sonarqube-webhook/

or Use localhost in place of IP in http://locahlhost:port/sonarqube-webhook/ solves issue in my case.

-1
votes

Adding a sh 'sleep 10' between stage('SonarQube analysis') AND stage("Quality Gate") fix the issue. Now the jenkins job receive

Checking status of SonarQube task 'AV3rHxhp3io6giaQF_OA' on server 'sonarserver'
SonarQube task 'AV3rHxhp3io6giaQF_OA' status is 'SUCCESS'
SonarQube task 'AV3rHxhp3io6giaQF_OA' completed. Quality gate is 'OK'