You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jenkins流水线中先检查Agent Node是否在线再执行操作?

解决Jenkins矩阵流水线预检查Agent节点状态的方案

问题分析

你当前的尝试存在几个关键问题:

  • checkStatus方法中使用continue语法错误——continue仅适用于循环结构,不能在方法内直接调用
  • when表达式中checkStatus(${SLAVE})的语法错误——Groovy表达式中无需用${}包裹变量,直接使用SLAVE即可
  • 全局变量finalResult的作用域问题——方法内修改全局变量会引发并发风险,不符合流水线最佳实践
  • 矩阵轴不支持动态赋值,无法直接将筛选后的节点列表赋值给轴值

方案一:改进when条件的节点状态检查

调整节点状态检查逻辑,适配声明式流水线的when表达式,同时修正语法错误:

def isNodeAvailable(String nodeName) {
    def node = Jenkins.instance.getNode(nodeName)
    if (!node) {
        println "ERROR: 节点 ${nodeName} 不存在"
        return false
    }
    def computer = node.toComputer()
    if (!computer) {
        println "ERROR: 节点 ${nodeName} 无法关联到计算机实例"
        return false
    }
    if (computer.isOffline()) {
        println "ERROR: 节点 ${nodeName} 处于离线状态"
        return false
    }
    if (computer.countBusy() > 0) {
        println "WARNING: 节点 ${nodeName} 正忙,跳过执行"
        return false
    }
    return true
}

pipeline {
    agent none
    stages {
        stage('执行任务') {            
            matrix {
                agent { label "${SLAVE}" }
                when {
                    expression { isNodeAvailable(SLAVE) }
                }
                axes {
                    axis {
                        name 'SLAVE'
                        values "slv1", "slv2", "slv3"
                    }
                }
                stages {
                    stage('执行操作') {
                        steps {
                            sh 'hostname'
                        }
                    }
                }
            }
        }
    }
}

说明:

  • 移除全局变量,改为方法直接返回布尔值,避免作用域冲突
  • 替换continue为条件判断返回,修正语法错误
  • when表达式中直接传入SLAVE变量,简化语法
  • 增加computer实例为空的边界检查,提升鲁棒性

方案二:先筛选可用节点,再动态执行并行任务

若希望完全跳过不可用节点的任务分支,可先在脚本块中筛选可用节点,再通过并行指令替代矩阵(因矩阵轴不支持动态值):

pipeline {
    agent none
    stages {
        stage('筛选可用节点并执行') {
            steps {
                script {
                    // 定义目标节点列表
                    def targetNodes = ["slv1", "slv2", "slv3"]
                    // 筛选可用节点
                    def availableNodes = targetNodes.findAll { nodeName ->
                        def node = Jenkins.instance.getNode(nodeName)
                        if (!node) {
                            println "ERROR: 节点 ${nodeName} 不存在"
                            return false
                        }
                        def computer = node.toComputer()
                        if (!computer || computer.isOffline() || computer.countBusy() > 0) {
                            println "跳过节点 ${nodeName}:状态不可用"
                            return false
                        }
                        return true
                    }
                    // 构建并行任务映射
                    def parallelTasks = availableNodes.collectEntries { nodeName ->
                        ["任务-${nodeName}": {
                            node(nodeName) {
                                stage("在 ${nodeName} 执行操作") {
                                    sh 'hostname'
                                }
                            }
                        }]
                    }
                    // 执行并行任务
                    parallel parallelTasks
                }
            }
        }
    }
}

说明:

  • 先筛选可用节点,避免生成无效任务分支
  • 使用parallel指令替代矩阵,实现多节点并行执行
  • 每个并行任务绑定对应可用节点,执行目标操作

注意事项

  1. 确保Jenkins流水线脚本拥有节点读取权限(需在全局安全配置中允许脚本访问Jenkins实例)
  2. 若使用Jenkins 2.300+版本,可能需要调整脚本安全策略,允许调用Jenkins.instance相关方法
  3. 方案一仍会为每个节点创建矩阵分支,但通过when条件跳过不可用节点;方案二则完全不会生成不可用节点的任务分支

内容的提问来源于stack exchange,提问作者himneh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 01:06:26