队列中的多个管道使用相同的执行程序,一个脱机

时间:2018-02-13 16:44:50

标签: jenkins jenkins-pipeline

我觉得这肯定是某人之前遇到的情况,但我无法为我的用例考虑一个非平凡的解决方案:

  • 让我们说我有两个管道,P1和P2,它们都需要相同的两个执行器/从机/节点A和B
  • P1首先进入队列并同时接受A和B并开始并行(使用并行)
  • 然后P2进入队列,而A和B正在使用,仍然是P1; A和B仍在线,但P2无法使用(你可以 看到它等待执行器在控制台中可用,为 例如)
  • 但是,B失败并且节点在失败时脱机
  • P1完成,A最终通过,B失败并取得节点 脱机。
  • 也许,根据时间安排,P2在通过时开始使用A.
  • P2将运行A完成,但将一直等到节点B 再次上线

如何在管道P2中检查节点B是否处于脱机状态并且刚刚爆发?

如果节点在P2开始时处于离线状态,则很容易检查并排除它。但是,如果B在线进入队列并设置A和B的并行运行并等待它们可用并且其中一个脱机,那么管道如何通知它处于脱机状态并继续执行随你?似乎没有自动发生,我无法弄清楚如何检查自身离线的节点块(B检查它本身是否脱机)。

这是一个简单的管道groovy脚本,我帮助我弄清楚问题:

// Branches for parallel node runs
def branches = [:]
// Nodes.  In real setup this would only contain nodes that are online at the time the pipeline runs
def node_names = ["A", "B"]
// Short sleep time of 15 seconds.  Later, it'll get reduced to 5 if the node name is B
def sleep_time = 15

// Loop through the nodes and create the data in the branch list to run in                             parallel on at the end
node_names.each { node_name ->
    println node_name

    branches["node_" + node_name] = {
        node(node_name) {
            // If the node that is being looked at is B then set the sleep time to 5 so that it runs
            // a shorter time than A.  Later, it's hardcoded to fail B and take it offline.  This way
            // A stays in the queue running and B is done and offline.
            def temp_sleep_time = sleep_time
            if (node_name == "B") {
                temp_sleep_time = 5
            }

            timestamps {
                stage("pre-build") {
                    println "Prebuilding " + node_name + "!"
                    sleep time: temp_sleep_time, unit: 'SECONDS'
                    println "Done with pre-build!"
                }
                stage("build") {
                    println "Building " + node_name + "!"
                    sleep time: temp_sleep_time, unit: 'SECONDS'
                    println "Done with build!"
                }
                stage("post-build") {
                    println "Post building " + node_name + "!"
                    if (node_name == "B") {
                        println "Taking node offline and failing build!"
                        takeNodeOffline("Derp", "B")
                        currentBuild.result = "FAILED"
                        return
                    }
                    sleep time: temp_sleep_time, unit: 'SECONDS'
                    println "Done with post-build!"
                }
            }
        }
    }
}
parallel branches

这可能吗?我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:0)

在你的例子中,P2确实会永远等待。但是当您使用每阶段代理方法而不是整个管道的一个代理时,P2在等待时不会占用任何资源。解决方案是您不仅提供一个,而且提供多个A和B节点。在这种情况下,B只会等待所有类型的节点都处于脱机状态,直到有一个节点可用,这是您通常想要的。除此之外,您可以使用超时指令在一定时间后终止管道或阶段:

options { timeout(time: 1, unit: 'HOURS') }

有关详细信息,请阅读https://jenkins.io/doc/book/pipeline/syntax/