【问题标题】:Sonarqube quality gate stuck on pending when inside jenkins pipeline node在詹金斯管道节点内时,Sonarqube 质量门卡在待处理状态
【发布时间】:2018-07-21 20:10:15
【问题描述】:

我们正在尝试将 Sonarqube 扫描添加为 Jenkins 流水线脚本的一部分。 我们有一个多模块 maven 项目,我们使用 Maven Sonarqube 插件来运行聚合扫描。为了启动扫描,我们按照 Sonarqube 文档中的说明进行操作,如 here 所示(向下滚动到页面末尾)。

所以管道脚本看起来像这样:

node {
    stage('SonarQube analysis') {
        withSonarQubeEnv('My SonarQube Server') {
            sh 'mvn clean package sonar:sonar'
        }
    }
}
stage("Quality Gate") {
    timeout(time: 1, unit: 'HOURS') { 
        def qg = waitForQualityGate() 
        if (qg.status != 'OK') {
            error "Pipeline aborted due to quality gate failure: ${qg.status}"
        }
    }
}

它按预期工作。但由于我们在多个文件中使用它,我们希望尽可能少地重复代码,因此我们希望将它放在节点中,如下所示:

node {
    stage('SonarQube analysis') {
        withSonarQubeEnv('My SonarQube Server') {
            sh 'mvn clean package sonar:sonar'
        }
    }
    stage("Quality Gate") {
        timeout(time: 1, unit: 'HOURS') { 
            def qg = waitForQualityGate() 
            if (qg.status != 'OK') {
                error "Pipeline aborted due to quality gate failure: ${qg.status}"
            }
        }
    }
}

但由于某种原因,这会使质量门卡在 PENDING 状态,直到达到超时。 我试图了解为什么会发生这种情况,以及可以做些什么来避免将质量门检查移到节点之外。

任何帮助将不胜感激!

【问题讨论】:

  • 将等待步骤放入节点不是一个好主意。该构建将不必要地持有一个代理(在等待阶段可能由另一个构建使用)。只需将调用放在 node 中,您如何减少重复?
  • 我们在节点内部有一个函数调用(来自另一个文件)来进行构建,我们希望等待阶段成为函数的一部分,据我所知,我们无法创建在没有节点加载的情况下调用不同文件中的函数。如果我错了,请纠正我,因为我是新手。
  • 您可以使用readTrustednode 之外的CSM 签出中加载任何文件。

标签: jenkins sonarqube jenkins-pipeline sonarqube-scan


【解决方案1】:

waitForQualityGate 向 SonarQube 服务器执行 HTTP call

确保您的构建节点对您的 SonarQube 实例具有 HTTP 访问权限(有权访问它的 Jenkins 主节点并不意味着构建节点也拥有它)。

无论如何,正如我在评论中所说,在 node 中使用等待步骤通常不是一个好主意。

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题,我通过在waitForQualityGate stage 之前添加 sleep 来修复它

    sleep 10
    stage("Quality Gate") {
            timeout(time: 1, unit: 'HOURS') { 
                def qg = waitForQualityGate() 
                if (qg.status != 'OK') {
                    error "Pipeline aborted due to quality gate failure: ${qg.status}"
                }
            }
        }
    

    【讨论】:

    • 如果您的分析没有在这 10 秒内完成怎么办? ;) 最好添加一个等待“x”的重试机制
    【解决方案3】:

    这可能是一种更好的重试方式。

    def retryForTimeoutExceeded(count = 3, Closure closure) {
        for (int i = 1; i <= count; i++) {
            try {
                closure()
                break
            } catch (FlowInterruptedException error) {
                int retriesLeft = count - i
                def hasTimeoutExceeded = error.causes[0].getClass().toString() == 'class org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout'
                println "Timeout Exceeded for clousre.\nRetries left: $retriesLeft"
                if (retriesLeft == 0 || !hasTimeoutExceeded) {
                    throw error
                }
            }
        }
    }
    
    stage("Quality Gate") {
            retryForTimeoutExceeded {
                timeout(time: 5, 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 sonar quality gate failure: ${qg.status}"
                    }
                }
            }
        }
    

    可以相应地配置超时

    【讨论】:

      猜你喜欢
      • 2021-07-07
      • 2018-01-23
      • 2017-06-22
      • 2019-10-21
      • 1970-01-01
      • 2019-07-20
      • 2021-09-12
      • 2017-06-24
      • 2020-07-21
      相关资源
      最近更新 更多